diff --git a/.flake8 b/.flake8 index 7b2865c1..88077af0 100644 --- a/.flake8 +++ b/.flake8 @@ -6,7 +6,7 @@ exclude = __pycache__, build, dist, - doc/source/conf.py + docs/source/conf.py max-line-length = 79 # Ignore some style 'errors' produced while formatting by 'black' # https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 47f7a017..aaa88895 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,4 +10,4 @@ python: - requirements: requirements/docs.txt sphinx: - configuration: doc/source/conf.py + configuration: docs/source/conf.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 81011da6..293830dc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,59 @@ Release notes .. current developments +0.2.0 +===== + +**Added:** + +* Added a tutorial for MorphFuncy +* Functionality for refining lists and dictionaries +* Add docformatter config to pyproject.toml +* Python interfacing to call PDFmorph +* Returns dictionary of morph metrics (dict) and the r, gr pair for plotting or further manipulation +* General morph function that applies a user-supplied Python function to the y-coordinates of morph data +* Spelling check via Codespell in pre-commit +* Coverage report in each PR +* Added tutorial for MorphSqueeze and MorphFuncy +* Polynomial squeeze of x-axis of morphed data +* --multiple-morphs: morph multiple files against a single target +* New --smear option applies the smear morph directly to the function (without transforming to RDF). +* Support for python 3.13 +* manual information is added into online docs. +* Option to set tolerance for the morph refinement (default 1e-08). +* Squeeze morph now added to CLI. +* Error thrown when squeeze morph given improper inputs. +* Shifting morph for vertical and horizontal shifts. + +**Changed:** + +* Paths to diffpy.utils.parsers functions made explicitly to the file level. +* Changed docstrings location for MorphFuncy and MorphSqueeze +* Typo fixes in documentation. +* Tutorial documentation files split into three sections. +* --multiple changed to --multiple-targets for clarity +* Former --smear option renamed to --smear-pdf (converts PDF to RDF before applying the smear morph). +* Renamed PDFmorph to diffpy.morph +* Stretch disabled when squeeze is above polynomial order 0. +* Horizontal shift morph disabled when squeeze is enabled. +* Squeeze morph now removes duplicate/repeated and trailing commas before parsing. +* Swap colors for morph and target. Morph is now blue and target red. + +**Fixed:** + +* add temperature field to tutorial/additionalData. +* Multiple morphs/targets used to break given multiple subdirectories. +* reduce the line width limit to 79 +* Support ``scikit-package`` Level 5 standard (https://scikit-package.github.io/scikit-package/). +* import `loadData` and `deserialize_data` directly to integrate with `diffpy.utils(3.6.0)` + +**Removed:** + +* diffpy.morph manual removed. +* Support for python 3.10 +* manual. + + 0.1.3 ===== diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 00000000..bfdaca5a --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,57 @@ +cff-version: 1.2.0 +title: diffpy.morph +message: >- + If you use this software, please cite the manuscript + associated with this repository (will be included here + when published). +type: software +authors: + - given-names: Andrew + family-names: Yang + email: ayang2@caltech.edu + affiliation: Caltech + orcid: "https://orcid.org/0000-0003-0553-715X" + - given-names: Christopher + family-names: Farrow + orcid: "https://orcid.org/0000-0001-5768-6654" + - given-names: Chia-Hao + family-names: Liu + affiliation: Columbia University + orcid: "https://orcid.org/0000-0002-3216-0354" + - given-names: Luis + family-names: Kitsu + orcid: "https://orcid.org/0000-0002-9292-4416" + affiliation: University of Colorado Boulder + email: Luis.Kitsu@echemes.ethz.ch + - given-names: Simon + family-names: Billinge + email: sb2896@columbia.edu + affiliation: Columbia University + orcid: "https://orcid.org/0000-0002-9734-4998" +abstract: >- + diffpy.morph is an open-source and free-to-use Python + package that increases the insight researchers can obtain + when comparing experimentally measured 1D functions such + as diffraction patterns and atomic distribution functions + (PDFs). For example, it is often difficult to identify + whether or not structural changes have occurred between + two diffraction patterns or PDFs of the same material + measured at different temperatures due to the presence of + benign thermal effects such as lattice expansion and + increased atomic motion. These contribute large signals in + the difference curves and Rw factors when comparing two + curves, which can hide small but significant structural + changes. diffpy.morph does its best to correct for these + benign effects by applying simple transformations, or + “morphs”, to a diffraction pattern or PDF prior to + comparison. Other morphs are also possible such as + corrections for nanoparticle shape effects on the PDF. + diffpy.morph is model-independent and also could be used + on other non-diffraction spectra, though it has not been + extensively tested beyond powder diffraction patterns + and the PDF. +keywords: + - diffpy + - pdf + - data interpretation +license: BSD-3-Clause diff --git a/CODE_OF_CONDUCT.rst b/CODE-OF-CONDUCT.rst similarity index 100% rename from CODE_OF_CONDUCT.rst rename to CODE-OF-CONDUCT.rst diff --git a/README.rst b/README.rst index ec134b6c..9f69ba7f 100644 --- a/README.rst +++ b/README.rst @@ -35,34 +35,35 @@ .. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue :target: https://github.com/diffpy/diffpy.morph/issues -Python package for manipulating and comparing PDF profiles +Python package for manipulating and comparing diffraction data ``diffpy.morph`` is a Python software package designed to increase the insight -researchers can obtain from measured atomic pair distribution functions +researchers can obtain from measured diffraction data +and atomic pair distribution functions (PDFs) in a model-independent way. The program was designed to help a researcher answer the question: "Has my material undergone a phase transition between these two measurements?" -One approach is to compare the two PDFs in a plot and view the difference -curve underneath. However, significant signal can be seen in the -difference curve from benign effects such as thermal expansion (peak -shifts) and increased thermal motion (peak broadening) or a change in +One approach is to compare the two diffraction patterns in a plot +and view the difference curve underneath. However, significant signal can +be seen in the difference curve from benign effects such as thermal expansion +(peak shifts) and increased thermal motion (peak broadening) or a change in scale due to differences in incident flux, for example. ``diffpy.morph`` will do its best to correct for these benign effects before computing and -plotting the difference curve. One measured PDF (typically that collected -at higher temperature) is identified as the target PDF and the second -PDF is then morphed by "stretching" (changing the r-axis to simulate a +plotting the difference curve. One measured function (typically that collected +at higher temperature) is identified as the target function and the second +function is then morphed by "stretching" (changing the r-axis to simulate a uniform lattice expansion), "smearing" (broadening peaks through a uniform convolution to simulate increased thermal motion), and "scaling" (self-explanatory). ``diffpy.morph`` will vary the amplitude of the morphing transformations to obtain the best fit between the morphed and the target -PDFs, then plot them on top of each other with the difference plotted +functions, then plot them on top of each other with the difference plotted below. There are also a few other morphing transformations in the program. -Finally, we note that ``diffpy.morph`` should work on other spectra that are not -PDFs, though it has not been extensively tested beyond the PDF. +Finally, we note that ``diffpy.morph`` should work on other spectra, +though it has not been extensively tested beyond spectral data and the PDF. For more information about the diffpy.morph library, please consult our `online documentation `_. @@ -82,7 +83,7 @@ and typing into a terminal window or Windows command prompt. It is recommended that you consult online resources and become somewhat familiar before using ``diffpy.morph``. -``diffpy.morph`` can be run with Python 3.10 or higher. It makes use of several third party +``diffpy.morph`` can be run with Python 3.11 or higher. It makes use of several third party libraries that you'll need to run the app and its components. * `NumPy` - library for scientific computing with Python @@ -140,8 +141,7 @@ You may consult our `online documentation `. +For detailed instructions and full tutorial, see our `website `. Once the required software, including ``diffpy.morph`` is all installed, open up a terminal and check installation has worked properly by running :: @@ -154,13 +154,12 @@ If installed correctly, this last command should return the version of ``diffpy.morph`` that you have installed on your system. To begin using ``diffpy.morph``, run a command like :: - diffpy.morph + diffpy.morph -where both PDFs file are text files which contain PDF data, such as ``.gr`` +where both files are text files which contain two-column data, such as ``.gr`` or ``.cgr`` files that are produced by ``PDFgetX2``, ``PDFgetX3``, -or ``PDFgui``. Though some file extensions other than ``.gr`` or ``.cgr``, -but with the same content structure, have been shown to work with -``diffpy.morph``, it is recommended to stick with ``.gr`` files. +or ``PDFgui``. File extensions other than ``.gr`` or ``.cgr``, +but with the same content structure, also work with ``diffpy.morph``. Enjoy! @@ -193,7 +192,7 @@ trying to commit again. Improvements and fixes are always appreciated. -Before contributing, please read our `Code of Conduct `_. +Before contributing, please read our `Code of Conduct `_. Contact ------- diff --git a/TUTORIAL.rst b/TUTORIAL.rst index 433c301a..86b8a06d 100644 --- a/TUTORIAL.rst +++ b/TUTORIAL.rst @@ -132,10 +132,10 @@ Basic diffpy.morph Workflow superficial and in most cases can be ignored. We see that this has had hardly any effect on our PDF. To see - an effect, we restrict the ``rmin`` and ``rmax`` values to + an effect, we restrict the ``xmin`` and ``xmax`` values to reflect relevant data range by typing :: - diffpy.morph --scale=0.8 --smear=0.5 --rmin=1.5 --rmax=30 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + diffpy.morph --scale=0.8 --smear=0.5 --xmin=1.5 --xmax=30 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr Now, we see that the difference Rw = 0.204 and that the optimized ``smear=-0.084138``. @@ -151,7 +151,7 @@ Basic diffpy.morph Workflow 8. Finally, we will examine the stretch factor. Provide an initial guess by typing :: - diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.5 --rmin=1.5 --rmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.5 --xmin=1.5 --xmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr And noting that the difference has increased. Before continuing, see if you can see which direction (higher or lower) our initial @@ -160,7 +160,7 @@ Basic diffpy.morph Workflow If you cannot, type :: - diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.005 --rmin=1.5 --rmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.005 --xmin=1.5 --xmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr to observe decreased difference and then remove ``-a`` to see the optimized ``--stretch=0.001762``. We have now reached diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst deleted file mode 100644 index 0164ce20..00000000 --- a/doc/source/quickstart.rst +++ /dev/null @@ -1,404 +0,0 @@ -.. _quick_start: - -diffpy.morph Tutorial -##################### - -Welcome! This will be a quick tutorial to accquaint users with ``diffpy.morph`` -and some of what it can do. To see more details and definitions about -the morphs please see the publication describing ``diffpy.morph``. - -To be published: - -* - - -As we described in the README and installation instructions, please make -sure that you are familiar with working with your command line terminal -before using this application. - -Before you've started this tutorial, please ensure that you've installed -all necessary software and dependencies. - -In this tutorial, we will demonstrate how to use ``diffpy.morph`` to compare -two -PDFs measured from the same material at different temperatures. -The morphs showcased include "stretch", "scale", and "smear". - -Basic diffpy.morph Workflow -=========================== - - 1. Open your Terminal or Command Prompt. - - 2. If it's not active already, activate your diffpy.morph-equipped - conda environment by typing in :: - - conda activate - - - * If you need to list your available conda environments, - run the command ``conda info --envs`` or - ``conda env list`` - - * Run the ``diffpy.morph --help`` command and read over the - info on that page for a brief overview of some of what we will - explore in this tutorial. - - 3. Using the ``mkdir`` command, create a directory where you'll - store the tutorial PDF files and use the ``cd`` command to change - into that directory. You can download the tutorial files - :download:`here <../../tutorial/tutorialData.zip>`. - Then, ``cd`` into the ``tutorialData`` directory. - - * The files in this dataset were collected by Soham Banerjee - at Brookhaven National Laboratory in Upton, New York. - - * The files are PDF data collected on Iridium Telluride with - 20% Rhodium Doping (IrRhTe2) with the first file (01) collected - at 10K and the last (44) at 300K. The samples increase in - temperature as their numbers increase. The "C" in their names - indicates that they have undergone cooling. - - * Note that these files have the ``.gr`` extension, which - indicates that they are measured PDFs. The ``.cgr`` file - extension indicates that a file is a calculated PDF, such as - those generated by the - `PDFgui `_ - program. - - 4. First, we will run the ``diffpy.morph`` application without any morphing - and only using one PDF. Type the following command into your - command line :: - - diffpy.morph darkSub_rh20_C_01.gr darkSub_rh20_C_01.gr - - This should produce two PDF curves which are congruent, resulting - in a flat green line underneath them. - - 5. Now, we will see ``diffpy.morph`` run with two different PDFs and no - morphing. Type the following command into your command line :: - - diffpy.morph darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - Without morphing, the difference Rw = 0.407. This indicates that - the two PDFs vary drastically. - - * While running the ``diffpy.morph`` command, it is important - to remember that the first PDF file argument you provide - (in this case, ``darkSub_rh20_C_01.gr``) is the PDF which - will get morphed, while the second PDF file argument you - provide (here, ``darkSub_rh20_C_44.gr``) is the PDF which - acts as the model and does not get morphed. Hereinafter, - we will refer to the first PDF argument as the "morph" - and the second as the "target", as the ``diffpy.morph`` display - does. - - .. figure:: images/qs_tutorial_unmorphed.png - :align: center - :figwidth: 100% - - Using ``diffpy.morph`` to compare two different PDFs without morphing. - - 6. Now, we will start the morphing process, which requires us to - provide initial guesses for our scaling factor, Gaussian smear, - and stretch, separately. We will start with the scaling factor. - Begin by typing the command :: - - diffpy.morph --scale=2 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - Now, the difference Rw = 1.457, a significant increase from our - value previously. We must modify our initial value for the - scaling factor and do so until we see a reduction in the - difference Rw from the unmorphed value. Type :: - - diffpy.morph --scale=0.9 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - The difference Rw is now 0.351, lower than our unmorphed - example's value. To see ``diffpy.morph`` optimize the scale factor, - simply drop ``-a`` from the command and type :: - - diffpy.morph --scale=0.9 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - ``diffpy.morph``, given a reasonable initial guess, will use find the - optimal value for each morphing feature. Here, we see that - ``diffpy.morph`` displays ``scale = 0.799025`` in the command prompt, - meaning that it has found this to be the most optimal value for - the scale factor. The difference Rw = 0.330, indicating a - better fit than our reasonable initial guess. - - * It is the choice of the user whether or not to run values - before removing ``-a`` when analyzing data with ``diffpy.morph``. - By including it, you allow the possibility to move towards - convergence before allowing the program to optimize by - removing it; when including it, you may reach a highly - optimized value on the first guess or diverge greatly. - In this tutorial, we will use it every time to check - for convergence. - - .. figure:: images/qs_tutorial_scaled.png - :align: center - :figwidth: 100% - - ``diffpy.morph`` found an optimal value for the scale factor. - - 7. Now, we will examine the Gaussian smearing factor. We provide an - initial guess by typing :: - - diffpy.morph --scale=0.8 --smear=0.5 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - And viewing the results. We've tailored our scale factor to be - close to the value given by ``diffpy.morph``, but see that the difference - Rw has increased substantially due to our smear value. One - approach, as described above, is to remove the ``-a`` from the - above command and run it again. - - * Note: The warnings that the Terminal/Command Prompt - displays are largely numerical in nature and do not - indicate a physically irrelevant guess. These are somewhat - superficial and in most cases can be ignored. - - We see that this has had hardly any effect on our PDF. To see - an effect, we restrict the ``rmin`` and ``rmax`` values to - reflect relevant data range by typing :: - - diffpy.morph --scale=0.8 --smear=0.5 --rmin=1.5 --rmax=30 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - Now, we see that the difference Rw = 0.204 and that the optimized - ``smear=-0.084138``. - - * We restricted the r values because some of the Gaussian - smear effects are only visible in a fixed r range. We - chose this r range by noting where most of our relevant - data was that was not exponentially decayed by - instrumental shortcomings. - - We are getting closer to an acceptably close fit to our data! - - 8. Finally, we will examine the stretch factor. Provide an initial - guess by typing :: - - diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.5 --rmin=1.5 --rmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - And noting that the difference has increased. Before continuing, - see if you can see which direction (higher or lower) our initial - estimate for the stretch factor needs to go and then removing - the ``-a`` to check optimized value! - - If you cannot, type :: - - diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.005 --rmin=1.5 --rmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr - - to observe decreased difference and then remove ``-a`` to see - the optimized ``--stretch=0.001762``. We have now reached - the optimal fit for our PDF! - - .. figure:: images/qs_tutorial_morphed.png - :align: center - :figwidth: 100% - - The optimal fit after applying the scale, smear, and stretch morphs. - - 9. Now, try it on your own! If you have personally collected or - otherwise readily available PDF data, try this process to see if - you can morph your PDFs to one another. Many of the parameters - provided in this tutorial are unique to it, so be cautious about - your choices and made sure that they remain physically relevant. - -Enjoy the software! - -.. Additional diffpy.morph Functionality/Exploration -.. ------------------------------------------------- -.. TODO include undoped PDF example - -Extra Tutorials -=============== -``diffpy.morph`` has some more functionalities not showcased in the basic workflow above -(see `diffpy.morph --help` for an overview of these functionalities). -Tutorials for these additional functionalities are included below. Additional -files for these tutorials can be downloaded -:download:`here <../../tutorial/additionalData.zip>`. - -Performing Multiple Morphs --------------------------- - -It may be useful to morph a PDF against multiple targets: -for example, you may want to morph a PDF against multiple PDFs measured -at various temperatures to determine whether a phase change has occurred. -``diffpy.morph`` currently allows users to morph a PDF against all files in a -selected directory and plot resulting :math:`R_w` values from each morph. - -1. Within the ``additionalData`` directory, ``cd`` into the - ``morphsequence`` directory. Inside, you will find multiple PDFs of - :math:`SrFe_2As_2` measured at various temperatures. These PDFs are - from `"Atomic Pair Distribution Function Analysis: A primer" - `_. - -2. Let us start by getting the Rw of ``SrFe2As2_150K.gr`` compared to - all other files in the directory. Run :: - - diffpy.morph SrFe2As2_150K.gr . --multiple-targets - - The multiple tag indicates we are comparing PDF file (first input) - against all PDFs in a directory (second input). Our choice of file - was ``SeFe2As2_150K.gr`` and directory was the cwd, which should be - ``morphsequence``.:: - - diffpy.morph SrFe2As2_150K.gr . --multiple-targets --sort-by=temperature - -.. figure:: images/ex_tutorial_bar.png - :align: center - :figwidth: 100% - - Bar chart of :math:`R_W` values for each target file. Target files are - listed in ASCII sort order. - -3. After running this, we get chart of Rw values for each target file. - However, this chart can be a bit confusing to interpret. To get a - more understandable plot, run :: - - diffpy.morph SrFe2As2_150K.gr . --multiple-targets --sort-by=temperature - - This plots the Rw against the temperature parameter value provided - at the top of each file. Parameters are entries of the form - `` = `` and are located above - the ``r`` versus ``gr`` table in each PDF file.:: - - # SrFe2As2_150K.gr - [PDF Parameters] - temperature = 150 - wavelength = 0.1 - ... - -.. figure:: images/ex_tutorial_temp.png - :align: center - :figwidth: 100% - - The :math:`R_W` plotted against the temperature the target PDF was - measured at. - -4. Between 192K and 198K, the Rw has a sharp increase, indicating that - we may have a phase change. To confirm, let us now apply morphs - onto `` SrFe2As2_150K.gr`` with all other files in - ``morphsequence`` as targets :: - - diffpy.morph --scale=1 --stretch=0 SrFe2As2_150K.gr . --multiple-targets --sort-by=temperature - - Note that we are not applying a smear since it takes a long time to - apply and does not significantly change the Rw values in this example. - -5. We should now see a sharper increase in Rw between 192K and 198K. - -6. Go back to the terminal to see optimized morphing parameters from each morph. - -7. On the morph with ``SrFe2As2_192K.gr`` as target, ``scale = - 0.972085`` and ``stretch = 0.000508`` and with ``SrFe2As2_198K.gr`` - as target, ``scale = 0.970276`` and ``stretch = 0.000510``. These - are very similar, meaning that thermal lattice expansion (accounted - for by ``stretch``) is not occurring. This, coupled with the fact - that the Rw significantly increases suggests a phase change in this - temperature regime. (In fact, :math:`SrFe_2As_2` does transition - from orthorhombic at lower temperature to tetragonal at higher - temperature!). More sophisticated analysis can be done with - `PDFgui `_. - -8. Finally, let us save all the morphed PDFs into a directory - named ``saved-morphs``. :: - - diffpy.morph SrFe2As2_150K.gr . --scale=1 --stretch=0 --multiple-targets \ - --sort-by=temperature --plot-parameter=stretch \ - --save=saved-morphs - - Entering the directory with ``cd`` and viewing its contents with - ``ls``, we see a file named ``morph-reference-table.txt`` with data - about the input morph parameters and re- fined output parameters - and a directory named ``morphs`` containing all the morphed - PDFs. See the ``--save-names-file`` option to see how you can set - the names for these saved morphs! - -Nanoparticle Shape Effects --------------------------- - -A nanoparticle's finite size and shape can affect the shape of its PDF. -We can use ``diffpy.morph`` to morph a bulk material PDF to simulate these shape effects. -Currently, the supported nanoparticle shapes include: spheres and spheroids. - -* Within the ``additionalData`` directory, ``cd`` into the - ``morphShape`` subdirectory. Inside, you will find a sample Ni bulk - material PDF ``Ni_bulk.gr``. This PDF is from `"Atomic Pair - Distribution Function Analysis: - A primer" `_. - There are also multiple ``.cgr`` files with calculated Ni nanoparticle PDFs. - -* Let us apply various shape effect morphs on the bulk material to - reproduce these calculated PDFs. - - * Spherical Shape - 1. The ``Ni_nano_sphere.cgr`` file contains a generated - spherical nanoparticle with unknown radius. First, let us - plot ``Ni_blk.gr`` against ``Ni_nano_sphere.cgr`` :: - - diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr - - Despite the two being the same material, the Rw is quite large. - To reduce the Rw, we will apply spherical shape effects onto the PDF. - However, in order to do so, we first need the radius of the - spherical nanoparticle. - - 2. To get the radius, we can first observe a plot of - ``Ni_nano_sphere.cgr`` :: - - diffpy.morph Ni_nano_sphere.cgr Ni_nano_sphere.cgr - - 3. Nanoparticles tend to have broader peaks at r-values larger - than the particle size, corresponding to the much weaker - correlations between molecules. On our plot, beyond r=22.5, - peaks are too broad to be visible, indicating our particle - size to be about 22.4. The approximate radius of a sphere - would be half of that, or 11.2.:: - - diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr --radius=11.2 -a - - - 4. Now, we are ready to perform a morph applying spherical - effects. To do so, we use the ``--radius`` parameter :: - - diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr --radius=11.2 -a - - 5. We can see that the Rw value has significantly decreased - from before. Run without the ``-a`` tag to refine :: - - diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr --radius=11.2 - - 6. After refining, we see the actual radius of the - nanoparticle was closer to 12. - - * Spheroidal Shape - - 1. The ``Ni_nano_spheroid.cgr`` file contains a calculated - spheroidal Ni nanoparticle. Again, we can begin by plotting - the bulk material against our nanoparticle :: - - diffpy.morph Ni_bulk.gr Ni_nano_spheroid.cgr - - 2. Inside the ``Ni_nano_spheroid.cgr`` file, we are given that - the equatorial radius is 12 and polar radius is 6. This is - enough information to define our spheroid. To apply - spheroid shape effects onto our bulk, run :: - - diffpy.morph Ni_bulk.gr Ni_nano_spheroid.cgr --radius=12 --pradius=6 -a - - Note that the equatorial radius corresponds to the - ``--radius`` parameter and polar radius to ``--pradius``. - - 3. Remove the ``-a`` tag to refine. - -There is also support for morphing from a nanoparticle to a bulk. When -applying the inverse morphs, it is recommended to set ``--rmax=psize`` -where ``psize`` is the longest diameter of the nanoparticle. - -Bug Reports -=========== - -Please enjoy using our software! If you come across any bugs in the -application, please report them to diffpy-users@googlegroups.com. diff --git a/doc/Makefile b/docs/Makefile similarity index 100% rename from doc/Makefile rename to docs/Makefile diff --git a/doc/make.bat b/docs/make.bat similarity index 100% rename from doc/make.bat rename to docs/make.bat diff --git a/doc/manual/Makefile b/docs/manual/Makefile similarity index 100% rename from doc/manual/Makefile rename to docs/manual/Makefile diff --git a/docs/manual/README.txt b/docs/manual/README.txt new file mode 100644 index 00000000..9044a013 --- /dev/null +++ b/docs/manual/README.txt @@ -0,0 +1,3 @@ +This directory included files to build a PDF and HTML version of the diffpy.morph user manual. +We are no longer maintaining the manual or this directory, but all files are intact for legacy reasons. +All relevant information from the manual has been migrated to the website at https://www.diffpy.org/diffpy.morph. diff --git a/doc/manual/acknowledgements.texinfo b/docs/manual/acknowledgements.texinfo similarity index 100% rename from doc/manual/acknowledgements.texinfo rename to docs/manual/acknowledgements.texinfo diff --git a/doc/manual/disclaimer.texinfo b/docs/manual/disclaimer.texinfo similarity index 100% rename from doc/manual/disclaimer.texinfo rename to docs/manual/disclaimer.texinfo diff --git a/doc/manual/images/aspirin_smear.png b/docs/manual/images/aspirin_smear.png similarity index 100% rename from doc/manual/images/aspirin_smear.png rename to docs/manual/images/aspirin_smear.png diff --git a/doc/manual/images/aspirin_stretch.png b/docs/manual/images/aspirin_stretch.png similarity index 100% rename from doc/manual/images/aspirin_stretch.png rename to docs/manual/images/aspirin_stretch.png diff --git a/doc/manual/images/ex_tutorial_bar.png b/docs/manual/images/ex_tutorial_bar.png similarity index 100% rename from doc/manual/images/ex_tutorial_bar.png rename to docs/manual/images/ex_tutorial_bar.png diff --git a/doc/manual/images/ex_tutorial_download.png b/docs/manual/images/ex_tutorial_download.png similarity index 100% rename from doc/manual/images/ex_tutorial_download.png rename to docs/manual/images/ex_tutorial_download.png diff --git a/doc/manual/images/ex_tutorial_params.png b/docs/manual/images/ex_tutorial_params.png similarity index 100% rename from doc/manual/images/ex_tutorial_params.png rename to docs/manual/images/ex_tutorial_params.png diff --git a/doc/manual/images/ex_tutorial_shape_download.png b/docs/manual/images/ex_tutorial_shape_download.png similarity index 100% rename from doc/manual/images/ex_tutorial_shape_download.png rename to docs/manual/images/ex_tutorial_shape_download.png diff --git a/doc/manual/images/ex_tutorial_shape_sphere_zoomed.png b/docs/manual/images/ex_tutorial_shape_sphere_zoomed.png similarity index 100% rename from doc/manual/images/ex_tutorial_shape_sphere_zoomed.png rename to docs/manual/images/ex_tutorial_shape_sphere_zoomed.png diff --git a/doc/manual/images/ex_tutorial_stretch.png b/docs/manual/images/ex_tutorial_stretch.png similarity index 100% rename from doc/manual/images/ex_tutorial_stretch.png rename to docs/manual/images/ex_tutorial_stretch.png diff --git a/doc/manual/images/ex_tutorial_temp.png b/docs/manual/images/ex_tutorial_temp.png similarity index 100% rename from doc/manual/images/ex_tutorial_temp.png rename to docs/manual/images/ex_tutorial_temp.png diff --git a/doc/manual/images/morph_ex1.png b/docs/manual/images/morph_ex1.png similarity index 100% rename from doc/manual/images/morph_ex1.png rename to docs/manual/images/morph_ex1.png diff --git a/doc/manual/images/morph_ex2.png b/docs/manual/images/morph_ex2.png similarity index 100% rename from doc/manual/images/morph_ex2.png rename to docs/manual/images/morph_ex2.png diff --git a/doc/manual/images/nacl_example.agr b/docs/manual/images/nacl_example.agr similarity index 100% rename from doc/manual/images/nacl_example.agr rename to docs/manual/images/nacl_example.agr diff --git a/doc/manual/images/nacl_example.png b/docs/manual/images/nacl_example.png similarity index 100% rename from doc/manual/images/nacl_example.png rename to docs/manual/images/nacl_example.png diff --git a/doc/manual/images/pdfmorph_example.agr b/docs/manual/images/pdfmorph_example.agr similarity index 100% rename from doc/manual/images/pdfmorph_example.agr rename to docs/manual/images/pdfmorph_example.agr diff --git a/doc/manual/images/pdfmorph_example.png b/docs/manual/images/pdfmorph_example.png similarity index 100% rename from doc/manual/images/pdfmorph_example.png rename to docs/manual/images/pdfmorph_example.png diff --git a/doc/manual/images/pdfmorph_example.xcf b/docs/manual/images/pdfmorph_example.xcf similarity index 100% rename from doc/manual/images/pdfmorph_example.xcf rename to docs/manual/images/pdfmorph_example.xcf diff --git a/doc/manual/images/pdfmorph_smear.png b/docs/manual/images/pdfmorph_smear.png similarity index 100% rename from doc/manual/images/pdfmorph_smear.png rename to docs/manual/images/pdfmorph_smear.png diff --git a/doc/manual/images/pdfmorph_smear2.png b/docs/manual/images/pdfmorph_smear2.png similarity index 100% rename from doc/manual/images/pdfmorph_smear2.png rename to docs/manual/images/pdfmorph_smear2.png diff --git a/doc/manual/images/pdfmorph_stretch.png b/docs/manual/images/pdfmorph_stretch.png similarity index 100% rename from doc/manual/images/pdfmorph_stretch.png rename to docs/manual/images/pdfmorph_stretch.png diff --git a/doc/manual/images/qs_tutorial_download.png b/docs/manual/images/qs_tutorial_download.png similarity index 100% rename from doc/manual/images/qs_tutorial_download.png rename to docs/manual/images/qs_tutorial_download.png diff --git a/doc/manual/images/qs_tutorial_morphed.png b/docs/manual/images/qs_tutorial_morphed.png similarity index 100% rename from doc/manual/images/qs_tutorial_morphed.png rename to docs/manual/images/qs_tutorial_morphed.png diff --git a/doc/manual/images/qs_tutorial_scaled.png b/docs/manual/images/qs_tutorial_scaled.png similarity index 100% rename from doc/manual/images/qs_tutorial_scaled.png rename to docs/manual/images/qs_tutorial_scaled.png diff --git a/doc/manual/images/qs_tutorial_unmorphed.png b/docs/manual/images/qs_tutorial_unmorphed.png similarity index 100% rename from doc/manual/images/qs_tutorial_unmorphed.png rename to docs/manual/images/qs_tutorial_unmorphed.png diff --git a/doc/manual/make.bat b/docs/manual/make.bat similarity index 100% rename from doc/manual/make.bat rename to docs/manual/make.bat diff --git a/doc/manual/pdfmorph.pdf b/docs/manual/pdfmorph.pdf similarity index 100% rename from doc/manual/pdfmorph.pdf rename to docs/manual/pdfmorph.pdf diff --git a/doc/manual/pdfmorph.texinfo b/docs/manual/pdfmorph.texinfo similarity index 100% rename from doc/manual/pdfmorph.texinfo rename to docs/manual/pdfmorph.texinfo diff --git a/doc/manual/redistribution.texinfo b/docs/manual/redistribution.texinfo similarity index 100% rename from doc/manual/redistribution.texinfo rename to docs/manual/redistribution.texinfo diff --git a/doc/source/_static/.placeholder b/docs/source/_static/.placeholder similarity index 100% rename from doc/source/_static/.placeholder rename to docs/source/_static/.placeholder diff --git a/doc/source/api/diffpy.morph.morph_helpers.rst b/docs/source/api/diffpy.morph.morph_helpers.rst similarity index 100% rename from doc/source/api/diffpy.morph.morph_helpers.rst rename to docs/source/api/diffpy.morph.morph_helpers.rst index e8889166..73e864d3 100644 --- a/doc/source/api/diffpy.morph.morph_helpers.rst +++ b/docs/source/api/diffpy.morph.morph_helpers.rst @@ -11,18 +11,18 @@ diffpy.morph.morph_helpers package Submodules ---------- -diffpy.morph.morph_helpers.transformpdftordf module +diffpy.morph.morph_helpers.transformrdftopdf module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morph_helpers.transformpdftordf +.. automodule:: diffpy.morph.morph_helpers.transformrdftopdf :members: :undoc-members: :show-inheritance: -diffpy.morph.morph_helpers.transformrdftopdf module +diffpy.morph.morph_helpers.transformpdftordf module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morph_helpers.transformrdftopdf +.. automodule:: diffpy.morph.morph_helpers.transformpdftordf :members: :undoc-members: :show-inheritance: diff --git a/doc/source/api/diffpy.morph.morphs.rst b/docs/source/api/diffpy.morph.morphs.rst similarity index 84% rename from doc/source/api/diffpy.morph.morphs.rst rename to docs/source/api/diffpy.morph.morphs.rst index c4b55150..2baaa24e 100644 --- a/doc/source/api/diffpy.morph.morphs.rst +++ b/docs/source/api/diffpy.morph.morphs.rst @@ -11,42 +11,58 @@ diffpy.morph.morphs package Submodules ---------- -diffpy.morph.morphs.morphishape module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.morphs.morphscale module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphishape +.. automodule:: diffpy.morph.morphs.morphscale :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphchain module +diffpy.morph.morphs.morphshape module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphchain +.. automodule:: diffpy.morph.morphs.morphshape :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphresolution module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.morphs.morphshift module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphresolution +.. automodule:: diffpy.morph.morphs.morphshift :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphshape module +diffpy.morph.morphs.morphfuncy module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphshape +.. automodule:: diffpy.morph.morphs.morphfuncy :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphshift module +diffpy.morph.morphs.morphchain module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphshift +.. automodule:: diffpy.morph.morphs.morphchain + :members: + :undoc-members: + :show-inheritance: + +diffpy.morph.morphs.morphresolution module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.morph.morphs.morphresolution + :members: + :undoc-members: + :show-inheritance: + +diffpy.morph.morphs.morphstretch module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.morph.morphs.morphstretch :members: :undoc-members: :show-inheritance: @@ -59,34 +75,34 @@ diffpy.morph.morphs.morph module :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphrgrid module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.morphs.morphsqueeze module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphrgrid +.. automodule:: diffpy.morph.morphs.morphsqueeze :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphsmear module +diffpy.morph.morphs.morphrgrid module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphsmear +.. automodule:: diffpy.morph.morphs.morphrgrid :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphstretch module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.morphs.morphishape module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphstretch +.. automodule:: diffpy.morph.morphs.morphishape :members: :undoc-members: :show-inheritance: -diffpy.morph.morphs.morphscale module +diffpy.morph.morphs.morphsmear module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.morphs.morphscale +.. automodule:: diffpy.morph.morphs.morphsmear :members: :undoc-members: :show-inheritance: diff --git a/doc/source/api/diffpy.morph.rst b/docs/source/api/diffpy.morph.rst similarity index 89% rename from doc/source/api/diffpy.morph.rst rename to docs/source/api/diffpy.morph.rst index 01046993..0c2381a8 100644 --- a/doc/source/api/diffpy.morph.rst +++ b/docs/source/api/diffpy.morph.rst @@ -14,8 +14,8 @@ Subpackages .. toctree:: :titlesonly: - diffpy.morph.morphs diffpy.morph.morph_helpers + diffpy.morph.morphs Submodules ---------- @@ -36,18 +36,18 @@ diffpy.morph.morph_api module :undoc-members: :show-inheritance: -diffpy.morph.refine module -^^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.tools module +^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.refine +.. automodule:: diffpy.morph.tools :members: :undoc-members: :show-inheritance: -diffpy.morph.tools module -^^^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.morphpy module +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.tools +.. automodule:: diffpy.morph.morphpy :members: :undoc-members: :show-inheritance: @@ -60,10 +60,10 @@ diffpy.morph.morph_io module :undoc-members: :show-inheritance: -diffpy.morph.log module -^^^^^^^^^^^^^^^^^^^^^^^ +diffpy.morph.refine module +^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.morph.log +.. automodule:: diffpy.morph.refine :members: :undoc-members: :show-inheritance: @@ -75,3 +75,11 @@ diffpy.morph.morphapp module :members: :undoc-members: :show-inheritance: + +diffpy.morph.log module +^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.morph.log + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/conf.py b/docs/source/conf.py similarity index 98% rename from doc/source/conf.py rename to docs/source/conf.py index badd3318..64a5c046 100644 --- a/doc/source/conf.py +++ b/docs/source/conf.py @@ -24,6 +24,12 @@ except Exception: fullversion = "No version found. The correct version will appear in the released version." # noqa: E501 +# Import modules referenced in documentation +# (resolves `WARNING: autodoc: failed to import module`) +autodoc_mock_imports = [ + "diffpy.utils", +] + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use Path().resolve() to make it absolute, like shown here. # noqa: E501 diff --git a/docs/source/funcxy.rst b/docs/source/funcxy.rst new file mode 100644 index 00000000..4f157680 --- /dev/null +++ b/docs/source/funcxy.rst @@ -0,0 +1,181 @@ +.. _funcxy: + +Using funcxy with Commonly-Used Diffraction Software +#################################################### + +The general xy morph ``funcxy`` can be used to tune parameters +of many popular diffraction software functions. + +Below, we give templates for how one can use ``funcxy`` +with `PDFgetx3 `_ +and `PyFai `_. + +Getting a Better PDF with PDFgetx3 +================================== + +In PDFgetx3, the ``PDFGetter`` takes in a 1D diffraction +pattern I(Q) and returns a PDF G(r). + +There are many parameters you can specify, such as + - ``qmin``: Lower Q-cutoff for the Fourier transform giving the PDF + - ``qmax``: Upper Q-cutoff for the Fourier transform giving the PDF + - ``qmaxinst``: Upper Q-boundary for meaningful signal + - ``rpoly``: Approximately the low-r bound of meaningful G(r) values + +Furthermore, you can supply a background file ``backgroundfile`` +and subtract a scaled version of the background file by the +scaling factor ``bgscale``. + +We will showcase an example of how one would refine over the +``PDFGetter`` parameters using ``funcxy`` to obtain a PDF. + +Let's say you have a measured I(Q) with Q in angstroms of +glass (composition SiO2) named ``sample.chi`` taken on a +kapton background. We want to match a target calculated PDF G(r) +stored in a file named ``target.cgr``. +Let's also say we have a measured I(Q) of the +kapton background ``background.chi``. + +.. code-block:: python + + from diffpy.pdfgetx.pdfgetter import PDFGetter + from diffpy.morph.morphpy import morph_arrays + from diffpy.utils.parsers.loaddata import loadData + + pg = PDFGetter() + + backgroundfile = "background.chi" + composition = "SiO2" + + + def wrap(x, y, **kwargs): + xy_out = pg.__call__( + x=x, y=y, dataformat="QA", + composition=composition, + backgroundfile=backgroundfile, + **kwargs + ) + r = xy_out[0] + gr = xy_out[1] + return (r, gr) + + + sample_iq = loadData("sample.chi") + target_gr = loadData("target.cgr") + params_to_morph = { + "bgscale": 1.0, + "qmin": 0.0, "qmax": 25.0, + "qmaxinst": 25.0, "rpoly": 0.9 + } + + morph_info, morphed_gr = morph_arrays( + sample_iq, target_gr, + funcxy=(wrap, params_to_morph) + ) + +You can now plot ``morphed_gr`` against your ``target_gr`` to see +how well your morphing refinement of the PDF-getting parameters +as done! +To see what the refined values of the parameters are, +print out ``morph_info``. +You can freely add and remove entries in +``params_to_morph`` to include or not include them as +parameters to refine over. + +If you expect to see thermal effect differences between your +measured PDF and ``target_gr``, you can also include +the ``stretch``, ``scale``, and ``smear`` morphs in your +call to ``morph_arrays``. + + +Performing Detector Calibration with PyFai +========================================== + +When performing azimuthal integration, it is important to +ensure your beam center and detector distances are calibrated. +However, it is possible that they have shifted +across measurements. Here, we will use morphing to the rescue! + +Let's say we just measured a diffraction pattern stored +as a NumPy object in ``diffraction_image.npy``, but some +of the detector geometries are off. +Our azimuthally integrated ``sample.chi`` looks a bit off. +Before this measurement, you measured an amazing +I(Q) pattern ``target.chi`` with a perfectly calibrated +sample-to-detector distance and beam center. +We will use morphing to try to match the integration of +the 2D pattern to the target 1D function. + +For the integration, we will need some information, such as +the wavelength of the beam, +the size of each pixel in the 2D image +(``pixel1`` is the horizontal length in meters and +``pixel2`` is the vertical length in meters), +and a guess of the beam center. +This information can be found on the +`PyFai documentation `_. +For our example, let's say we have a ``1024``x``1024`` pixel image +where each pixel is a ``100`` micron by ``100`` micron region, and +our wavelength was ``1.11`` angstroms. + +.. code-block:: python + + import numpy as np + import pyFAI.integrator.azimuthal as pyfai + import pyFAI.detectors as pfd + from diffpy.morph.morphpy import morph_arrays + from diffpy.utils.parsers.loaddata import loadData + + pattern_2d = np.load("diffraction_image.npy") + wavelength = 0.1110e-9 # in m + pixel1 = 1e-4 # in m + pixel2 = 1e-4 # in m + cent_x = 511 # in number of pixels + cent_y = 511 # in number of pixels + + ai = pyfai.AzimuthalIntegrator() + ai.wavelength = wavelength + detector = pfd.Detector() + detector.max_shape = pattern_2d.shape + + + def wrap(x, y, sample_to_detector_dist, cent_offset_x, cent_offset_y): + detector.pixel1 = pixel1 + detector.pixel2 = pixel2 + ai.detector = detector + + ai.setFit2D( + directDist=sample_to_detector_dist, + centerX=cent_x+cent_offset_x, + centerY=cent_y+cent_offset_y + ) + + return ai.integrate1d_ng( + pattern_2d, + npt=1000, unit="q_A^-1", + method="mean" + ) + + + params_to_morph = { + "sample_to_detector_dist": 60, # in mm + "cent_offset_x": 0, # in number of pixels + "cent_offset_y": 0 # in number of pixels + } + + sample_chi = loadData("sample.chi") + target_chi = loadData("target.chi") + + morph_info, morphed_chi = morph_arrays( + sample_chi, target_chi, + funcxy=(wrap, params_to_morph) + ) + +You can now plot ``morphed_chi`` against your ``target_chi`` +to see if the refinement has helped in the calibration! +To see the calibrated values, you can print out ``morph_info``. + +If you would like to morph over other PyFai parameters +(e.g. ``rot1``, ``tilt``, ``wavelength``), +you can adjust the wrapper function ``wrap`` to take in +these parameters. diff --git a/doc/source/images/ex_tutorial_bar.png b/docs/source/images/ex_tutorial_bar.png similarity index 100% rename from doc/source/images/ex_tutorial_bar.png rename to docs/source/images/ex_tutorial_bar.png diff --git a/doc/source/images/ex_tutorial_temp.png b/docs/source/images/ex_tutorial_temp.png similarity index 100% rename from doc/source/images/ex_tutorial_temp.png rename to docs/source/images/ex_tutorial_temp.png diff --git a/doc/source/images/qs_tutorial_morphed.png b/docs/source/images/qs_tutorial_morphed.png similarity index 100% rename from doc/source/images/qs_tutorial_morphed.png rename to docs/source/images/qs_tutorial_morphed.png diff --git a/doc/source/images/qs_tutorial_scaled.png b/docs/source/images/qs_tutorial_scaled.png similarity index 100% rename from doc/source/images/qs_tutorial_scaled.png rename to docs/source/images/qs_tutorial_scaled.png diff --git a/doc/source/images/qs_tutorial_unmorphed.png b/docs/source/images/qs_tutorial_unmorphed.png similarity index 100% rename from doc/source/images/qs_tutorial_unmorphed.png rename to docs/source/images/qs_tutorial_unmorphed.png diff --git a/doc/source/index.rst b/docs/source/index.rst similarity index 83% rename from doc/source/index.rst rename to docs/source/index.rst index ee85d452..eb981226 100644 --- a/doc/source/index.rst +++ b/docs/source/index.rst @@ -1,6 +1,6 @@ -####### +########################## diffpy.morph documentation -####### +########################## ``diffpy.morph`` - Tools for manipulating and comparing PDF profiles @@ -34,12 +34,17 @@ plotted below. There are also a few other morphing transformations in the program. If no morphing transformation is specified, ``diffpy.morph`` will return just -the plotted PDFs. +the plotted functions. Finally, we note that though ``diffpy.morph`` should work on other spectra -that are not PDFs, it has not been extensively tested beyond the PDF. +that are not from diffraction, it has not been extensively tested beyond 1D +diffraction patterns and PDFs. -To get started, please visit the :ref:`quick_start`. +To get started, please visit the `quickstart tutorial `__. +For those looking to see more advanced features, you can read our +`advanced tutorials `__. +Finally, for those seeking to integrate ``diffpy.morph`` into their +Python scripts, check out the `morphpy page `__. ======= Authors @@ -72,6 +77,8 @@ Table of contents :titlesonly: quickstart + tutorials + morphpy license release Package API diff --git a/doc/source/license.rst b/docs/source/license.rst similarity index 100% rename from doc/source/license.rst rename to docs/source/license.rst diff --git a/docs/source/morphpy.rst b/docs/source/morphpy.rst new file mode 100644 index 00000000..09e0f92e --- /dev/null +++ b/docs/source/morphpy.rst @@ -0,0 +1,546 @@ +.. _morphpy: + +Using diffpy.morph in Python +############################ + +On top of the command-line (CLI) usage described in the `quickstart tutorial `__, +``diffpy.morph`` also supports Python integration. +All functionality supported on the CLI is also available for Python. +This page is intended for those acquainted with the basic morphs +described in the aforementioned quickstart tutorial who want to use ``diffpy.morph`` in their +Python scripts. + +For those looking to use the Python-specific morph ``MorphFuncxy`` (described below) +with commonly used diffraction software like `PDFgetx3 `_ +and `PyFai `_ are directed to the +`funcxy tutorials `__. + +Python Morphing Functions +========================= + + 1. In the quickstart tutorial, you were asked to try a combined scale, stretch, and smear + morph on the files `darkSub_rh20_C_01.gr` and `darkSub_rh20_C_44.gr` using the command-line + command :: + + diffpy.morph --scale=0.8 --smear=-0.08 --stretch=0.005 --xmin=1.5 --xmax=30 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + 2. To do the same on Python, we must first create a new Python script in the same directory as the + data files `darkSub_rh20_C_01.gr` and `darkSub_rh20_C_44.gr`. + 3. Then, in that script, import :: + + from diffpy.morph.morphpy import morph + + 3. Finally, we run the ``morph`` function :: + + morph_info, morph_table = morph("darkSub_rh20_C_01.gr", "darkSub_rh20_C_44.gr", scale=0.8, smear_pdf=-0.08, stretch=0.005, xmin=1.5, xmax=30) + + * The ``morph`` function takes in two file names (or paths). You can also provide various parameters + for morphing (see the Full Parameter List below). + * If, let's say, the file `darkSub_rh20_C_01.gr` is in a subdirectory `subdir/darkSub_rh20_C_01.gr`, + you should replace ``"darkSub_rh20_C_01.gr"`` in the above example with ``"subdir/darkSub_rh20_C_01.gr"``. + + 4. The ``morph`` function returns a dictionary ``morph_info`` and a numpy array ``morph_table``. + + * ``morph_info`` contains all morphs as keys (e.g. ``"scale"``, ``"stretch"``, ``"smear"``) with + the optimized morphing parameters found by ``diffpy.morph`` as values. ``morph_info`` also contains + the Rw and Pearson correlation coefficients found post-morphing. Try printing ``print(morph_info)`` + and compare the values stored in this dictionary to those given by the CLI output! + * ``morph_table`` is a two-column array of the morphed function interpolated onto the grid of the + target function (e.g. in our example, it returns the contents of `darkSub_rh20_C_01.gr` after + the morphs are applied interpolated onto the grid of `darkSub_rh20_C_44.gr`). + 5. Notice that most parameters you are able to use are the same as the options provided in the command-line + interface version of ``diffpy.morph``. For example, the ``--apply`` option becomes the ``apply=True`` parameter. + 6. With that, you have already mastered the basics of using ``diffpy.morph`` on Python! + 7. Note that instead of passing two files to ``diffpy.morph``, you might instead want to directly + pass arrays. For example, rather than passing `darkSub_rh20_C_01.gr`, I may want to pass + a two-column array named ``ds_rh20_c_01_array`` containing the data table contents of the file + `darkSub_rh20_C_01.gr`. In this case, we have a separate function :: + + from diffpy.morph.morphpy import morph_arrays + + 8. Assuming we have loaded the data in `darkSub_rh20_C_01.gr` into ``ds_rh20_c_01_array`` and + `darkSub_rh20_C_44.gr` into ``ds_rh20_c_44_array``, we can apply the same morph as step 3 + by running :: + + morph_info, morph_table = morph_arrays(ds_rh20_c_01_array, ds_rh20_c_44_array, scale=0.8, smear_pdf=-0.08, stretch=0.5, xmin=1.5, xmax=30) + + 9. Notice that the two-column format of the input to ``morph_arrays`` is the same as the + output of ``morph`` and ``morph_arrays``. It is VERY IMPORTANT that the data is in two-column format + rather than the traditional two-row format. This is to reflect the file formats conventionally + used to store PDFs. Again, try printing ``print(morph_info)`` and compare! + 10. For a full list of parameters used by (both) ``morph`` and ``morph_arrays``, see the Full Parameter List + section below. + +Full Parameter List +=================== + +General Parameters +------------------ + +save: str or path + Save the morphed function to a the file passed to save. Use '-' for stdout. +get_diff: bool + Return the difference function (morphed function minus target function) instead of + the morphed function (default). When save is enabled, the difference function + is saved instead of the morphed function. +verbose: bool + Print additional header details to saved files. These include details about the morph + inputs and outputs. +xmin: float + Minimum r-value (abscissa) to use for function comparisons. +xmax: float + Maximum r-value (abscissa) to use for function comparisons. +tolerance: float + Specify least squares refiner tolerance when optimizing for morph parameters. Default: 10e-8. +pearson: bool + The refiner instead maximizes agreement in the Pearson function + (default behavior is to minimize the residual). + Note that this is insensitive to scale. +addpearson: bool + Maximize agreement in the Pearson function as well as minimizing the residual. + +Manipulations +------------- +These parameters select the manipulations that are to be applied to the +function. The passed values will be refined unless specifically +excluded with the apply or exclude parameters. + +apply: bool + Apply morphs but do not refine. +exclude: list of str + Exclude a manipulations from refinement by name + (e.g. exclude=["scale", "stretch"] excludes the scale and stretch morphs). +scale: float + Apply scale factor. + + This multiplies the function ordinate by scale. +stretch: float + Stretch function grid by a fraction stretch. + + This multiplies the function grid by 1+stretch. +squeeze: list of float + Squeeze function grid given a polynomial + p(x) = squeeze[0]+squeeze[1]*x+...+squeeze[n]*x^n. + + n is dependent on the number + of values in the user-inputted comma-separated list. + The morph transforms the function grid from x to x+p(x). + When this parameter is given, hshift is disabled. + When n>1, stretch is disabled. +smear: float + Smear the peaks with a Gaussian of width smear. + + This is done by convolving the function with a Gaussian + with standard deviation smear. If both smear and + smear_pdf are used, only smear_pdf will be + applied. +smear_pdf: float + Convert PDF to RDF. Then, smear peaks with a Gaussian + of width smear_pdf. Convert back to PDF. If both smear and + smear_pdf are used, only smear_pdf will be + applied. +slope: float + Slope of the baseline used in converting from PDF to RDF. + + This is used with the option smear_pdf. The slope will + be estimated if not provided. +hshift: float + Shift the function horizontally by hshift to the right. +vshift: float + Shift the function vertically by vshift upward. +qdamp: float + Dampen PDF by a factor qdamp. +radius: float + Apply characteristic function of sphere with radius + given by parameter radius. + + If pradius is also specified, instead apply + characteristic function of spheroid with equatorial + radius radius and polar radius pradius. +pradius: float + Apply characteristic function of spheroid with + equatorial radius given by above parameter radius and polar radius pradius. + + If only pradius is specified, instead apply + characteristic function of sphere with radius pradius. +iradius: float + Apply inverse characteristic function of sphere with + radius iradius. + + If ipradius is also specified, instead + apply inverse characteristic function of spheroid with + equatorial radius iradius and polar radius ipradius. +ipradius: float + Apply inverse characteristic function of spheroid with + equatorial radius iradius and polar radius ipradius. + + If only ipradius is specified, instead apply inverse + characteristic function of sphere with radius ipradius. +funcy: tuple (function, dict) + Apply a function to the y-axis of the (two-column) data. + + This morph applies the function funcy[0] with parameters given in funcy[1]. + The function funcy[0] take in as parameters both the abscissa and ordinate + (i.e. take in at least two inputs with as many additional parameters as needed). + The y-axis values of the data are then replaced by the return value of funcy[0]. + + For example, let's start with a two-column table with abscissa x and ordinate y. + let us say we want to apply the function :: + + def linear(x, y, a, b, c): + return a * x + b * y + c + + This example function above takes in both the abscissa and ordinate on top of + three additional parameters a, b, and c. + To use the funcy parameter with parameter values a=1.0, b=2.0, and c=3.0, + we would pass ``funcy=(linear, {"a": 1.0, "b": 2.0, "c": 3.0})``. + For an explicit example, see the Python-Specific Morphs section below. +funcx: tuple (function, dict) + Apply a function to the x-axis of the (two-column) data. + + This morph works fundamentally differently from the other grid morphs + (e.g. stretch and squeeze) as it directly modifies the grid of the + morph function. + The other morphs maintain the original grid and apply the morphs by interpolating + the function ***. + + This morph applies the function funcx[0] with parameters given in funcx[1]. + The function funcx[0] take in as parameters both the abscissa and ordinate + (i.e. take in at least two inputs with as many additional parameters as needed). + The x-axis values of the data are then replaced by the return value of funcx[0]. + Note that diffpy.morph requires the x-axis be monotonic increasing + (i.e. for i < j, x[i] < x[j]): as such, + if funcx[0] is not a monotonic increasing function of the provided x-axis data, + the error ``x must be a strictly increasing sequence`` will be thrown. + + For example, let's start with a two-column table with abscissa x and ordinate y. + let us say we want to apply the function :: + + def exponential(x, y, amp, decay): + return abs(amp) * (1 - 2**(-decay * x)) + + This example function above takes in both the abscissa and ordinate on top of + three additional parameters amp and decay. + (Even though the ordinate is not used in the function, + it is still required that the function take in both acscissa and ordinate.) + To use the funcx parameter with parameter values amp=1.0 and decay=2.0, + we would pass ``funcx=(exponential, {"amp": 1.0, "decay:: 2.0})``. + For an explicit example, see the Python-Specific Morphs section below. +funcxy: tuple (function, dict) + Apply a function the (two-column) data. + + This morph applies the function funcxy[0] with parameters given in funcxy[1]. + The function funcxy[0] take in as parameters both the abscissa and ordinate + (i.e. take in at least two inputs with as many additional parameters as needed). + The two columns of the data are then replaced by the two return values of funcxy[0]. + + For example, let's start with a two-column table with abscissa x and ordinate y. + let us say we want to apply the function :: + + def shift(x, y, hshift, vshift): + return x + hshift, y + vshift + + This example function above takes in both the abscissa and ordinate on top of + two additional parameters hshift and vshift. + To use the funcy parameter with parameter values hshift=1.0 and vshift=2.0, + we would pass ``funcy=(shift, {"hshift": 1.0, "vshift": 1.0})``. + For an example use-case, see the Python-Specific Morphs section below. + +Python-Specific Morphs +====================== + +Some morphs in ``diffpy.morph`` are supported only in Python. Here, we detail +how they are used and how to call them. + +MorphFunc: Applying custom functions +------------------------------------- + +In these tutorial, we walk through how to use the ``MorphFunc`` morphs +(``MorphFuncy``, ``MorphFuncx``, ``MorphFuncxy``) +with some example transformations. + +Unlike other morphs that can be run from the command line, +``MorphFunc`` moprhs require a Python function and is therefore +intended to be used through Python scripting. + +MorphFuncy: +^^^^^^^^^^^ + +The ``MorphFuncy`` morph allows users to apply a custom Python function +to the y-axis values of a dataset, enabling flexible and user-defined +transformations. + +Let's try out this morph! + + 1. Import the necessary modules into your Python script: + + .. code-block:: python + + from diffpy.morph.morphpy import morph_arrays + import numpy as np + + 2. Define a custom Python function to apply a transformation to the data. + The function must take ``x`` and ``y`` (1D arrays of the same length) + along with named parameters, and return a transformed ``y`` array of the + same length. + For this example, we will use a simple linear transformation that + scales the input and applies an offset: + + .. code-block:: python + + def linear_function(x, y, scale, offset): + return (scale * x) * y + offset + + 3. In this example, we use a sine function for the morph data and generate + the target data by applying the linear transformation with known scale + and offset to it: + + .. code-block:: python + + x_morph = np.linspace(0, 10, 101) + y_morph = np.sin(x_morph) + x_target = x_morph.copy() + y_target = np.sin(x_target) * 20 * x_target + 0.8 + + 4. Setup and run the morph using the ``morph_arrays(...)``. + ``morph_arrays`` expects the morph and target data as **2D arrays** in + *two-column* format ``[[x0, y0], [x1, y1], ...]``. This will apply + the user-defined function and refine the parameters to best align the + morph data with the target data. This includes both the transformation + parameters (our initial guess) and the transformation function itself: + + .. code-block:: python + + morph_params, morph_table = morph_arrays(np.array([x_morph, y_morph]).T, np.array([x_target, y_target]).T, + funcy=(linear_function,{'scale': 1.2, 'offset': 0.1})) + + 5. Extract the fitted parameters from the result: + + .. code-block:: python + + fitted_params = morph_params["funcy"] + print(f"Fitted scale: {fitted_params['scale']}") + print(f"Fitted offset: {fitted_params['offset']}") + +As you can see, the fitted scale and offset values match the ones used +to generate the target (scale=20 & offset=0.8). This example shows how +``MorphFuncy`` can be used to fit and apply custom transformations. Now +it's your turn to experiment with other custom functions that may be useful +for analyzing your data. + +MorphFuncx: +^^^^^^^^^^^ + +The ``MorphFuncx`` morph allows users to apply a custom Python function +to the x-axis values of a dataset, similar to the ``MorphFuncy`` morph. + +One caveat to this morph is that the x-axis values must remain monotonic +increasing, so it is possible to run into errors when applying this morph. +For example, if your initial grid is ``[-1, 0, 1]``, and your function is +``lambda x, y: x**2``, the grid after the function is applied will be +``[1, 0, 1]``, which is no longer monotonic increasing. +In this case, the error ``x must be a strictly increasing sequence`` +will be thrown. + +Let's try out this morph! + + 1. Import the necessary modules into your Python script: + + .. code-block:: python + + from diffpy.morph.morphpy import morph_arrays + import numpy as np + + 2. Define a custom Python function to apply a transformation to the data. + The function must take ``x`` and ``y`` (1D arrays of the same length) + along with named parameters, and return a transformed ``x`` array of the + same length. Recall that this function must maintain the monotonic + increasing nature of the ``x`` array. + + For this example, we will use a simple exponential function transformation that + greatly modifies the input: + + .. code-block:: python + + def exp_function(x, y, scale, rate): + return np.abs(scale) * np.exp(np.abs(rate) * x) + + Notice that, though the function only uses the ``x`` input, + the function signature takes in both ``x`` and ``y``. + + 3. Like in the previous example, we will use a sine function for the morph + data and generate the target data by applying the decay transfomration + with a known scale and rate: + + .. code-block:: python + + x_morph = np.linspace(0, 10, 1001) + y_morph = np.sin(x_morph) + x_target = x_target = 20 * np.exp(0.8 * x_morph) + y_target = y_morph.copy() + + 4. Setup and run the morph using the ``morph_arrays(...)``. + ``morph_arrays`` expects the morph and target data as **2D arrays** in + *two-column* format ``[[x0, y0], [x1, y1], ...]``. This will apply + the user-defined function and refine the parameters to best align the + morph data with the target data. This includes both the transformation + parameters (our initial guess) and the transformation function itself: + + .. code-block:: python + + morph_params, morph_table = morph_arrays(np.array([x_morph, y_morph]).T, np.array([x_target, y_target]).T, + funcx=(decay_function, {'scale': 1.2, 'rate': 1.0})) + + 5. Extract the fitted parameters from the result: + + .. code-block:: python + + fitted_params = morph_params["funcx"] + print(f"Fitted scale: {fitted_params['scale']}") + print(f"Fitted rate: {fitted_params['rate']}") + +Again, we should see that the fitted scale and offset values match the ones used +to generate the target (scale=20 & rate=0.8). + +For fun, you can plot the original function to the morphed function to see +how much the + +MorphFuncxy: +^^^^^^^^^^^^ +The ``MorphFuncxy`` morph allows users to apply a custom Python function +to a dataset that modifies both the ``x`` and ``y`` column values. +This is equivalent to applying a ``MorphFuncx`` and ``MorphFuncy`` +simultaneously. + +This morph is useful when you want to apply operations that modify both +the grid and function value. +Examples of using ``MorphFuncxy`` with ``PyFai`` azimuthal integration +and ``PDFgetx3`` PDF calculation are included `here `__. + + +For this tutorial, we will go through two examples. One simple one +involving shifting a function in the ``x`` and ``y`` directions, and +another involving a Fourier transform. + + 1. Let's start by taking a simple ``sine`` function. + + .. code-block:: python + + import numpy as np + morph_x = np.linspace(0, 10, 101) + morph_y = np.sin(morph_x) + morph_table = np.array([morph_x, morph_y]).T + + 2. Then, let our target function be that same ``sine`` function shifted + to the right by ``0.3`` and up by ``0.7``. + + .. code-block:: python + + target_x = morph_x + 0.3 + target_y = morph_y + 0.7 + target_table = np.array([target_x, target_y]).T + + 3. While we could use the ``hshift`` and ``vshift`` morphs, + this would require us to refine over two separate morph + operations. We can instead perform these morphs simultaneously + by defining a function: + + .. code-block:: python + + def shift(x, y, hshift, vshift): + return x + hshift, y + vshift + + 4. Now, let's try finding the optimal shift parameters using the ``MorphFuncxy`` morph. + We can try an initial guess of ``hshift=0.0`` and ``vshift=0.0``. + + .. code-block:: python + + from diffpy.morph.morphpy import morph_arrays + initial_guesses = {"hshift": 0.0, "vshift": 0.0} + info, table = morph_arrays(morph_table, target_table, funcxy=(shift, initial_guesses)) + + 5. Finally, to see the refined ``hshift`` and ``vshift`` parameters, we extract them from ``info``. + + .. code-block:: python + + print(f"Refined hshift: {info["funcxy"]["hshift"]}") + print(f"Refined vshift: {info["funcxy"]["vshift"]}") + +Now for an example involving a Fourier transform. + + 1. Let's say you measured a signal of the form :math:`f(x)=\exp\{\cos(\pi x)\}`. + Unfortunately, your measurement was taken against a noisy sinusoidal + background of the form :math:`n(x)=A\sin(Bx)`, where ``A``, ``B`` are unknown. + For our example, let's say (unknown to us) that ``A=2`` and ``B=1.7``. + + .. code-block:: python + + import numpy as np + n = 201 + dx = 0.01 + measured_x = np.linspace(0, 2, n) + + def signal(x): + return np.exp(np.cos(np.pi * x)) + + def noise(x, A, B): + return A * np.sin(B * x) + + measured_f = signal(measured_x) + noise(measured_x, 2, 1.7) + morph_table = np.array([measured_x, measured_f]).T + + 2. Your colleague remembers they previously computed the Fourier transform + of the function and has sent that to you. + + .. code-block:: python + + # We only consider the region where the grid is positive for simplicity + target_x = np.fft.fftfreq(n, dx)[:n//2] + target_f = np.real(np.fft.fft(signal(measured_x))[:n//2]) + target_table = np.array([target_x, target_f]).T + + 3. We can now write a noise subtraction function that takes in our measured + signal and guesses for parameters ``A``, ``B``, and computes the Fourier + transform post-noise-subtraction. + + .. code-block:: python + + def noise_subtracted_ft(x, y, A, B): + n = 201 + dx = 0.01 + background_subtracted_y = y - noise(x, A, B) + + ft_x = np.fft.fftfreq(n, dx)[:n//2] + ft_f = np.real(np.fft.fft(background_subtracted_y)[:n//2]) + + return ft_x, ft_f + + 4. Finally, we can provide initial guesses of ``A=0`` and ``B=1`` to the + ``MorphFuncxy`` morph and see what refined values we get. + + .. code-block:: python + + from diffpy.morph.morphpy import morph_arrays + initial_guesses = {"A": 0, "B": 1} + info, table = morph_arrays(morph_table, target_table, funcxy=(background_subtracted_ft, initial_guesses)) + + 5. Print these values to see if they match with the true values of + of ``A=2.0`` and ``B=1.7``! + + .. code-block:: python + + print(f"Refined A: {info["funcxy"]["A"]}") + print(f"Refined B: {info["funcxy"]["B"]}") + +You can also use this morph to help find optimal parameters +(e.g. ``rpoly``, ``qmin``, ``qmax``, ``bgscale``) for computing +PDFs of materials with known structures. +One does this by setting the ``MorphFuncxy`` function to a PDF +computing function such as +`PDFgetx3 `_. +The input (morphed) 1D function should be the 1D diffraction data +one wishes to compute the PDF of and the target 1D function +can be the PDF of a target material with similar geometry. +More information about this will be released in the ``diffpy.morph`` +manuscript, and we plan to integrate this feature automatically into +``PDFgetx3`` soon. diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst new file mode 100644 index 00000000..89a95ce8 --- /dev/null +++ b/docs/source/quickstart.rst @@ -0,0 +1,222 @@ +.. _quick_start: + +Quickstart +########## + +Welcome! This will be a quick tutorial to accquaint users with ``diffpy.morph`` +and some of what it can do on the command-line. +Tutorials for more advanced features can be found on the `advanced tutorials page `__. +For those wishing to integrate ``diffpy.morph`` into their Python scripts, +see the `morphpy tutorial `__. + +To see more details and definitions about +the morphs please see the publication describing ``diffpy.morph``. + +To be published: + +* + + +As we described in the README and installation instructions, please make +sure that you are familiar with working with your command line terminal +before using this application. + +Before you've started this tutorial, please ensure that you've installed +all necessary software and dependencies. + +In this tutorial, we will demonstrate how to use ``diffpy.morph`` to compare +two +PDFs measured from the same material at different temperatures. +The morphs showcased include "stretch", "scale", and "smear". + +Basic diffpy.morph Workflow +=========================== + + 1. Open your Terminal or Command Prompt. + + 2. If it's not active already, activate your diffpy.morph-equipped + conda environment by typing in :: + + conda activate + + + * If you need to list your available conda environments, + run the command ``conda info --envs`` or + ``conda env list`` + + * Run the ``diffpy.morph --help`` command and read over the + info on that page for a brief overview of some of what we will + explore in this tutorial. + + 3. Using the ``mkdir`` command, create a directory where you'll + store the tutorial PDF files and use the ``cd`` command to change + into that directory. You can download the tutorial files + :download:`here <../../tutorial/quickstartData.zip>`. + Then, ``cd`` into the ``quickstartData`` directory. + + * The files in this dataset were collected by Soham Banerjee + at Brookhaven National Laboratory in Upton, New York. + + * The files are PDF data collected on Iridium Telluride with + 20% Rhodium Doping (IrRhTe2) with the first file (01) collected + at 10K and the last (44) at 300K. The samples increase in + temperature as their numbers increase. The "C" in their names + indicates that they have undergone cooling. + + * Note that these files have the ``.gr`` extension, which + indicates that they are measured PDFs. The ``.cgr`` file + extension indicates that a file is a calculated PDF, such as + those generated by the + `PDFgui `_ + program. + + 4. First, we will run the ``diffpy.morph`` application without any morphing + and only using one PDF. Type the following command into your + command line :: + + diffpy.morph darkSub_rh20_C_01.gr darkSub_rh20_C_01.gr + + This should produce two PDF curves which are congruent, resulting + in a flat green line underneath them. + + 5. Now, we will see ``diffpy.morph`` run with two different PDFs and no + morphing. Type the following command into your command line :: + + diffpy.morph darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + Without morphing, the difference Rw = 0.407. This indicates that + the two PDFs vary drastically. + + * While running the ``diffpy.morph`` command, it is important + to remember that the first PDF file argument you provide + (in this case, ``darkSub_rh20_C_01.gr``) is the PDF which + will get morphed, while the second PDF file argument you + provide (here, ``darkSub_rh20_C_44.gr``) is the PDF which + acts as the model and does not get morphed. Hereinafter, + we will refer to the first PDF argument as the "morph" + and the second as the "target", as the ``diffpy.morph`` display + does. + + .. figure:: images/qs_tutorial_unmorphed.png + :align: center + :figwidth: 100% + + Using ``diffpy.morph`` to compare two different PDFs without morphing. + + 6. Now, we will start the morphing process, which requires us to + provide initial guesses for our scaling factor, Gaussian smear, + and stretch, separately. We will start with the scaling factor. + Begin by typing the command :: + + diffpy.morph --scale=2 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + Now, the difference Rw = 1.457, a significant increase from our + value previously. We must modify our initial value for the + scaling factor and do so until we see a reduction in the + difference Rw from the unmorphed value. Type :: + + diffpy.morph --scale=0.9 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + The difference Rw is now 0.351, lower than our unmorphed + example's value. To see ``diffpy.morph`` optimize the scale factor, + simply drop ``-a`` from the command and type :: + + diffpy.morph --scale=0.9 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + ``diffpy.morph``, given a reasonable initial guess, will use find the + optimal value for each morphing feature. Here, we see that + ``diffpy.morph`` displays ``scale = 0.799025`` in the command prompt, + meaning that it has found this to be the most optimal value for + the scale factor. The difference Rw = 0.330, indicating a + better fit than our reasonable initial guess. + + * It is the choice of the user whether or not to run values + before removing ``-a`` when analyzing data with ``diffpy.morph``. + By including it, you allow the possibility to move towards + convergence before allowing the program to optimize by + removing it; when including it, you may reach a highly + optimized value on the first guess or diverge greatly. + In this tutorial, we will use it every time to check + for convergence. + + .. figure:: images/qs_tutorial_scaled.png + :align: center + :figwidth: 100% + + ``diffpy.morph`` found an optimal value for the scale factor. + + 7. Now, we will examine the Gaussian smearing factor. We provide an + initial guess by typing :: + + diffpy.morph --scale=0.8 --smear-pdf=0.5 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + And viewing the results. We've tailored our scale factor to be + close to the value given by ``diffpy.morph``, but see that the difference + Rw has increased substantially due to our smear value. One + approach, as described above, is to remove the ``-a`` from the + above command and run it again. + + * Note: The warnings that the Terminal/Command Prompt + displays are largely numerical in nature and do not + indicate a physically irrelevant guess. These are somewhat + superficial and in most cases can be ignored. + + We see that this has had hardly any effect on our PDF. To see + an effect, we restrict the ``xmin`` and ``xmax`` values to + reflect relevant data range by typing :: + + diffpy.morph --scale=0.8 --smear-pdf=0.5 --xmin=1.5 --xmax=30 darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + Now, we see that the difference Rw = 0.204 and that the optimized + ``smear=-0.084138``. + + * We restricted the ``x``-axis (``r``) values because some of the Gaussian + smear effects are only visible in a fixed ``x`` range. We + chose this ``x`` range by noting where most of our relevant + data was that was not exponentially decayed by + instrumental shortcomings. + + We are getting closer to an acceptably close fit to our data! + + 8. Finally, we will examine the stretch factor. Provide an initial + guess by typing :: + + diffpy.morph --scale=0.8 --smear-pdf=-0.08 --stretch=0.005 --xmin=1.5 --xmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + And noting that the difference has increased. Before continuing, + see if you can see which direction (higher or lower) our initial + estimate for the stretch factor needs to go and then removing + the ``-a`` to check optimized value! + + If you cannot, type :: + + diffpy.morph --scale=0.8 --smear-pdf=-0.08 --stretch=0.005 --xmin=1.5 --xmax=30 -a darkSub_rh20_C_01.gr darkSub_rh20_C_44.gr + + to observe decreased difference and then remove ``-a`` to see + the optimized ``--stretch=0.001762``. We have now reached + the optimal fit for our PDF! + + .. figure:: images/qs_tutorial_morphed.png + :align: center + :figwidth: 100% + + The optimal fit after applying the scale, smear, and stretch morphs. + + 9. Now, try it on your own! If you have personally collected or + otherwise readily available PDF data, try this process to see if + you can morph your PDFs to one another. Many of the parameters + provided in this tutorial are unique to it, so be cautious about + your choices and made sure that they remain physically relevant. + +Enjoy the software! + +.. Additional diffpy.morph Functionality/Exploration +.. ------------------------------------------------- +.. TODO include undoped PDF example + + +Bug Reports +=========== + +Please enjoy using our software! If you come across any bugs in the +application, please report them to diffpy-users@googlegroups.com. diff --git a/doc/source/release.rst b/docs/source/release.rst similarity index 100% rename from doc/source/release.rst rename to docs/source/release.rst diff --git a/doc/source/tutorialfiles.rst b/docs/source/tutorialfiles.rst similarity index 72% rename from doc/source/tutorialfiles.rst rename to docs/source/tutorialfiles.rst index 04e2124b..c89cb221 100644 --- a/doc/source/tutorialfiles.rst +++ b/docs/source/tutorialfiles.rst @@ -2,7 +2,7 @@ Download Tutorial Files Here ############################ Quick start tutorial data: -:download:`tutorialData.zip <../../tutorial/tutorialData.zip>` +:download:`tutorialData.zip <../../tutorial/quickstartData.zip>` Extra tutorial data: :download:`additionalData.zip <../../tutorial/additionalData.zip>` diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst new file mode 100644 index 00000000..6e8b6bf5 --- /dev/null +++ b/docs/source/tutorials.rst @@ -0,0 +1,272 @@ +.. _tutorials: + +Advanced Tutorials +################## +``diffpy.morph`` has some more functionalities not showcased in the `quickstart tutorial `__. +Tutorials for these are included below. The files required for these tutorials can be downloaded +:download:`here <../../tutorial/additionalData.zip>`. + +For a full list of options offered by ``diffpy.morph``, please run ``diffpy.morph --help`` on the command line. + +Using MorphFuncxy +================= + +Examples of how to use the general morph ``MorphFuncxy`` with commonly used +diffraction software like `PDFgetx3 `_ +and `PyFai `_ are directed to the +`funcxy tutorials `__. + +Performing Multiple Morphs +========================== + +It may be useful to morph a PDF against multiple targets: +for example, you may want to morph a PDF against multiple PDFs measured +at various temperatures to determine whether a phase change has occurred. +``diffpy.morph`` currently allows users to morph a PDF against all files in a +selected directory and plot resulting :math:`R_w` values from each morph. + +1. Within the ``additionalData`` directory, ``cd`` into the + ``morphsequence`` directory. Inside, you will find multiple PDFs of + :math:`SrFe_2As_2` measured at various temperatures. These PDFs are + from `"Atomic Pair Distribution Function Analysis: A primer" + `_. + +2. Let us start by getting the :math:`R_w` of ``SrFe2As2_150K.gr`` compared to + all other files in the directory. Run :: + + diffpy.morph SrFe2As2_150K.gr . --multiple-targets + + The multiple tag indicates we are comparing PDF file (first input) + against all PDFs in a directory (second input). Our choice of file + was ``SeFe2As2_150K.gr`` and directory was the cwd, which should be + ``morphsequence``. + +.. figure:: images/ex_tutorial_bar.png + :align: center + :figwidth: 100% + + Bar chart of :math:`R_W` values for each target file. Target files are + listed in ASCII sort order. + +3. After running this, we get chart of :math:`R_w` values for each target file. + However, this chart can be a bit confusing to interpret. To get a + more understandable plot, run :: + + diffpy.morph SrFe2As2_150K.gr . --multiple-targets --sort-by=temperature + + This plots the :math:`R_w` against the temperature parameter value provided + at the top of each file. Parameters are entries of the form + `` = `` and are located above + the ``r`` versus ``gr`` table in each PDF file. :: + + # SrFe2As2_150K.gr + [PDF Parameters] + temperature = 150 + wavelength = 0.1 + ... + +.. figure:: images/ex_tutorial_temp.png + :align: center + :figwidth: 100% + + The :math:`R_W` plotted against the temperature the target PDF was + measured at. + +4. Between 192K and 198K, the Rw has a sharp increase, indicating that + we may have a phase change. To confirm, let us now apply morphs + onto ``SrFe2As2_150K.gr`` with all other files in + ``morphsequence`` as targets :: + + diffpy.morph --scale=1 --stretch=0 SrFe2As2_150K.gr . --multiple-targets --sort-by=temperature + + Note that we are not applying a smear since it takes a long time to + apply and does not significantly change the Rw values in this example. + +5. We should now see a sharper increase in :math:`R_w` between 192K and 198K. + +6. Go back to the terminal to see optimized morphing parameters from each morph. + +7. On the morph with ``SrFe2As2_192K.gr`` as target, ``scale = + 0.972085`` and ``stretch = 0.000508`` and with ``SrFe2As2_198K.gr`` + as target, ``scale = 0.970276`` and ``stretch = 0.000510``. These + are very similar, meaning that thermal lattice expansion (accounted + for by ``stretch``) is not occurring. This, coupled with the fact + that the Rw significantly increases suggests a phase change in this + temperature regime. (In fact, :math:`SrFe_2As_2` does transition + from orthorhombic at lower temperature to tetragonal at higher + temperature!). More sophisticated analysis can be done with + `PDFgui `_. + +8. Finally, let us save all the morphed PDFs into a directory + named ``saved-morphs``. :: + + diffpy.morph SrFe2As2_150K.gr . --scale=1 --stretch=0 --multiple-targets \ + --sort-by=temperature --plot-parameter=stretch \ + --save=saved-morphs + + Entering the directory with ``cd`` and viewing its contents with + ``ls``, we see a file named ``morph-reference-table.txt`` with data + about the input morph parameters and re- fined output parameters + and a directory named ``morphs`` containing all the morphed + PDFs. See the ``--save-names-file`` option to see how you can set + the names for these saved morphs! + +Polynomial Squeeze Morph +========================= + +Another advanced feature in ``diffpy.morph`` is the ``MorphSqueeze`` morph, +which applies a user-defined polynomial to squeeze the morph function along the +x-axis. This provides a flexible way to correct for higher-order distortions +that simple shift or stretch morphs cannot fully address. +Such distortions can arise from geometric artifacts in X-ray detector modules, +including tilts, curved detection planes, or angle-dependent offsets, as well +as from intrinsic structural effects in the sample. + +A first-order squeeze polynomial recovers the behavior of simple shift or stretch, +while higher-order terms enable non-linear corrections. The squeeze transformation +is defined as: + +.. math:: + + \Delta r(r) = a_0 + a_1 r + a_2 r^2 + \dots + a_n r^n + +where :math:`a_0, a_1, ..., a_n` are the polynomial coefficients defined by the user. + +In this example, we show how to apply a squeeze morph in combination +with a scale morph to match a morph function to its target. The required +files can be found in ``additionalData/morphsqueeze/``. + +1. ``cd`` into the ``morphsqueeze`` directory:: + + cd additionalData/morphsqueeze + + Here you will find: + + - ``squeeze_morph.cgr`` — the morph function with a small built-in polynomial distortion. + - ``squeeze_target.cgr`` — the target function. + +2. Suppose we know that the morph needs a quadratic and cubic squeeze, + plus a scale factor to best match the target. As an initial guess, + we can use: + + - ``squeeze = 0,-0.001,-0.0001,0.0001`` + (for a polynomial: :math:`a_0 + a_1 x + a_2 x^2 + a_3 x^3`) + - ``scale = 1.1`` + + The squeeze polynomial is provided as a comma-separated list (no spaces):: + + diffpy.morph --scale=1.1 --squeeze=0,-0.001,-0.0001,0.0001 -a squeeze_morph.cgr squeeze_target.cgr + +3. ``diffpy.morph`` will apply the polynomial squeeze and scale, + display the initial and refined coefficients, and show the final + difference ``Rw``. + + To refine the squeeze polynomial and scale automatically, remove + the ``-a`` tag if you used it. For example:: + + diffpy.morph --scale=1.1 --squeeze=0,-0.001,-0.0001,0.0001 squeeze_morph.cgr squeeze_target.cgr + +4. Check the output for the final squeeze polynomial coefficients and scale. + They should match the true values used to generate the test data: + + - ``squeeze = 0, 0.01, 0.0001, 0.001`` + - ``scale = 0.5`` + + ``diffpy.morph`` refines the coefficients to minimize the residual + between the squeezed, scaled morph function and the target. + +.. warning:: + + **Extrapolation risk:** + A polynomial squeeze can shift morph data outside the target’s grid + (``x``-axis) range, + so parts of the output may be extrapolated. + This is generally fine if the polynomial coefficients are small and + the distortion is therefore small. If your coefficients are large, check the + plots carefully — strong extrapolation can produce unrealistic features at + the edges. If needed, adjust the coefficients to keep the morph physically + meaningful. + +Experiment with your own squeeze polynomials to fine-tune your morphs — even +small higher-order corrections can make a big difference! + +Nanoparticle Shape Effects +========================== + +A nanoparticle's finite size and shape can affect the shape of its PDF. +We can use ``diffpy.morph`` to morph a bulk material PDF to simulate these shape effects. +Currently, the supported nanoparticle shapes include: spheres and spheroids. + +* Within the ``additionalData`` directory, ``cd`` into the + ``morphShape`` subdirectory. Inside, you will find a sample Ni bulk + material PDF ``Ni_bulk.gr``. This PDF is from + `"Atomic Pair Distribution Function Analysis: A primer" + `_. + There are also multiple ``.cgr`` files with calculated Ni nanoparticle PDFs. + +* Let us apply various shape effect morphs on the bulk material to + reproduce these calculated PDFs. + + * Spherical Shape + 1. The ``Ni_nano_sphere.cgr`` file contains a generated + spherical nanoparticle with unknown radius. First, let us + plot ``Ni_blk.gr`` against ``Ni_nano_sphere.cgr`` :: + + diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr + + Despite the two being the same material, the Rw is quite large. + To reduce the Rw, we will apply spherical shape effects onto the PDF. + However, in order to do so, we first need the radius of the + spherical nanoparticle. + + 2. To get the radius, we can first observe a plot of + ``Ni_nano_sphere.cgr`` :: + + diffpy.morph Ni_nano_sphere.cgr Ni_nano_sphere.cgr + + Nanoparticles tend to have broader peaks at r-values larger + than the particle size, corresponding to the much weaker + correlations between molecules. On our plot, beyond r=22.5, + peaks are too broad to be visible, indicating our particle + size to be about 22.4. The approximate radius of a sphere + would be half of that, or 11.2. + + + 3. Now, we are ready to perform a morph applying spherical + effects. To do so, we use the ``--radius`` parameter :: + + diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr --radius=11.2 -a --xmax=30 + + 4. We can see that the :math:`Rw` value has significantly decreased + from before. Run without the ``-a`` tag to refine :: + + diffpy.morph Ni_bulk.gr Ni_nano_sphere.cgr --radius=11.2 --xmax=30 + + 5. After refining, we see the actual radius of the + nanoparticle was closer to 12. + + * Spheroidal Shape + + 1. The ``Ni_nano_spheroid.cgr`` file contains a calculated + spheroidal Ni nanoparticle. Again, we can begin by plotting + the bulk material against our nanoparticle :: + + diffpy.morph Ni_bulk.gr Ni_nano_spheroid.cgr + + 2. Inside the ``Ni_nano_spheroid.cgr`` file, we are given that + the equatorial radius is 12 and polar radius is 6. This is + enough information to define our spheroid. To apply + spheroid shape effects onto our bulk, run :: + + diffpy.morph Ni_bulk.gr Ni_nano_spheroid.cgr --radius=12 --pradius=6 -a --xmax=30 + + Note that the equatorial radius corresponds to the + ``--radius`` parameter and polar radius to ``--pradius``. + + 3. Remove the ``-a`` tag to refine. + +There is also support for morphing from a nanoparticle to a bulk. When +applying the inverse morphs, it is recommended to set ``--xmax=psize`` +where ``psize`` is the longest diameter of the nanoparticle. diff --git a/news/bugfix.rst b/news/bugfix.rst deleted file mode 100644 index ec2da171..00000000 --- a/news/bugfix.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Swap colors for morph and target. Morph is now blue and target red. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Multiple morphs/targets used to break given multiple subdirectories. - -**Security:** - -* diff --git a/news/diffpy_morph.rst b/news/citation.rst similarity index 81% rename from news/diffpy_morph.rst rename to news/citation.rst index 32740fb1..4b69694c 100644 --- a/news/diffpy_morph.rst +++ b/news/citation.rst @@ -1,10 +1,10 @@ **Added:** -* +* no news: style changes **Changed:** -* Renamed PDFmorph to diffpy.morph +* **Deprecated:** diff --git a/news/morphsqueeze.rst b/news/coc.rst similarity index 77% rename from news/morphsqueeze.rst rename to news/coc.rst index 750fbcf1..be44844e 100644 --- a/news/morphsqueeze.rst +++ b/news/coc.rst @@ -1,6 +1,6 @@ **Added:** -* Polynomial squeeze of x-axis of morphed data +* no news needed: file name change chore **Changed:** diff --git a/news/config_order.rst b/news/config_order.rst new file mode 100644 index 00000000..718a0f61 --- /dev/null +++ b/news/config_order.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* The interpolation of the morphed/objective function onto the target function grid is now done at the end of the morphing chain. Prior, it was done before. This change is desirable as the target function grid may be much smaller/larger than that of the objective, but a morph (e.g. stretch) accounts for that difference. Then, we ensure the morph is done before we regrid for comparison. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/doc.rst b/news/doc.rst deleted file mode 100644 index b0ec659f..00000000 --- a/news/doc.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Support ``scikit-package`` Level 5 standard (https://scikit-package.github.io/scikit-package/). - -**Security:** - -* diff --git a/news/enough-regression-points.rst b/news/enough-regression-points.rst new file mode 100644 index 00000000..8ff9e7c6 --- /dev/null +++ b/news/enough-regression-points.rst @@ -0,0 +1,23 @@ +**Added:** + +* Raise ``ValueError`` if the number of shared grid points between morphed and target functions is less than the number of parameters. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/epsilon.rst b/news/epsilon.rst new file mode 100644 index 00000000..f19b1999 --- /dev/null +++ b/news/epsilon.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* MorphRGrid can now handle grids denser than 1e-08. Previously, it was possible that multiple points on the intersection range could be excluded. + +**Security:** + +* diff --git a/news/example_fix.rst b/news/example_fix.rst new file mode 100644 index 00000000..36eb11b5 --- /dev/null +++ b/news/example_fix.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Tutorial examples for funcxy and pyfai now run properly. + +**Security:** + +* diff --git a/news/exclude.rst b/news/exclude.rst new file mode 100644 index 00000000..dd0173bd --- /dev/null +++ b/news/exclude.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* Exclude option in morphpy now takes in a list of morphs to exclude rather than excluding a single morph. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/explicit_paths.rst b/news/explicit_paths.rst deleted file mode 100644 index 2b418ce4..00000000 --- a/news/explicit_paths.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Paths to diffpy.utils.parsers functions made explicitly to the file level. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/dict_lists_refinement.rst b/news/extrap-warnings.rst similarity index 75% rename from news/dict_lists_refinement.rst rename to news/extrap-warnings.rst index 4e7fcb39..2ed88c6c 100644 --- a/news/dict_lists_refinement.rst +++ b/news/extrap-warnings.rst @@ -1,6 +1,6 @@ **Added:** -* Functionality for refining lists and dictionaries +* Enable ``diffpy.morph`` to detect extrapolation. **Changed:** diff --git a/news/extrapolate-warning.rst b/news/extrapolate-warning.rst new file mode 100644 index 00000000..c669afc9 --- /dev/null +++ b/news/extrapolate-warning.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: Add warning for extrapolation in morphsqueeze.py. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/funcxy_tutorial.rst b/news/funcxy_tutorial.rst new file mode 100644 index 00000000..f035aaf4 --- /dev/null +++ b/news/funcxy_tutorial.rst @@ -0,0 +1,23 @@ +**Added:** + +* Tutorials for wrapping PDFgetx3 and PyFai with funcxy. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/kwargs.rst b/news/kwargs.rst new file mode 100644 index 00000000..052ffdab --- /dev/null +++ b/news/kwargs.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Docstring for kwargs updated from dict to Any since various input types from kwargs are possible (e.g. a list/tuple for squeeze, a tuple for funcy, a float for smear-pdf). This should remove the warning that inputs are not dicts. + +**Security:** + +* diff --git a/news/morphfuncxy.rst b/news/morphfuncxy.rst new file mode 100644 index 00000000..ef89e304 --- /dev/null +++ b/news/morphfuncxy.rst @@ -0,0 +1,24 @@ +**Added:** + +* morphfuncx added: apply a function to the grid of your morphed function; this function should maintain the monotonic increasing nature of the grid +* morphfuncxy added: apply a general function which can modify both the ordinate and abscissa; useful when applying fourier transform or integration functions + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/morphfuncy.rst b/news/morphfuncy.rst deleted file mode 100644 index c6410817..00000000 --- a/news/morphfuncy.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* General morph function that applies a user-supplied Python function to the y-coordinates of morph data - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/morphshift.rst b/news/morphshift.rst deleted file mode 100644 index 71a2714a..00000000 --- a/news/morphshift.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Shifting morph for vertical and horizontal shifts. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/multiple_morphs.rst b/news/multiple_morphs.rst deleted file mode 100644 index d05da828..00000000 --- a/news/multiple_morphs.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* --multiple-morphs: morph multiple files against a single target - -**Changed:** - -* --multiple changed to --multiple-targets for clarity - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/new_parser_api.rst b/news/new_parser_api.rst deleted file mode 100644 index cd9139b3..00000000 --- a/news/new_parser_api.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* import `loadData` and `deserialize_data` directly to integrate with `diffpy.utils(3.6.0)` - -**Security:** - -* diff --git a/news/no-subprocess.rst b/news/no-subprocess.rst new file mode 100644 index 00000000..90f37de5 --- /dev/null +++ b/news/no-subprocess.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* Removed subprocess calls in test functions. diff --git a/news/py313.rst b/news/py313.rst deleted file mode 100644 index 34bb75e8..00000000 --- a/news/py313.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Support for python 3.13 - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* Support for python 3.10 - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/reduce-warns.rst b/news/reduce-warns.rst new file mode 100644 index 00000000..d8c99b5a --- /dev/null +++ b/news/reduce-warns.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Only give user extrapolation warning after refinement. + +**Security:** + +* diff --git a/news/refactor_pdf.rst b/news/refactor_pdf.rst new file mode 100644 index 00000000..4d24450b --- /dev/null +++ b/news/refactor_pdf.rst @@ -0,0 +1,25 @@ +**Added:** + +* + +**Changed:** + +* Changed tutorial language away from PDF-specific names +* Names of rmin, rmax, rstep renamed to xmin, xmax, xstep +* Removed PDF-specific labels from plotting functions + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/refactor_plot.rst b/news/refactor_plot.rst new file mode 100644 index 00000000..d4e3ffad --- /dev/null +++ b/news/refactor_plot.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* Removed PDF-specific language from all plotting functions. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/restructure_morphpy.rst b/news/restructure_morphpy.rst new file mode 100644 index 00000000..401c25d2 --- /dev/null +++ b/news/restructure_morphpy.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* For diffpy.morph developers: both morphpy functions now have shared code in a separate function for easier maintenance. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/rm_texinfo.rst b/news/rm_texinfo.rst deleted file mode 100644 index 8e6242f0..00000000 --- a/news/rm_texinfo.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* manual information is added into online docs. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* manual. - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/data_temperature.rst b/news/rst-markup.rst similarity index 74% rename from news/data_temperature.rst rename to news/rst-markup.rst index e251bcfe..2ceaf1e2 100644 --- a/news/data_temperature.rst +++ b/news/rst-markup.rst @@ -1,6 +1,6 @@ **Added:** -* +* No news added: Fix rst markup in the documentation. **Changed:** @@ -16,7 +16,7 @@ **Fixed:** -* add temperature field to tutorial/additionalData. +* **Security:** diff --git a/news/save_diff.rst b/news/save_diff.rst new file mode 100644 index 00000000..5ddb57fd --- /dev/null +++ b/news/save_diff.rst @@ -0,0 +1,23 @@ +**Added:** + +* There is now an option to save the difference curve. This is computed on the common interval between the two curves. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/smear_pdf_bug.rst b/news/smear_pdf_bug.rst new file mode 100644 index 00000000..1b897755 --- /dev/null +++ b/news/smear_pdf_bug.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* When transforming from the RDF to PDF in the smear-pdf morph, we incorrectly referenced the target grid zero point, when we should be referencing the morph grid zero point. This would lead to the morph PDF being set to zero on a point corresponding to when the target PDF grid value is zero. The correct behavior is for the morph PDF to be set to zero when the morph PDF grid value is zero. This has been fixed. + +**Security:** + +* diff --git a/news/codecov.rst b/news/stretch-extrapolation.rst similarity index 63% rename from news/codecov.rst rename to news/stretch-extrapolation.rst index 1c91077e..1992487c 100644 --- a/news/codecov.rst +++ b/news/stretch-extrapolation.rst @@ -1,7 +1,6 @@ **Added:** -* Spelling check via Codespell in pre-commit -* Coverage report in each PR +* No news added: Add warning for extrapolation in morphstretch and tests for extrapolations. **Changed:** diff --git a/news/line79.rst b/news/update_tests.rst similarity index 81% rename from news/line79.rst rename to news/update_tests.rst index 932cde58..790d30b1 100644 --- a/news/line79.rst +++ b/news/update_tests.rst @@ -16,7 +16,7 @@ **Fixed:** -* reduce the line width limit to 79 +* **Security:** diff --git a/pyproject.toml b/pyproject.toml index f007f315..735b5e78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,11 @@ exclude-file = ".codespell/ignore_lines.txt" ignore-words = ".codespell/ignore_words.txt" skip = "*.cif,*.dat,*agr" +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 + [tool.black] line-length = 79 include = '\.pyi?$' diff --git a/requirements/conda.txt b/requirements/conda.txt index e67cf6e2..378eecb5 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,5 +1,5 @@ numpy scipy -diffpy.utils +diffpy.utils>=3.6.1 matplotlib-base bg-mpl-stylesheets diff --git a/requirements/test.txt b/requirements/tests.txt similarity index 100% rename from requirements/test.txt rename to requirements/tests.txt diff --git a/src/diffpy/morph/morph_api.py b/src/diffpy/morph/morph_api.py index f4b06a72..25374cce 100644 --- a/src/diffpy/morph/morph_api.py +++ b/src/diffpy/morph/morph_api.py @@ -86,9 +86,9 @@ def morph( y_morph, x_target, y_target, - rmin=None, - rmax=None, - rstep=None, + xmin=None, + xmax=None, + xstep=None, pearson=False, add_pearson=False, fixed_operations=None, @@ -112,12 +112,12 @@ def morph( y_morph: numpy.array An array of target y values, i.e., those will be kept constant by morphing. - rmin: float, optional - A value to specify lower r-limit of morph operations. - rmax: float, optional - A value to specify upper r-limit of morph operations. - rstep: float, optional - A value to specify rstep of morph operations. + xmin: float, optional + A value to specify lower x-limit of morph operations. + xmax: float, optional + A value to specify upper x-limit of morph operations. + xstep: float, optional + A value to specify xstep of morph operations. pearson: Bool, optional Option to include Pearson coefficient as a minimizing target during morphing. Default to False. @@ -191,9 +191,9 @@ def morph( for k, v in rv_cfg.items() if (v is not None) and k in _morph_step_dict ] - rv_cfg["rmin"] = rmin - rv_cfg["rmax"] = rmax - rv_cfg["rstep"] = rstep + rv_cfg["xmin"] = xmin + rv_cfg["xmax"] = xmax + rv_cfg["xstep"] = xstep # configure smear, guess baselineslope when it is not provided if rv_cfg.get("smear") is not None and rv_cfg.get("baselineslope") is None: rv_cfg["baselineslope"] = -0.5 @@ -209,7 +209,7 @@ def morph( refpars.append("baselineslope") elif k == "funcy": morph_inst = morph_cls() - morph_inst.function = rv_cfg.get("function", None) + morph_inst.function = rv_cfg.get("funcy_function", None) if morph_inst.function is None: raise ValueError( "Must provide a 'function' when using 'parameters'" @@ -295,9 +295,9 @@ def plot_morph(chain, ax=None, **kwargs): rdat, grdat = chain.xy_target_out l_list = ax.plot(rfit, grfit, label="morph", **kwargs) l_list += ax.plot(rdat, grdat, label="target", **kwargs) - ax.set_xlim([chain.config["rmin"], chain.config["rmax"]]) + ax.set_xlim([chain.config["xmin"], chain.config["xmax"]]) ax.legend() - ax.set_xlabel(r"r ($\mathrm{\AA}$)") - ax.set_ylabel(r"G ($\mathrm{\AA}^{-2}$)") + # ax.set_xlabel(r"r ($\mathrm{\AA}$)") + # ax.set_ylabel(r"G ($\mathrm{\AA}^{-2}$)") return l_list diff --git a/src/diffpy/morph/morph_helpers/__init__.py b/src/diffpy/morph/morph_helpers/__init__.py index fe7eeae5..c59dd2f5 100644 --- a/src/diffpy/morph/morph_helpers/__init__.py +++ b/src/diffpy/morph/morph_helpers/__init__.py @@ -10,8 +10,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""List of helpers for certain morphing operations (currently only used for -smear).""" +"""List of helpers for certain morphing operations (currently only used +for smear).""" from diffpy.morph.morph_helpers.transformpdftordf import TransformXtalPDFtoRDF from diffpy.morph.morph_helpers.transformrdftopdf import TransformXtalRDFtoPDF diff --git a/src/diffpy/morph/morph_helpers/transformrdftopdf.py b/src/diffpy/morph/morph_helpers/transformrdftopdf.py index 495c7dda..54656ccf 100644 --- a/src/diffpy/morph/morph_helpers/transformrdftopdf.py +++ b/src/diffpy/morph/morph_helpers/transformrdftopdf.py @@ -57,7 +57,7 @@ def morph(self, x_morph, y_morph, x_target, y_target): self.y_morph_out = ( self.y_morph_in / self.x_morph_in + morph_baseline ) - self.y_morph_out[self.x_target_in == 0] = 0 + self.y_morph_out[self.x_morph_in == 0] = 0 return self.xyallout diff --git a/src/diffpy/morph/morph_io.py b/src/diffpy/morph/morph_io.py index a306542b..84d5c15a 100644 --- a/src/diffpy/morph/morph_io.py +++ b/src/diffpy/morph/morph_io.py @@ -16,7 +16,9 @@ from __future__ import print_function +import inspect import sys +import warnings from pathlib import Path import numpy @@ -25,6 +27,13 @@ from diffpy.morph import __save_morph_as__ +def custom_formatwarning(msg, *args, **kwargs): + return f"{msg}\n" + + +warnings.formatwarning = custom_formatwarning + + def single_morph_output( morph_inputs, morph_results, @@ -34,8 +43,8 @@ def single_morph_output( verbose=False, stdout_flag=False, ): - """Helper function for printing details about a single morph. Handles both - printing to terminal and printing to a file. + """Helper function for printing details about a single morph. + Handles both printing to terminal and printing to a file. Parameters ---------- @@ -46,7 +55,7 @@ def single_morph_output( save_file Name of file to print to. If None (default) print to terminal. morph_file - Name of the morphed PDF file. Required when printing to a + Name of the morphed function file. Required when printing to a non-terminal file. param xy_out: list List of the form [x_morph_out, y_morph_out]. x_morph_out is a List of @@ -66,18 +75,64 @@ def single_morph_output( + "\n" ) + mr_copy = morph_results.copy() morphs_out = "# Optimized morphing parameters:\n" + # Handle special inputs (numerical) + if "squeeze" in mr_copy: + sq_dict = mr_copy.pop("squeeze") + rw_pos = list(mr_copy.keys()).index("Rw") + morph_results_list = list(mr_copy.items()) + for idx, _ in enumerate(sq_dict): + morph_results_list.insert( + rw_pos + idx, (f"squeeze a{idx}", sq_dict[f"a{idx}"]) + ) + mr_copy = dict(morph_results_list) + + # Handle special inputs (functional remove) + func_dicts = { + "funcxy": [None, None], + "funcx": [None, None], + "funcy": [None, None], + } + for func in func_dicts.keys(): + if f"{func}_function" in mr_copy: + func_dicts[func][0] = mr_copy.pop(f"{func}_function") + if func in mr_copy: + func_dicts[func][1] = mr_copy.pop(func) + rw_pos = list(mr_copy.keys()).index("Rw") + morph_results_list = list(mr_copy.items()) + for idx, key in enumerate(func_dicts[func][1]): + morph_results_list.insert( + rw_pos + idx, (f"{func} {key}", func_dicts[func][1][key]) + ) + mr_copy = dict(morph_results_list) + + # Normal inputs morphs_out += "\n".join( - f"# {key} = {morph_results[key]:.6f}" for key in morph_results.keys() + f"# {key} = {mr_copy[key]:.6f}" for key in mr_copy.keys() ) + # Handle special inputs (functional add) + for func in func_dicts.keys(): + if func_dicts[func][0] is not None: + morphs_in += f'# {func} function =\n"""\n' + f_code, _ = inspect.getsourcelines(func_dicts[func][0]) + n_leading = len(f_code[0]) - len(f_code[0].lstrip()) + for idx, f_line in enumerate(f_code): + f_code[idx] = f_line[n_leading:] + morphs_in += "".join(f_code) + morphs_in += '"""\n' + # Printing to terminal if stdout_flag: print(f"{morphs_in}\n{morphs_out}\n") # Saving to file if save_file is not None: - path_name = str(Path(morph_file).resolve()) + if not Path(morph_file).exists(): + path_name = "NO FILE PATH PROVIDED" + else: + path_name = str(Path(morph_file).resolve()) header = "# PDF created by diffpy.morph\n" header += f"# from {path_name}" @@ -106,7 +161,7 @@ def single_morph_output( def create_morphs_directory(save_directory): - """Create a directory for saving multiple morphed PDFs. + """Create a directory for saving multiple morphed functions. Takes in a user-given path to a directory save_directory and create a subdirectory named Morphs. diffpy.morph will save all morphs into the @@ -135,17 +190,17 @@ def create_morphs_directory(save_directory): def get_multisave_names(target_list: list, save_names_file=None, mm=False): - """Create or import a dictionary that specifies names to save morphs as. - First attempt to import names from a specified file. If names for certain - morphs not found, use default naming scheme: 'Morph_with_Target_.cgr'. + """Create or import a dictionary that specifies names to save morphs + as. First attempt to import names from a specified file. If names + for certain morphs not found, use default naming scheme: + 'Morph_with_Target_.cgr'. Used when saving multiple morphs. Parameters ---------- target_list: list - Target (or Morph if mm enabled) PDFs used for each morph. + Target (or Morph if mm enabled) functions used for each morph. save_names_file Name of file to import save names dictionary from (default None). mm: bool @@ -154,8 +209,8 @@ def get_multisave_names(target_list: list, save_names_file=None, mm=False): Returns ------- dict - The names to save each morph as. Keys are the target PDF file names - used to produce that morph. + The names to save each morph as. Keys are the target function file + names used to produce that morph. """ # Dictionary storing save file names @@ -204,8 +259,8 @@ def multiple_morph_output( stdout_flag=False, mm=False, ): - """Helper function for printing details about a series of multiple morphs. - Handles both printing to terminal and printing to a file. + """Helper function for printing details about a series of multiple + morphs. Handles both printing to terminal and printing to a file. Parameters ---------- @@ -214,20 +269,20 @@ def multiple_morph_output( morph_results: dict Resulting data after morphing. target_files: list - PDF files that acted as targets to morphs. + Files that acted as targets to morphs. save_directory Name of directory to save morphs in. field Name of field if data was sorted by a particular field. Otherwise, leave blank. field_list: list - List of field values for each target PDF. + List of field values for each target function. Generated by diffpy.morph.tools.field_sort(). morph_file - Name of the morphed PDF file. + Name of the morphed function file. Required to give summary data after saving to a directory. target_directory - Name of the directory containing the target PDF files. + Name of the directory containing the target function files. Required to give summary data after saving to a directory. verbose: bool Print additional summary details when True (default False). @@ -320,8 +375,8 @@ def multiple_morph_output( def tabulate_results(multiple_morph_results): - """Helper function to make a data table summarizing details about the - results of multiple morphs. + """Helper function to make a data table summarizing details about + the results of multiple morphs. Parameters ---------- @@ -351,3 +406,40 @@ def tabulate_results(multiple_morph_results): } ) return tabulated_results + + +def handle_warnings(squeeze_morph): + if squeeze_morph is not None: + extrapolation_info = squeeze_morph.extrapolation_info + is_extrap_low = extrapolation_info["is_extrap_low"] + is_extrap_high = extrapolation_info["is_extrap_high"] + cutoff_low = extrapolation_info["cutoff_low"] + cutoff_high = extrapolation_info["cutoff_high"] + + if is_extrap_low and is_extrap_high: + wmsg = ( + "Warning: points with grid value below " + f"{cutoff_low} and above " + f"{cutoff_high} " + f"are extrapolated." + ) + elif is_extrap_low: + wmsg = ( + "Warning: points with grid value below " + f"{cutoff_low} " + f"are extrapolated." + ) + elif is_extrap_high: + wmsg = ( + "Warning: points with grid value above " + f"{cutoff_high} " + f"are extrapolated." + ) + else: + wmsg = None + + if wmsg: + warnings.warn( + wmsg, + UserWarning, + ) diff --git a/src/diffpy/morph/morphapp.py b/src/diffpy/morph/morphapp.py index ad7ca73c..327ed2da 100755 --- a/src/diffpy/morph/morphapp.py +++ b/src/diffpy/morph/morphapp.py @@ -18,6 +18,8 @@ import sys from pathlib import Path +import numpy + import diffpy.morph.morph_helpers as helpers import diffpy.morph.morph_io as io import diffpy.morph.morphs as morphs @@ -79,14 +81,27 @@ def custom_error(self, msg): metavar="NAME", dest="slocation", help=( - "Save the manipulated PDF to a file named NAME. " + "Save the manipulated function to a file named NAME. " "Use '-' for stdout.\n" "When --multiple- is enabled, " - "save each manipulated PDF as a file in a directory named NAME;\n" - "you can specify names for each saved PDF file using " + "save each manipulated function as a file in a directory " + "named NAME;\n" + "you can specify names for each saved function file using " "--save-names-file." ), ) + parser.add_option( + "--diff", + "--get-diff", + dest="get_diff", + action="store_true", + help=( + "Save the difference curve rather than the manipulated function.\n" + "This is computed as manipulated function minus target function.\n" + "The difference curve is computed on the interval shared by the " + "grid of the objective and target function." + ), + ) parser.add_option( "-v", "--verbose", @@ -95,14 +110,23 @@ def custom_error(self, msg): help="Print additional header details to saved files.", ) parser.add_option( - "--rmin", + "--xmin", + type="float", + metavar="XMIN", + help="Minimum x-value (abscissa) to use for function comparisons.", + ) + parser.add_option( + "--xmax", type="float", - help="Minimum r-value to use for PDF comparisons.", + metavar="XMAX", + help="Maximum x-value (abscissa) to use for function comparisons.", ) parser.add_option( - "--rmax", + "--tolerance", + "-t", type="float", - help="Maximum r-value to use for PDF comparisons.", + metavar="TOL", + help="Specify refiner tolerance as TOL. Default: 10e-8.", ) parser.add_option( "--pearson", @@ -148,33 +172,73 @@ def custom_error(self, msg): action="append", dest="exclude", metavar="MANIP", - help="""Exclude a manipulation from refinement by name. This can - appear multiple times.""", + help=( + "Exclude a manipulation from refinement by name. " + "This can appear multiple times." + ), ) group.add_option( "--scale", type="float", metavar="SCALE", - help="Apply scale factor SCALE.", + help=( + "Apply scale factor SCALE. " + "This multiplies the function ordinate by SCALE." + ), ) group.add_option( "--stretch", type="float", metavar="STRETCH", - help="Stretch PDF by a fraction STRETCH.", + help=( + "Stretch function grid by a fraction STRETCH. " + "This multiplies the function grid by 1+STRETCH." + ), + ) + group.add_option( + "--squeeze", + metavar="a0,a1,...,an", + help=( + "Squeeze function grid given a polynomial " + "a0+a1*x+a2*x^2+...a_n*x^n." + "n is dependent on the number of values in the " + "user-inputted comma-separated list. " + "Repeated and trailing commas are removed before parsing." + "When this option is enabled, --hshift is disabled. " + "When n>1, --stretch is disabled. " + "See online documentation for more information." + ), ) group.add_option( "--smear", type="float", metavar="SMEAR", - help="Smear peaks with a Gaussian of width SMEAR.", + help=( + "Smear the peaks with a Gaussian of width SMEAR. " + "This is done by convolving the function with a " + "Gaussian with standard deviation SMEAR. " + "If both --smear and --smear-pdf are enabled, " + "only --smear-pdf will be applied." + ), + ) + group.add_option( + "--smear-pdf", + type="float", + metavar="SMEAR", + help=( + "Convert PDF to RDF. " + "Then, smear peaks with a Gaussian of width SMEAR. " + "Convert back to PDF. " + "If both --smear and --smear-pdf are enabled, " + "only --smear-pdf will be applied." + ), ) group.add_option( "--slope", type="float", dest="baselineslope", - help="""Slope of the baseline. This is used when applying the smear - factor. It will be estimated if not provided.""", + help="""Slope of the baseline. This is used with the option --smear-pdf + to convert from the PDF to RDF. It will be estimated if not provided.""", ) group.add_option( "--hshift", @@ -281,12 +345,12 @@ def custom_error(self, msg): group.add_option( "--pmin", type="float", - help="Minimum r-value to plot. Defaults to RMIN.", + help="Minimum x-value to plot. Defaults to XMIN.", ) group.add_option( "--pmax", type="float", - help="Maximum r-value to plot. Defaults to RMAX.", + help="Maximum x-value to plot. Defaults to XMAX.", ) group.add_option( "--maglim", @@ -370,8 +434,9 @@ def custom_error(self, msg): "using a serial file NAMESFILE. The format of NAMESFILE should be " "as follows: each target PDF is an entry in NAMESFILE. For each " "entry, there should be a key {__save_morph_as__} whose value " - "specifies the name to save the manipulated PDF as. An example " - ".json serial file is shown in the diffpy.morph manual." + "specifies the name to save the manipulated function as." + "An example .json serial file is included in the tutorial " + "directory on the package GitHub repository." ), ) group.add_option( @@ -403,22 +468,38 @@ def custom_error(self, msg): return parser -def single_morph(parser, opts, pargs, stdout_flag=True): +def single_morph( + parser, opts, pargs, stdout_flag=True, python_wrap=False, pymorphs=None +): if len(pargs) < 2: parser.error("You must supply FILE1 and FILE2.") - elif len(pargs) > 2: + elif len(pargs) > 2 and not python_wrap: parser.error( "Too many arguments. Make sure you only supply FILE1 and FILE2." ) + elif not (len(pargs) == 2 or len(pargs) == 6) and python_wrap: + parser.error("Python wrapper error.") # Get the PDFs - x_morph, y_morph = getPDFFromFile(pargs[0]) - x_target, y_target = getPDFFromFile(pargs[1]) + # If we get from python, we may wrap, which has input size 4 + if len(pargs) == 6 and python_wrap: + x_morph = pargs[2] + y_morph = pargs[3] + x_target = pargs[4] + y_target = pargs[5] + else: + x_morph, y_morph = getPDFFromFile(pargs[0]) + x_target, y_target = getPDFFromFile(pargs[1]) if y_morph is None: - parser.error(f"No data table found in file: {pargs[0]}.") + parser.error(f"No data table found in: {pargs[0]}.") if y_target is None: - parser.error(f"No data table found in file: {pargs[1]}.") + parser.error(f"No data table found in: {pargs[1]}.") + + # Get tolerance + tolerance = 1e-08 + if opts.tolerance is not None: + tolerance = opts.tolerance # Get configuration values scale_in = "None" @@ -426,24 +507,78 @@ def single_morph(parser, opts, pargs, stdout_flag=True): smear_in = "None" hshift_in = "None" vshift_in = "None" - config = {} - config["rmin"] = opts.rmin - config["rmax"] = opts.rmax - config["rstep"] = None + config = {"xmin": opts.xmin, "xmax": opts.xmax, "xstep": None} if ( - opts.rmin is not None - and opts.rmax is not None - and opts.rmax <= opts.rmin + opts.xmin is not None + and opts.xmax is not None + and opts.xmax <= opts.xmin ): - e = "rmin must be less than rmax" + e = "xmin must be less than xmax" parser.custom_error(e) # Set up the morphs chain = morphs.MorphChain(config) - # Add the r-range morph, we will remove it when saving and plotting - chain.append(morphs.MorphRGrid()) refpars = [] + # Python-Specific Morphs + if pymorphs is not None: + # funcxy/funcx/funcy value is a tuple (function,{param_dict}) + if "funcxy" in pymorphs: + mfxy_function = pymorphs["funcxy"][0] + mfxy_params = pymorphs["funcxy"][1] + chain.append(morphs.MorphFuncxy()) + config["funcxy_function"] = mfxy_function + config["funcxy"] = mfxy_params + refpars.append("funcxy") + if "funcx" in pymorphs: + mfx_function = pymorphs["funcx"][0] + mfx_params = pymorphs["funcx"][1] + chain.append(morphs.MorphFuncx()) + config["funcx_function"] = mfx_function + config["funcx"] = mfx_params + refpars.append("funcx") + if "funcy" in pymorphs: + mfy_function = pymorphs["funcy"][0] + mfy_params = pymorphs["funcy"][1] + chain.append(morphs.MorphFuncy()) + config["funcy_function"] = mfy_function + config["funcy"] = mfy_params + refpars.append("funcy") + + # Squeeze + squeeze_poly_deg = -1 + squeeze_dict_in = {} + squeeze_morph = None + if opts.squeeze is not None: + # Handles both list and csv input + if ( + len(opts.squeeze) > 1 + and opts.squeeze[0] == "[" + and opts.squeeze[-1] == "]" + ): + opts.squeeze = opts.squeeze[1:-1] + elif ( + len(opts.squeeze) > 1 + and opts.squeeze[0] == "(" + and opts.squeeze[-1] == ")" + ): + opts.squeeze = opts.squeeze[1:-1] + squeeze_coeffs = opts.squeeze.strip().split(",") + idx = 0 + for _, coeff in enumerate(squeeze_coeffs): + if coeff.strip() != "": + try: + squeeze_dict_in.update({f"a{idx}": float(coeff)}) + idx += 1 + except ValueError: + parser.error(f"{coeff} could not be converted to float.") + squeeze_poly_deg = len(squeeze_dict_in.keys()) + squeeze_morph = morphs.MorphSqueeze() + chain.append(squeeze_morph) + config["squeeze"] = squeeze_dict_in + # config["extrap_index_low"] = None + # config["extrap_index_high"] = None + refpars.append("squeeze") # Scale if opts.scale is not None: scale_in = opts.scale @@ -451,25 +586,17 @@ def single_morph(parser, opts, pargs, stdout_flag=True): config["scale"] = scale_in refpars.append("scale") # Stretch - if opts.stretch is not None: + # Only enable stretch if squeeze is lower than degree 1 + stretch_morph = None + if opts.stretch is not None and squeeze_poly_deg < 1: + stretch_morph = morphs.MorphStretch() + chain.append(stretch_morph) stretch_in = opts.stretch - chain.append(morphs.MorphStretch()) config["stretch"] = stretch_in refpars.append("stretch") - # Shift - if opts.hshift is not None or opts.vshift is not None: - chain.append(morphs.MorphShift()) - if opts.hshift is not None: - hshift_in = opts.hshift - config["hshift"] = hshift_in - refpars.append("hshift") - if opts.vshift is not None: - vshift_in = opts.vshift - config["vshift"] = vshift_in - refpars.append("vshift") # Smear - if opts.smear is not None: - smear_in = opts.smear + if opts.smear_pdf is not None: + smear_in = opts.smear_pdf chain.append(helpers.TransformXtalPDFtoRDF()) chain.append(morphs.MorphSmear()) chain.append(helpers.TransformXtalRDFtoPDF()) @@ -480,6 +607,27 @@ def single_morph(parser, opts, pargs, stdout_flag=True): if opts.baselineslope is None: config["baselineslope"] = -0.5 refpars.append("baselineslope") + elif opts.smear is not None: + smear_in = opts.smear + chain.append(morphs.MorphSmear()) + refpars.append("smear") + config["smear"] = smear_in + # Shift + # Only enable hshift is squeeze is not enabled + shift_morph = None + if ( + opts.hshift is not None and squeeze_poly_deg < 0 + ) or opts.vshift is not None: + shift_morph = morphs.MorphShift() + chain.append(shift_morph) + if opts.hshift is not None and squeeze_poly_deg < 0: + hshift_in = opts.hshift + config["hshift"] = hshift_in + refpars.append("hshift") + if opts.vshift is not None: + vshift_in = opts.vshift + config["vshift"] = vshift_in + refpars.append("vshift") # Size radii = [opts.radius, opts.pradius] nrad = 2 - radii.count(None) @@ -514,12 +662,20 @@ def single_morph(parser, opts, pargs, stdout_flag=True): refpars.append("qdamp") config["qdamp"] = opts.qdamp + # Add the r-range morph, we will remove it when saving and plotting + mrg = morphs.MorphRGrid() + chain.append(mrg) + # Now remove non-refinable parameters if opts.exclude is not None: refpars = list(set(refpars) - set(opts.exclude)) + if "stretch" in opts.exclude: + stretch_morph = None # Refine or execute the morph - refiner = refine.Refiner(chain, x_morph, y_morph, x_target, y_target) + refiner = refine.Refiner( + chain, x_morph, y_morph, x_target, y_target, tolerance=tolerance + ) if opts.pearson: refiner.residual = refiner._pearson if opts.addpearson: @@ -550,13 +706,24 @@ def single_morph(parser, opts, pargs, stdout_flag=True): else: chain(x_morph, y_morph, x_target, y_target) + # THROW ANY WARNINGS HERE + io.handle_warnings(squeeze_morph) + io.handle_warnings(shift_morph) + io.handle_warnings(stretch_morph) + # Get Rw for the morph range rw = tools.getRw(chain) pcc = tools.get_pearson(chain) # Replace the MorphRGrid with Morph identity - chain[0] = morphs.Morph() + # This removes the r-range morph as mentioned above + mrg = morphs.Morph() chain(x_morph, y_morph, x_target, y_target) + # FOR FUTURE MAINTAINERS + # Any new morph should have their input morph parameters updated here + # You should also update the IO in morph_io + # if you think there requires special handling + # Input morph parameters morph_inputs = { "scale": scale_in, @@ -564,6 +731,31 @@ def single_morph(parser, opts, pargs, stdout_flag=True): "smear": smear_in, } morph_inputs.update({"hshift": hshift_in, "vshift": vshift_in}) + # More complex input morph parameters are only displayed conditionally + if opts.squeeze is not None: + squeeze_dict = squeeze_dict_in.copy() + for idx, _ in enumerate(squeeze_dict): + morph_inputs.update({f"squeeze a{idx}": squeeze_dict[f"a{idx}"]}) + if pymorphs is not None: + if "funcxy" in pymorphs: + for funcxy_param in pymorphs["funcxy"][1].keys(): + morph_inputs.update( + { + f"funcxy {funcxy_param}": pymorphs["funcxy"][1][ + funcxy_param + ] + } + ) + if "funcy" in pymorphs: + for funcy_param in pymorphs["funcy"][1].keys(): + morph_inputs.update( + {f"funcy {funcy_param}": pymorphs["funcy"][1][funcy_param]} + ) + if "funcx" in pymorphs: + for funcy_param in pymorphs["funcx"][1].keys(): + morph_inputs.update( + {f"funcx {funcy_param}": pymorphs["funcx"][1][funcy_param]} + ) # Output morph parameters morph_results = dict(config.items()) @@ -572,13 +764,29 @@ def single_morph(parser, opts, pargs, stdout_flag=True): morph_results.update({"Pearson": pcc}) # Print summary to terminal and save morph to file if requested + xy_save = [chain.x_morph_out, chain.y_morph_out] + if opts.get_diff is not None: + diff_chain = morphs.MorphChain( + {"xmin": None, "xmax": None, "xstep": None} + ) + diff_chain.append(morphs.MorphRGrid()) + diff_chain( + chain.x_morph_out, + chain.y_morph_out, + chain.x_target_in, + chain.y_target_in, + ) + xy_save = [ + diff_chain.x_morph_out, + diff_chain.y_morph_out - diff_chain.y_target_out, + ] try: io.single_morph_output( morph_inputs, morph_results, save_file=opts.slocation, morph_file=pargs[0], - xy_out=[chain.x_morph_out, chain.y_morph_out], + xy_out=xy_save, verbose=opts.verbose, stdout_flag=stdout_flag, ) @@ -598,26 +806,32 @@ def single_morph(parser, opts, pargs, stdout_flag=True): labels[0] = opts.tlabel # Plot extent defaults to calculation extent - pmin = opts.pmin if opts.pmin is not None else opts.rmin - pmax = opts.pmax if opts.pmax is not None else opts.rmax + pmin = opts.pmin if opts.pmin is not None else opts.xmin + pmax = opts.pmax if opts.pmax is not None else opts.xmax maglim = opts.maglim mag = opts.mag l_width = opts.lwidth plot.compare_funcs( pairlist, labels, - rmin=pmin, - rmax=pmax, + xmin=pmin, + xmax=pmax, maglim=maglim, mag=mag, rw=rw, l_width=l_width, ) - return morph_results + # Return different things depending on whether it is python interfaced + if python_wrap: + morph_info = morph_results + morph_table = numpy.array(xy_save).T + return morph_info, morph_table + else: + return morph_results -def multiple_targets(parser, opts, pargs, stdout_flag=True): +def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False): # Custom error messages since usage is distinct when --multiple tag is # applied if len(pargs) < 2: @@ -742,7 +956,7 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True): morph_inputs = { "scale": opts.scale, "stretch": opts.stretch, - "smear": opts.smear, + "smear": opts.smear_pdf, } morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift}) @@ -800,7 +1014,7 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True): return morph_results -def multiple_morphs(parser, opts, pargs, stdout_flag=True): +def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False): # Custom error messages since usage is distinct when --multiple tag is # applied if len(pargs) < 2: @@ -925,7 +1139,7 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True): morph_inputs = { "scale": opts.scale, "stretch": opts.stretch, - "smear": opts.smear, + "smear": opts.smear_pdf, } morph_inputs.update({"hshift": opts.hshift, "vshift": opts.vshift}) diff --git a/src/diffpy/morph/morphpy.py b/src/diffpy/morph/morphpy.py new file mode 100644 index 00000000..bac6eee8 --- /dev/null +++ b/src/diffpy/morph/morphpy.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python + +import numpy as np + +from diffpy.morph.morphapp import create_option_parser, single_morph + + +def get_args(parser, params, kwargs): + inputs = [] + for key, value in params.items(): + if value is not None: + inputs.append(f"--{key}") + inputs.append(f"{value}") + for key, value in kwargs.items(): + key = key.replace("_", "-") + if key == "exclude": + for param in value: + inputs.append(f"--{key}") + inputs.append(f"{param}") + else: + inputs.append(f"--{key}") + inputs.append(f"{value}") + (opts, pargs) = parser.parse_args(inputs) + return opts, pargs + + +def __get_morph_opts__(parser, scale, stretch, smear, plot, **kwargs): + # Check for Python-specific options + python_morphs = ["funcy", "funcx", "funcxy"] + pymorphs = {} + for pmorph in python_morphs: + if pmorph in kwargs: + pmorph_value = kwargs.pop(pmorph) + pymorphs.update({pmorph: pmorph_value}) + + # Special handling of parameters with dashes + kwargs_copy = kwargs.copy() + kwargs = {} + for key in kwargs_copy.keys(): + new_key = key + if "_" in key: + new_key = key.replace("_", "-") + kwargs.update({new_key: kwargs_copy[key]}) + + # Special handling of store_true and store_false parameters + opts_storing_values = [ + "verbose", + "pearson", + "addpearson", + "apply", + "reverse", + "diff", + "get-diff", + ] + opts_to_ignore = ["multiple-morphs", "multiple-targets"] + for opt in opts_storing_values: + if opt in kwargs: + # Remove if user sets false in params + if not kwargs[opt]: + kwargs.pop(opt) + for opt in opts_to_ignore: + if opt in kwargs: + kwargs.pop(opt) + + # Wrap the CLI + params = { + "scale": scale, + "stretch": stretch, + "smear": smear, + "noplot": True if not plot else None, + } + opts, _ = get_args(parser, params, kwargs) + + if not len(pymorphs) > 0: + pymorphs = None + + return opts, pymorphs + + +# Take in file names as input. +def morph( + morph_file, + target_file, + scale=None, + stretch=None, + smear=None, + plot=False, + **kwargs, +): + """Run diffpy.morph at Python level. + + Parameters + ---------- + morph_file: str or numpy.array + Path-like object to the file to be morphed. + target_file: str or numpy.array + Path-like object to the target file. + scale: float, optional + Initial guess for the scaling parameter. + Refinement is done only for parameter that are not None. + stretch: float, optional + Initial guess for the stretching parameter. + smear: float, optional + Initial guess for the smearing parameter. + plot: bool + Show a plot of the morphed and target functions as well as the + difference curve (default: False). + kwargs: str, float, list, tuple, bool + See the diffpy.morph website for full list of options. + Returns + ------- + morph_info: dict + Summary of morph parameters (e.g. scale, stretch, smear, rmin, rmax) + and results (e.g. Pearson, Rw). + morph_table: list + Function after morph where morph_table[:,0] is the abscissa and + morph_table[:,1] is the ordinate. + """ + pargs = [morph_file, target_file] + parser = create_option_parser() + opts, pymorphs = __get_morph_opts__( + parser, scale, stretch, smear, plot, **kwargs + ) + + return single_morph( + parser, + opts, + pargs, + stdout_flag=False, + python_wrap=True, + pymorphs=pymorphs, + ) + + +# Take in array-like objects as input. +def morph_arrays( + morph_table, + target_table, + scale=None, + stretch=None, + smear=None, + plot=False, + **kwargs, +): + """Run diffpy.morph at Python level. + + Parameters + ---------- + morph_table: numpy.array + Two-column array of (r, gr) for morphed function. + target_table: numpy.array + Two-column array of (r, gr) for target function. + scale: float, optional + Initial guess for the scaling parameter. + Refinement is done only for parameter that are not None. + stretch: float, optional + Initial guess for the stretching parameter. + smear: float, optional + Initial guess for the smearing parameter. + plot: bool + Show a plot of the morphed and target functions as well as the + difference curve (default: False). + kwargs: str, float, list, tuple, bool + See the diffpy.morph website for full list of options. + Returns + ------- + morph_info: dict + Summary of morph parameters (e.g. scale, stretch, smear, rmin, rmax) + and results (e.g. Pearson, Rw). + morph_table: list + Function after morph where morph_table[:,0] is the abscissa and + morph_table[:,1] is the ordinate. + """ + morph_table = np.array(morph_table) + target_table = np.array(target_table) + x_morph = morph_table[:, 0] + y_morph = morph_table[:, 1] + x_target = target_table[:, 0] + y_target = target_table[:, 1] + pargs = ["Morph", "Target", x_morph, y_morph, x_target, y_target] + parser = create_option_parser() + opts, pymorphs = __get_morph_opts__( + parser, scale, stretch, smear, plot, **kwargs + ) + + return single_morph( + parser, + opts, + pargs, + stdout_flag=False, + python_wrap=True, + pymorphs=pymorphs, + ) diff --git a/src/diffpy/morph/morphs/__init__.py b/src/diffpy/morph/morphs/__init__.py index a1cbdc88..e66f8e3d 100644 --- a/src/diffpy/morph/morphs/__init__.py +++ b/src/diffpy/morph/morphs/__init__.py @@ -17,6 +17,8 @@ from diffpy.morph.morphs.morph import Morph # noqa: F401 from diffpy.morph.morphs.morphchain import MorphChain # noqa: F401 +from diffpy.morph.morphs.morphfuncx import MorphFuncx +from diffpy.morph.morphs.morphfuncxy import MorphFuncxy from diffpy.morph.morphs.morphfuncy import MorphFuncy from diffpy.morph.morphs.morphishape import MorphISphere, MorphISpheroid from diffpy.morph.morphs.morphresolution import MorphResolutionDamping @@ -42,6 +44,8 @@ MorphShift, MorphSqueeze, MorphFuncy, + MorphFuncx, + MorphFuncxy, ] # End of file diff --git a/src/diffpy/morph/morphs/morph.py b/src/diffpy/morph/morphs/morph.py index 5f6c2ccc..7ffccd15 100644 --- a/src/diffpy/morph/morphs/morph.py +++ b/src/diffpy/morph/morphs/morph.py @@ -12,9 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""Morph -- base class for defining a morph. -""" - +"""Morph -- base class for defining a morph.""" +import numpy LABEL_RA = "r (A)" # r-grid LABEL_GR = "G (1/A^2)" # PDF G(r) @@ -246,6 +245,36 @@ def plotOutputs(self, xylabels=True, **plotargs): ylabel(self.youtlabel) return rv + def set_extrapolation_info(self, x_true, x_extrapolate): + """Set extrapolation information of the concerned morphing + process. + + Parameters + ---------- + x_true : array + original x values + x_extrapolate : array + x values after a morphing process + """ + + cutoff_low = min(x_true) + extrap_low_x = numpy.where(x_extrapolate < cutoff_low)[0] + is_extrap_low = False if len(extrap_low_x) == 0 else True + cutoff_high = max(x_true) + extrap_high_x = numpy.where(x_extrapolate > cutoff_high)[0] + is_extrap_high = False if len(extrap_high_x) == 0 else True + extrap_index_low = extrap_low_x[-1] if is_extrap_low else 0 + extrap_index_high = extrap_high_x[0] if is_extrap_high else -1 + extrapolation_info = { + "is_extrap_low": is_extrap_low, + "cutoff_low": cutoff_low, + "extrap_index_low": extrap_index_low, + "is_extrap_high": is_extrap_high, + "cutoff_high": cutoff_high, + "extrap_index_high": extrap_index_high, + } + self.extrapolation_info = extrapolation_info + def __getattr__(self, name): """Obtain the value from self.config, when normal lookup fails. diff --git a/src/diffpy/morph/morphs/morphfuncx.py b/src/diffpy/morph/morphs/morphfuncx.py new file mode 100644 index 00000000..d2c6edc1 --- /dev/null +++ b/src/diffpy/morph/morphs/morphfuncx.py @@ -0,0 +1,87 @@ +"""Class MorphFuncx -- apply a user-supplied python function to the +x-axis.""" + +from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph + + +class MorphFuncx(Morph): + """Apply a custom function to the x-axis (grid) of the morph + function. + + General morph function that applies a user-supplied function to the + x-coordinates of morph data to make it align with a target. + + Notice: the function provided must preserve the monotonic + increase of the grid. + I.e. the function f applied on the grid x must ensure for all + indices i>> from diffpy.morph.morphs.morphfuncx import MorphFuncx + + Define or import the user-supplied transformation function: + + >>> import numpy as np + >>> def exp_function(x, y, scale, rate): + >>> return abs(scale) * np.exp(rate * x) + + Note that this transformation is monotonic increasing, so will preserve + the monotonic increasing nature of the provided grid. + + Provide initial guess for parameters: + + >>> parameters = {'scale': 1, 'rate': 1} + + Run the funcy morph given input morph array (x_morph, y_morph)and target + array (x_target, y_target): + + >>> morph = MorphFuncx() + >>> morph.funcx_function = exp_function + >>> morph.funcx = parameters + >>> x_morph_out, y_morph_out, x_target_out, y_target_out = + ... morph.morph(x_morph, y_morph, x_target, y_target) + + To access parameters from the morph instance: + + >>> x_morph_in = morph.x_morph_in + >>> y_morph_in = morph.y_morph_in + >>> x_target_in = morph.x_target_in + >>> y_target_in = morph.y_target_in + >>> parameters_out = morph.funcx + """ + + # Define input output types + summary = "Apply a Python function to the x-axis data" + xinlabel = LABEL_RA + yinlabel = LABEL_GR + xoutlabel = LABEL_RA + youtlabel = LABEL_GR + parnames = ["funcx_function", "funcx"] + + def morph(self, x_morph, y_morph, x_target, y_target): + """Apply the user-supplied Python function to the x-coordinates + of the morph data.""" + Morph.morph(self, x_morph, y_morph, x_target, y_target) + self.x_morph_out = self.funcx_function( + self.x_morph_in, self.y_morph_in, **self.funcx + ) + return self.xyallout diff --git a/src/diffpy/morph/morphs/morphfuncxy.py b/src/diffpy/morph/morphs/morphfuncxy.py new file mode 100644 index 00000000..1a802bc7 --- /dev/null +++ b/src/diffpy/morph/morphs/morphfuncxy.py @@ -0,0 +1,85 @@ +"""Class MorphFuncxy -- apply a user-supplied python function to both +the x and y axes.""" + +from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph + + +class MorphFuncxy(Morph): + """Apply a custom function to the morph function. + + General morph function that applies a user-supplied function to the + morph data to make it align with a target. + + This function may modify both the grid (x-axis) and function (y-axis) + of the morph data. + + The user-provided function must return a two-column 1D function. + + Configuration Variables + ----------------------- + function: callable + The user-supplied function that applies a transformation to the + grid (x-axis) and morph function (y-axis). + + parameters: dict + A dictionary of parameters to pass to the function. + + Returns + ------- + A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out) + where the target values remain the same and the morph data is + transformed according to the user-specified function and parameters + The morphed data is returned on the same grid as the unmorphed data + + Example (EDIT) + ------- + Import the funcxy morph function: + + >>> from diffpy.morph.morphs.morphfuncxy import MorphFuncxy + + Define or import the user-supplied transformation function: + + >>> import numpy as np + >>> def shift_function(x, y, hshift, vshift): + >>> return x + hshift, y + vshift + + Provide initial guess for parameters: + + >>> parameters = {'hshift': 1, 'vshift': 1} + + Run the funcy morph given input morph array (x_morph, y_morph)and target + array (x_target, y_target): + + >>> morph = MorphFuncxy() + >>> morph.function = shift_function + >>> morph.funcy = parameters + >>> x_morph_out, y_morph_out, x_target_out, y_target_out = + ... morph.morph(x_morph, y_morph, x_target, y_target) + + To access parameters from the morph instance: + + >>> x_morph_in = morph.x_morph_in + >>> y_morph_in = morph.y_morph_in + >>> x_target_in = morph.x_target_in + >>> y_target_in = morph.y_target_in + >>> parameters_out = morph.funcxy + """ + + # Define input output types + summary = ( + "Apply a Python function to the data (y-axis) and data grid (x-axis)" + ) + xinlabel = LABEL_RA + yinlabel = LABEL_GR + xoutlabel = LABEL_RA + youtlabel = LABEL_GR + parnames = ["funcxy_function", "funcxy"] + + def morph(self, x_morph, y_morph, x_target, y_target): + """Apply the user-supplied Python function to the y-coordinates + of the morph data.""" + Morph.morph(self, x_morph, y_morph, x_target, y_target) + self.x_morph_out, self.y_morph_out = self.funcxy_function( + self.x_morph_in, self.y_morph_in, **self.funcxy + ) + return self.xyallout diff --git a/src/diffpy/morph/morphs/morphfuncy.py b/src/diffpy/morph/morphs/morphfuncy.py index 9e72b719..176a0241 100644 --- a/src/diffpy/morph/morphs/morphfuncy.py +++ b/src/diffpy/morph/morphs/morphfuncy.py @@ -1,69 +1,78 @@ +"""Class MorphFuncy -- apply a user-supplied python function to the +y-axis.""" + from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph class MorphFuncy(Morph): - """Apply the user-supplied Python function to the y-coordinates of the - morph data.""" + """Apply a custom function to the y-axis of the morph function. - # Define input output types - summary = "Apply a Python function to the y-axis data" - xinlabel = LABEL_RA - yinlabel = LABEL_GR - xoutlabel = LABEL_RA - youtlabel = LABEL_GR - parnames = ["funcy"] + General morph function that applies a user-supplied function to the + y-coordinates of morph data to make it align with a target. + + Configuration Variables + ----------------------- + function: callable + The user-supplied function that applies a transformation to the + y-coordinates of the data. + + parameters: dict + A dictionary of parameters to pass to the function. + + Returns + ------- + A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out) + where the target values remain the same and the morph data is + transformed according to the user-specified function and parameters + The morphed data is returned on the same grid as the unmorphed data + + Example + ------- + Import the funcy morph function: - def morph(self, x_morph, y_morph, x_target, y_target): - """General morph function that applies a user-supplied function to the - y-coordinates of morph data to make it align with a target. - - Configuration Variables - ----------------------- - function: callable - The user-supplied function that applies a transformation to the - y-coordinates of the data. - - parameters: dict - A dictionary of parameters to pass to the function. - These parameters are unpacked using **kwargs. - - Returns - ------- - A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out) - where the target values remain the same and the morph data is - transformed according to the user-specified function and parameters - The morphed data is returned on the same grid as the unmorphed data - - Example - ------- - Import the funcy morph function: >>> from diffpy.morph.morphs.morphfuncy import MorphFuncy - Define or import the user-supplied transformation function: + Define or import the user-supplied transformation function: + + >>> import numpy as np >>> def sine_function(x, y, amplitude, frequency): >>> return amplitude * np.sin(frequency * x) * y - Provide initial guess for parameters: + Provide initial guess for parameters: + >>> parameters = {'amplitude': 2, 'frequency': 2} - Run the funcy morph given input morph array (x_morph, y_morph) - and target array (x_target, y_target): + Run the funcy morph given input morph array (x_morph, y_morph)and target + array (x_target, y_target): + >>> morph = MorphFuncy() - >>> morph.function = sine_function + >>> morph.funcy_function = sine_function >>> morph.funcy = parameters - >>> x_morph_out, y_morph_out, x_target_out, y_target_out = morph.morph( - ... x_morph, y_morph, x_target, y_target) + >>> x_morph_out, y_morph_out, x_target_out, y_target_out = + ... morph.morph(x_morph, y_morph, x_target, y_target) + + To access parameters from the morph instance: - To access parameters from the morph instance: >>> x_morph_in = morph.x_morph_in >>> y_morph_in = morph.y_morph_in >>> x_target_in = morph.x_target_in >>> y_target_in = morph.y_target_in >>> parameters_out = morph.funcy - """ - Morph.morph(self, x_morph, y_morph, x_target, y_target) + """ - self.y_morph_out = self.function( + # Define input output types + summary = "Apply a Python function to the y-axis data" + xinlabel = LABEL_RA + yinlabel = LABEL_GR + xoutlabel = LABEL_RA + youtlabel = LABEL_GR + parnames = ["funcy_function", "funcy"] + + def morph(self, x_morph, y_morph, x_target, y_target): + """Apply the user-supplied Python function to the y-coordinates + of the morph data.""" + Morph.morph(self, x_morph, y_morph, x_target, y_target) + self.y_morph_out = self.funcy_function( self.x_morph_in, self.y_morph_in, **self.funcy ) return self.xyallout diff --git a/src/diffpy/morph/morphs/morphresolution.py b/src/diffpy/morph/morphs/morphresolution.py index 922e39d3..eb4b65b1 100644 --- a/src/diffpy/morph/morphs/morphresolution.py +++ b/src/diffpy/morph/morphs/morphresolution.py @@ -12,7 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""Class MorphResolutionDamping -- apply resolution broadening to the morph.""" +"""Class MorphResolutionDamping -- apply resolution broadening to the +morph.""" import numpy diff --git a/src/diffpy/morph/morphs/morphrgrid.py b/src/diffpy/morph/morphs/morphrgrid.py index fadce9f7..9b20cf67 100644 --- a/src/diffpy/morph/morphs/morphrgrid.py +++ b/src/diffpy/morph/morphs/morphrgrid.py @@ -19,9 +19,6 @@ from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph -# roundoff tolerance for selecting bounds on arrays. -epsilon = 1e-8 - class MorphRGrid(Morph): """Resample to specified r-grid. @@ -31,12 +28,12 @@ class MorphRGrid(Morph): Configuration Variables ----------------------- - rmin - The lower-bound on the r-range. - rmax - The upper-bound on the r-range (exclusive within tolerance of 1e-8). - rstep - The r-spacing. + xmin + The lower-bound on the x-range. + xmax + The upper-bound on the x-range (exclusive within tolerance of 1e-8). + xstep + The x-spacing. Notes ----- @@ -52,28 +49,47 @@ class MorphRGrid(Morph): yinlabel = LABEL_GR xoutlabel = LABEL_RA youtlabel = LABEL_GR - parnames = ["rmin", "rmax", "rstep"] + parnames = ["xmin", "xmax", "xstep"] + + # Define xmin xmax holders for adaptive x-grid refinement + # Without these, the program r-grid can only decrease in interval size + xmin_origin = None + xmax_origin = None + xstep_origin = None def morph(self, x_morph, y_morph, x_target, y_target): """Resample arrays onto specified grid.""" + if self.xmin is not None: + self.xmin_origin = self.xmin + if self.xmax is not None: + self.xmax_origin = self.xmax + if self.xstep is not None: + self.xstep_origin = self.xstep + Morph.morph(self, x_morph, y_morph, x_target, y_target) - rmininc = max(self.x_target_in[0], self.x_morph_in[0]) - r_step_target = self.x_target_in[1] - self.x_target_in[0] - r_step_morph = self.x_morph_in[1] - self.x_morph_in[0] - rstepinc = max(r_step_target, r_step_morph) - rmaxinc = min( - self.x_target_in[-1] + r_step_target, - self.x_morph_in[-1] + r_step_morph, + xmininc = max(min(self.x_target_in), min(self.x_morph_in)) + x_step_target = (max(self.x_target_in) - min(self.x_target_in)) / ( + len(self.x_target_in) - 1 + ) + x_step_morph = (max(self.x_morph_in) - min(self.x_morph_in)) / ( + len(self.x_morph_in) - 1 + ) + xstepinc = max(x_step_target, x_step_morph) + xmaxinc = min( + max(self.x_target_in) + x_step_target, + max(self.x_morph_in) + x_step_morph, ) - if self.rmin is None or self.rmin < rmininc: - self.rmin = rmininc - if self.rmax is None or self.rmax > rmaxinc: - self.rmax = rmaxinc - if self.rstep is None or self.rstep < rstepinc: - self.rstep = rstepinc - # Make sure that rmax is exclusive + if self.xmin_origin is None or self.xmin_origin < xmininc: + self.xmin = xmininc + if self.xmax_origin is None or self.xmax_origin > xmaxinc: + self.xmax = xmaxinc + if self.xstep_origin is None or self.xstep_origin < xstepinc: + self.xstep = xstepinc + # roundoff tolerance for selecting bounds on arrays. + epsilon = self.xstep / 2 + # Make sure that xmax is exclusive self.x_morph_out = numpy.arange( - self.rmin, self.rmax - epsilon, self.rstep + self.xmin, self.xmax - epsilon, self.xstep ) self.y_morph_out = numpy.interp( self.x_morph_out, self.x_morph_in, self.y_morph_in diff --git a/src/diffpy/morph/morphs/morphshift.py b/src/diffpy/morph/morphs/morphshift.py index b4f6c9f8..abe5f063 100644 --- a/src/diffpy/morph/morphs/morphshift.py +++ b/src/diffpy/morph/morphs/morphshift.py @@ -57,6 +57,7 @@ def morph(self, x_morph, y_morph, x_target, y_target): r = self.x_morph_in - hshift self.y_morph_out = numpy.interp(r, self.x_morph_in, self.y_morph_in) self.y_morph_out += vshift + self.set_extrapolation_info(self.x_morph_in, r) return self.xyallout diff --git a/src/diffpy/morph/morphs/morphsqueeze.py b/src/diffpy/morph/morphs/morphsqueeze.py index 6e41fc3d..3d0250da 100644 --- a/src/diffpy/morph/morphs/morphsqueeze.py +++ b/src/diffpy/morph/morphs/morphsqueeze.py @@ -1,4 +1,6 @@ -import numpy as np +"""Class MorphSqueeze -- Apply a polynomial to squeeze the morph +function.""" + from numpy.polynomial import Polynomial from scipy.interpolate import CubicSpline @@ -6,9 +8,50 @@ class MorphSqueeze(Morph): - """Apply a polynomial to squeeze the morph function. + """Squeeze the morph function. + + This applies a polynomial to squeeze the morph non-linearly. + + Configuration Variables + ----------------------- + squeeze : Dictionary + The polynomial coefficients {a0, a1, ..., an} for the squeeze + function where the polynomial would be of the form + a0 + a1*x + a2*x^2 and so on. The order of the polynomial is + determined by the length of the dictionary. + + Returns + ------- + A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out) + where the target values remain the same and the morph data is + shifted according to the squeeze. The morphed data is returned on + the same grid as the unmorphed data. + + Example + ------- + Import the squeeze morph function: + + >>> from diffpy.morph.morphs.morphsqueeze import MorphSqueeze + + Provide initial guess for squeezing coefficients: - The morphed data is returned on the same grid as the unmorphed data. + >>> squeeze_coeff = {"a0":0.1, "a1":-0.01, "a2":0.005} + + Run the squeeze morph given input morph array (x_morph, y_morph) and target + array (x_target, y_target): + + >>> morph = MorphSqueeze() + >>> morph.squeeze = squeeze_coeff + >>> x_morph_out, y_morph_out, x_target_out, y_target_out = + ... morph(x_morph, y_morph, x_target, y_target) + + To access parameters from the morph instance: + + >>> x_morph_in = morph.x_morph_in + >>> y_morph_in = morph.y_morph_in + >>> x_target_in = morph.x_target_in + >>> y_target_in = morph.y_target_in + >>> squeeze_coeff_out = morph.squeeze """ # Define input output types @@ -22,45 +65,17 @@ class MorphSqueeze(Morph): # extrap_index_high: first index after interpolation region extrap_index_low = None extrap_index_high = None + squeeze_cutoff_low = None + squeeze_cutoff_high = None + + def __init__(self, config=None): + super().__init__(config) def morph(self, x_morph, y_morph, x_target, y_target): - """Squeeze the morph function. - - This applies a polynomial to squeeze the morph non-linearly. - - Configuration Variables - ----------------------- - squeeze : Dictionary - The polynomial coefficients {a0, a1, ..., an} for the squeeze - function where the polynomial would be of the form - a0 + a1*x + a2*x^2 and so on. The order of the polynomial is - determined by the length of the dictionary. - - Returns - ------- - A tuple (x_morph_out, y_morph_out, x_target_out, y_target_out) - where the target values remain the same and the morph data is - shifted according to the squeeze. The morphed data is returned on - the same grid as the unmorphed data. - - Example - ------- - Import the squeeze morph function: - >>> from diffpy.morph.morphs.morphsqueeze import MorphSqueeze - Provide initial guess for squeezing coefficients: - >>> squeeze_coeff = {"a0":0.1, "a1":-0.01, "a2":0.005} - Run the squeeze morph given input morph array (x_morph, y_morph) - and target array (x_target, y_target): - >>> morph = MorphSqueeze() - >>> morph.squeeze = squeeze_coeff - >>> x_morph_out, y_morph_out, x_target_out, y_target_out = morph( - ... x_morph, y_morph, x_target, y_target) - To access parameters from the morph instance: - >>> x_morph_in = morph.x_morph_in - >>> y_morph_in = morph.y_morph_in - >>> x_target_in = morph.x_target_in - >>> y_target_in = morph.y_target_in - >>> squeeze_coeff_out = morph.squeeze + """Apply a polynomial to squeeze the morph function. + + The morphed data is returned on the same grid as the unmorphed + data. """ Morph.morph(self, x_morph, y_morph, x_target, y_target) @@ -70,8 +85,6 @@ def morph(self, x_morph, y_morph, x_target, y_target): self.y_morph_out = CubicSpline(x_squeezed, self.y_morph_in)( self.x_morph_in ) - low_extrap = np.where(self.x_morph_in < x_squeezed[0])[0] - high_extrap = np.where(self.x_morph_in > x_squeezed[-1])[0] - self.extrap_index_low = low_extrap[-1] if low_extrap.size else None - self.extrap_index_high = high_extrap[0] if high_extrap.size else None + self.set_extrapolation_info(x_squeezed, self.x_morph_in) + return self.xyallout diff --git a/src/diffpy/morph/morphs/morphstretch.py b/src/diffpy/morph/morphs/morphstretch.py index 78c25c8b..21f50a68 100644 --- a/src/diffpy/morph/morphs/morphstretch.py +++ b/src/diffpy/morph/morphs/morphstretch.py @@ -48,6 +48,7 @@ def morph(self, x_morph, y_morph, x_target, y_target): r = self.x_morph_in / (1.0 + self.stretch) self.y_morph_out = numpy.interp(r, self.x_morph_in, self.y_morph_in) + self.set_extrapolation_info(self.x_morph_in, r) return self.xyallout diff --git a/src/diffpy/morph/plot.py b/src/diffpy/morph/plot.py index 21e94e8d..e10c963e 100644 --- a/src/diffpy/morph/plot.py +++ b/src/diffpy/morph/plot.py @@ -12,7 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## -"""Collection of plotting functions (originally specifically) for PDFs.""" +"""Collection of plotting functions (originally specifically) for +PDFs.""" import matplotlib.pyplot as plt import numpy @@ -23,13 +24,13 @@ # FIXME - make this return the figure object in the future, so several views # can be composed. -def plot_funcs(pairlist, labels=None, offset="auto", rmin=None, rmax=None): - """Plots several functions g(r) on top of one another. +def plot_funcs(pairlist, labels=None, offset="auto", xmin=None, xmax=None): + """Plots several functions f(x) on top of one another. Parameters ---------- pairlist - Iterable of (r, gr) pairs to plot. + Iterable of (x, fx) pairs to plot. labels Iterable of names for the pairs. If this is not the same length as the pairlist, a legend will not be shown (default []). @@ -37,10 +38,10 @@ def plot_funcs(pairlist, labels=None, offset="auto", rmin=None, rmax=None): Offset to place between plots. Functions will be sequentially shifted in the y-direction by the offset. If offset is 'auto' (default), the optimal offset will be determined automatically. - rmin + xmin The minimum r-value to plot. If this is None (default), the lower bound of the function is not altered. - rmax + xmax The maximum r-value to plot. If this is None (default), the upper bound of the function is not altered. """ @@ -54,16 +55,16 @@ def plot_funcs(pairlist, labels=None, offset="auto", rmin=None, rmax=None): labels.extend([""] * gap) for idx, pair in enumerate(pairlist): - r, gr = pair - plt.plot(r, gr + idx * offset, label=labels[idx]) - plt.xlim(rmin, rmax) + x, fx = pair + plt.plot(x, fx + idx * offset, label=labels[idx]) + plt.xlim(xmin, xmax) if gap == 0: plt.legend(loc=0) plt.legend() - plt.xlabel(r"$r (\mathrm{\AA})$") - plt.ylabel(r"$G (\mathrm{\AA}^{-1})$") + # plt.xlabel(r"$r (\mathrm{\AA})$") + # plt.ylabel(r"$G (\mathrm{\AA}^{-1})$") plt.show() return @@ -71,8 +72,8 @@ def plot_funcs(pairlist, labels=None, offset="auto", rmin=None, rmax=None): def compare_funcs( pairlist, labels=None, - rmin=None, - rmax=None, + xmin=None, + xmax=None, show=True, maglim=None, mag=5, @@ -80,7 +81,8 @@ def compare_funcs( legend=True, l_width=1.5, ): - """Plot two functions g(r) on top of each other and difference curve. + """Plot two functions g(r) on top of each other and difference + curve. The second function will be shown as blue circles below and the first as a red line. The difference curve will be in green and offset for clarity. @@ -92,11 +94,11 @@ def compare_funcs( labels Iterable of names for the pairs. If this is not the same length as the pairlist, a legend will not be shown (default []). - rmin - The minimum r-value to plot. If this is None (default), the lower + xmin + The minimum x-value to plot. If this is None (default), the lower bound of the function is not altered. - rmax - The maximum r-value to plot. If this is None (default), the upper + xmax + The maximum x-value to plot. If this is None (default), the upper bound of the function is not altered. show Show the plot (default True) @@ -117,24 +119,24 @@ def compare_funcs( else: labeldata = labels[1] labelfit = labels[0] - rfit, grfit = pairlist[0] - rdat, grdat = pairlist[1] + xfit, fxfit = pairlist[0] + xdat, fxdat = pairlist[1] # View min and max - rvmin = max(rfit[0], rdat[0]) - rvmin = rmin or rvmin - rvmax = min(rfit[-1], rdat[-1]) - rvmax = rmax or rvmax + xvmin = max(xfit[0], xdat[0]) + xvmin = xmin or xvmin + xvmax = min(xfit[-1], xdat[-1]) + xvmax = xmax or xvmax gap = 2 - len(labels) labels = list(labels) labels.extend([""] * gap) - # Put gr1 on the same grid as rdat - gtemp = numpy.interp(rdat, rfit, grfit) + # Put fx1 on the same grid as xdat + ftemp = numpy.interp(xdat, xfit, fxfit) # Calculate the difference - diff = grdat - gtemp + diff = fxdat - ftemp # Put rw in the label labeldiff = "difference" if len(labels) < 3 else labels[2] @@ -143,24 +145,24 @@ def compare_funcs( # Magnify if necessary if maglim is not None: - grfit = grfit.copy() - grfit[rfit > maglim] *= mag - sel = rdat > maglim - grdat = grdat.copy() - grdat[sel] *= mag + fxfit = fxfit.copy() + fxfit[xfit > maglim] *= mag + sel = xdat > maglim + fxdat = fxdat.copy() + fxdat[sel] *= mag diff[sel] *= mag - gtemp[sel] *= mag + ftemp[sel] *= mag # Determine the offset for the difference curve. - sel = numpy.logical_and(rdat <= rvmax, rdat >= rvmin) - ymin = min(min(grdat[sel]), min(gtemp[sel])) + sel = numpy.logical_and(xdat <= xvmax, xdat >= xvmin) + ymin = min(min(fxdat[sel]), min(ftemp[sel])) ymax = max(diff[sel]) offset = -1.1 * (ymax - ymin) # Scale the x-limit based on the r-extent of the signal. This gives a nice # density of function peaks. - rlim = rvmax - rvmin - scale = rlim / 25.0 + xlim = xvmax - xvmin + scale = xlim / 25.0 # Set a reasonable minimum of .8 and maximum of 1 scale = min(1, max(scale, 0.8)) figsize = [13.5, 4.5] @@ -175,12 +177,12 @@ def compare_funcs( fig.add_axes(axes) plt.minorticks_on() - plt.plot(rdat, grdat, linewidth=l_width, label=labeldata) - plt.plot(rfit, grfit, linewidth=l_width, label=labelfit) - plt.plot(rdat, offset * numpy.ones_like(diff), linewidth=3, color="black") + plt.plot(xdat, fxdat, linewidth=l_width, label=labeldata) + plt.plot(xfit, fxfit, linewidth=l_width, label=labelfit) + plt.plot(xdat, offset * numpy.ones_like(diff), linewidth=3, color="black") diff += offset - plt.plot(rdat, diff, linewidth=l_width, label=labeldiff) + plt.plot(xdat, diff, linewidth=l_width, label=labeldiff) if maglim is not None: # Add a line for the magnification cutoff @@ -194,14 +196,14 @@ def compare_funcs( dashes=(14, 7), ) # FIXME - look for a place to put the maglim - xpos = (rvmax * 0.85 + maglim) / 2 / (rvmax - rvmin) + xpos = (xvmax * 0.85 + maglim) / 2 / (xvmax - xvmin) if xpos <= 0.9: plt.figtext(xpos, 0.7, "x%.1f" % mag, backgroundcolor="w") # Get a tight view - plt.xlim(rvmin, rvmax) + plt.xlim(xvmin, xvmax) ymin = min(diff[sel]) - ymax = max(max(grdat[sel]), max(gtemp[sel])) + ymax = max(max(fxdat[sel]), max(ftemp[sel])) yspan = ymax - ymin # Give a small border to the plot gap = 0.05 * yspan @@ -210,8 +212,8 @@ def compare_funcs( plt.ylim(ymin, ymax) # Make labels and legends - plt.xlabel(r"r ($\mathrm{\AA})$") - plt.ylabel(r"G $(\mathrm{\AA}^{-1})$") + # plt.xlabel(r"r ($\mathrm{\AA})$") + # plt.ylabel(r"G $(\mathrm{\AA}^{-1})$") if legend: plt.legend( bbox_to_anchor=(0.005, 1.02, 0.99, 0.10), @@ -304,38 +306,38 @@ def plot_param(target_labels, param_list, param_name=None, field=None): return -def truncate_func(r, gr, rmin=None, rmax=None): - """Truncate a function g(r) to specified bounds. +def truncate_func(x, fx, xmin=None, xmax=None): + """Truncate a function f(x) to specified bounds. Parameters ---------- - r - The r-values of the function g(r). - gr - Function g(r) values. - rmin - The minimum r-value. If this is None (default), the lower bound of + x + The x-values of the function f(x). + fx + Function f(x) values at each x-value. + xmin + The minimum x-value. If this is None (default), the lower bound of the function is not altered. - rmax - The maximum r-value. If this is None (default), the upper bound of + xmax + The maximum x-value. If this is None (default), the upper bound of the function is not altered. Returns ------- - r, gr - Returns the truncated r, gr. + x, fx + Returns the truncated x, fx. """ - if rmin is not None: - sel = r >= rmin - gr = gr[sel] - r = r[sel] - if rmax is not None: - sel = r <= rmax - gr = gr[sel] - r = r[sel] + if xmin is not None: + sel = x >= xmin + fx = fx[sel] + x = x[sel] + if xmax is not None: + sel = x <= xmax + fx = fx[sel] + x = x[sel] - return r, gr + return x, fx def _find_offset(pairlist): diff --git a/src/diffpy/morph/refine.py b/src/diffpy/morph/refine.py index 9514f8d8..8f1390d9 100644 --- a/src/diffpy/morph/refine.py +++ b/src/diffpy/morph/refine.py @@ -15,7 +15,7 @@ """refine -- Refine a morph or morph chain """ -from numpy import concatenate, dot, exp, ones_like +from numpy import array, concatenate, dot, exp, ones_like from scipy.optimize import leastsq from scipy.stats import pearsonr @@ -42,15 +42,22 @@ class Refiner(object): to other functions. """ - def __init__(self, chain, x_morph, y_morph, x_target, y_target): + def __init__( + self, chain, x_morph, y_morph, x_target, y_target, tolerance=1e-08 + ): self.chain = chain self.x_morph = x_morph self.y_morph = y_morph self.x_target = x_target self.y_target = y_target + self.tolerance = tolerance self.pars = [] self.residual = self._residual self.flat_to_grouped = {} + + # Padding required for the residual vector to ensure constant length + # across the entire morph process + self.res_length = None return def _update_chain(self, pvals): @@ -76,6 +83,34 @@ def _residual(self, pvals): self.x_morph, self.y_morph, self.x_target, self.y_target ) rvec = _y_target - _y_morph + if len(rvec) < len(pvals): + raise ValueError( + f"\nNumber of parameters (currently {len(pvals)}) cannot " + "exceed the number of shared grid points " + f"(currently {len(rvec)}). " + "Please reduce the number of morphing parameters or " + "provide new morphing and target functions with more " + "shared grid points." + ) + # If first time computing residual + if self.res_length is None: + self.res_length = len(rvec) + # Ensure residual length is constant + else: + # Padding + if len(rvec) < self.res_length: + diff_length = self.res_length - len(rvec) + rvec = list(rvec) + rvec.extend([0] * diff_length) + rvec = array(rvec) + # Removal + # For removal, pass the average RMS + # This is fast and easy to compute + # For sufficiently functions, this approximation becomes exact + elif len(rvec) > self.res_length: + avg_rms = sum(rvec**2) / len(rvec) + rvec = array([avg_rms for _ in range(self.res_length)]) + return rvec def _pearson(self, pvals): @@ -118,6 +153,9 @@ def refine(self, *args, **kw): ------ ValueError Exception raised if a minimum cannot be found. + ValueError + If the number of shared grid points between morphed function and + target function is smaller than the number of parameters. """ self.pars = args or self.chain.config.keys() @@ -143,7 +181,11 @@ def refine(self, *args, **kw): self.flat_to_grouped[len(initial) - 1] = (p, None) sol, cov_sol, infodict, emesg, ier = leastsq( - self.residual, initial, full_output=1 + self.residual, + array(initial), + full_output=True, + ftol=self.tolerance, + xtol=self.tolerance, ) fvec = infodict["fvec"] diff --git a/src/diffpy/morph/tools.py b/src/diffpy/morph/tools.py index 706b33db..3b56cc87 100644 --- a/src/diffpy/morph/tools.py +++ b/src/diffpy/morph/tools.py @@ -177,8 +177,8 @@ def case_insensitive_dictionary_search(key: str, dictionary: dict): def field_sort( filepaths: list, field, reverse=False, serfile=None, get_field_values=False ): - """Sort a list of files by a field stored in header information. All files - must contain this header information. + """Sort a list of files by a field stored in header information. All + files must contain this header information. Parameters ---------- @@ -240,9 +240,9 @@ def field_sort( def get_values_from_dictionary_collection( dictionary_collection: iter, target_key ): - """In an (iterable) collection of dictionaries, search for a target key in - each dictionary. Return a list of all found values corresponding to that - key. + """In an (iterable) collection of dictionaries, search for a target + key in each dictionary. Return a list of all found values + corresponding to that key. Parameters ---------- diff --git a/tests/helper.py b/tests/helper.py new file mode 100644 index 00000000..e21bdcee --- /dev/null +++ b/tests/helper.py @@ -0,0 +1,16 @@ +def create_morph_data_file( + data_dir_path, x_morph, y_morph, x_target, y_target +): + morph_file = data_dir_path / "morph_data.txt" + morph_data_text = [ + str(x_morph[i]) + " " + str(y_morph[i]) for i in range(len(x_morph)) + ] + morph_data_text = "\n".join(morph_data_text) + morph_file.write_text(morph_data_text) + target_file = data_dir_path / "target_data.txt" + target_data_text = [ + str(x_target[i]) + " " + str(y_target[i]) for i in range(len(x_target)) + ] + target_data_text = "\n".join(target_data_text) + target_file.write_text(target_data_text) + return morph_file, target_file diff --git a/tests/test_morph_func.py b/tests/test_morph_func.py index cb0442d1..2fba0a33 100644 --- a/tests/test_morph_func.py +++ b/tests/test_morph_func.py @@ -145,7 +145,7 @@ def linear_function(x, y, scale, offset): x_target = x_morph.copy() y_target = np.sin(x_target) * 2 * x_target + 0.4 cfg = morph_default_config(funcy={"scale": 1.2, "offset": 0.1}) - cfg["function"] = linear_function + cfg["funcy_function"] = linear_function morph_rv = morph(x_morph, y_morph, x_target, y_target, **cfg) morphed_cfg = morph_rv["morphed_config"] x_morph_out, y_morph_out, x_target_out, y_target_out = morph_rv[ diff --git a/tests/test_morphapp.py b/tests/test_morphapp.py index b66ec0e7..97682aec 100644 --- a/tests/test_morphapp.py +++ b/tests/test_morphapp.py @@ -2,6 +2,7 @@ from pathlib import Path +import numpy as np import pytest from diffpy.morph.morphapp import ( @@ -51,8 +52,8 @@ def test_parser_numerical(self, setup_parser): # Check values parsed correctly n_names = [ - "--rmin", - "--rmax", + "--xmin", + "--xmax", "--scale", "--smear", "--stretch", @@ -104,27 +105,43 @@ def test_parser_numerical(self, setup_parser): ) # Check correct value parsed assert len(n_args) == 1 # Check one leftover - def test_parser_systemexits(self, setup_parser): + def test_parser_systemexits(self, capsys, setup_parser): # ###Basic tests for any variety of morphing### # Ensure only two pargs given for morphing (opts, pargs) = self.parser.parse_args(["toofewfiles"]) with pytest.raises(SystemExit): single_morph(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "You must supply FILE1 and FILE2." in err with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "You must supply FILE and DIRECTORY." in err (opts, pargs) = self.parser.parse_args(["too", "many", "files"]) with pytest.raises(SystemExit): single_morph(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert ( + "Too many arguments. Make sure you only supply FILE1 and FILE2." + in err + ) with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert ( + "Too many arguments. You must only supply a FILE and a DIRECTORY." + in err + ) - # Make sure rmax greater than rmin + # Make sure xmax greater than xmin (opts, pargs) = self.parser.parse_args( - [f"{nickel_PDF}", f"{nickel_PDF}", "--rmin", "10", "--rmax", "1"] + [f"{nickel_PDF}", f"{nickel_PDF}", "--xmin", "10", "--xmax", "1"] ) with pytest.raises(SystemExit): single_morph(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "xmin must be less than xmax" in err # ###Tests exclusive to multiple morphs### # Make sure we save to a directory that exists @@ -139,8 +156,12 @@ def test_parser_systemexits(self, setup_parser): ) with pytest.raises(SystemExit): single_morph(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "Unable to save to designated location." in err with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "is not a directory." in err # Ensure first parg is a FILE and second parg is a DIRECTORY (opts, pargs) = self.parser.parse_args( @@ -151,8 +172,12 @@ def test_parser_systemexits(self, setup_parser): (opts, pargs) = self.parser.parse_args( [f"{testsequence_dir}", f"{testsequence_dir}"] ) + _, err = capsys.readouterr() + assert "is not a directory." in err with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "is not a file." in err # Try sorting by non-existing field (opts, pargs) = self.parser.parse_args( @@ -160,6 +185,8 @@ def test_parser_systemexits(self, setup_parser): ) with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "The requested field is missing from a PDF file header." in err (opts, pargs) = self.parser.parse_args( [ f"{nickel_PDF}", @@ -172,6 +199,8 @@ def test_parser_systemexits(self, setup_parser): ) with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "The requested field was not found in the metadata file." in err # Try plotting an unknown parameter (opts, pargs) = self.parser.parse_args( @@ -184,6 +213,8 @@ def test_parser_systemexits(self, setup_parser): ) with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "Cannot find specified plot parameter. No plot shown." in err # Try plotting an unrefined parameter (opts, pargs) = self.parser.parse_args( @@ -196,6 +227,26 @@ def test_parser_systemexits(self, setup_parser): ) with pytest.raises(SystemExit): multiple_targets(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert ( + "The plot parameter is missing values for at " + "least one morph and target pair. " + "No plot shown." in err + ) + + # Pass a non-float list to squeeze + (opts, pargs) = self.parser.parse_args( + [ + f"{nickel_PDF}", + f"{nickel_PDF}", + "--squeeze", + "1,a,0", + ] + ) + with pytest.raises(SystemExit): + single_morph(self.parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert "a could not be converted to float." in err def test_morphsequence(self, setup_morphsequence): # Parse arguments sorting by field @@ -255,6 +306,64 @@ def test_morphsequence(self, setup_morphsequence): ) assert s_sequence_results == sequence_results + def test_morphsmear(self, setup_parser, tmp_path): + def gaussian(x, mu, sigma): + return np.exp(-((x - mu) ** 2) / (2 * sigma**2)) / ( + sigma * np.sqrt(2 * np.pi) + ) + + # Generate the test files + x_grid = np.linspace(1, 101, 1001) + # Gaussian with STD 3 (morph) + g2 = gaussian(x_grid, 51, 3) + mf = tmp_path / "morph.txt" + with open(mf, "w") as f: + np.savetxt(f, np.array([x_grid, g2]).T) + # Gaussian with STD 5 (target) + g3 = gaussian(x_grid, 51, 5) + tf = tmp_path / "target.txt" + with open(tf, "w") as f: + np.savetxt(f, np.array([x_grid, g3]).T) + # Gaussian with STD 3 and baseline slope -0.5 (PDF morph) + g2_bl = gaussian(x_grid, 51, 3) / x_grid - 0.5 * x_grid + pmf = tmp_path / "pdf_morph.txt" + with open(pmf, "w") as f: + np.savetxt(f, np.array([x_grid, g2_bl]).T) + # Gaussian with STD 5 with baseline slope -0.5 (PDF target) + g3_bl = gaussian(x_grid, 51, 5) / x_grid - 0.5 * x_grid + ptf = tmp_path / "pdf_target.txt" + with open(ptf, "w") as f: + np.savetxt(f, np.array([x_grid, g3_bl]).T) -if __name__ == "__main__": - TestApp() + # No PDF smear (should not activate baseline slope) + (opts, _) = self.parser.parse_args( + [ + "--smear", + "1", + "-n", + ] + ) + pargs = [mf, tf] + smear_results = single_morph( + self.parser, opts, pargs, stdout_flag=False + ) + # Variances add, and 3^2+4^2=5^2 + assert pytest.approx(abs(smear_results["smear"])) == 4.0 + assert pytest.approx(smear_results["Rw"]) == 0.0 + + # PDF-specific smear (should activate baseline slope) + (opts, _) = self.parser.parse_args( + [ + "--smear", + "100", + "--smear-pdf", + "1", + "-n", + ] + ) + pargs = [pmf, ptf] + pdf_smear_results = single_morph( + self.parser, opts, pargs, stdout_flag=False + ) + assert pytest.approx(abs(pdf_smear_results["smear"])) == 4.0 + assert pytest.approx(pdf_smear_results["Rw"]) == 0.0 diff --git a/tests/test_morphchain.py b/tests/test_morphchain.py index 4c567379..004b5f2b 100644 --- a/tests/test_morphchain.py +++ b/tests/test_morphchain.py @@ -30,9 +30,9 @@ def test_morph(self, setup): """Check MorphChain.morph()""" # Define the morphs config = { - "rmin": 1, - "rmax": 6, - "rstep": 0.1, + "xmin": 1, + "xmax": 6, + "xstep": 0.1, "scale": 3.0, } @@ -48,16 +48,8 @@ def test_morph(self, setup): pytest.approx(x_morph[0], 1.0) pytest.approx(x_morph[-1], 4.9) pytest.approx(x_morph[1] - x_morph[0], 0.1) - pytest.approx(x_morph[0], mgrid.rmin) - pytest.approx(x_morph[-1], mgrid.rmax - mgrid.rstep) - pytest.approx(x_morph[1] - x_morph[0], mgrid.rstep) + pytest.approx(x_morph[0], mgrid.xmin) + pytest.approx(x_morph[-1], mgrid.xmax - mgrid.xstep) + pytest.approx(x_morph[1] - x_morph[0], mgrid.xstep) assert numpy.allclose(y_morph, y_target) return - - -# End of class TestMorphChain - -if __name__ == "__main__": - TestMorphChain() - -# End of file diff --git a/tests/test_morphfuncx.py b/tests/test_morphfuncx.py new file mode 100644 index 00000000..48444db6 --- /dev/null +++ b/tests/test_morphfuncx.py @@ -0,0 +1,68 @@ +import numpy as np +import pytest + +from diffpy.morph.morphs.morphfuncx import MorphFuncx + + +def x_exponential_function(x, y, x_amplitude, x_rate): + return x_amplitude * np.exp(x_rate * x) + + +def x_linear_function(x, y, x_slope, x_intercept): + return x_slope * x + x_intercept + + +def x_cubic_function(x, y, x_amplitude, x_shift): + return x_amplitude * (x - x_shift) ** 3 + + +def x_arctan_function(x, y, x_amplitude, x_frequency): + return x_amplitude * np.arctan(x_frequency * x) + + +funcx_test_suite = [ + ( + x_exponential_function, + {"x_amplitude": 2, "x_rate": 5}, + lambda x, y: 2 * np.exp(5 * x), + ), + ( + x_linear_function, + {"x_slope": 5, "x_intercept": 0.1}, + lambda x, y: 5 * x + 0.1, + ), + ( + x_cubic_function, + {"x_amplitude": 2, "x_shift": 5}, + lambda x, y: 2 * (x - 5) ** 3, + ), + ( + x_arctan_function, + {"x_amplitude": 4, "x_frequency": 2}, + lambda x, y: 4 * np.arctan(2 * x), + ), +] + + +@pytest.mark.parametrize( + "function, parameters, expected_function", + funcx_test_suite, +) +def test_funcy(function, parameters, expected_function): + x_morph = np.linspace(0, 10, 101) + y_morph = np.sin(x_morph) + x_target = x_morph.copy() + y_target = y_morph.copy() + x_morph_expected = expected_function(x_morph, y_morph) + y_morph_expected = y_morph + morph = MorphFuncx() + morph.funcx_function = function + morph.funcx = parameters + x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = ( + morph.morph(x_morph, y_morph, x_target, y_target) + ) + + assert np.allclose(y_morph_actual, y_morph_expected) + assert np.allclose(x_morph_actual, x_morph_expected) + assert np.allclose(x_target_actual, x_target) + assert np.allclose(y_target_actual, y_target) diff --git a/tests/test_morphfuncxy.py b/tests/test_morphfuncxy.py new file mode 100644 index 00000000..1de86874 --- /dev/null +++ b/tests/test_morphfuncxy.py @@ -0,0 +1,71 @@ +import numpy as np +import pytest + +from diffpy.morph.morphs.morphfuncxy import MorphFuncxy + +from .test_morphfuncx import funcx_test_suite +from .test_morphfuncy import funcy_test_suite + +funcxy_test_suite = [] +for entry_y in funcy_test_suite: + for entry_x in funcx_test_suite: + funcxy_test_suite.append( + ( + entry_x[0], + entry_y[0], + entry_x[1], + entry_y[1], + entry_x[2], + entry_y[2], + ) + ) + + +# FIXME: +@pytest.mark.parametrize( + "funcx_func, funcy_func, funcx_params, funcy_params, " + "funcx_lambda, funcy_lambda", + funcxy_test_suite, +) +def test_funcy( + funcx_func, + funcy_func, + funcx_params, + funcy_params, + funcx_lambda, + funcy_lambda, +): + x_morph = np.linspace(0, 10, 101) + y_morph = np.sin(x_morph) + x_target = x_morph.copy() + y_target = y_morph.copy() + x_morph_expected = funcx_lambda(x_morph, y_morph) + y_morph_expected = funcy_lambda(x_morph, y_morph) + + funcxy_params = {} + funcxy_params.update(funcx_params) + funcxy_params.update(funcy_params) + + def funcxy_func(x, y, **funcxy_params): + funcx_params = {} + funcy_params = {} + for param in funcxy_params.keys(): + if param[:2] == "x_": + funcx_params.update({param: funcxy_params[param]}) + elif param[:2] == "y_": + funcy_params.update({param: funcxy_params[param]}) + return funcx_func(x, y, **funcx_params), funcy_func( + x, y, **funcy_params + ) + + morph = MorphFuncxy() + morph.funcxy_function = funcxy_func + morph.funcxy = funcxy_params + x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = ( + morph.morph(x_morph, y_morph, x_target, y_target) + ) + + assert np.allclose(y_morph_actual, y_morph_expected) + assert np.allclose(x_morph_actual, x_morph_expected) + assert np.allclose(x_target_actual, x_target) + assert np.allclose(y_target_actual, y_target) diff --git a/tests/test_morphfuncy.py b/tests/test_morphfuncy.py index 31749fd6..a7753260 100644 --- a/tests/test_morphfuncy.py +++ b/tests/test_morphfuncy.py @@ -4,55 +4,58 @@ from diffpy.morph.morphs.morphfuncy import MorphFuncy -def sine_function(x, y, amplitude, frequency): - return amplitude * np.sin(frequency * x) * y +def y_sine_function(x, y, y_amplitude, y_frequency): + return y_amplitude * np.sin(y_frequency * x) * y -def exponential_decay_function(x, y, amplitude, decay_rate): - return amplitude * np.exp(-decay_rate * x) * y +def y_exponential_decay_function(x, y, y_amplitude, y_decay_rate): + return y_amplitude * np.exp(-y_decay_rate * x) * y -def gaussian_function(x, y, amplitude, mean, sigma): - return amplitude * np.exp(-((x - mean) ** 2) / (2 * sigma**2)) * y +def y_gaussian_function(x, y, y_amplitude, y_mean, y_sigma): + return y_amplitude * np.exp(-((x - y_mean) ** 2) / (2 * y_sigma**2)) * y -def polynomial_function(x, y, a, b, c): - return (a * x**2 + b * x + c) * y +def y_polynomial_function(x, y, y_a, y_b, y_c): + return (y_a * x**2 + y_b * x + y_c) * y -def logarithmic_function(x, y, scale): - return scale * np.log(1 + x) * y +def y_logarithmic_function(x, y, y_scale): + return y_scale * np.log(1 + x) * y + + +funcy_test_suite = [ + ( + y_sine_function, + {"y_amplitude": 2, "y_frequency": 5}, + lambda x, y: 2 * np.sin(5 * x) * y, + ), + ( + y_exponential_decay_function, + {"y_amplitude": 5, "y_decay_rate": 0.1}, + lambda x, y: 5 * np.exp(-0.1 * x) * y, + ), + ( + y_gaussian_function, + {"y_amplitude": 1, "y_mean": 5, "y_sigma": 1}, + lambda x, y: np.exp(-((x - 5) ** 2) / (2 * 1**2)) * y, + ), + ( + y_polynomial_function, + {"y_a": 1, "y_b": 2, "y_c": 0}, + lambda x, y: (x**2 + 2 * x) * y, + ), + ( + y_logarithmic_function, + {"y_scale": 0.5}, + lambda x, y: 0.5 * np.log(1 + x) * y, + ), +] @pytest.mark.parametrize( "function, parameters, expected_function", - [ - ( - sine_function, - {"amplitude": 2, "frequency": 5}, - lambda x, y: 2 * np.sin(5 * x) * y, - ), - ( - exponential_decay_function, - {"amplitude": 5, "decay_rate": 0.1}, - lambda x, y: 5 * np.exp(-0.1 * x) * y, - ), - ( - gaussian_function, - {"amplitude": 1, "mean": 5, "sigma": 1}, - lambda x, y: np.exp(-((x - 5) ** 2) / (2 * 1**2)) * y, - ), - ( - polynomial_function, - {"a": 1, "b": 2, "c": 0}, - lambda x, y: (x**2 + 2 * x) * y, - ), - ( - logarithmic_function, - {"scale": 0.5}, - lambda x, y: 0.5 * np.log(1 + x) * y, - ), - ], + funcy_test_suite, ) def test_funcy(function, parameters, expected_function): x_morph = np.linspace(0, 10, 101) @@ -62,7 +65,7 @@ def test_funcy(function, parameters, expected_function): x_morph_expected = x_morph y_morph_expected = expected_function(x_morph, y_morph) morph = MorphFuncy() - morph.function = function + morph.funcy_function = function morph.funcy = parameters x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = ( morph.morph(x_morph, y_morph, x_target, y_target) diff --git a/tests/test_morphio.py b/tests/test_morphio.py index 5b85c12a..2eed0135 100644 --- a/tests/test_morphio.py +++ b/tests/test_morphio.py @@ -2,6 +2,7 @@ from pathlib import Path +import numpy as np import pytest from diffpy.morph.morphapp import ( @@ -9,6 +10,8 @@ multiple_targets, single_morph, ) +from diffpy.morph.morphpy import morph_arrays +from diffpy.utils.parsers.loaddata import loadData # Support Python 2 try: @@ -27,6 +30,64 @@ tssf = testdata_dir.joinpath("testsequence_serialfile.json") +# Ignore PATH data when comparing files +def ignore_path(line): + # Lines containing FILE PATH data begin with '# from ' + if "# from " in line: + return False + # Lines containing DIRECTORY PATH data begin with '# with ' + if "# with " in line: + return False + return True + + +def isfloat(s): + """True if s is convertible to float.""" + try: + float(s) + return True + except ValueError: + pass + return False + + +def are_files_same(file1, file2): + """Assert that two files have (approximately) the same numerical + values.""" + for f1_row, f2_row in zip(file1, file2): + f1_arr = f1_row.split() + f2_arr = f2_row.split() + assert len(f1_arr) == len(f2_arr) + for idx, _ in enumerate(f1_arr): + if isfloat(f1_arr[idx]) and isfloat(f2_arr[idx]): + assert np.isclose(float(f1_arr[idx]), float(f2_arr[idx])) + else: + assert f1_arr[idx] == f2_arr[idx] + + +def are_diffs_right(file1, file2, diff_file): + """Assert that diff_file ordinate data is approximately file1 + ordinate data minus file2 ordinate data.""" + f1_data = loadData(file1) + f2_data = loadData(file2) + diff_data = loadData(diff_file) + + xmin = max(min(f1_data[:, 0]), min(f1_data[:, 1])) + xmax = min(max(f2_data[:, 0]), max(f2_data[:, 1])) + xnumsteps = max( + len(f1_data[:, 0][(xmin <= f1_data[:, 0]) & (f1_data[:, 0] <= xmax)]), + len(f2_data[:, 0][(xmin <= f2_data[:, 0]) & (f2_data[:, 0] <= xmax)]), + ) + + share_grid = np.linspace(xmin, xmax, xnumsteps) + f1_interp = np.interp(share_grid, f1_data[:, 0], f1_data[:, 1]) + f2_interp = np.interp(share_grid, f2_data[:, 0], f2_data[:, 1]) + diff_interp = np.interp(share_grid, diff_data[:, 0], diff_data[:, 1]) + + for idx, diff in enumerate(diff_interp): + assert np.isclose(f1_interp[idx] - f2_interp[idx], diff) + + class TestApp: @pytest.fixture def setup(self): @@ -46,16 +107,6 @@ def setup(self): return def test_morph_outputs(self, setup, tmp_path): - # Ignore PATH data when comparing files - def ignore_path(line): - # Lines containing FILE PATH data begin with '# from ' - if "# from " in line: - return False - # Lines containing DIRECTORY PATH data begin with '# with ' - if "# with " in line: - return False - return True - morph_file = self.testfiles[0] target_file = self.testfiles[-1] @@ -93,9 +144,9 @@ def ignore_path(line): for file in common: with open(tmp_succinct.joinpath(file)) as gf: with open(test_saving_succinct.joinpath(file)) as tf: - generated = filter(ignore_path, gf) - target = filter(ignore_path, tf) - assert all(x == y for x, y in zip(generated, target)) + actual = filter(ignore_path, gf) + expected = filter(ignore_path, tf) + are_files_same(actual, expected) # Save multiple verbose morphs tmp_verbose = tmp_path.joinpath("verbose") @@ -134,6 +185,117 @@ def ignore_path(line): for file in common: with open(tmp_verbose.joinpath(file)) as gf: with open(test_saving_verbose.joinpath(file)) as tf: - generated = filter(ignore_path, gf) - target = filter(ignore_path, tf) - assert all(x == y for x, y in zip(generated, target)) + actual = filter(ignore_path, gf) + expected = filter(ignore_path, tf) + are_files_same(actual, expected) + + # Similar format as test_morph_outputs + def test_morph_diff_outputs(self, setup, tmp_path): + morph_file = self.testfiles[0] + target_file = self.testfiles[-1] + + # Save multiple diff morphs + tmp_diff = tmp_path.joinpath("diff") + tmp_diff_name = tmp_diff.resolve().as_posix() + + (opts, pargs) = self.parser.parse_args( + [ + "--multiple-targets", + "--sort-by", + "temperature", + "-s", + tmp_diff_name, + "-n", + "--save-names-file", + tssf, + "--diff", + ] + ) + pargs = [morph_file, testsequence_dir] + multiple_targets(self.parser, opts, pargs, stdout_flag=False) + + # Save a single diff morph + diff_name = "single_diff_morph.cgr" + diff_file = tmp_diff.joinpath(diff_name) + df_name = diff_file.resolve().as_posix() + (opts, pargs) = self.parser.parse_args(["-s", df_name, "-n", "--diff"]) + pargs = [morph_file, target_file] + single_morph(self.parser, opts, pargs, stdout_flag=False) + + # Check that the saved diff matches the morph minus target + # Morphs are saved in testdata/testsequence/testsaving/succinct + # Targets are stored in testdata/testsequence + + # Single morph diff + morphed_file = test_saving_succinct / diff_name.replace( + "diff", "succinct" + ) + are_diffs_right(morphed_file, target_file, diff_file) + + # Multiple morphs diff + diff_files = list((tmp_diff / "Morphs").iterdir()) + morphed_files = list((test_saving_succinct / "Morphs").iterdir()) + target_files = self.testfiles[1:] + diff_files.sort() + morphed_files.sort() + target_files.sort() + for idx, diff_file in enumerate(diff_files): + are_diffs_right(morphed_files[idx], target_files[idx], diff_file) + + def test_morphsqueeze_outputs(self, setup, tmp_path): + # The file squeeze_morph has a squeeze and stretch applied + morph_file = testdata_dir / "squeeze_morph.cgr" + target_file = testdata_dir / "squeeze_target.cgr" + sqr = tmp_path / "squeeze_morph_result.cgr" + sqr_name = sqr.resolve().as_posix() + # Note that stretch and hshift should not be considered + (opts, _) = self.parser.parse_args( + [ + "--scale", + "2", + "--squeeze", + # Ignore duplicate commas and trailing commas + # Handle spaces and non-spaces + "0,, ,-0.001, -0.0001,0.0001,", + "--stretch", + "1", + "--hshift", + "1", + "-s", + sqr_name, + "-n", + "--verbose", + ] + ) + pargs = [morph_file, target_file] + single_morph(self.parser, opts, pargs, stdout_flag=False) + + # Check squeeze morph generates the correct output + with open(sqr) as mf: + with open(target_file) as tf: + actual = filter(ignore_path, mf) + expected = filter(ignore_path, tf) + are_files_same(actual, expected) + + def test_morphfuncy_outputs(self, tmp_path): + def quadratic(x, y, a0, a1, a2): + return a0 + a1 * x + a2 * y**2 + + r = np.linspace(0, 10, 101) + gr = np.linspace(0, 10, 101) + + morph_arrays( + np.array([r, gr]).T, + np.array([r, quadratic(r, gr, 1, 2, 3)]).T, + squeeze=[0, 0, 0], + funcy=(quadratic, {"a0": 1.0, "a1": 2.0, "a2": 3.0}), + apply=True, + save=tmp_path / "funcy_target.cgr", + verbose=True, + ) + + with open(testdata_dir.joinpath("funcy_target.cgr")) as tf: + with open(tmp_path.joinpath("funcy_target.cgr")) as gf: + actual = filter(ignore_path, gf) + expected = filter(ignore_path, tf) + are_files_same(actual, expected) diff --git a/tests/test_morphpdftordf.py b/tests/test_morphpdftordf.py index 6cdacb4a..af42625e 100644 --- a/tests/test_morphpdftordf.py +++ b/tests/test_morphpdftordf.py @@ -43,11 +43,3 @@ def test_transform(self, setup): assert numpy.allclose(rdf1, y_morph) assert numpy.allclose(rdf2, y_target) return - - -# End of class TestTransformXtalPDFtoRDF - -if __name__ == "__main__": - TestTransformXtalPDFtoRDF() - -# End of file diff --git a/tests/test_morphpy.py b/tests/test_morphpy.py new file mode 100644 index 00000000..621f844d --- /dev/null +++ b/tests/test_morphpy.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python + +from pathlib import Path + +import numpy as np +import pytest + +from diffpy.morph.morphapp import create_option_parser, single_morph +from diffpy.morph.morphpy import __get_morph_opts__, morph, morph_arrays +from diffpy.morph.tools import getRw + +thisfile = locals().get("__file__", "file.py") +tests_dir = Path(thisfile).parent.resolve() +testdata_dir = tests_dir.joinpath("testdata") +testsequence_dir = testdata_dir.joinpath("testsequence") + +nickel_PDF = testdata_dir.joinpath("nickel_ss0.01.cgr") +serial_JSON = testdata_dir.joinpath("testsequence_serialfile.json") + +testsaving_dir = testsequence_dir.joinpath("testsaving") +test_saving_succinct = testsaving_dir.joinpath("succinct") +test_saving_verbose = testsaving_dir.joinpath("verbose") +tssf = testdata_dir.joinpath("testsequence_serialfile.json") + + +class TestMorphpy: + @pytest.fixture + def setup_morph(self): + self.parser = create_option_parser() + filenames = [ + "g_174K.gr", + "f_180K.gr", + "e_186K.gr", + "d_192K.gr", + "c_198K.gr", + "b_204K.gr", + "a_210K.gr", + ] + self.testfiles = [] + self.morphapp_results = {} + + # Parse arguments sorting by field + (opts, pargs) = self.parser.parse_args( + [ + "--scale", + "1", + "--stretch", + "0", + "-n", + "--sort-by", + "temperature", + ] + ) + for filename in filenames: + self.testfiles.append(testsequence_dir.joinpath(filename)) + + # Run multiple single morphs + morph_file = self.testfiles[0] + for target_file in self.testfiles[1:]: + pargs = [morph_file, target_file] + # store in same format of dictionary as multiple_targets + self.morphapp_results.update( + { + target_file.name: single_morph( + self.parser, opts, pargs, stdout_flag=False + ) + } + ) + return + + def test_morph_opts(self, setup_morph): + kwargs = { + "verbose": False, + "pearson": False, + "addpearson": False, + "apply": False, + "reverse": False, + "get_diff": False, + "multiple_morphs": False, + "multiple_targets": False, + } + kwargs_copy = kwargs.copy() + opts, _ = __get_morph_opts__( + self.parser, scale=1, stretch=0, smear=0, plot=False, **kwargs_copy + ) + # Special set true/false operations should be removed + # when their input value is False + for opt in kwargs: + if opt == "apply": + assert getattr(opts, "refine") + else: + assert getattr(opts, opt) is None or not getattr(opts, opt) + + kwargs = { + "verbose": True, + "pearson": True, + "addpearson": True, + "apply": True, + "reverse": True, + "get_diff": True, + "multiple_morphs": True, + "multiple_targets": True, + } + kwargs_copy = kwargs.copy() + opts, _ = __get_morph_opts__( + self.parser, scale=1, stretch=0, smear=0, plot=False, **kwargs_copy + ) + for opt in kwargs: + if opt == "apply": + assert not getattr(opts, "refine") + # These options are not enabled in morphpy + elif opt == "multiple_morphs" or opt == "multiple_targets": + assert getattr(opts, opt) is None or not getattr(opts, opt) + # Special set true/false operations should NOT be removed + # when their input value is True + else: + assert getattr(opts, opt) + + def test_morph(self, setup_morph): + morph_results = {} + morph_file = self.testfiles[0] + for target_file in self.testfiles[1:]: + mr, grm = morph( + morph_file, + target_file, + scale=1, + stretch=0, + sort_by="temperature", + ) + _, grt = morph(target_file, target_file) + morph_results.update({target_file.name: mr}) + + class Chain: + xyallout = grm[:, 0], grm[:, 1], grt[:, 0], grt[:, 1] + + chain = Chain() + rw = getRw(chain) + del chain + assert np.allclose( + [rw], [self.morphapp_results[target_file.name]["Rw"]] + ) + # Check values in dictionaries are approximately equal + for file in morph_results.keys(): + morph_params = morph_results[file] + morphapp_params = self.morphapp_results[file] + for key in morph_params.keys(): + assert morph_params[key] == pytest.approx( + morphapp_params[key], abs=1e-08 + ) + + def test_exclude(self, setup_morph): + morph_file = self.testfiles[0] + target_file = self.testfiles[-1] + morph_info, _ = morph( + morph_file, + target_file, + scale=1, + stretch=0, + exclude=["scale", "stretch"], + sort_by="temperature", + ) + + # Nothing should be refined + assert pytest.approx(morph_info["scale"]) == 1 + assert pytest.approx(morph_info["stretch"]) == 0 + + morph_info, _ = morph( + morph_file, + target_file, + scale=1, + stretch=0, + exclude=["scale"], + sort_by="temperature", + ) + + # Stretch only should be refined + assert pytest.approx(morph_info["scale"]) == 1 + assert pytest.approx(morph_info["stretch"]) != 0 + + morph_info, _ = morph( + morph_file, + target_file, + scale=1, + stretch=0, + exclude=["stretch"], + sort_by="temperature", + ) + + # Scale only should be refined + assert pytest.approx(morph_info["scale"]) != 1 + assert pytest.approx(morph_info["stretch"]) == 0 + + def test_morphpy(self, setup_morph): + morph_results = {} + morph_file = self.testfiles[0] + for target_file in self.testfiles[1:]: + _, grm0 = morph(morph_file, morph_file) + _, grt = morph(target_file, target_file) + mr, grm = morph_arrays( + grm0, grt, scale=1, stretch=0, sort_by="temperature" + ) + morph_results.update({target_file.name: mr}) + + class Chain: + xyallout = grm[:, 0], grm[:, 1], grt[:, 0], grt[:, 1] + + chain = Chain() + rw = getRw(chain) + del chain + assert np.allclose( + [rw], [self.morphapp_results[target_file.name]["Rw"]] + ) + # Check values in dictionaries are approximately equal + for file in morph_results.keys(): + morph_params = morph_results[file] + morphapp_params = self.morphapp_results[file] + for key in morph_params.keys(): + assert morph_params[key] == pytest.approx( + morphapp_params[key], abs=1e-08 + ) + + def test_morphfuncy(self, setup_morph): + def gaussian(x, mu, sigma): + return np.exp(-((x - mu) ** 2) / (2 * sigma**2)) / ( + sigma * np.sqrt(2 * np.pi) + ) + + def gaussian_like_function(x, y, mu): + return gaussian((x + y) / 2, mu, 3) + + morph_r = np.linspace(0, 100, 1001) + morph_gr = np.linspace(0, 100, 1001) + + target_r = np.linspace(0, 100, 1001) + target_gr = 0.5 * gaussian(target_r, 50, 5) + 0.05 + + morph_info, _ = morph_arrays( + np.array([morph_r, morph_gr]).T, + np.array([target_r, target_gr]).T, + scale=1, + smear=3.75, + vshift=0.01, + funcy=(gaussian_like_function, {"mu": 47.5}), + tolerance=1e-12, + ) + + assert pytest.approx(morph_info["scale"]) == 0.5 + assert pytest.approx(morph_info["vshift"]) == 0.05 + assert pytest.approx(abs(morph_info["smear"])) == 4.0 + assert pytest.approx(morph_info["funcy"]["mu"]) == 50.0 + + # FIXME: + def test_morphfuncx(self, setup_morph): + def gaussian(x, mu, sigma): + return np.exp(-((x - mu) ** 2) / (2 * sigma**2)) / ( + sigma * np.sqrt(2 * np.pi) + ) + + def gaussian_like_function(x, y, mu): + return gaussian((x + y) / 2, mu, 3) + + morph_r = np.linspace(0, 100, 1001) + morph_gr = np.linspace(0, 100, 1001) + + target_r = np.linspace(0, 100, 1001) + target_gr = 0.5 * gaussian(target_r, 50, 5) + 0.05 + + morph_info, _ = morph_arrays( + np.array([morph_r, morph_gr]).T, + np.array([target_r, target_gr]).T, + scale=1, + smear=3.75, + vshift=0.01, + funcy=(gaussian_like_function, {"mu": 47.5}), + tolerance=1e-12, + ) + + assert pytest.approx(morph_info["scale"]) == 0.5 + assert pytest.approx(morph_info["vshift"]) == 0.05 + assert pytest.approx(abs(morph_info["smear"])) == 4.0 + assert pytest.approx(morph_info["funcy"]["mu"]) == 50.0 + + # FIXME: + def test_morphfuncxy(self, setup_morph): + def gaussian(x, mu, sigma): + return np.exp(-((x - mu) ** 2) / (2 * sigma**2)) / ( + sigma * np.sqrt(2 * np.pi) + ) + + def gaussian_like_function(x, y, mu): + return gaussian((x + y) / 2, mu, 3) + + morph_r = np.linspace(0, 100, 1001) + morph_gr = np.linspace(0, 100, 1001) + + target_r = np.linspace(0, 100, 1001) + target_gr = 0.5 * gaussian(target_r, 50, 5) + 0.05 + + morph_info, _ = morph_arrays( + np.array([morph_r, morph_gr]).T, + np.array([target_r, target_gr]).T, + scale=1, + smear=3.75, + vshift=0.01, + funcy=(gaussian_like_function, {"mu": 47.5}), + tolerance=1e-12, + ) + + assert pytest.approx(morph_info["scale"]) == 0.5 + assert pytest.approx(morph_info["vshift"]) == 0.05 + assert pytest.approx(abs(morph_info["smear"])) == 4.0 + assert pytest.approx(morph_info["funcy"]["mu"]) == 50.0 + + def test_morphpy_outputs(self, tmp_path): + r = np.linspace(0, 1, 11) + gr = np.linspace(0, 1, 11) + + def linear(x, y, s): + return s * (x + y) + + morph_info, _ = morph_arrays( + np.array([r, gr]).T, + np.array([r, gr]).T, + squeeze=[1, 2, 3, 4, 5], + funcy=(linear, {"s": 2.5}), + apply=True, + ) + + print(morph_info) + for i in range(5): + assert pytest.approx(morph_info["squeeze"][f"a{i}"]) == i + 1 + assert pytest.approx(morph_info["funcy"]["s"]) == 2.5 diff --git a/tests/test_morphrdftopdf.py b/tests/test_morphrdftopdf.py index 05fd09cb..207b6c0d 100644 --- a/tests/test_morphrdftopdf.py +++ b/tests/test_morphrdftopdf.py @@ -37,11 +37,3 @@ def test_transform(self, setup): assert numpy.allclose(rdf1, y_morph) assert numpy.allclose(rdf2, y_target) return - - -# End of class TestTransformXtalRDFtoPDF - -if __name__ == "__main__": - TestTransformXtalRDFtoPDF() - -# End of file diff --git a/tests/test_morphresolution.py b/tests/test_morphresolution.py index 40566113..c0d57ed0 100644 --- a/tests/test_morphresolution.py +++ b/tests/test_morphresolution.py @@ -35,11 +35,3 @@ def test_morph(self, setup): assert numpy.allclose(self.y_target, y_target) assert numpy.allclose(y_morph, y_target) return - - -# End of class TestMorphScale - -if __name__ == "__main__": - TestMorphScale() - -# End of file diff --git a/tests/test_morphrgrid.py b/tests/test_morphrgrid.py index 4187698c..8d85a2c2 100644 --- a/tests/test_morphrgrid.py +++ b/tests/test_morphrgrid.py @@ -27,9 +27,9 @@ def setup(self): def _runTests(self, xyallout, morph): x_morph, y_morph, x_target, y_target = xyallout assert (x_morph == x_target).all() - pytest.approx(x_morph[0], morph.rmin) - pytest.approx(x_morph[-1], morph.rmax - morph.rstep) - pytest.approx(x_morph[1] - x_morph[0], morph.rstep) + pytest.approx(x_morph[0], morph.xmin) + pytest.approx(x_morph[-1], morph.xmax - morph.xstep) + pytest.approx(x_morph[1] - x_morph[0], morph.xstep) pytest.approx(len(y_morph), len(y_target)) return @@ -37,78 +37,70 @@ def testRangeInBounds(self, setup): """Selected range is within input bounds.""" config = { - "rmin": 1.0, - "rmax": 2.0, - "rstep": 0.1, + "xmin": 1.0, + "xmax": 2.0, + "xstep": 0.1, } morph = MorphRGrid(config) xyallout = morph( self.x_morph, self.y_morph, self.x_target, self.y_target ) - pytest.approx(config["rmin"], morph.rmin) - pytest.approx(config["rmax"], morph.rmax) - pytest.approx(config["rstep"], morph.rstep) + pytest.approx(config["xmin"], morph.xmin) + pytest.approx(config["xmax"], morph.xmax) + pytest.approx(config["xstep"], morph.xstep) self._runTests(xyallout, morph) return - def testRmaxOut(self, setup): - """Selected rmax is outside of input bounds.""" + def testxmaxOut(self, setup): + """Selected xmax is outside of input bounds.""" config = { - "rmin": 1.0, - "rmax": 15.0, - "rstep": 0.1, + "xmin": 1.0, + "xmax": 15.0, + "xstep": 0.1, } morph = MorphRGrid(config) xyallout = morph( self.x_morph, self.y_morph, self.x_target, self.y_target ) - pytest.approx(config["rmin"], morph.rmin) - pytest.approx(5, morph.rmax) - pytest.approx(config["rstep"], morph.rstep) + pytest.approx(config["xmin"], morph.xmin) + pytest.approx(5, morph.xmax) + pytest.approx(config["xstep"], morph.xstep) self._runTests(xyallout, morph) return - def testRminOut(self, setup): - """Selected rmin is outside of input bounds.""" + def testxminOut(self, setup): + """Selected xmin is outside of input bounds.""" config = { - "rmin": 0.0, - "rmax": 2.0, - "rstep": 0.01, + "xmin": 0.0, + "xmax": 2.0, + "xstep": 0.01, } morph = MorphRGrid(config) xyallout = morph( self.x_morph, self.y_morph, self.x_target, self.y_target ) - pytest.approx(1.0, morph.rmin) - pytest.approx(config["rmax"], morph.rmax) - pytest.approx(config["rstep"], morph.rstep) + pytest.approx(1.0, morph.xmin) + pytest.approx(config["xmax"], morph.xmax) + pytest.approx(config["xstep"], morph.xstep) self._runTests(xyallout, morph) return - def testRstepOut(self, setup): - """Selected rstep is outside of input bounds.""" + def testxstepOut(self, setup): + """Selected xstep is outside of input bounds.""" config = { - "rmin": 1.0, - "rmax": 2.0, - "rstep": 0.001, + "xmin": 1.0, + "xmax": 2.0, + "xstep": 0.001, } morph = MorphRGrid(config) xyallout = morph( self.x_morph, self.y_morph, self.x_target, self.y_target ) - pytest.approx(config["rmin"], morph.rmin) - pytest.approx(config["rmax"], morph.rmax) - pytest.approx(0.01, morph.rstep) + pytest.approx(config["xmin"], morph.xmin) + pytest.approx(config["xmax"], morph.xmax) + pytest.approx(0.01, morph.xstep) self._runTests(xyallout, morph) return - - -# End of class TestMorphRGrid - -if __name__ == "__main__": - TestMorphRGrid() - -# End of file diff --git a/tests/test_morphscale.py b/tests/test_morphscale.py index fa39042c..e52159f8 100644 --- a/tests/test_morphscale.py +++ b/tests/test_morphscale.py @@ -35,11 +35,3 @@ def test_morph(self, setup): assert numpy.allclose(2 * self.y_morph, y_morph) assert numpy.allclose(self.y_target, y_target) return - - -# End of class TestMorphScale - -if __name__ == "__main__": - TestMorphScale() - -# End of file diff --git a/tests/test_morphshape.py b/tests/test_morphshape.py index 18cd49ad..6e309d11 100644 --- a/tests/test_morphshape.py +++ b/tests/test_morphshape.py @@ -45,13 +45,14 @@ def test_morph(self, setup): class TestMorphSpheroid: # Common configs for testing MorphSpheroid and MorphISpheroid - # FIXME: add test data for prolate spheroids config_sphere = {"radius": 17.5, "pradius": 17.5} config_oblate = {"radius": 17.5, "pradius": 5.0} - spheroid_configs = [config_sphere, config_oblate] + config_prolate = {"radius": 5.0, "pradius": 17.5} + spheroid_configs = [config_sphere, config_oblate, config_prolate] iconfig_sphere = {"iradius": 17.5, "ipradius": 17.5} iconfig_oblate = {"iradius": 17.5, "ipradius": 5.0} - ispheroid_configs = [iconfig_sphere, iconfig_oblate] + iconfig_prolate = {"iradius": 5.0, "ipradius": 17.5} + ispheroid_configs = [iconfig_sphere, iconfig_oblate, iconfig_prolate] # Files used for testing flag_inverse = ( @@ -60,6 +61,7 @@ class TestMorphSpheroid: testfiles = [ ["ni_qmax25.cgr", "ni_qmax25_psize35.cgr"], # Sphere ["ni_qmax25.cgr", "ni_qmax25_e17.5_p5.0.cgr"], # Oblate spheroid + ["ni_qmax25.cgr", "ni_qmax25_e5.0_p17.5.cgr"], # Prolate spheroid ] testfile = [] # Initialize testfile array @@ -123,12 +125,3 @@ def ishape_test_helper(self, config): else: # Outside the particle morph should be zero assert y_morph[idx] == 0 return - - -# End of class TestMorphSpheroid - -if __name__ == "__main__": - TestMorphSphere() - TestMorphSpheroid() - -# End of file diff --git a/tests/test_morphshift.py b/tests/test_morphshift.py index 895022d7..1ae2e0f7 100644 --- a/tests/test_morphshift.py +++ b/tests/test_morphshift.py @@ -6,7 +6,10 @@ import numpy import pytest +import diffpy.morph.morphpy as morphpy +from diffpy.morph.morphapp import create_option_parser, single_morph from diffpy.morph.morphs.morphshift import MorphShift +from tests.helper import create_morph_data_file # useful variables thisfile = locals().get("__file__", "file.py") @@ -46,9 +49,59 @@ def test_morph(self, setup): return -# End of class TestMorphScale - -if __name__ == "__main__": - TestMorphShift() - -# End of file +@pytest.mark.parametrize( + "hshift, wmsg_gen", + [ + # extrapolate below + ( + 0.01, + lambda x: ( + "Warning: points with grid value below " + f"{x[0]} are extrapolated." + ), + ), + # extrapolate above + ( + -0.01, + lambda x: ( + "Warning: points with grid value above " + f"{x[1]} are extrapolated." + ), + ), + ], +) +def test_morphshift_extrapolate(user_filesystem, capsys, hshift, wmsg_gen): + x_morph = numpy.linspace(0, 10, 101) + y_morph = numpy.sin(x_morph) + x_target = x_morph.copy() + y_target = y_morph.copy() + with pytest.warns() as w: + morphpy.morph_arrays( + numpy.array([x_morph, y_morph]).T, + numpy.array([x_target, y_target]).T, + hshift=hshift, + apply=True, + ) + assert len(w) == 1 + assert w[0].category is UserWarning + actual_wmsg = str(w[0].message) + expected_wmsg = wmsg_gen([min(x_morph), max(x_morph)]) + assert actual_wmsg == expected_wmsg + + # CLI test + morph_file, target_file = create_morph_data_file( + user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target + ) + + parser = create_option_parser() + (opts, pargs) = parser.parse_args( + [ + f"--hshift={hshift}", + f"{morph_file.as_posix()}", + f"{target_file.as_posix()}", + "--apply", + "-n", + ] + ) + with pytest.warns(UserWarning, match=expected_wmsg): + single_morph(parser, opts, pargs, stdout_flag=False) diff --git a/tests/test_morphsmear.py b/tests/test_morphsmear.py index a0162840..b05d237d 100644 --- a/tests/test_morphsmear.py +++ b/tests/test_morphsmear.py @@ -46,11 +46,3 @@ def test_morph(self, setup): assert numpy.allclose(ysmear, y_morph) return - - -# End of class TestMorphSmear - -if __name__ == "__main__": - TestMorphSmear() - -# End of file diff --git a/tests/test_morphsqueeze.py b/tests/test_morphsqueeze.py index e5ce2a56..07b99372 100644 --- a/tests/test_morphsqueeze.py +++ b/tests/test_morphsqueeze.py @@ -2,7 +2,10 @@ import pytest from numpy.polynomial import Polynomial +import diffpy.morph.morphpy as morphpy +from diffpy.morph.morphapp import create_option_parser, single_morph from diffpy.morph.morphs.morphsqueeze import MorphSqueeze +from tests.helper import create_morph_data_file squeeze_coeffs_dic = [ # The order of coefficients is {a0, a1, a2, ..., an} @@ -44,44 +47,126 @@ @pytest.mark.parametrize("squeeze_coeffs", squeeze_coeffs_dic) def test_morphsqueeze(x_morph, x_target, squeeze_coeffs): y_target = np.sin(x_target) + y_morph = np.sin(x_morph) + # expected output + y_morph_expected = y_morph + x_morph_expected = x_morph + x_target_expected = x_target + y_target_expected = y_target + # actual output coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))] squeeze_polynomial = Polynomial(coeffs) x_squeezed = x_morph + squeeze_polynomial(x_morph) y_morph = np.sin(x_squeezed) - low_extrap = np.where(x_morph < x_squeezed[0])[0] - high_extrap = np.where(x_morph > x_squeezed[-1])[0] - extrap_index_low_expected = low_extrap[-1] if low_extrap.size else None - extrap_index_high_expected = high_extrap[0] if high_extrap.size else None - x_morph_expected = x_morph - y_morph_expected = np.sin(x_morph) morph = MorphSqueeze() morph.squeeze = squeeze_coeffs x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = morph( x_morph, y_morph, x_target, y_target ) - extrap_index_low = morph.extrap_index_low - extrap_index_high = morph.extrap_index_high - if extrap_index_low is None: - extrap_index_low = 0 - elif extrap_index_high is None: - extrap_index_high = -1 + + extrap_low = np.where(x_morph < min(x_squeezed))[0] + extrap_high = np.where(x_morph > max(x_squeezed))[0] + extrap_index_low_expected = extrap_low[-1] if extrap_low.size else 0 + extrap_index_high_expected = extrap_high[0] if extrap_high.size else -1 + + extrapolation_info = morph.extrapolation_info + extrap_index_low_actual = extrapolation_info["extrap_index_low"] + extrap_index_high_actual = extrapolation_info["extrap_index_high"] + assert np.allclose( - y_morph_actual[extrap_index_low + 1 : extrap_index_high], - y_morph_expected[extrap_index_low + 1 : extrap_index_high], + y_morph_actual[ + extrap_index_low_expected + 1 : extrap_index_high_expected + ], + y_morph_expected[ + extrap_index_low_expected + 1 : extrap_index_high_expected + ], atol=1e-6, ) assert np.allclose( - y_morph_actual[:extrap_index_low], - y_morph_expected[:extrap_index_low], + y_morph_actual[:extrap_index_low_expected], + y_morph_expected[:extrap_index_low_expected], atol=1e-3, ) assert np.allclose( - y_morph_actual[extrap_index_high:], - y_morph_expected[extrap_index_high:], + y_morph_actual[extrap_index_high_expected:], + y_morph_expected[extrap_index_high_expected:], atol=1e-3, ) - assert morph.extrap_index_low == extrap_index_low_expected - assert morph.extrap_index_high == extrap_index_high_expected assert np.allclose(x_morph_actual, x_morph_expected) - assert np.allclose(x_target_actual, x_target) - assert np.allclose(y_target_actual, y_target) + assert np.allclose(x_target_actual, x_target_expected) + assert np.allclose(y_target_actual, y_target_expected) + assert extrap_index_low_actual == extrap_index_low_expected + assert extrap_index_high_actual == extrap_index_high_expected + + +@pytest.mark.parametrize( + "squeeze_coeffs, wmsg_gen", + [ + # extrapolate below + ( + {"a0": 0.01}, + lambda x: ( + "Warning: points with grid value below " + f"{x[0]} are extrapolated." + ), + ), + # extrapolate above + ( + {"a0": -0.01}, + lambda x: ( + "Warning: points with grid value above " + f"{x[1]} are extrapolated." + ), + ), + # extrapolate below and above + ( + {"a0": 0.01, "a1": -0.002}, + lambda x: ( + "Warning: points with grid value below " + f"{x[0]} and above {x[1]} are " + "extrapolated." + ), + ), + ], +) +def test_morphsqueeze_extrapolate(user_filesystem, squeeze_coeffs, wmsg_gen): + x_morph = np.linspace(0, 10, 101) + y_morph = np.sin(x_morph) + x_target = x_morph.copy() + y_target = y_morph.copy() + morph = MorphSqueeze() + morph.squeeze = squeeze_coeffs + coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))] + squeeze_polynomial = Polynomial(coeffs) + x_squeezed = x_morph + squeeze_polynomial(x_morph) + with pytest.warns() as w: + morphpy.morph_arrays( + np.array([x_morph, y_morph]).T, + np.array([x_target, y_target]).T, + squeeze=coeffs, + apply=True, + ) + assert len(w) == 1 + assert w[0].category is UserWarning + actual_wmsg = str(w[0].message) + expected_wmsg = wmsg_gen([min(x_squeezed), max(x_squeezed)]) + assert actual_wmsg == expected_wmsg + + # CLI test + morph_file, target_file = create_morph_data_file( + user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target + ) + + parser = create_option_parser() + (opts, pargs) = parser.parse_args( + [ + "--squeeze", + ",".join(map(str, coeffs)), + f"{morph_file.as_posix()}", + f"{target_file.as_posix()}", + "--apply", + "-n", + ] + ) + with pytest.warns(UserWarning, match=expected_wmsg): + single_morph(parser, opts, pargs, stdout_flag=False) diff --git a/tests/test_morphstretch.py b/tests/test_morphstretch.py index 8137b166..311c92e4 100644 --- a/tests/test_morphstretch.py +++ b/tests/test_morphstretch.py @@ -6,7 +6,10 @@ import numpy import pytest +import diffpy.morph.morphpy as morphpy +from diffpy.morph.morphapp import create_option_parser, single_morph from diffpy.morph.morphs.morphstretch import MorphStretch +from tests.helper import create_morph_data_file # useful variables thisfile = locals().get("__file__", "file.py") @@ -64,9 +67,6 @@ def test_morph(self, setup): return -# End of class TestMorphSmear - - def heaviside(x, lb, ub): """The Heaviside function.""" y = numpy.ones_like(x) @@ -75,7 +75,59 @@ def heaviside(x, lb, ub): return y -if __name__ == "__main__": - TestMorphStretch() - -# End of file +@pytest.mark.parametrize( + "stretch, wmsg_gen", + [ + # extrapolate below + ( + 0.01, + lambda x: ( + "Warning: points with grid value below " + f"{x[0]} are extrapolated." + ), + ), + # extrapolate above + ( + -0.01, + lambda x: ( + "Warning: points with grid value above " + f"{x[1]} are extrapolated." + ), + ), + ], +) +def test_morphshift_extrapolate(user_filesystem, stretch, wmsg_gen): + x_morph = numpy.linspace(1, 10, 101) + y_morph = numpy.sin(x_morph) + x_target = x_morph.copy() + y_target = y_morph.copy() + with pytest.warns() as w: + morphpy.morph_arrays( + numpy.array([x_morph, y_morph]).T, + numpy.array([x_target, y_target]).T, + stretch=stretch, + apply=True, + ) + assert len(w) == 1 + assert w[0].category is UserWarning + actual_wmsg = str(w[0].message) + expected_wmsg = wmsg_gen([min(x_morph), max(x_morph)]) + assert actual_wmsg == expected_wmsg + + # CLI test + morph_file, target_file = create_morph_data_file( + user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target + ) + + parser = create_option_parser() + (opts, pargs) = parser.parse_args( + [ + f"--stretch={stretch}", + f"{morph_file.as_posix()}", + f"{target_file.as_posix()}", + "--apply", + "-n", + ] + ) + with pytest.warns(UserWarning, match=expected_wmsg): + single_morph(parser, opts, pargs, stdout_flag=False) diff --git a/tests/test_refine.py b/tests/test_refine.py index 33d8d4ac..b64bccd1 100644 --- a/tests/test_refine.py +++ b/tests/test_refine.py @@ -8,7 +8,10 @@ from diffpy.morph.morph_helpers.transformpdftordf import TransformXtalPDFtoRDF from diffpy.morph.morph_helpers.transformrdftopdf import TransformXtalRDFtoPDF +from diffpy.morph.morphapp import create_option_parser, single_morph from diffpy.morph.morphs.morphchain import MorphChain +from diffpy.morph.morphs.morphfuncx import MorphFuncx +from diffpy.morph.morphs.morphrgrid import MorphRGrid from diffpy.morph.morphs.morphscale import MorphScale from diffpy.morph.morphs.morphsmear import MorphSmear from diffpy.morph.morphs.morphstretch import MorphStretch @@ -46,7 +49,7 @@ def test_refine_morph(self, setup): assert (x_morph == x_target).all() assert numpy.allclose(y_morph, y_target) - pytest.approx(config["scale"], 3.0) + assert pytest.approx(config["scale"]) == 3.0 return def test_refine_chain(self, setup): @@ -74,10 +77,165 @@ def test_refine_chain(self, setup): err = 15.0 * 2 res = sum(numpy.fabs(y_target - y_morph)) assert res < err - pytest.approx(chain.scale, 3, 2) - pytest.approx(chain.stretch, 0.1, 2) + assert pytest.approx(chain.scale, 0.01, 0.01) == 3.0 + assert pytest.approx(chain.stretch, 0.01, 0.01) == 0.1 return + def test_refine_tolerance(self, setup): + # Check that small tolerance gives good result + stol = 1e-16 + config = { + "scale": 1.0, + } + mscale = MorphScale(config) + refiner = Refiner( + mscale, + self.x_morph, + self.y_morph, + self.x_target, + self.y_target, + tolerance=stol, + ) + refiner.refine() + assert pytest.approx(config["scale"], stol, stol) == 3.0 + + # Check that larger tolerance does not give as good of result + ltol = 100 + config = { + "scale": 1.0, + } + mscale = MorphScale(config) + refiner = Refiner( + mscale, + self.x_morph, + self.y_morph, + self.x_target, + self.y_target, + tolerance=ltol, + ) + refiner.refine() + assert not pytest.approx(config["scale"], stol, stol) == 3.0 + return + + def test_refine_grid_change(self): + err = 1e-08 + + # First test what occurs when the grid overlap increases + # As we shift, the overlap number increases + # In this case, overlap goes from 41 -> 51 + exp_hshift = 1 + grid1 = numpy.linspace(0, 5, 51) + grid2 = numpy.linspace(0 + exp_hshift, 5 + exp_hshift, 51) + func1 = numpy.zeros(grid1.shape) + func1[(1 < grid1) & (grid1 < 4)] = 1 + func2 = numpy.zeros(grid2.shape) + func2[(1 + exp_hshift < grid2) & (grid2 < 4 + exp_hshift)] = 1 + + def shift(x, y, hshift): + return x + hshift + + config = { + "funcx_function": shift, + "funcx": {"hshift": 0}, + "xmin": 0, + "xmax": 7, + "xstep": 0.01, + } + + mfuncx = MorphFuncx(config) + mrgrid = MorphRGrid(config) + chain = MorphChain(config, mfuncx, mrgrid) + refiner = Refiner(chain, grid1, func1, grid2, func2) + refpars = ["funcx"] + res = refiner.refine(*refpars) + + assert res < err + + # Second test when the grid overlap decreases + # As we stretch, the grid spacing increases + # Thus, the overlap number decreases + # For this test, overlap goes from 12 -> 10 + grid1 = numpy.linspace(0, 4, 41) + grid2 = numpy.linspace(2, 4, 21) + func1 = numpy.zeros(grid1.shape) + func1[grid1 <= 2] = 1 + func1[2 < grid1] = 2 + func2 = numpy.zeros(grid2.shape) + 1 + + def stretch(x, y, stretch): + return x * (1 + stretch) + + config = { + "funcx_function": stretch, + "funcx": {"stretch": 0.7}, + "xmin": 0, + "xmax": 4, + "xstep": 0.01, + } + + mfuncx = MorphFuncx(config) + mrgrid = MorphRGrid(config) + chain = MorphChain(config, mfuncx, mrgrid) + refiner = Refiner(chain, grid1, func1, grid2, func2) + refpars = ["funcx"] + res = refiner.refine(*refpars) + + assert res < err + + def test_refine_grid_bad(self, user_filesystem, capsys): + grid = numpy.arange(2) + func = numpy.sin(grid) + grid1, func1, grid2, func2 = grid, func, grid, func + config = { + "stretch": 0.005, + "scale": 1.0, + "smear": 0, + } + chain = MorphChain(config) + refiner = Refiner(chain, grid1, func1, grid2, func2) + refpars = ["stretch", "scale", "smear"] + expected_error_message = ( + "\nNumber of parameters (currently 3) cannot " + "exceed the number of shared grid points " + "(currently 2). " + "Please reduce the number of morphing parameters or " + "provide new morphing and target functions with more " + "shared grid points." + ) + with pytest.raises( + ValueError, + ) as error: + refiner.refine(*refpars) + actual_error_message = str(error.value) + assert actual_error_message == expected_error_message + + # Test from command line + data_dir_path = user_filesystem / "cwd_dir" + morph_file = data_dir_path / "morph_data" + morph_data_text = [ + str(grid1[i]) + " " + str(func1[i]) for i in range(len(grid1)) + ] + morph_data_text = "\n".join(morph_data_text) + morph_file.write_text(morph_data_text) + target_file = data_dir_path / "target_data" + target_data_text = [ + str(grid2[i]) + " " + str(func2[i]) for i in range(len(grid2)) + ] + target_data_text = "\n".join(target_data_text) + target_file.write_text(target_data_text) + run_cmd = [] + for key, value in config.items(): + run_cmd.append(f"--{key}") + run_cmd.append(f"{value}") + run_cmd.extend([str(morph_file), str(target_file)]) + run_cmd.append("-n") + parser = create_option_parser() + (opts, pargs) = parser.parse_args(run_cmd) + with pytest.raises(SystemExit): + single_morph(parser, opts, pargs, stdout_flag=False) + _, err = capsys.readouterr() + assert expected_error_message in actual_error_message + # End of class TestRefine @@ -131,10 +289,3 @@ def test_refine(self, setup): rw = (numpy.dot(diff, diff) / numpy.dot(yrsel, yrsel)) ** 0.5 assert rw < 0.01 return - - -if __name__ == "__main__": - TestRefine() - TestRefineUC() - -# End of file diff --git a/tests/test_tools.py b/tests/test_tools.py index 4fcbd7f0..ee4c00c9 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -153,11 +153,3 @@ def test_get_values_from_dictionary_collection(self): ) == target_list ) - - -# End of class TestTools - -if __name__ == "__main__": - TestTools() - -# End of file diff --git a/tests/testdata/funcy_target.cgr b/tests/testdata/funcy_target.cgr new file mode 100644 index 00000000..fa36dc6b --- /dev/null +++ b/tests/testdata/funcy_target.cgr @@ -0,0 +1,136 @@ +# PDF created by diffpy.morph +# from NO FILE PATH PROVIDED + +# Input morphing parameters: +# scale = None +# stretch = None +# smear = None +# hshift = None +# vshift = None +# squeeze a0 = 0.0 +# squeeze a1 = 0.0 +# squeeze a2 = 0.0 +# funcy a0 = 1.0 +# funcy a1 = 2.0 +# funcy a2 = 3.0 +# funcy function = +""" +def quadratic(x, y, a0, a1, a2): + return a0 + a1 * x + a2 * y**2 +""" + +# Optimized morphing parameters: +# xmin = 0.000000 +# xmax = 10.100000 +# xstep = 0.100000 +# squeeze a0 = 0.000000 +# squeeze a1 = 0.000000 +# squeeze a2 = 0.000000 +# funcy a0 = 1.000000 +# funcy a1 = 2.000000 +# funcy a2 = 3.000000 +# Rw = 0.000000 +# Pearson = 1.000000 + +# Labels: [r] [gr] +0.000000000000000000e+00 1.000000000000000000e+00 +1.000000000000000056e-01 1.229999999999999982e+00 +2.000000000000000111e-01 1.520000000000000018e+00 +3.000000000000000444e-01 1.870000000000000107e+00 +4.000000000000000222e-01 2.280000000000000249e+00 +5.000000000000000000e-01 2.750000000000000000e+00 +6.000000000000000888e-01 3.280000000000000249e+00 +7.000000000000000666e-01 3.870000000000000551e+00 +8.000000000000000444e-01 4.520000000000000462e+00 +9.000000000000000222e-01 5.230000000000000426e+00 +1.000000000000000000e+00 6.000000000000000000e+00 +1.100000000000000089e+00 6.830000000000000959e+00 +1.200000000000000178e+00 7.720000000000001528e+00 +1.300000000000000044e+00 8.669999999999999929e+00 +1.400000000000000133e+00 9.680000000000001492e+00 +1.500000000000000000e+00 1.075000000000000000e+01 +1.600000000000000089e+00 1.188000000000000256e+01 +1.700000000000000178e+00 1.307000000000000206e+01 +1.800000000000000044e+00 1.432000000000000028e+01 +1.900000000000000133e+00 1.563000000000000256e+01 +2.000000000000000000e+00 1.700000000000000000e+01 +2.100000000000000089e+00 1.842999999999999972e+01 +2.200000000000000178e+00 1.992000000000000171e+01 +2.300000000000000266e+00 2.147000000000000242e+01 +2.400000000000000355e+00 2.308000000000000540e+01 +2.500000000000000000e+00 2.475000000000000000e+01 +2.600000000000000089e+00 2.648000000000000043e+01 +2.700000000000000178e+00 2.827000000000000313e+01 +2.800000000000000266e+00 3.012000000000000455e+01 +2.900000000000000355e+00 3.203000000000000114e+01 +3.000000000000000000e+00 3.400000000000000000e+01 +3.100000000000000089e+00 3.603000000000000824e+01 +3.200000000000000178e+00 3.812000000000000455e+01 +3.300000000000000266e+00 4.027000000000001023e+01 +3.400000000000000355e+00 4.248000000000000398e+01 +3.500000000000000000e+00 4.475000000000000000e+01 +3.600000000000000089e+00 4.707999999999999829e+01 +3.700000000000000178e+00 4.947000000000000597e+01 +3.800000000000000266e+00 5.192000000000000881e+01 +3.900000000000000355e+00 5.443000000000000682e+01 +4.000000000000000000e+00 5.700000000000000000e+01 +4.100000000000000533e+00 5.963000000000002387e+01 +4.200000000000000178e+00 6.232000000000000028e+01 +4.299999999999999822e+00 6.506999999999999318e+01 +4.400000000000000355e+00 6.788000000000000966e+01 +4.500000000000000000e+00 7.075000000000000000e+01 +4.600000000000000533e+00 7.368000000000000682e+01 +4.700000000000000178e+00 7.667000000000001592e+01 +4.800000000000000711e+00 7.972000000000002728e+01 +4.900000000000000355e+00 8.283000000000001251e+01 +5.000000000000000000e+00 8.600000000000000000e+01 +5.100000000000000533e+00 8.923000000000001819e+01 +5.200000000000000178e+00 9.252000000000001023e+01 +5.300000000000000711e+00 9.587000000000003297e+01 +5.400000000000000355e+00 9.928000000000001535e+01 +5.500000000000000000e+00 1.027500000000000000e+02 +5.600000000000000533e+00 1.062800000000000153e+02 +5.700000000000000178e+00 1.098700000000000045e+02 +5.800000000000000711e+00 1.135200000000000102e+02 +5.900000000000000355e+00 1.172300000000000040e+02 +6.000000000000000000e+00 1.210000000000000000e+02 +6.100000000000000533e+00 1.248300000000000267e+02 +6.200000000000000178e+00 1.287200000000000273e+02 +6.300000000000000711e+00 1.326700000000000443e+02 +6.400000000000000355e+00 1.366800000000000352e+02 +6.500000000000000000e+00 1.407500000000000000e+02 +6.600000000000000533e+00 1.448800000000000239e+02 +6.700000000000000178e+00 1.490700000000000216e+02 +6.800000000000000711e+00 1.533200000000000216e+02 +6.900000000000000355e+00 1.576300000000000239e+02 +7.000000000000000000e+00 1.620000000000000000e+02 +7.100000000000000533e+00 1.664300000000000068e+02 +7.200000000000000178e+00 1.709200000000000159e+02 +7.300000000000000711e+00 1.754700000000000273e+02 +7.400000000000000355e+00 1.800800000000000409e+02 +7.500000000000000000e+00 1.847500000000000000e+02 +7.600000000000000533e+00 1.894800000000000182e+02 +7.700000000000000178e+00 1.942700000000000102e+02 +7.800000000000000711e+00 1.991200000000000330e+02 +7.900000000000000355e+00 2.040300000000000296e+02 +8.000000000000000000e+00 2.090000000000000000e+02 +8.099999999999999645e+00 2.140299999999999727e+02 +8.200000000000001066e+00 2.191200000000000898e+02 +8.300000000000000711e+00 2.242700000000000387e+02 +8.400000000000000355e+00 2.294800000000000182e+02 +8.500000000000000000e+00 2.347500000000000000e+02 +8.599999999999999645e+00 2.400799999999999841e+02 +8.700000000000001066e+00 2.454700000000000557e+02 +8.800000000000000711e+00 2.509200000000000443e+02 +8.900000000000000355e+00 2.564300000000000068e+02 +9.000000000000000000e+00 2.620000000000000000e+02 +9.099999999999999645e+00 2.676299999999999386e+02 +9.200000000000001066e+00 2.733200000000000500e+02 +9.300000000000000711e+00 2.790700000000000500e+02 +9.400000000000000355e+00 2.848800000000000523e+02 +9.500000000000000000e+00 2.907500000000000000e+02 +9.600000000000001421e+00 2.966800000000000637e+02 +9.700000000000001066e+00 3.026700000000000159e+02 +9.800000000000000711e+00 3.087200000000000841e+02 +9.900000000000000355e+00 3.148300000000000409e+02 +1.000000000000000000e+01 3.210000000000000000e+02 diff --git a/tests/testdata/ni_qmax25_e5.0_p17.5.cgr b/tests/testdata/ni_qmax25_e5.0_p17.5.cgr new file mode 100644 index 00000000..70846dfc --- /dev/null +++ b/tests/testdata/ni_qmax25_e5.0_p17.5.cgr @@ -0,0 +1,4006 @@ +# qmax = 25 +# erad = 5.0 +# prad = 17.5 + +##### start data +#L r(A) G(r) +0.000000000000000000e+00 0.000000000000000000e+00 +1.000000000000000021e-02 -1.241842098860425521e-02 +2.000000000000000042e-02 -2.474426803467946745e-02 +2.999999999999999889e-02 -3.691951840649777133e-02 +4.000000000000000083e-02 -4.889415088366782375e-02 +5.000000000000000278e-02 -6.062934821187750123e-02 +5.999999999999999778e-02 -7.209999266033891019e-02 +7.000000000000000666e-02 -8.329629877624560030e-02 +8.000000000000000167e-02 -9.422448022583837512e-02 +8.999999999999999667e-02 -1.049064067425640456e-01 +1.000000000000000056e-01 -1.153782691624341827e-01 +1.100000000000000006e-01 -1.256883316278638585e-01 +1.199999999999999956e-01 -1.358939066321427080e-01 +1.300000000000000044e-01 -1.460577372475404256e-01 +1.400000000000000133e-01 -1.562440086665493055e-01 +1.499999999999999944e-01 -1.665142357399460593e-01 +1.600000000000000033e-01 -1.769232829317587130e-01 +1.700000000000000122e-01 -1.875157673033696626e-01 +1.799999999999999933e-01 -1.983230739753222838e-01 +1.900000000000000022e-01 -2.093611780962537083e-01 +2.000000000000000111e-01 -2.206294196379871564e-01 +2.099999999999999922e-01 -2.321103200556200175e-01 +2.200000000000000011e-01 -2.437704663364216595e-01 +2.300000000000000100e-01 -2.555624219687446796e-01 +2.399999999999999911e-01 -2.674275598621673189e-01 +2.500000000000000000e-01 -2.792996531889782585e-01 +2.600000000000000089e-01 -2.911090101871352531e-01 +2.700000000000000178e-01 -3.027869013760093875e-01 +2.800000000000000266e-01 -3.142700049156627040e-01 +2.899999999999999800e-01 -3.255045896668695704e-01 +2.999999999999999889e-01 -3.364501665913389727e-01 +3.099999999999999978e-01 -3.470823671458333481e-01 +3.200000000000000067e-01 -3.573948509064254764e-01 +3.300000000000000155e-01 -3.674001014651009367e-01 +3.400000000000000244e-01 -3.771290364615907942e-01 +3.500000000000000333e-01 -3.866294305480581506e-01 +3.599999999999999867e-01 -3.959632247624254031e-01 +3.699999999999999956e-01 -4.052028676182575229e-01 +3.800000000000000044e-01 -4.144268976750756783e-01 +3.900000000000000133e-01 -4.237150302389533496e-01 +4.000000000000000222e-01 -4.331430485705656808e-01 +4.100000000000000311e-01 -4.427778197999228671e-01 +4.199999999999999845e-01 -4.526727559540421608e-01 +4.299999999999999933e-01 -4.628640205578690159e-01 +4.400000000000000022e-01 -4.733677418722169183e-01 +4.500000000000000111e-01 -4.841784369205336391e-01 +4.600000000000000200e-01 -4.952687791144974594e-01 +4.700000000000000289e-01 -5.065907605942598924e-01 +4.799999999999999822e-01 -5.180782131992448525e-01 +4.899999999999999911e-01 -5.296505646139979540e-01 +5.000000000000000000e-01 -5.412176241972972424e-01 +5.100000000000000089e-01 -5.526851216358920071e-01 +5.200000000000000178e-01 -5.639606656936261286e-01 +5.300000000000000266e-01 -5.749597539475218566e-01 +5.400000000000000355e-01 -5.856114504035534463e-01 +5.500000000000000444e-01 -5.958633578291592237e-01 +5.600000000000000533e-01 -6.056855456249752301e-01 +5.700000000000000622e-01 -6.150731506612144850e-01 +5.799999999999999600e-01 -6.240474448247859129e-01 +5.899999999999999689e-01 -6.326552548164973144e-01 +5.999999999999999778e-01 -6.409667216433263537e-01 +6.099999999999999867e-01 -6.490714930932055537e-01 +6.199999999999999956e-01 -6.570735456370915273e-01 +6.300000000000000044e-01 -6.650849260114021222e-01 +6.400000000000000133e-01 -6.732187809111005450e-01 +6.500000000000000222e-01 -6.815821002819131280e-01 +6.600000000000000311e-01 -6.902686313225522285e-01 +6.700000000000000400e-01 -6.993524236606342148e-01 +6.800000000000000488e-01 -7.088824401322504354e-01 +6.900000000000000577e-01 -7.188786128975985790e-01 +7.000000000000000666e-01 -7.293296438469978327e-01 +7.099999999999999645e-01 -7.401927457266611610e-01 +7.199999999999999734e-01 -7.513954020129375300e-01 +7.299999999999999822e-01 -7.628390963649758216e-01 +7.399999999999999911e-01 -7.744048343641924959e-01 +7.500000000000000000e-01 -7.859601593957967758e-01 +7.600000000000000089e-01 -7.973672589370319752e-01 +7.700000000000000178e-01 -8.084916744647597797e-01 +7.800000000000000266e-01 -8.192110737499606055e-01 +7.900000000000000355e-01 -8.294235228973887430e-01 +8.000000000000000444e-01 -8.390547095678119183e-01 +8.100000000000000533e-01 -8.480636186385964725e-01 +8.200000000000000622e-01 -8.564462450779287694e-01 +8.300000000000000711e-01 -8.642370417546210160e-01 +8.399999999999999689e-01 -8.715079359729670516e-01 +8.499999999999999778e-01 -8.783648997068246311e-01 +8.599999999999999867e-01 -8.849422155712998173e-01 +8.699999999999999956e-01 -8.913947335918191994e-01 +8.800000000000000044e-01 -8.978885528229660906e-01 +8.900000000000000133e-01 -9.045906774209534484e-01 +9.000000000000000222e-01 -9.116582806737836275e-01 +9.100000000000000311e-01 -9.192282563011452412e-01 +9.200000000000000400e-01 -9.274077398543313366e-01 +9.300000000000000488e-01 -9.362662426663754811e-01 +9.400000000000000577e-01 -9.458299576916856521e-01 +9.500000000000000666e-01 -9.560786746951156490e-01 +9.599999999999999645e-01 -9.669455881942231601e-01 +9.699999999999999734e-01 -9.783201042088189858e-01 +9.799999999999999822e-01 -9.900535619062584836e-01 +9.899999999999999911e-01 -1.001967595489957619e+00 +1.000000000000000000e+00 -1.013864682442248144e+00 +1.010000000000000009e+00 -1.025540268439300240e+00 +1.020000000000000018e+00 -1.036795737724250710e+00 +1.030000000000000027e+00 -1.047451419414810125e+00 +1.040000000000000036e+00 -1.057358791599678050e+00 +1.050000000000000044e+00 -1.066411069613036222e+00 +1.060000000000000053e+00 -1.074551442721703332e+00 +1.070000000000000062e+00 -1.081778351330887844e+00 +1.080000000000000071e+00 -1.088147368092966305e+00 +1.090000000000000080e+00 -1.093769451349477562e+00 +1.100000000000000089e+00 -1.098805566017122981e+00 +1.110000000000000098e+00 -1.103457901415422659e+00 +1.120000000000000107e+00 -1.107958142747261787e+00 +1.130000000000000115e+00 -1.112553458078555879e+00 +1.140000000000000124e+00 -1.117491031754356490e+00 +1.150000000000000133e+00 -1.123002096137525996e+00 +1.159999999999999920e+00 -1.129286476980079890e+00 +1.169999999999999929e+00 -1.136498667657103168e+00 +1.179999999999999938e+00 -1.144736381836280348e+00 +1.189999999999999947e+00 -1.154032405014500773e+00 +1.199999999999999956e+00 -1.164350378986878543e+00 +1.209999999999999964e+00 -1.175584919882267654e+00 +1.219999999999999973e+00 -1.187566203435240997e+00 +1.229999999999999982e+00 -1.200068866808417845e+00 +1.239999999999999991e+00 -1.212824792325474466e+00 +1.250000000000000000e+00 -1.225539073277901014e+00 +1.260000000000000009e+00 -1.237908233274240377e+00 +1.270000000000000018e+00 -1.249639594383761265e+00 +1.280000000000000027e+00 -1.260470578701354594e+00 +1.290000000000000036e+00 -1.270186692238491011e+00 +1.300000000000000044e+00 -1.278636984011157551e+00 +1.310000000000000053e+00 -1.285745896647732422e+00 +1.320000000000000062e+00 -1.291520622439073618e+00 +1.330000000000000071e+00 -1.296053340195834958e+00 +1.340000000000000080e+00 -1.299518018798746954e+00 +1.350000000000000089e+00 -1.302161814499532388e+00 +1.360000000000000098e+00 -1.304291439835127964e+00 +1.370000000000000107e+00 -1.306255220113168081e+00 +1.380000000000000115e+00 -1.308421856542244299e+00 +1.390000000000000124e+00 -1.311157162457053049e+00 +1.400000000000000133e+00 -1.314800212867134332e+00 +1.409999999999999920e+00 -1.319640434026675191e+00 +1.419999999999999929e+00 -1.325897150342814079e+00 +1.429999999999999938e+00 -1.333702998067717749e+00 +1.439999999999999947e+00 -1.343092412477994602e+00 +1.449999999999999956e+00 -1.353996107501804991e+00 +1.459999999999999964e+00 -1.366242109698317941e+00 +1.469999999999999973e+00 -1.379563502823840881e+00 +1.479999999999999982e+00 -1.393612609479571107e+00 +1.489999999999999991e+00 -1.407980909469755959e+00 +1.500000000000000000e+00 -1.422223598195460958e+00 +1.510000000000000009e+00 -1.435887349343909714e+00 +1.520000000000000018e+00 -1.448539588219869945e+00 +1.530000000000000027e+00 -1.459797424816397404e+00 +1.540000000000000036e+00 -1.469354352842086042e+00 +1.550000000000000044e+00 -1.477002899221287135e+00 +1.560000000000000053e+00 -1.482651607298556717e+00 +1.570000000000000062e+00 -1.486335047552757027e+00 +1.580000000000000071e+00 -1.488215955984824257e+00 +1.590000000000000080e+00 -1.488579079659701598e+00 +1.600000000000000089e+00 -1.487816832804364831e+00 +1.610000000000000098e+00 -1.486407403135697969e+00 +1.620000000000000107e+00 -1.484886462489935832e+00 +1.630000000000000115e+00 -1.483814094282842611e+00 +1.640000000000000124e+00 -1.483738921133108013e+00 +1.650000000000000133e+00 -1.485161671891338520e+00 +1.660000000000000142e+00 -1.488500547485250403e+00 +1.669999999999999929e+00 -1.494060716533912592e+00 +1.679999999999999938e+00 -1.502010090806641385e+00 +1.689999999999999947e+00 -1.512363203185023819e+00 +1.699999999999999956e+00 -1.524974552374060988e+00 +1.709999999999999964e+00 -1.539542213777425950e+00 +1.719999999999999973e+00 -1.555621877087103755e+00 +1.729999999999999982e+00 -1.572650796653258132e+00 +1.739999999999999991e+00 -1.589980472818320223e+00 +1.750000000000000000e+00 -1.606916264592415100e+00 +1.760000000000000009e+00 -1.622761608308462167e+00 +1.770000000000000018e+00 -1.636864120990756843e+00 +1.780000000000000027e+00 -1.648660632057808550e+00 +1.790000000000000036e+00 -1.657718134550350220e+00 +1.800000000000000044e+00 -1.663767788389267865e+00 +1.810000000000000053e+00 -1.666729442298553243e+00 +1.820000000000000062e+00 -1.666724654623614521e+00 +1.830000000000000071e+00 -1.664076860883394682e+00 +1.840000000000000080e+00 -1.659298121073394805e+00 +1.850000000000000089e+00 -1.653062736893786910e+00 +1.860000000000000098e+00 -1.646168905975565311e+00 +1.870000000000000107e+00 -1.639490420953785499e+00 +1.880000000000000115e+00 -1.633921169782523775e+00 +1.890000000000000124e+00 -1.630315797184906934e+00 +1.900000000000000133e+00 -1.629430299546153149e+00 +1.910000000000000142e+00 -1.631866510839821371e+00 +1.919999999999999929e+00 -1.638024371999567519e+00 +1.929999999999999938e+00 -1.648065551957446528e+00 +1.939999999999999947e+00 -1.661891412818730318e+00 +1.949999999999999956e+00 -1.679137508081988583e+00 +1.959999999999999964e+00 -1.699185810787819051e+00 +1.969999999999999973e+00 -1.721194741231384606e+00 +1.979999999999999982e+00 -1.744145865915950111e+00 +1.989999999999999991e+00 -1.766904943097365122e+00 +2.000000000000000000e+00 -1.788293871669885515e+00 +2.010000000000000231e+00 -1.807169134631221974e+00 +2.020000000000000018e+00 -1.822501585911760147e+00 +2.030000000000000249e+00 -1.833451970004710940e+00 +2.040000000000000036e+00 -1.839436433560968309e+00 +2.049999999999999822e+00 -1.840176515318058037e+00 +2.060000000000000053e+00 -1.835728693654447241e+00 +2.069999999999999840e+00 -1.826489516256644574e+00 +2.080000000000000071e+00 -1.813173598443608814e+00 +2.089999999999999858e+00 -1.796763299222213117e+00 +2.100000000000000089e+00 -1.778430592068460214e+00 +2.109999999999999876e+00 -1.759433450451496794e+00 +2.120000000000000107e+00 -1.740990865279109512e+00 +2.129999999999999893e+00 -1.724142296465328128e+00 +2.140000000000000124e+00 -1.709598828020709727e+00 +2.149999999999999911e+00 -1.697594446487385111e+00 +2.160000000000000142e+00 -1.687746609975769640e+00 +2.169999999999999929e+00 -1.678935551587299901e+00 +2.180000000000000160e+00 -1.669211521738517945e+00 +2.189999999999999947e+00 -1.655738400603513849e+00 +2.200000000000000178e+00 -1.634780815260513664e+00 +2.209999999999999964e+00 -1.601740116517437640e+00 +2.220000000000000195e+00 -1.551242376907759013e+00 +2.229999999999999982e+00 -1.477279059296547015e+00 +2.240000000000000213e+00 -1.373398292309490287e+00 +2.250000000000000000e+00 -1.232941908372086504e+00 +2.260000000000000231e+00 -1.049320696462437530e+00 +2.270000000000000018e+00 -8.163178412204397105e-01 +2.280000000000000249e+00 -5.284084040144326755e-01 +2.290000000000000036e+00 -1.810810780343284632e-01 +2.300000000000000266e+00 2.288525739265880876e-01 +2.310000000000000053e+00 7.029765329944982488e-01 +2.319999999999999840e+00 1.241031136562589898e+00 +2.330000000000000071e+00 1.840729908948182114e+00 +2.339999999999999858e+00 2.497644185628400404e+00 +2.350000000000000089e+00 3.205164809027753581e+00 +2.359999999999999876e+00 3.954547122158530659e+00 +2.370000000000000107e+00 4.735042010600284179e+00 +2.379999999999999893e+00 5.534111999255005188e+00 +2.390000000000000124e+00 6.337727572241069751e+00 +2.399999999999999911e+00 7.130735136183980138e+00 +2.410000000000000142e+00 7.897284573560837906e+00 +2.419999999999999929e+00 8.621301309255461121e+00 +2.430000000000000160e+00 9.286985397528610520e+00 +2.439999999999999947e+00 9.879318459043641809e+00 +2.450000000000000178e+00 1.038455845542325306e+01 +2.459999999999999964e+00 1.079070233963798842e+01 +2.470000000000000195e+00 1.108789757888079208e+01 +2.479999999999999982e+00 1.126878538250580597e+01 +2.490000000000000213e+00 1.132876110749591625e+01 +2.500000000000000000e+00 1.126614064364450307e+01 +2.510000000000000231e+00 1.108222545081831356e+01 +2.520000000000000018e+00 1.078126315385551948e+01 +2.530000000000000249e+00 1.037030500000911459e+01 +2.540000000000000036e+00 9.858965842936713742e+00 +2.550000000000000266e+00 9.259096430397603328e+00 +2.560000000000000053e+00 8.584381445549286838e+00 +2.569999999999999840e+00 7.849879810592179652e+00 +2.580000000000000071e+00 7.071526062942436575e+00 +2.589999999999999858e+00 6.265613051786417920e+00 +2.600000000000000089e+00 5.448276713086626977e+00 +2.609999999999999876e+00 4.635003246008873035e+00 +2.620000000000000107e+00 3.840177662127465030e+00 +2.629999999999999893e+00 3.076690484503502798e+00 +2.640000000000000124e+00 2.355616451788713039e+00 +2.649999999999999911e+00 1.685975582870084422e+00 +2.660000000000000142e+00 1.074583057339164149e+00 +2.669999999999999929e+00 5.259902611777579340e-01 +2.680000000000000160e+00 4.251523809195282416e-02 +2.689999999999999947e+00 -3.756431253554815552e-01 +2.700000000000000178e+00 -7.302163816495387261e-01 +2.709999999999999964e+00 -1.024615453799191167e+00 +2.720000000000000195e+00 -1.263631700187418438e+00 +2.729999999999999982e+00 -1.453106121620752367e+00 +2.740000000000000213e+00 -1.599583414139586379e+00 +2.750000000000000000e+00 -1.709967425468083224e+00 +2.760000000000000231e+00 -1.791193620430420186e+00 +2.770000000000000018e+00 -1.849932475885790684e+00 +2.780000000000000249e+00 -1.892335419718305323e+00 +2.790000000000000036e+00 -1.923832141813964114e+00 +2.800000000000000266e+00 -1.948984999920915673e+00 +2.810000000000000053e+00 -1.971402994264991992e+00 +2.819999999999999840e+00 -1.993714568782194885e+00 +2.830000000000000071e+00 -2.017595483688944924e+00 +2.839999999999999858e+00 -2.043845347415723435e+00 +2.850000000000000089e+00 -2.072504224915228122e+00 +2.859999999999999876e+00 -2.102999152362548418e+00 +2.870000000000000107e+00 -2.134309448044082291e+00 +2.879999999999999893e+00 -2.165139440345400956e+00 +2.890000000000000124e+00 -2.194087622180209696e+00 +2.899999999999999911e+00 -2.219802236169268195e+00 +2.910000000000000142e+00 -2.241114812703276726e+00 +2.919999999999999929e+00 -2.257145112818700117e+00 +2.930000000000000160e+00 -2.267373138613787198e+00 +2.939999999999999947e+00 -2.271676222838785453e+00 +2.950000000000000178e+00 -2.270331550163321666e+00 +2.959999999999999964e+00 -2.263986654746083627e+00 +2.970000000000000195e+00 -2.253602355027676918e+00 +2.979999999999999982e+00 -2.240374120907535183e+00 +2.990000000000000213e+00 -2.225638941109441937e+00 +3.000000000000000000e+00 -2.210775320867651939e+00 +3.010000000000000231e+00 -2.197104076379126081e+00 +3.020000000000000018e+00 -2.185797120266078863e+00 +3.030000000000000249e+00 -2.177800500428659358e+00 +3.040000000000000036e+00 -2.173776639633092422e+00 +3.050000000000000266e+00 -2.174069123766122935e+00 +3.060000000000000053e+00 -2.178691617362874755e+00 +3.070000000000000284e+00 -2.187340668447263159e+00 +3.080000000000000071e+00 -2.199430423894154885e+00 +3.089999999999999858e+00 -2.214145726940230041e+00 +3.100000000000000089e+00 -2.230508810950814436e+00 +3.109999999999999876e+00 -2.247453917994676420e+00 +3.120000000000000107e+00 -2.263903711339921188e+00 +3.129999999999999893e+00 -2.278841342887978794e+00 +3.140000000000000124e+00 -2.291372474790045022e+00 +3.149999999999999911e+00 -2.300772404367861679e+00 +3.160000000000000142e+00 -2.306514641128153187e+00 +3.169999999999999929e+00 -2.308278749238044547e+00 +3.180000000000000160e+00 -2.305936896028717431e+00 +3.189999999999999947e+00 -2.299520223907984828e+00 +3.200000000000000178e+00 -2.289167773114564319e+00 +3.209999999999999964e+00 -2.275062113848493883e+00 +3.220000000000000195e+00 -2.257356997743436899e+00 +3.229999999999999982e+00 -2.236103127710099781e+00 +3.240000000000000213e+00 -2.211178512623499071e+00 +3.250000000000000000e+00 -2.182229787284280853e+00 +3.260000000000000231e+00 -2.148630336300513033e+00 +3.270000000000000018e+00 -2.109460090718925152e+00 +3.280000000000000249e+00 -2.063510524520210776e+00 +3.290000000000000036e+00 -2.009316745705202134e+00 +3.300000000000000266e+00 -1.945216755009452347e+00 +3.310000000000000053e+00 -1.869436049571355118e+00 +3.320000000000000284e+00 -1.780193901168510839e+00 +3.330000000000000071e+00 -1.675825960061762876e+00 +3.339999999999999858e+00 -1.554916438641632759e+00 +3.350000000000000089e+00 -1.416432110831448155e+00 +3.359999999999999876e+00 -1.259849798450454639e+00 +3.370000000000000107e+00 -1.085268952406974741e+00 +3.379999999999999893e+00 -8.935013923055109553e-01 +3.390000000000000124e+00 -6.861312286305520924e-01 +3.399999999999999911e+00 -4.655394115584776116e-01 +3.410000000000000142e+00 -2.348891550794597605e-01 +3.419999999999999929e+00 1.929424928218923495e-03 +3.430000000000000160e+00 2.403948632717901879e-01 +3.439999999999999947e+00 4.754872004169224398e-01 +3.450000000000000178e+00 7.018530577917561075e-01 +3.459999999999999964e+00 9.139958879978782313e-01 +3.470000000000000195e+00 1.106482741403454373e+00 +3.479999999999999982e+00 1.274157728567888892e+00 +3.490000000000000213e+00 1.412351722589583858e+00 +3.500000000000000000e+00 1.517077782353754234e+00 +3.510000000000000231e+00 1.585202299310347174e+00 +3.520000000000000018e+00 1.614582955230847716e+00 +3.530000000000000249e+00 1.604166171606270064e+00 +3.540000000000000036e+00 1.554038747964797240e+00 +3.550000000000000266e+00 1.465430715966836273e+00 +3.560000000000000053e+00 1.340668949115254804e+00 +3.570000000000000284e+00 1.183083623121541583e+00 +3.580000000000000071e+00 9.968720748453095970e-01 +3.589999999999999858e+00 7.869268188516603812e-01 +3.600000000000000089e+00 5.586363239473494113e-01 +3.609999999999999876e+00 3.176685223524874369e-01 +3.620000000000000107e+00 6.974784336448200395e-02 +3.629999999999999893e+00 -1.795632147629175890e-01 +3.640000000000000124e+00 -4.250673480439820517e-01 +3.649999999999999911e+00 -6.621108904832985198e-01 +3.660000000000000142e+00 -8.867292828109100133e-01 +3.669999999999999929e+00 -1.095753348159505869e+00 +3.680000000000000160e+00 -1.286872418015262642e+00 +3.689999999999999947e+00 -1.458652804043061302e+00 +3.700000000000000178e+00 -1.610512610469237549e+00 +3.709999999999999964e+00 -1.742656281170848809e+00 +3.720000000000000195e+00 -1.855974435385865595e+00 +3.729999999999999982e+00 -1.951916340649564763e+00 +3.740000000000000213e+00 -2.032343698020552925e+00 +3.750000000000000000e+00 -2.099375198136145038e+00 +3.760000000000000231e+00 -2.155231505297054984e+00 +3.770000000000000018e+00 -2.202089934246194591e+00 +3.780000000000000249e+00 -2.241957130067799842e+00 +3.790000000000000036e+00 -2.276566609310844314e+00 +3.800000000000000266e+00 -2.307306163977555613e+00 +3.810000000000000053e+00 -2.335177988030718410e+00 +3.820000000000000284e+00 -2.360792094693895837e+00 +3.830000000000000071e+00 -2.384391297443621216e+00 +3.839999999999999858e+00 -2.405903874038993973e+00 +3.850000000000000089e+00 -2.425018158522303402e+00 +3.859999999999999876e+00 -2.441271831230908074e+00 +3.870000000000000107e+00 -2.454147697444215570e+00 +3.879999999999999893e+00 -2.463167326855046024e+00 +3.890000000000000124e+00 -2.467974099411493150e+00 +3.899999999999999911e+00 -2.468397962176938520e+00 +3.910000000000000142e+00 -2.464495503841584778e+00 +3.919999999999999929e+00 -2.456560720991066038e+00 +3.930000000000000160e+00 -2.445103975638421634e+00 +3.939999999999999947e+00 -2.430798995378973260e+00 +3.950000000000000178e+00 -2.414400198177852452e+00 +3.959999999999999964e+00 -2.396634978207504929e+00 +3.970000000000000195e+00 -2.378077714219275940e+00 +3.979999999999999982e+00 -2.359014015819266952e+00 +3.990000000000000213e+00 -2.339304983885091893e+00 +4.000000000000000000e+00 -2.318261935024110265e+00 +4.009999999999999787e+00 -2.294542066005194503e+00 +4.020000000000000462e+00 -2.266074889988131336e+00 +4.030000000000000249e+00 -2.230027979517848369e+00 +4.040000000000000036e+00 -2.182818658582199145e+00 +4.049999999999999822e+00 -2.120175891350761788e+00 +4.060000000000000497e+00 -2.037253844304613537e+00 +4.070000000000000284e+00 -1.928795602298929879e+00 +4.080000000000000071e+00 -1.789342465463133580e+00 +4.089999999999999858e+00 -1.613481317916862556e+00 +4.099999999999999645e+00 -1.396119913659204625e+00 +4.110000000000000320e+00 -1.132777729734493422e+00 +4.120000000000000107e+00 -8.198784300774943912e-01 +4.129999999999999893e+00 -4.550290734067396481e-01 +4.139999999999999680e+00 -3.727105663202333330e-02 +4.150000000000000355e+00 4.327115582791497550e-01 +4.160000000000000142e+00 9.524392444155127535e-01 +4.169999999999999929e+00 1.517550477298456713e+00 +4.179999999999999716e+00 2.121789408469794136e+00 +4.190000000000000391e+00 2.757072384989728953e+00 +4.200000000000000178e+00 3.413634319612140811e+00 +4.209999999999999964e+00 4.080252128434587178e+00 +4.219999999999999751e+00 4.744538705111954080e+00 +4.230000000000000426e+00 5.393297386842812458e+00 +4.240000000000000213e+00 6.012923770673165969e+00 +4.250000000000000000e+00 6.589839222492816617e+00 +4.259999999999999787e+00 7.110938619746238309e+00 +4.270000000000000462e+00 7.564033880418673306e+00 +4.280000000000000249e+00 7.938274711799718553e+00 +4.290000000000000036e+00 8.224528774756366900e+00 +4.299999999999999822e+00 8.415705069382624970e+00 +4.310000000000000497e+00 8.507006729090706543e+00 +4.320000000000000284e+00 8.496102446311370571e+00 +4.330000000000000071e+00 8.383209294746055917e+00 +4.339999999999999858e+00 8.171083586240859731e+00 +4.350000000000000533e+00 7.864920414698373996e+00 +4.360000000000000320e+00 7.472166499112952387e+00 +4.370000000000000107e+00 7.002254651414992814e+00 +4.379999999999999893e+00 6.466271485371385630e+00 +4.389999999999999680e+00 5.876572696795939521e+00 +4.400000000000000355e+00 5.246362260377847697e+00 +4.410000000000000142e+00 4.589253119151178062e+00 +4.419999999999999929e+00 3.918827344451218053e+00 +4.429999999999999716e+00 3.248213314999930379e+00 +4.440000000000000391e+00 2.589696243097176609e+00 +4.450000000000000178e+00 1.954376442103404887e+00 +4.459999999999999964e+00 1.351887194643792478e+00 +4.469999999999999751e+00 7.901810845811182427e-01 +4.480000000000000426e+00 2.753903563564321089e-01 +4.490000000000000213e+00 -1.882365682196132650e-01 +4.500000000000000000e+00 -5.983236829175427873e-01 +4.509999999999999787e+00 -9.542855653327210197e-01 +4.520000000000000462e+00 -1.257182438646581746e+00 +4.530000000000000249e+00 -1.509521828428479706e+00 +4.540000000000000036e+00 -1.715018334997996829e+00 +4.549999999999999822e+00 -1.878324234336846033e+00 +4.560000000000000497e+00 -2.004744158970575896e+00 +4.570000000000000284e+00 -2.099947001877261687e+00 +4.580000000000000071e+00 -2.169687471447678373e+00 +4.589999999999999858e+00 -2.219548473204722150e+00 +4.600000000000000533e+00 -2.254713797937259123e+00 +4.610000000000000320e+00 -2.279778567590389660e+00 +4.620000000000000107e+00 -2.298602652110638189e+00 +4.629999999999999893e+00 -2.314209948575111753e+00 +4.639999999999999680e+00 -2.328734130962619719e+00 +4.650000000000000355e+00 -2.343409347380340790e+00 +4.660000000000000142e+00 -2.358602458163866711e+00 +4.669999999999999929e+00 -2.373881849429886781e+00 +4.679999999999999716e+00 -2.388116675393953781e+00 +4.690000000000000391e+00 -2.399599607151332581e+00 +4.700000000000000178e+00 -2.406185798840540624e+00 +4.709999999999999964e+00 -2.405440803985326781e+00 +4.719999999999999751e+00 -2.394790544666756560e+00 +4.730000000000000426e+00 -2.371667096812762221e+00 +4.740000000000000213e+00 -2.333644937349814263e+00 +4.750000000000000000e+00 -2.278563327750606327e+00 +4.759999999999999787e+00 -2.204631606940701261e+00 +4.770000000000000462e+00 -2.110515261784385199e+00 +4.780000000000000249e+00 -1.995401671038869340e+00 +4.790000000000000036e+00 -1.859045326397128939e+00 +4.799999999999999822e+00 -1.701793084373567133e+00 +4.810000000000000497e+00 -1.524590573792457660e+00 +4.820000000000000284e+00 -1.328971270324355913e+00 +4.830000000000000071e+00 -1.117029962038249780e+00 +4.839999999999999858e+00 -8.913823917415232279e-01 +4.850000000000000533e+00 -6.551128067379011766e-01 +4.860000000000000320e+00 -4.117110150416259939e-01 +4.870000000000000107e+00 -1.650003822931614406e-01 +4.879999999999999893e+00 8.094195240083711107e-02 +4.889999999999999680e+00 3.218714738334297332e-01 +4.900000000000000355e+00 5.534681695288097281e-01 +4.910000000000000142e+00 7.714327025170671925e-01 +4.919999999999999929e+00 9.715855375949133954e-01 +4.929999999999999716e+00 1.149967438263705732e+00 +4.940000000000000391e+00 1.302939439929809096e+00 +4.950000000000000178e+00 1.427280055080384136e+00 +4.959999999999999964e+00 1.520277117304197345e+00 +4.969999999999999751e+00 1.579811367547916623e+00 +4.980000000000000426e+00 1.604428673495603253e+00 +4.990000000000000213e+00 1.593397694332660208e+00 +5.000000000000000000e+00 1.546749894673133285e+00 +5.009999999999999787e+00 1.465299099177749920e+00 +5.020000000000000462e+00 1.350638276360825341e+00 +5.030000000000000249e+00 1.205111944135356605e+00 +5.040000000000000036e+00 1.031763482508301522e+00 +5.049999999999999822e+00 8.342576862772037583e-01 +5.060000000000000497e+00 6.167800437334171049e-01 +5.070000000000000284e+00 3.839154252251328336e-01 +5.080000000000000071e+00 1.405100382536546011e-01 +5.089999999999999858e+00 -1.084784206032316650e-01 +5.100000000000000533e+00 -3.581365860755488795e-01 +5.110000000000000320e+00 -6.037507270353323907e-01 +5.120000000000000107e+00 -8.409546828361738058e-01 +5.129999999999999893e+00 -1.065863568709761067e+00 +5.139999999999999680e+00 -1.275186739186987994e+00 +5.150000000000000355e+00 -1.466314225172048014e+00 +5.160000000000000142e+00 -1.637371942084971499e+00 +5.169999999999999929e+00 -1.787242362776021665e+00 +5.179999999999999716e+00 -1.915548997940534015e+00 +5.190000000000000391e+00 -2.022604848377505427e+00 +5.200000000000000178e+00 -2.109326893129551461e+00 +5.209999999999999964e+00 -2.177120551517408131e+00 +5.219999999999999751e+00 -2.227739798099762414e+00 +5.230000000000000426e+00 -2.263130113249313791e+00 +5.240000000000000213e+00 -2.285262623120607017e+00 +5.250000000000000000e+00 -2.295968541269429508e+00 +5.259999999999999787e+00 -2.296783310544632251e+00 +5.270000000000000462e+00 -2.288809623346272470e+00 +5.280000000000000249e+00 -2.272607763843685014e+00 +5.290000000000000036e+00 -2.248120489235049924e+00 +5.299999999999999822e+00 -2.214637999309209349e+00 +5.310000000000000497e+00 -2.170806511874917799e+00 +5.320000000000000284e+00 -2.114681666585254582e+00 +5.330000000000000071e+00 -2.043825539851275241e+00 +5.339999999999999858e+00 -1.955443599199754523e+00 +5.350000000000000533e+00 -1.846555591509498440e+00 +5.360000000000000320e+00 -1.714192278062873998e+00 +5.370000000000000107e+00 -1.555608221791627166e+00 +5.379999999999999893e+00 -1.368499602378274504e+00 +5.389999999999999680e+00 -1.151215362997674019e+00 +5.400000000000000355e+00 -9.029499295118432745e-01 +5.410000000000000142e+00 -6.239063074998765224e-01 +5.419999999999999929e+00 -3.154195391129448467e-01 +5.429999999999999716e+00 1.996775904495872930e-02 +5.440000000000000391e+00 3.784838352398094408e-01 +5.450000000000000178e+00 7.551636845173823609e-01 +5.459999999999999964e+00 1.143943004786056150e+00 +5.469999999999999751e+00 1.537807930535931789e+00 +5.480000000000000426e+00 1.928995379243879205e+00 +5.490000000000000213e+00 2.309236189837731601e+00 +5.500000000000000000e+00 2.670030933216093416e+00 +5.509999999999999787e+00 3.002946457818648440e+00 +5.520000000000000462e+00 3.299920000076348892e+00 +5.530000000000000249e+00 3.553557111272714231e+00 +5.540000000000000036e+00 3.757409765353004083e+00 +5.549999999999999822e+00 3.906221816102602329e+00 +5.560000000000000497e+00 3.996130429372978465e+00 +5.570000000000000284e+00 4.024814153916081771e+00 +5.580000000000000071e+00 3.991580808729518370e+00 +5.589999999999999858e+00 3.897391225615753907e+00 +5.600000000000000533e+00 3.744817944131971554e+00 +5.610000000000000320e+00 3.537941052793763586e+00 +5.620000000000000107e+00 3.282186343884523350e+00 +5.629999999999999893e+00 2.984113644995438630e+00 +5.639999999999999680e+00 2.651165469311829170e+00 +5.650000000000000355e+00 2.291387872457139263e+00 +5.660000000000000142e+00 1.913136529456362034e+00 +5.669999999999999929e+00 1.524781498062282248e+00 +5.679999999999999716e+00 1.134423897957517191e+00 +5.690000000000000391e+00 7.496368302331266609e-01 +5.700000000000000178e+00 3.772413450481871822e-01 +5.709999999999999964e+00 2.312622704737076970e-02 +5.719999999999999751e+00 -3.078820751629140484e-01 +5.730000000000000426e+00 -6.120957599212734079e-01 +5.740000000000000213e+00 -8.869874362090741649e-01 +5.750000000000000000e+00 -1.131159343246060489e+00 +5.759999999999999787e+00 -1.344264632454691855e+00 +5.770000000000000462e+00 -1.526887597005299302e+00 +5.780000000000000249e+00 -1.680391571314878929e+00 +5.790000000000000036e+00 -1.806744528147502971e+00 +5.799999999999999822e+00 -1.908333115441290806e+00 +5.810000000000000497e+00 -1.987775974039600824e+00 +5.820000000000000284e+00 -2.047746671693927212e+00 +5.830000000000000071e+00 -2.090815522647573754e+00 +5.839999999999999858e+00 -2.119318011392275825e+00 +5.850000000000000533e+00 -2.135255605545564261e+00 +5.860000000000000320e+00 -2.140232547811554475e+00 +5.870000000000000107e+00 -2.135429894741839973e+00 +5.879999999999999893e+00 -2.121615759084142461e+00 +5.889999999999999680e+00 -2.099188547812276262e+00 +5.900000000000000355e+00 -2.068248092895383028e+00 +5.910000000000000142e+00 -2.028688051354561761e+00 +5.919999999999999929e+00 -1.980301885610450618e+00 +5.929999999999999716e+00 -1.922894176202663230e+00 +5.940000000000000391e+00 -1.856388986946164943e+00 +5.950000000000000178e+00 -1.780927485701038204e+00 +5.959999999999999964e+00 -1.696947979558449449e+00 +5.969999999999999751e+00 -1.605242880998435817e+00 +5.980000000000000426e+00 -1.506988787979611111e+00 +5.990000000000000213e+00 -1.403747725432764604e+00 +6.000000000000000000e+00 -1.297439537615398653e+00 +6.009999999999999787e+00 -1.190287317024549818e+00 +6.020000000000000462e+00 -1.084739487839925465e+00 +6.030000000000000249e+00 -9.833736241478286955e-01 +6.040000000000000036e+00 -8.887881880147580071e-01 +6.049999999999999822e+00 -8.034890561171686985e-01 +6.060000000000000497e+00 -7.297779297866183734e-01 +6.070000000000000284e+00 -6.696494850652444653e-01 +6.080000000000000071e+00 -6.247034392564083660e-01 +6.089999999999999858e+00 -5.960766388821976403e-01 +6.100000000000000533e+00 -5.843988857195107078e-01 +6.110000000000000320e+00 -5.897746069983552664e-01 +6.120000000000000107e+00 -6.117907506771507187e-01 +6.129999999999999893e+00 -6.495495612943619212e-01 +6.140000000000000568e+00 -7.017232798728536558e-01 +6.150000000000000355e+00 -7.666264184706033102e-01 +6.160000000000000142e+00 -8.423001773992692121e-01 +6.169999999999999929e+00 -9.266028716962870782e-01 +6.179999999999999716e+00 -1.017299959126032771e+00 +6.190000000000000391e+00 -1.112147433012024678e+00 +6.200000000000000178e+00 -1.208962948787912994e+00 +6.209999999999999964e+00 -1.305680054132836609e+00 +6.219999999999999751e+00 -1.400382223742105303e+00 +6.230000000000000426e+00 -1.491314973979253944e+00 +6.240000000000000213e+00 -1.576876046043552471e+00 +6.250000000000000000e+00 -1.655585384890355005e+00 +6.259999999999999787e+00 -1.726038287950830030e+00 +6.270000000000000462e+00 -1.786846540037484221e+00 +6.280000000000000249e+00 -1.836573487507611846e+00 +6.290000000000000036e+00 -1.873669752595300553e+00 +6.299999999999999822e+00 -1.896416588067978637e+00 +6.310000000000000497e+00 -1.902883690777198655e+00 +6.320000000000000284e+00 -1.890907627942572500e+00 +6.330000000000000071e+00 -1.858095910353955160e+00 +6.339999999999999858e+00 -1.801860229613423181e+00 +6.350000000000000533e+00 -1.719480545826698181e+00 +6.360000000000000320e+00 -1.608199673136353480e+00 +6.370000000000000107e+00 -1.465345884057992043e+00 +6.379999999999999893e+00 -1.288478969134587260e+00 +6.390000000000000568e+00 -1.075553276221871357e+00 +6.400000000000000355e+00 -8.250896370824002402e-01 +6.410000000000000142e+00 -5.363468767946326654e-01 +6.419999999999999929e+00 -2.094828815138639611e-01 +6.429999999999999716e+00 1.543049666448737534e-01 +6.440000000000000391e+00 5.526697622099324692e-01 +6.450000000000000178e+00 9.820442340030380857e-01 +6.459999999999999964e+00 1.437616324464979778e+00 +6.469999999999999751e+00 1.913356411079277786e+00 +6.480000000000000426e+00 2.402098996131483588e+00 +6.490000000000000213e+00 2.895679039792507403e+00 +6.500000000000000000e+00 3.385120341247561893e+00 +6.509999999999999787e+00 3.860870630957542016e+00 +6.520000000000000462e+00 4.313075473232189871e+00 +6.530000000000000249e+00 4.731880834335750130e+00 +6.540000000000000036e+00 5.107752374671572504e+00 +6.549999999999999822e+00 5.431798279409681740e+00 +6.560000000000000497e+00 5.696081827243631324e+00 +6.570000000000000284e+00 5.893909956076502255e+00 +6.580000000000000071e+00 6.020084826153433433e+00 +6.589999999999999858e+00 6.071106778030808115e+00 +6.600000000000000533e+00 6.045319072295199270e+00 +6.610000000000000320e+00 5.942987285712726830e+00 +6.620000000000000107e+00 5.766309103106904921e+00 +6.629999999999999893e+00 5.519353343765164510e+00 +6.640000000000000568e+00 5.207930240573626079e+00 +6.650000000000000355e+00 4.839398089643776046e+00 +6.660000000000000142e+00 4.422414251978609379e+00 +6.669999999999999929e+00 3.966640972897152118e+00 +6.679999999999999716e+00 3.482418465428927412e+00 +6.690000000000000391e+00 2.980419082964979260e+00 +6.700000000000000178e+00 2.471297117813518796e+00 +6.709999999999999964e+00 1.965348774490056183e+00 +6.719999999999999751e+00 1.472196184427136068e+00 +6.730000000000000426e+00 1.000507993002879514e+00 +6.740000000000000213e+00 5.577671344581142110e-01 +6.750000000000000000e+00 1.500940187032165918e-01 +6.759999999999999787e+00 -2.178693870332518989e-01 +6.770000000000000462e+00 -5.430120460399772142e-01 +6.780000000000000249e+00 -8.237433753179611573e-01 +6.790000000000000036e+00 -1.059923173340706626e+00 +6.799999999999999822e+00 -1.252737981774890041e+00 +6.810000000000000497e+00 -1.404532197855025810e+00 +6.820000000000000284e+00 -1.518604060604611172e+00 +6.830000000000000071e+00 -1.598977879134223734e+00 +6.839999999999999858e+00 -1.650164505254807068e+00 +6.850000000000000533e+00 -1.676922059245816721e+00 +6.860000000000000320e+00 -1.684028313897813600e+00 +6.870000000000000107e+00 -1.676074976894605939e+00 +6.879999999999999893e+00 -1.657292462837164582e+00 +6.890000000000000568e+00 -1.631411715235615123e+00 +6.900000000000000355e+00 -1.601567344990276975e+00 +6.910000000000000142e+00 -1.570243925673639351e+00 +6.919999999999999929e+00 -1.539264861462544154e+00 +6.929999999999999716e+00 -1.509820951353957774e+00 +6.940000000000000391e+00 -1.482533733154191014e+00 +6.950000000000000178e+00 -1.457547005519657546e+00 +6.959999999999999964e+00 -1.434638676717695294e+00 +6.969999999999999751e+00 -1.413344329360360696e+00 +6.980000000000000426e+00 -1.393083647294976135e+00 +6.990000000000000213e+00 -1.373281121085700773e+00 +7.000000000000000000e+00 -1.353473200779103935e+00 +7.009999999999999787e+00 -1.333395241757743488e+00 +7.020000000000000462e+00 -1.313043112265811274e+00 +7.030000000000000249e+00 -1.292706103380936389e+00 +7.040000000000000036e+00 -1.272969696252737926e+00 +7.049999999999999822e+00 -1.254688684754931227e+00 +7.060000000000000497e+00 -1.238933013100713687e+00 +7.070000000000000284e+00 -1.226910363783219271e+00 +7.080000000000000071e+00 -1.219870930878796500e+00 +7.089999999999999858e+00 -1.219000864578973831e+00 +7.100000000000000533e+00 -1.225311523513612055e+00 +7.110000000000000320e+00 -1.239531894437191362e+00 +7.120000000000000107e+00 -1.262011331258753533e+00 +7.129999999999999893e+00 -1.292639148438140984e+00 +7.140000000000000568e+00 -1.330786620997713499e+00 +7.150000000000000355e+00 -1.375275657642876403e+00 +7.160000000000000142e+00 -1.424376902829973313e+00 +7.169999999999999929e+00 -1.475838376626140702e+00 +7.179999999999999716e+00 -1.526944071682049264e+00 +7.190000000000000391e+00 -1.574600288273609872e+00 +7.200000000000000178e+00 -1.615445989525509107e+00 +7.209999999999999964e+00 -1.645982177893146714e+00 +7.219999999999999751e+00 -1.662714294919013680e+00 +7.230000000000000426e+00 -1.662300976124319041e+00 +7.240000000000000213e+00 -1.641702179284914243e+00 +7.250000000000000000e+00 -1.598319754714784713e+00 +7.259999999999999787e+00 -1.530123928051497328e+00 +7.270000000000000462e+00 -1.435759888359934067e+00 +7.280000000000000249e+00 -1.314629669913442989e+00 +7.290000000000000036e+00 -1.166945724559848241e+00 +7.299999999999999822e+00 -9.937539337492441449e-01 +7.310000000000000497e+00 -7.969252307252615575e-01 +7.320000000000000284e+00 -5.791164190253568211e-01 +7.330000000000000071e+00 -3.437021117658813352e-01 +7.339999999999999858e+00 -9.468091298360577224e-02 +7.350000000000000533e+00 1.634400361129585422e-01 +7.360000000000000320e+00 4.257772574107626107e-01 +7.370000000000000107e+00 6.872144902382962828e-01 +7.379999999999999893e+00 9.425519759434378697e-01 +7.390000000000000568e+00 1.186655885350607065e+00 +7.400000000000000355e+00 1.414602587490935592e+00 +7.410000000000000142e+00 1.621812962103184041e+00 +7.419999999999999929e+00 1.804172640198175914e+00 +7.429999999999999716e+00 1.958134868949936269e+00 +7.440000000000000391e+00 2.080803588130221371e+00 +7.450000000000000178e+00 2.169995223597271927e+00 +7.459999999999999964e+00 2.224278599962813185e+00 +7.469999999999999751e+00 2.242993205836154136e+00 +7.480000000000000426e+00 2.226246774940737083e+00 +7.490000000000000213e+00 2.174893748145865668e+00 +7.500000000000000000e+00 2.090496638522142181e+00 +7.509999999999999787e+00 1.975272627881748289e+00 +7.520000000000000462e+00 1.832027882939940566e+00 +7.530000000000000249e+00 1.664082105272140621e+00 +7.540000000000000036e+00 1.475185742084372142e+00 +7.549999999999999822e+00 1.269432110306737416e+00 +7.560000000000000497e+00 1.051166453641231957e+00 +7.570000000000000284e+00 8.248936907168913368e-01 +7.580000000000000071e+00 5.951863507028506417e-01 +7.589999999999999858e+00 3.665939553275682217e-01 +7.600000000000000533e+00 1.435549127196661112e-01 +7.610000000000000320e+00 -6.968814820477957361e-02 +7.620000000000000107e+00 -2.691687481644495228e-01 +7.629999999999999893e+00 -4.512717911535291115e-01 +7.640000000000000568e+00 -6.128027802496424092e-01 +7.650000000000000355e+00 -7.510500570770834994e-01 +7.660000000000000142e+00 -8.638390100922150872e-01 +7.669999999999999929e+00 -9.495771037353952782e-01 +7.679999999999999716e+00 -1.007288513636467098e+00 +7.690000000000000391e+00 -1.036637134561268381e+00 +7.700000000000000178e+00 -1.037936776856077215e+00 +7.709999999999999964e+00 -1.012147498415974178e+00 +7.719999999999999751e+00 -9.608572413498773779e-01 +7.730000000000000426e+00 -8.862482573158725341e-01 +7.740000000000000213e+00 -7.910482073719760088e-01 +7.750000000000000000e+00 -6.784662982496749706e-01 +7.759999999999999787e+00 -5.521153476204668786e-01 +7.770000000000000462e+00 -4.159212309577832167e-01 +7.780000000000000249e+00 -2.740217226114579629e-01 +7.790000000000000036e+00 -1.306572719701193375e-01 +7.799999999999999822e+00 9.943279996656012240e-03 +7.810000000000000497e+00 1.436786683062468428e-01 +7.820000000000000284e+00 2.666892307256941153e-01 +7.830000000000000071e+00 3.754652612817787616e-01 +7.839999999999999858e+00 4.669460064152251566e-01 +7.850000000000000533e+00 5.386058297577793752e-01 +7.860000000000000320e+00 5.885244404508147564e-01 +7.870000000000000107e+00 6.154385960296768765e-01 +7.879999999999999893e+00 6.187733341305394763e-01 +7.890000000000000568e+00 5.986515302293442531e-01 +7.900000000000000355e+00 5.558813879516936174e-01 +7.910000000000000142e+00 4.919223067193795318e-01 +7.919999999999999929e+00 4.088303990687373046e-01 +7.930000000000000604e+00 3.091857074545247830e-01 +7.940000000000000391e+00 1.960038606259438265e-01 +7.950000000000000178e+00 7.263548000233147062e-02 +7.959999999999999964e+00 -5.734292963891344380e-02 +7.969999999999999751e+00 -1.902426122891599514e-01 +7.980000000000000426e+00 -3.223766397507142889e-01 +7.990000000000000213e+00 -4.501704552537055259e-01 +8.000000000000000000e+00 -5.702651613776515971e-01 +8.009999999999999787e+00 -6.796102459517393557e-01 +8.019999999999999574e+00 -7.755429812714824678e-01 +8.029999999999999361e+00 -8.558523711518144506e-01 +8.040000000000000924e+00 -9.188262225906376202e-01 +8.050000000000000711e+00 -9.632806474641990579e-01 +8.060000000000000497e+00 -9.885720179197283741e-01 +8.070000000000000284e+00 -9.945920721331014125e-01 +8.080000000000000071e+00 -9.817474639005905335e-01 +8.089999999999999858e+00 -9.509255447021596197e-01 +8.099999999999999645e+00 -9.034485417885692593e-01 +8.109999999999999432e+00 -8.410185395406203357e-01 +8.120000000000000995e+00 -7.656557808810611210e-01 +8.130000000000000782e+00 -6.796327858308512937e-01 +8.140000000000000568e+00 -5.854066476134366370e-01 +8.150000000000000355e+00 -4.855516314834011360e-01 +8.160000000000000142e+00 -3.826938909871226979e-01 +8.169999999999999929e+00 -2.794497571241983391e-01 +8.179999999999999716e+00 -1.783686756926325390e-01 +8.189999999999999503e+00 -8.188149428406657493e-02 +8.199999999999999289e+00 7.745542023590154361e-03 +8.210000000000000853e+00 8.845101709666176870e-02 +8.220000000000000639e+00 1.584129444568558309e-01 +8.230000000000000426e+00 2.160780373595434234e-01 +8.240000000000000213e+00 2.601860045765469476e-01 +8.250000000000000000e+00 2.897892111848809904e-01 +8.259999999999999787e+00 3.042679579951356184e-01 +8.269999999999999574e+00 3.033414940563497475e-01 +8.279999999999999361e+00 2.870747033178833174e-01 +8.290000000000000924e+00 2.558802211848499875e-01 +8.300000000000000711e+00 2.105155626943906733e-01 +8.310000000000000497e+00 1.520747041068695182e-01 +8.320000000000000284e+00 8.197347431317415778e-02 +8.330000000000000071e+00 1.928098241963735991e-03 +8.339999999999999858e+00 -8.607369708964179855e-02 +8.349999999999999645e+00 -1.798094467067919699e-01 +8.359999999999999432e+00 -2.768667714973286342e-01 +8.370000000000000995e+00 -3.746961292346064898e-01 +8.380000000000000782e+00 -4.706709742545257535e-01 +8.390000000000000568e+00 -5.621543774851174291e-01 +8.400000000000000355e+00 -6.465707100739983559e-01 +8.410000000000000142e+00 -7.214805548536037394e-01 +8.419999999999999929e+00 -7.846566099250631421e-01 +8.429999999999999716e+00 -8.341580169393210120e-01 +8.439999999999999503e+00 -8.684003101686138537e-01 +8.449999999999999289e+00 -8.862180641273209591e-01 +8.460000000000000853e+00 -8.869173346535063063e-01 +8.470000000000000639e+00 -8.703151514558598034e-01 +8.480000000000000426e+00 -8.367636318379354510e-01 +8.490000000000000213e+00 -7.871567400552130778e-01 +8.500000000000000000e+00 -7.229183007156764207e-01 +8.509999999999999787e+00 -6.459705662054270325e-01 +8.519999999999999574e+00 -5.586834088727894443e-01 +8.529999999999999361e+00 -4.638050247000668480e-01 +8.540000000000000924e+00 -3.643758586656976606e-01 +8.550000000000000711e+00 -2.636282532717041382e-01 +8.560000000000000497e+00 -1.648750412463882153e-01 +8.570000000000000284e+00 -7.139091392041516104e-02 +8.580000000000000071e+00 1.370913487342026275e-02 +8.589999999999999858e+00 8.758969038177945310e-02 +8.599999999999999645e+00 1.478084146145187405e-01 +8.609999999999999432e+00 1.924185400392700029e-01 +8.620000000000000995e+00 2.200560297428477419e-01 +8.630000000000000782e+00 2.300075583774017496e-01 +8.640000000000000568e+00 2.222561281889804952e-01 +8.650000000000000355e+00 1.975019448253300391e-01 +8.660000000000000142e+00 1.571571054199120965e-01 +8.669999999999999929e+00 1.033136578600793304e-01 +8.679999999999999716e+00 3.868563244033873527e-02 +8.689999999999999503e+00 -3.347331936932309432e-02 +8.700000000000001066e+00 -1.094740640028040585e-01 +8.710000000000000853e+00 -1.853144027919754466e-01 +8.720000000000000639e+00 -2.568155154275031937e-01 +8.730000000000000426e+00 -3.197675923270959508e-01 +8.740000000000000213e+00 -3.700794223007105588e-01 +8.750000000000000000e+00 -4.039265121554412863e-01 +8.759999999999999787e+00 -4.178923386404143070e-01 +8.769999999999999574e+00 -4.090975683574663568e-01 +8.779999999999999361e+00 -3.753125169272684691e-01 +8.790000000000000924e+00 -3.150487354364693293e-01 +8.800000000000000711e+00 -2.276263833221578714e-01 +8.810000000000000497e+00 -1.132149397214840814e-01 +8.820000000000000284e+00 2.715421713629178474e-02 +8.830000000000000071e+00 1.916038104436596778e-01 +8.839999999999999858e+00 3.774546664439292210e-01 +8.849999999999999645e+00 5.812961471911091138e-01 +8.859999999999999432e+00 7.990805261131408432e-01 +8.870000000000000995e+00 1.026238005885577342e+00 +8.880000000000000782e+00 1.257808400245666203e+00 +8.890000000000000568e+00 1.488584979731373048e+00 +8.900000000000000355e+00 1.713265631050689963e+00 +8.910000000000000142e+00 1.926606308885383090e+00 +8.919999999999999929e+00 2.123571768302186413e+00 +8.929999999999999716e+00 2.299478749661132415e+00 +8.939999999999999503e+00 2.450127133807353808e+00 +8.950000000000001066e+00 2.571915075790836003e+00 +8.960000000000000853e+00 2.661934738271681589e+00 +8.970000000000000639e+00 2.718045955622782284e+00 +8.980000000000000426e+00 2.738925938756399781e+00 +8.990000000000000213e+00 2.724093949972821616e+00 +9.000000000000000000e+00 2.673910707733775372e+00 +9.009999999999999787e+00 2.589553095272193239e+00 +9.019999999999999574e+00 2.472965518326461165e+00 +9.029999999999999361e+00 2.326789962638526887e+00 +9.040000000000000924e+00 2.154277421030085460e+00 +9.050000000000000711e+00 1.959183876389372747e+00 +9.060000000000000497e+00 1.745654428230015931e+00 +9.070000000000000284e+00 1.518099428160327724e+00 +9.080000000000000071e+00 1.281066639223604753e+00 +9.089999999999999858e+00 1.039113455173978462e+00 +9.099999999999999645e+00 7.966831115927972551e-01 +9.109999999999999432e+00 5.579885980126413347e-01 +9.120000000000000995e+00 3.269076486683880067e-01 +9.130000000000000782e+00 1.068917616073585403e-01 +9.140000000000000568e+00 -9.910831357390276208e-02 +9.150000000000000355e+00 -2.886987535094220902e-01 +9.160000000000000142e+00 -4.600792597954011520e-01 +9.169999999999999929e+00 -6.120594832255803475e-01 +9.179999999999999716e+00 -7.440553354239295425e-01 +9.189999999999999503e+00 -8.560658956476758785e-01 +9.200000000000001066e+00 -9.486322356399835565e-01 +9.210000000000000853e+00 -1.022780051279601476e+00 +9.220000000000000639e+00 -1.079948489258053979e+00 +9.230000000000000426e+00 -1.121907974756578996e+00 +9.240000000000000213e+00 -1.150670168985065356e+00 +9.250000000000000000e+00 -1.168393403054730717e+00 +9.259999999999999787e+00 -1.177287039627801457e+00 +9.269999999999999574e+00 -1.179518202169210328e+00 +9.279999999999999361e+00 -1.177124183122659762e+00 +9.290000000000000924e+00 -1.171933600464461378e+00 +9.300000000000000711e+00 -1.165499024221573254e+00 +9.310000000000000497e+00 -1.159043351798790589e+00 +9.320000000000000284e+00 -1.153421687987910893e+00 +9.330000000000000071e+00 -1.149099900109214589e+00 +9.339999999999999858e+00 -1.146150391255779555e+00 +9.349999999999999645e+00 -1.144264987419359780e+00 +9.359999999999999432e+00 -1.142784190899682084e+00 +9.370000000000000995e+00 -1.140741436683755383e+00 +9.380000000000000782e+00 -1.136920423678609460e+00 +9.390000000000000568e+00 -1.129923100510958234e+00 +9.400000000000000355e+00 -1.118245485352095336e+00 +9.410000000000000142e+00 -1.100358206886917767e+00 +9.419999999999999929e+00 -1.074788481109447247e+00 +9.429999999999999716e+00 -1.040200193483521662e+00 +9.439999999999999503e+00 -9.954688405466904921e-01 +9.450000000000001066e+00 -9.397482964542562822e-01 +9.460000000000000853e+00 -8.725267002906532676e-01 +9.470000000000000639e+00 -7.936691963419633122e-01 +9.480000000000000426e+00 -7.034457846279382753e-01 +9.490000000000000213e+00 -6.025431317986154056e-01 +9.500000000000000000e+00 -4.920598291036596406e-01 +9.509999999999999787e+00 -3.734852387710164701e-01 +9.519999999999999574e+00 -2.486627162501219013e-01 +9.529999999999999361e+00 -1.197386072273857738e-01 +9.540000000000000924e+00 1.090102953614709158e-02 +9.550000000000000711e+00 1.407035517276840619e-01 +9.560000000000000497e+00 2.670299226890020527e-01 +9.570000000000000284e+00 3.872389108882260400e-01 +9.580000000000000071e+00 4.987721169170646895e-01 +9.589999999999999858e+00 5.992366393959093207e-01 +9.599999999999999645e+00 6.864823113678847344e-01 +9.609999999999999432e+00 7.586706784043253382e-01 +9.620000000000000995e+00 8.143332371949166815e-01 +9.630000000000000782e+00 8.524168930081004181e-01 +9.640000000000000568e+00 8.723151066885607152e-01 +9.650000000000000355e+00 8.738837647885885351e-01 +9.660000000000000142e+00 8.574413963764142554e-01 +9.669999999999999929e+00 8.237539528460933180e-01 +9.679999999999999716e+00 7.740049389995750095e-01 +9.689999999999999503e+00 7.097522126259119268e-01 +9.700000000000001066e+00 6.328732360258514378e-01 +9.710000000000000853e+00 5.455009498606139262e-01 +9.720000000000000639e+00 4.499527345471072137e-01 +9.730000000000000426e+00 3.486551185450010304e-01 +9.740000000000000213e+00 2.440669820043076810e-01 +9.750000000000000000e+00 1.386039884265337641e-01 +9.759999999999999787e+00 3.456686043579480089e-02 +9.769999999999999574e+00 -6.592409358311283885e-02 +9.779999999999999361e+00 -1.609860861459878889e-01 +9.790000000000000924e+00 -2.490208334928613598e-01 +9.800000000000000711e+00 -3.287500681872084773e-01 +9.810000000000000497e+00 -3.992386810120059359e-01 +9.820000000000000284e+00 -4.599050554098962351e-01 +9.830000000000000071e+00 -5.105186221652002754e-01 +9.839999999999999858e+00 -5.511851109774634772e-01 +9.849999999999999645e+00 -5.823203942093575503e-01 +9.859999999999999432e+00 -6.046141934140236707e-01 +9.870000000000000995e+00 -6.189852404059306146e-01 +9.880000000000000782e+00 -6.265297431174760012e-01 +9.890000000000000568e+00 -6.284651961865521663e-01 +9.900000000000000355e+00 -6.260716934654581012e-01 +9.910000000000000142e+00 -6.206329430701528205e-01 +9.919999999999999929e+00 -6.133791560124036701e-01 +9.929999999999999716e+00 -6.054338796654403776e-01 +9.939999999999999503e+00 -5.977666818569644658e-01 +9.950000000000001066e+00 -5.911533663500657676e-01 +9.960000000000000853e+00 -5.861451232726342386e-01 +9.970000000000000639e+00 -5.830476972173592731e-01 +9.980000000000000426e+00 -5.819113007201224264e-01 +9.990000000000000213e+00 -5.825316218641882759e-01 +1.000000000000000000e+01 -5.844618826907095333e-01 +1.000999999999999979e+01 -5.870352677168909628e-01 +1.001999999999999957e+01 -5.893972187081357728e-01 +1.002999999999999936e+01 -5.905471667020981696e-01 +1.004000000000000092e+01 -5.893865766357646585e-01 +1.005000000000000071e+01 -5.847723966064677370e-01 +1.006000000000000050e+01 -5.755738169868864773e-01 +1.007000000000000028e+01 -5.607301140083525981e-01 +1.008000000000000007e+01 -5.393072788461481526e-01 +1.008999999999999986e+01 -5.105511217329163909e-01 +1.009999999999999964e+01 -4.739346103957169376e-01 +1.010999999999999943e+01 -4.291973566558462405e-01 +1.012000000000000099e+01 -3.763754035556607369e-01 +1.013000000000000078e+01 -3.158197836188600949e-01 +1.014000000000000057e+01 -2.482027091246823969e-01 +1.015000000000000036e+01 -1.745107065066486551e-01 +1.016000000000000014e+01 -9.602450485894281629e-02 +1.016999999999999993e+01 -1.428601580647286678e-02 +1.017999999999999972e+01 6.894672101742377324e-02 +1.018999999999999950e+01 1.517552274130994361e-01 +1.020000000000000107e+01 2.321250204878701207e-01 +1.021000000000000085e+01 3.080164661598794318e-01 +1.022000000000000064e+01 3.774393713837534969e-01 +1.023000000000000043e+01 4.385283757159936235e-01 +1.024000000000000021e+01 4.896160582966945785e-01 +1.025000000000000000e+01 5.293006578796776163e-01 +1.025999999999999979e+01 5.565054183588477033e-01 +1.026999999999999957e+01 5.705268217934046371e-01 +1.027999999999999936e+01 5.710693505761599287e-01 +1.029000000000000092e+01 5.582649191695604474e-01 +1.030000000000000071e+01 5.326757166505169394e-01 +1.031000000000000050e+01 4.952798813694302416e-01 +1.032000000000000028e+01 4.474401606505221118e-01 +1.033000000000000007e+01 3.908564601352513823e-01 +1.033999999999999986e+01 3.275039251226631309e-01 +1.034999999999999964e+01 2.595588851924122142e-01 +1.035999999999999943e+01 1.893155993696916117e-01 +1.037000000000000099e+01 1.190972304582484098e-01 +1.038000000000000078e+01 5.116482646414497598e-02 +1.039000000000000057e+01 -1.237172746017341923e-02 +1.040000000000000036e+01 -6.963681603614778337e-02 +1.041000000000000014e+01 -1.190624671700212661e-01 +1.041999999999999993e+01 -1.594485593631804754e-01 +1.042999999999999972e+01 -1.900069628328628635e-01 +1.043999999999999950e+01 -2.103873969336473859e-01 +1.045000000000000107e+01 -2.206835923415885192e-01 +1.046000000000000085e+01 -2.214192399237244480e-01 +1.047000000000000064e+01 -2.135141484775423815e-01 +1.048000000000000043e+01 -1.982319761860892315e-01 +1.049000000000000021e+01 -1.771117998059079657e-01 +1.050000000000000000e+01 -1.518865961889706018e-01 +1.050999999999999979e+01 -1.243923907422613689e-01 +1.051999999999999957e+01 -9.647234018851888471e-02 +1.052999999999999936e+01 -6.988033320244946278e-02 +1.054000000000000092e+01 -4.618879191014675645e-02 +1.055000000000000071e+01 -2.670522994887736257e-02 +1.056000000000000050e+01 -1.240177000877137545e-02 +1.057000000000000028e+01 -3.861258090171268247e-03 +1.058000000000000007e+01 -1.242856681989683125e-03 +1.058999999999999986e+01 -4.269088331907448450e-03 +1.059999999999999964e+01 -1.223527685402199007e-02 +1.060999999999999943e+01 -2.404124453572216782e-02 +1.062000000000000099e+01 -3.824402325768591626e-02 +1.063000000000000078e+01 -5.312928015668053061e-02 +1.064000000000000057e+01 -6.679819792916558141e-02 +1.065000000000000036e+01 -7.726573577353179623e-02 +1.066000000000000014e+01 -8.256557244507152504e-02 +1.066999999999999993e+01 -8.085663222607442080e-02 +1.067999999999999972e+01 -7.052594128243122595e-02 +1.068999999999999950e+01 -5.028266719926501732e-02 +1.070000000000000107e+01 -1.923855681547374102e-02 +1.071000000000000085e+01 2.302940791017418082e-02 +1.072000000000000064e+01 7.643749660443630023e-02 +1.073000000000000043e+01 1.403772241666863818e-01 +1.074000000000000021e+01 2.137220911084908304e-01 +1.075000000000000000e+01 2.948591120213907013e-01 +1.075999999999999979e+01 3.817439614450924834e-01 +1.076999999999999957e+01 4.719774009848230478e-01 +1.077999999999999936e+01 5.628995918911805507e-01 +1.079000000000000092e+01 6.516979976311396694e-01 +1.080000000000000071e+01 7.355238877183116752e-01 +1.081000000000000050e+01 8.116120035460967497e-01 +1.082000000000000028e+01 8.773977633669727272e-01 +1.083000000000000007e+01 9.306264776014442353e-01 +1.083999999999999986e+01 9.694494139346095940e-01 +1.084999999999999964e+01 9.925021767206981815e-01 +1.085999999999999943e+01 9.989617163982813519e-01 +1.087000000000000099e+01 9.885793195521095367e-01 +1.088000000000000078e+01 9.616880970120098571e-01 +1.089000000000000057e+01 9.191847271223339000e-01 +1.090000000000000036e+01 8.624864613424056969e-01 +1.091000000000000014e+01 7.934655963238594900e-01 +1.091999999999999993e+01 7.143646999013635313e-01 +1.092999999999999972e+01 6.276967932153662000e-01 +1.093999999999999950e+01 5.361353913498537738e-01 +1.095000000000000107e+01 4.423997554257314002e-01 +1.096000000000000085e+01 3.491408880031467432e-01 +1.097000000000000064e+01 2.588337029775338305e-01 +1.098000000000000043e+01 1.736804274739063847e-01 +1.099000000000000021e+01 9.552966726675829467e-02 +1.100000000000000000e+01 2.581472272503640766e-02 +1.100999999999999979e+01 -3.448627581937489806e-02 +1.101999999999999957e+01 -8.486698224465299978e-02 +1.102999999999999936e+01 -1.252859651618623282e-01 +1.104000000000000092e+01 -1.561373168405084388e-01 +1.105000000000000071e+01 -1.782008331768112352e-01 +1.106000000000000050e+01 -1.925748650160859221e-01 +1.107000000000000028e+01 -2.005957745054846031e-01 +1.108000000000000007e+01 -2.037485473788168133e-01 +1.108999999999999986e+01 -2.035734830544142782e-01 +1.109999999999999964e+01 -2.015739923116369736e-01 +1.110999999999999943e+01 -1.991303743259330850e-01 +1.112000000000000099e+01 -1.974240323386675655e-01 +1.113000000000000078e+01 -1.973759449928830234e-01 +1.114000000000000057e+01 -1.996023751588939243e-01 +1.115000000000000036e+01 -2.043898166256391535e-01 +1.116000000000000014e+01 -2.116901054260349468e-01 +1.116999999999999993e+01 -2.211355152735670904e-01 +1.117999999999999972e+01 -2.320725753031882832e-01 +1.118999999999999950e+01 -2.436123507110857511e-01 +1.120000000000000107e+01 -2.546940655494051575e-01 +1.121000000000000085e+01 -2.641582665299848642e-01 +1.122000000000000064e+01 -2.708252616607667029e-01 +1.123000000000000043e+01 -2.735743403055956868e-01 +1.124000000000000021e+01 -2.714193011379381071e-01 +1.125000000000000000e+01 -2.635760772790373130e-01 +1.125999999999999979e+01 -2.495187363711485473e-01 +1.126999999999999957e+01 -2.290208180833961937e-01 +1.127999999999999936e+01 -2.021798128966642849e-01 +1.129000000000000092e+01 -1.694235362207902884e-01 +1.130000000000000071e+01 -1.314981578496377812e-01 +1.131000000000000050e+01 -8.943865293639838288e-02 +1.132000000000000028e+01 -4.452339220572133771e-02 +1.133000000000000007e+01 1.784565205158077268e-03 +1.133999999999999986e+01 4.790621786727030512e-02 +1.134999999999999964e+01 9.222164037512815826e-02 +1.135999999999999943e+01 1.331472107126589199e-01 +1.137000000000000099e+01 1.692109125149413307e-01 +1.138000000000000078e+01 1.991217332703605347e-01 +1.139000000000000057e+01 2.218295493316677636e-01 +1.140000000000000036e+01 2.365724498239460960e-01 +1.141000000000000014e+01 2.429091707062502881e-01 +1.141999999999999993e+01 2.407351456715087767e-01 +1.142999999999999972e+01 2.302815847302509822e-01 +1.143999999999999950e+01 2.120979135588454967e-01 +1.145000000000000107e+01 1.870187960549877515e-01 +1.146000000000000085e+01 1.561177706232606544e-01 +1.147000000000000064e+01 1.206502142913947334e-01 +1.148000000000000043e+01 8.198887213133852769e-02 +1.149000000000000021e+01 4.155552632570794908e-02 +1.150000000000000000e+01 7.525140099962975438e-04 +1.150999999999999979e+01 -3.910226838491050877e-02 +1.151999999999999957e+01 -7.683350676612481223e-02 +1.152999999999999936e+01 -1.114568401155607985e-01 +1.154000000000000092e+01 -1.422151464518293662e-01 +1.155000000000000071e+01 -1.686011493167583475e-01 +1.156000000000000050e+01 -1.903655433766132665e-01 +1.157000000000000028e+01 -2.075106595910335416e-01 +1.158000000000000007e+01 -2.202704944326507042e-01 +1.158999999999999986e+01 -2.290786691829667931e-01 +1.159999999999999964e+01 -2.345265239645222266e-01 +1.160999999999999943e+01 -2.373140529164785573e-01 +1.162000000000000099e+01 -2.381967260576761114e-01 +1.163000000000000078e+01 -2.379314037645666458e-01 +1.164000000000000057e+01 -2.372245256202973884e-01 +1.165000000000000036e+01 -2.366855513743367778e-01 +1.166000000000000014e+01 -2.367882626796914691e-01 +1.166999999999999993e+01 -2.378420240231657878e-01 +1.167999999999999972e+01 -2.399744813025666001e-01 +1.168999999999999950e+01 -2.431264839913733489e-01 +1.170000000000000107e+01 -2.470592924158604431e-01 +1.171000000000000085e+01 -2.513734171286780006e-01 +1.172000000000000064e+01 -2.555377732079664455e-01 +1.173000000000000043e+01 -2.589272555032182677e-01 +1.174000000000000021e+01 -2.608663827506031430e-01 +1.175000000000000000e+01 -2.606763431573342893e-01 +1.175999999999999979e+01 -2.577226170198971267e-01 +1.176999999999999957e+01 -2.514603594079110049e-01 +1.177999999999999936e+01 -2.414748946219714143e-01 +1.179000000000000092e+01 -2.275149915658322419e-01 +1.180000000000000071e+01 -2.095170346069984424e-01 +1.181000000000000050e+01 -1.876187502063717816e-01 +1.182000000000000028e+01 -1.621617625794807283e-01 +1.183000000000000007e+01 -1.336828956231818633e-01 +1.183999999999999986e+01 -1.028947758694766651e-01 +1.184999999999999964e+01 -7.065688590422755655e-02 +1.185999999999999943e+01 -3.793873621059983686e-02 +1.187000000000000099e+01 -5.777237436137340823e-03 +1.188000000000000078e+01 2.476935716382165989e-02 +1.189000000000000057e+01 5.266842201122813594e-02 +1.190000000000000036e+01 7.695832395284087080e-02 +1.191000000000000014e+01 9.678980540681247913e-02 +1.191999999999999993e+01 1.114612843707002560e-01 +1.192999999999999972e+01 1.204463580797923705e-01 +1.193999999999999950e+01 1.234122744404895222e-01 +1.195000000000000107e+01 1.202286721969031275e-01 +1.196000000000000085e+01 1.109664546878850050e-01 +1.197000000000000064e+01 9.588721960657560495e-02 +1.198000000000000043e+01 7.542418596818548093e-02 +1.199000000000000021e+01 5.015600998124545434e-02 +1.200000000000000000e+01 2.077523872076809941e-02 +1.200999999999999979e+01 -1.194660461054763805e-02 +1.201999999999999957e+01 -4.719518952675139795e-02 +1.203000000000000114e+01 -8.414869522619569664e-02 +1.204000000000000092e+01 -1.220103036235186122e-01 +1.205000000000000071e+01 -1.600361452581947341e-01 +1.206000000000000050e+01 -1.975573213914565696e-01 +1.207000000000000028e+01 -2.339950468745159162e-01 +1.208000000000000007e+01 -2.688684274549712483e-01 +1.208999999999999986e+01 -3.017948726859547293e-01 +1.209999999999999964e+01 -3.324836214576463722e-01 +1.210999999999999943e+01 -3.607232924688467679e-01 +1.212000000000000099e+01 -3.863647406342146096e-01 +1.213000000000000078e+01 -4.093007807874990966e-01 +1.214000000000000057e+01 -4.294445160123003813e-01 +1.215000000000000036e+01 -4.467080699364511798e-01 +1.216000000000000014e+01 -4.609834677977208139e-01 +1.216999999999999993e+01 -4.721272445450804267e-01 +1.217999999999999972e+01 -4.799500909412078853e-01 +1.218999999999999950e+01 -4.842124978406102676e-01 +1.220000000000000107e+01 -4.846269467111362639e-01 +1.221000000000000085e+01 -4.808667467696519648e-01 +1.222000000000000064e+01 -4.725811635214577922e-01 +1.223000000000000043e+01 -4.594160480482014641e-01 +1.224000000000000021e+01 -4.410387877429425285e-01 +1.225000000000000000e+01 -4.171660810724900914e-01 +1.225999999999999979e+01 -3.875928107600491446e-01 +1.226999999999999957e+01 -3.522201654845560359e-01 +1.228000000000000114e+01 -3.110811475063973153e-01 +1.229000000000000092e+01 -2.643617036159567335e-01 +1.230000000000000071e+01 -2.124159238473232736e-01 +1.231000000000000050e+01 -1.557740545800980758e-01 +1.232000000000000028e+01 -9.514245247494912405e-02 +1.233000000000000007e+01 -3.139504114846793786e-02 +1.233999999999999986e+01 3.444370160888870352e-02 +1.234999999999999964e+01 1.012237288334275065e-01 +1.235999999999999943e+01 1.677014384217269394e-01 +1.237000000000000099e+01 2.325773761218268565e-01 +1.238000000000000078e+01 2.945379622143625697e-01 +1.239000000000000057e+01 3.522993415336077017e-01 +1.240000000000000036e+01 4.046513246545483389e-01 +1.241000000000000014e+01 4.504993666676053166e-01 +1.241999999999999993e+01 4.889026197811500163e-01 +1.242999999999999972e+01 5.191062914838356912e-01 +1.243999999999999950e+01 5.405668296339281031e-01 +1.245000000000000107e+01 5.529688228255971172e-01 +1.246000000000000085e+01 5.562329276673845246e-01 +1.247000000000000064e+01 5.505145901510695161e-01 +1.248000000000000043e+01 5.361937904602454008e-01 +1.249000000000000021e+01 5.138564836411747550e-01 +1.250000000000000000e+01 4.842688081944921397e-01 +1.250999999999999979e+01 4.483454692761832949e-01 +1.251999999999999957e+01 4.071139552316050958e-01 +1.253000000000000114e+01 3.616764029856711637e-01 +1.254000000000000092e+01 3.131709823486139022e-01 +1.255000000000000071e+01 2.627346204938038610e-01 +1.256000000000000050e+01 2.114687405810553866e-01 +1.257000000000000028e+01 1.604094531732028484e-01 +1.258000000000000007e+01 1.105033310618914327e-01 +1.258999999999999986e+01 6.258953666056826792e-02 +1.259999999999999964e+01 1.738867828898263065e-02 +1.260999999999999943e+01 -2.450162903671031581e-02 +1.262000000000000099e+01 -6.260490772288430927e-02 +1.263000000000000078e+01 -9.655842314841756036e-02 +1.264000000000000057e+01 -1.261012967159552134e-01 +1.265000000000000036e+01 -1.510593885451609053e-01 +1.266000000000000014e+01 -1.713283432279300578e-01 +1.266999999999999993e+01 -1.868562324525184504e-01 +1.267999999999999972e+01 -1.976271772034281504e-01 +1.268999999999999950e+01 -2.036471945368578951e-01 +1.270000000000000107e+01 -2.049332996199904333e-01 +1.271000000000000085e+01 -2.015066172811693090e-01 +1.272000000000000064e+01 -1.933899367891233345e-01 +1.273000000000000043e+01 -1.806097994650507910e-01 +1.274000000000000021e+01 -1.632028627544927502e-01 +1.275000000000000000e+01 -1.412259581888890281e-01 +1.275999999999999979e+01 -1.147689745275578960e-01 +1.276999999999999957e+01 -8.396946901004534447e-02 +1.278000000000000114e+01 -4.902775319611155785e-02 +1.279000000000000092e+01 -1.022112505059527728e-02 +1.280000000000000071e+01 3.208406948704813078e-02 +1.281000000000000050e+01 7.742376466474544527e-02 +1.282000000000000028e+01 1.252319341225963667e-01 +1.283000000000000007e+01 1.748415745939547461e-01 +1.283999999999999986e+01 2.254914043306738280e-01 +1.284999999999999964e+01 2.763384257785775899e-01 +1.285999999999999943e+01 3.264761439919959818e-01 +1.287000000000000099e+01 3.749578781112354320e-01 +1.288000000000000078e+01 4.208242739709768254e-01 +1.289000000000000057e+01 4.631338412053235265e-01 +1.290000000000000036e+01 5.009951151844291850e-01 +1.291000000000000014e+01 5.335988963653411910e-01 +1.291999999999999993e+01 5.602489564863504246e-01 +1.292999999999999972e+01 5.803896269853944245e-01 +1.293999999999999950e+01 5.936287995211974033e-01 +1.295000000000000107e+01 5.997550659405560536e-01 +1.296000000000000085e+01 5.987479951900672726e-01 +1.297000000000000064e+01 5.907808731344945663e-01 +1.298000000000000043e+01 5.762156003506585522e-01 +1.299000000000000021e+01 5.555898327673164383e-01 +1.300000000000000000e+01 5.295968394083439001e-01 +1.300999999999999979e+01 4.990589193836625914e-01 +1.301999999999999957e+01 4.648955467683131282e-01 +1.303000000000000114e+01 4.280876795177770422e-01 +1.304000000000000092e+01 3.896398627436869488e-01 +1.305000000000000071e+01 3.505418672046115569e-01 +1.306000000000000050e+01 3.117316250083173590e-01 +1.307000000000000028e+01 2.740611553884600982e-01 +1.308000000000000007e+01 2.382670179946430045e-01 +1.308999999999999986e+01 2.049465980195717962e-01 +1.309999999999999964e+01 1.745412293893088551e-01 +1.310999999999999943e+01 1.473268152510989193e-01 +1.312000000000000099e+01 1.234122276724274186e-01 +1.313000000000000078e+01 1.027453808232785815e-01 +1.314000000000000057e+01 8.512649430642102444e-02 +1.315000000000000036e+01 7.022771532658879379e-02 +1.316000000000000014e+01 5.761796784364956597e-02 +1.316999999999999993e+01 4.679165879301199621e-02 +1.317999999999999972e+01 3.719970742272745573e-02 +1.318999999999999950e+01 2.828128125216953018e-02 +1.320000000000000107e+01 1.949462414011915098e-02 +1.321000000000000085e+01 1.034544698026654448e-02 +1.322000000000000064e+01 4.115137719233594497e-04 +1.323000000000000043e+01 -1.063771458708815711e-02 +1.324000000000000021e+01 -2.302723268928972764e-02 +1.325000000000000000e+01 -3.686897103569040934e-02 +1.325999999999999979e+01 -5.216079353995749929e-02 +1.326999999999999957e+01 -6.879185598341515384e-02 +1.328000000000000114e+01 -8.655383979495845370e-02 +1.329000000000000092e+01 -1.051572786527674441e-01 +1.330000000000000071e+01 -1.242519459880172539e-01 +1.331000000000000050e+01 -1.434500815507369631e-01 +1.332000000000000028e+01 -1.623511134214916940e-01 +1.333000000000000007e+01 -1.805664830937651899e-01 +1.333999999999999986e+01 -1.977432064397770806e-01 +1.334999999999999964e+01 -2.135848995337588374e-01 +1.335999999999999943e+01 -2.278691588169275140e-01 +1.337000000000000099e+01 -2.404604001114583056e-01 +1.338000000000000078e+01 -2.513175180799508968e-01 +1.339000000000000057e+01 -2.604960125481494138e-01 +1.340000000000000036e+01 -2.681445252469596419e-01 +1.341000000000000014e+01 -2.744960243294451985e-01 +1.341999999999999993e+01 -2.798541494136806418e-01 +1.342999999999999972e+01 -2.845754731918154201e-01 +1.343999999999999950e+01 -2.890486351720971125e-01 +1.345000000000000107e+01 -2.936714498199636258e-01 +1.346000000000000085e+01 -2.988271791618488105e-01 +1.347000000000000064e+01 -3.048611859477073360e-01 +1.348000000000000043e+01 -3.120591481306718706e-01 +1.349000000000000021e+01 -3.206279222382821814e-01 +1.350000000000000000e+01 -3.306799985420804666e-01 +1.350999999999999979e+01 -3.422223035514755929e-01 +1.351999999999999957e+01 -3.551498858996195995e-01 +1.353000000000000114e+01 -3.692447820334622266e-01 +1.354000000000000092e+01 -3.841801107277304506e-01 +1.355000000000000071e+01 -3.995292026862239942e-01 +1.356000000000000050e+01 -4.147793450223564715e-01 +1.357000000000000028e+01 -4.293495205775994528e-01 +1.358000000000000007e+01 -4.426113574202173440e-01 +1.358999999999999986e+01 -4.539123809087606265e-01 +1.359999999999999964e+01 -4.626005834758344926e-01 +1.360999999999999943e+01 -4.680492973909471388e-01 +1.362000000000000099e+01 -4.696813723720957290e-01 +1.363000000000000078e+01 -4.669917199499126759e-01 +1.364000000000000057e+01 -4.595673848795666649e-01 +1.365000000000000036e+01 -4.471044339700481207e-01 +1.366000000000000014e+01 -4.294211066107284092e-01 +1.366999999999999993e+01 -4.064668404807852964e-01 +1.367999999999999972e+01 -3.783269616806342328e-01 +1.368999999999999950e+01 -3.452230023418402793e-01 +1.370000000000000107e+01 -3.075087728618026151e-01 +1.371000000000000085e+01 -2.656624635365337772e-01 +1.372000000000000064e+01 -2.202751761326453839e-01 +1.373000000000000043e+01 -1.720363859818750119e-01 +1.374000000000000021e+01 -1.217169072532154339e-01 +1.375000000000000000e+01 -7.014997753086146814e-02 +1.375999999999999979e+01 -1.821109359210966103e-02 +1.376999999999999957e+01 3.320277942794960802e-02 +1.378000000000000114e+01 8.319403514456004400e-02 +1.379000000000000092e+01 1.308847488042106100e-01 +1.380000000000000071e+01 1.754360186317128756e-01 +1.381000000000000050e+01 2.160659200684496573e-01 +1.382000000000000028e+01 2.520657429153724816e-01 +1.383000000000000007e+01 2.828142565675598186e-01 +1.383999999999999986e+01 3.077898196505520767e-01 +1.384999999999999964e+01 3.265802146153182761e-01 +1.385999999999999943e+01 3.388901433037228572e-01 +1.387000000000000099e+01 3.445463651930273374e-01 +1.388000000000000078e+01 3.435004959164540406e-01 +1.389000000000000057e+01 3.358295105139623149e-01 +1.390000000000000036e+01 3.217340151505601598e-01 +1.391000000000000014e+01 3.015343647086842771e-01 +1.391999999999999993e+01 2.756647139657092405e-01 +1.392999999999999972e+01 2.446650993342703029e-01 +1.393999999999999950e+01 2.091716585585853827e-01 +1.395000000000000107e+01 1.699051091818959969e-01 +1.396000000000000085e+01 1.276576243931273058e-01 +1.397000000000000064e+01 8.327826777919629386e-02 +1.398000000000000043e+01 3.765717662425810408e-02 +1.399000000000000021e+01 -8.291283919437803657e-03 +1.400000000000000000e+01 -5.364613750848454266e-02 +1.400999999999999979e+01 -9.749788850327743839e-02 +1.401999999999999957e+01 -1.389667570475171809e-01 +1.403000000000000114e+01 -1.772206924790647453e-01 +1.404000000000000092e+01 -2.114927737401566532e-01 +1.405000000000000071e+01 -2.410975879996786475e-01 +1.406000000000000050e+01 -2.654461726857199610e-01 +1.407000000000000028e+01 -2.840591135279521007e-01 +1.408000000000000007e+01 -2.965774134064290135e-01 +1.408999999999999986e+01 -3.027707844632967493e-01 +1.409999999999999964e+01 -3.025430689332537781e-01 +1.410999999999999943e+01 -2.959345615432773524e-01 +1.412000000000000099e+01 -2.831210863723935267e-01 +1.413000000000000078e+01 -2.644097712573350023e-01 +1.414000000000000057e+01 -2.402315600515706473e-01 +1.415000000000000036e+01 -2.111306036725439927e-01 +1.416000000000000014e+01 -1.777507709598309116e-01 +1.416999999999999993e+01 -1.408196158381776197e-01 +1.417999999999999972e+01 -1.011302241215294995e-01 +1.418999999999999950e+01 -5.952143775727869457e-02 +1.420000000000000107e+01 -1.685701308976319743e-02 +1.421000000000000085e+01 2.599568987721976102e-02 +1.422000000000000064e+01 6.818687017306085396e-02 +1.423000000000000043e+01 1.089046848498494008e-01 +1.424000000000000021e+01 1.473942916788797408e-01 +1.425000000000000000e+01 1.829749870361427333e-01 +1.425999999999999979e+01 2.150549539816625222e-01 +1.426999999999999957e+01 2.431432161537665226e-01 +1.428000000000000114e+01 2.668584877520251974e-01 +1.429000000000000092e+01 2.859347149512462827e-01 +1.430000000000000071e+01 3.002232155490293652e-01 +1.431000000000000050e+01 3.096914372464769638e-01 +1.432000000000000028e+01 3.144184663925814749e-01 +1.433000000000000007e+01 3.145875241151933066e-01 +1.433999999999999986e+01 3.104757816447504815e-01 +1.434999999999999964e+01 3.024419078951590123e-01 +1.435999999999999943e+01 2.909118271700330549e-01 +1.437000000000000099e+01 2.763632110722129553e-01 +1.438000000000000078e+01 2.593092549332601249e-01 +1.439000000000000057e+01 2.402822947723924352e-01 +1.440000000000000036e+01 2.198178061752124879e-01 +1.441000000000000014e+01 1.984392925680555086e-01 +1.441999999999999993e+01 1.766445188961113522e-01 +1.442999999999999972e+01 1.548934800780604470e-01 +1.443999999999999950e+01 1.335984147276105816e-01 +1.445000000000000107e+01 1.131160868358270649e-01 +1.446000000000000085e+01 9.374246500391464343e-02 +1.447000000000000064e+01 7.570983414002795120e-02 +1.448000000000000043e+01 5.918628200385682436e-02 +1.449000000000000021e+01 4.427741615682131981e-02 +1.450000000000000000e+01 3.103008901605644465e-02 +1.450999999999999979e+01 1.943784266263950261e-02 +1.451999999999999957e+01 9.447733143707446810e-03 +1.453000000000000114e+01 9.681579549867640189e-04 +1.454000000000000092e+01 -6.122708748949228300e-03 +1.455000000000000071e+01 -1.196827053742118355e-02 +1.456000000000000050e+01 -1.672503494745359448e-02 +1.457000000000000028e+01 -2.055466292297606495e-02 +1.458000000000000007e+01 -2.361684765314258846e-02 +1.458999999999999986e+01 -2.606327194542031739e-02 +1.459999999999999964e+01 -2.803282700605171096e-02 +1.460999999999999943e+01 -2.964820315633573747e-02 +1.462000000000000099e+01 -3.101388794561412907e-02 +1.463000000000000078e+01 -3.221553279346384829e-02 +1.464000000000000057e+01 -3.332057912655784354e-02 +1.465000000000000036e+01 -3.437997220538804161e-02 +1.466000000000000014e+01 -3.543073837004070276e-02 +1.466999999999999993e+01 -3.649916172121062813e-02 +1.467999999999999972e+01 -3.760427116847585294e-02 +1.468999999999999950e+01 -3.876133953298189355e-02 +1.470000000000000107e+01 -3.998510346511558594e-02 +1.471000000000000085e+01 -4.129243604138527202e-02 +1.472000000000000064e+01 -4.270424198081282374e-02 +1.473000000000000043e+01 -4.424639667396765286e-02 +1.474000000000000021e+01 -4.594961218039622652e-02 +1.475000000000000000e+01 -4.784818298338699288e-02 +1.475999999999999979e+01 -4.997763811260577671e-02 +1.476999999999999957e+01 -5.237140048401849046e-02 +1.478000000000000114e+01 -5.505662507538520989e-02 +1.479000000000000092e+01 -5.804945103573940640e-02 +1.480000000000000071e+01 -6.134995545565614938e-02 +1.481000000000000050e+01 -6.493713517675470115e-02 +1.482000000000000028e+01 -6.876426517376423020e-02 +1.483000000000000007e+01 -7.275498592936439912e-02 +1.483999999999999986e+01 -7.680045693072634627e-02 +1.484999999999999964e+01 -8.075787897230476964e-02 +1.485999999999999943e+01 -8.445063534273526684e-02 +1.487000000000000099e+01 -8.767023314547377211e-02 +1.488000000000000078e+01 -9.018014377989448660e-02 +1.489000000000000057e+01 -9.172154959538564301e-02 +1.490000000000000036e+01 -9.202090615257703388e-02 +1.491000000000000014e+01 -9.079913104570828952e-02 +1.491999999999999993e+01 -8.778213573872958864e-02 +1.492999999999999972e+01 -8.271233120849712239e-02 +1.493999999999999950e+01 -7.536066597568118197e-02 +1.495000000000000107e+01 -6.553870044569166942e-02 +1.496000000000000085e+01 -5.311018777004872238e-02 +1.497000000000000064e+01 -3.800162115827768888e-02 +1.498000000000000043e+01 -2.021122214874732440e-02 +1.499000000000000021e+01 1.841159497774479549e-04 +1.500000000000000000e+01 2.302435134753236246e-02 +1.500999999999999979e+01 4.806461976482887671e-02 +1.501999999999999957e+01 7.497659438400328114e-02 +1.503000000000000114e+01 1.033529917887491406e-01 +1.504000000000000092e+01 1.327152072357040968e-01 +1.505000000000000071e+01 1.625239301302437434e-01 +1.506000000000000050e+01 1.921924602953960504e-01 +1.507000000000000028e+01 2.211023235507158236e-01 +1.508000000000000007e+01 2.486206770263285626e-01 +1.508999999999999986e+01 2.741189057595672662e-01 +1.509999999999999964e+01 2.969917468917497305e-01 +1.510999999999999943e+01 3.166762396076698294e-01 +1.512000000000000099e+01 3.326697900392537877e-01 +1.513000000000000078e+01 3.445466615560303092e-01 +1.514000000000000057e+01 3.519722516663893463e-01 +1.515000000000000036e+01 3.547145952530907365e-01 +1.516000000000000014e+01 3.526526368573930093e-01 +1.516999999999999993e+01 3.457809378438824743e-01 +1.517999999999999972e+01 3.342106221963261903e-01 +1.518999999999999950e+01 3.181665113811920076e-01 +1.520000000000000107e+01 2.979805477132198566e-01 +1.521000000000000085e+01 2.740817503976049618e-01 +1.522000000000000064e+01 2.469830825370851746e-01 +1.523000000000000043e+01 2.172657250174266641e-01 +1.524000000000000021e+01 1.855613492456530123e-01 +1.525000000000000000e+01 1.525330511620769658e-01 +1.525999999999999979e+01 1.188556509460812066e-01 +1.526999999999999957e+01 8.519607489525664323e-02 +1.528000000000000114e+01 5.219451798884262167e-02 +1.529000000000000092e+01 2.044703895299540899e-02 +1.530000000000000071e+01 -9.509833157790888516e-03 +1.531000000000000050e+01 -3.721199697893097513e-02 +1.532000000000000028e+01 -6.227781027778932915e-02 +1.533000000000000007e+01 -8.441500846255077517e-02 +1.533999999999999986e+01 -1.034243948237706101e-01 +1.534999999999999964e+01 -1.192003183528275168e-01 +1.535999999999999943e+01 -1.317280804246898085e-01 +1.537000000000000099e+01 -1.410785258932084618e-01 +1.538000000000000078e+01 -1.474001724786274115e-01 +1.539000000000000057e+01 -1.509093108996306942e-01 +1.540000000000000036e+01 -1.518785642662371926e-01 +1.541000000000000014e+01 -1.506244272417317787e-01 +1.541999999999999993e+01 -1.474943130628861288e-01 +1.542999999999999972e+01 -1.428536205418199090e-01 +1.543999999999999950e+01 -1.370732956390406376e-01 +1.545000000000000107e+01 -1.305183060488101510e-01 +1.546000000000000085e+01 -1.235373762134058806e-01 +1.547000000000000064e+01 -1.164542485818557682e-01 +1.548000000000000043e+01 -1.095606493653430574e-01 +1.549000000000000021e+01 -1.031110481899015496e-01 +1.550000000000000000e+01 -9.731921539178695069e-02 +1.550999999999999979e+01 -9.235650230766617730e-02 +1.551999999999999957e+01 -8.835170222883126367e-02 +1.553000000000000114e+01 -8.539229539015581738e-02 +1.554000000000000092e+01 -8.352684224240643218e-02 +1.555000000000000071e+01 -8.276826616622517951e-02 +1.556000000000000050e+01 -8.309775964623802857e-02 +1.557000000000000028e+01 -8.446905576946943384e-02 +1.558000000000000007e+01 -8.681282799579503884e-02 +1.558999999999999986e+01 -9.004101308055177666e-02 +1.559999999999999964e+01 -9.405089195285597226e-02 +1.561000000000000121e+01 -9.872880813304489578e-02 +1.562000000000000099e+01 -1.039534496979748202e-01 +1.563000000000000078e+01 -1.095986657819808807e-01 +1.564000000000000057e+01 -1.155358293422121541e-01 +1.565000000000000036e+01 -1.216357920821490440e-01 +1.566000000000000014e+01 -1.277705032533347496e-01 +1.566999999999999993e+01 -1.338143804345428012e-01 +1.567999999999999972e+01 -1.396455269033047286e-01 +1.568999999999999950e+01 -1.451468871344748224e-01 +1.570000000000000107e+01 -1.502074201858789315e-01 +1.571000000000000085e+01 -1.547233517109617429e-01 +1.572000000000000064e+01 -1.585995409495379871e-01 +1.573000000000000043e+01 -1.617509714546691013e-01 +1.574000000000000021e+01 -1.641043458148924716e-01 +1.575000000000000000e+01 -1.655997375013015804e-01 +1.575999999999999979e+01 -1.661922293110556781e-01 +1.576999999999999957e+01 -1.658534494898920297e-01 +1.578000000000000114e+01 -1.645729048778708237e-01 +1.579000000000000092e+01 -1.623590062245120480e-01 +1.580000000000000071e+01 -1.592396845137129813e-01 +1.581000000000000050e+01 -1.552625085334001787e-01 +1.582000000000000028e+01 -1.504942323109781654e-01 +1.583000000000000007e+01 -1.450197252496923106e-01 +1.583999999999999986e+01 -1.389402663117848269e-01 +1.584999999999999964e+01 -1.323712146147556223e-01 +1.586000000000000121e+01 -1.254391004158563194e-01 +1.587000000000000099e+01 -1.182782107315113601e-01 +1.588000000000000078e+01 -1.110267709665214014e-01 +1.589000000000000057e+01 -1.038228463395015483e-01 +1.590000000000000036e+01 -9.680010333991839744e-02 +1.591000000000000014e+01 -9.008358108885050619e-02 +1.591999999999999993e+01 -8.378562488865012869e-02 +1.592999999999999972e+01 -7.800212947271722985e-02 +1.593999999999999950e+01 -7.280922797146610614e-02 +1.595000000000000107e+01 -6.826054524099471610e-02 +1.596000000000000085e+01 -6.438511211347149044e-02 +1.597000000000000064e+01 -6.118601169862212391e-02 +1.598000000000000043e+01 -5.863980158740973031e-02 +1.599000000000000021e+01 -5.669672818765608691e-02 +1.600000000000000000e+01 -5.528172287131247892e-02 +1.601000000000000156e+01 -5.429614536645389206e-02 +1.601999999999999957e+01 -5.362021885785960007e-02 +1.603000000000000114e+01 -5.311608423129512285e-02 +1.603999999999999915e+01 -5.263138813252889875e-02 +1.605000000000000071e+01 -5.200331099717891981e-02 +1.605999999999999872e+01 -5.106293661157020047e-02 +1.607000000000000028e+01 -4.963986349328182446e-02 +1.608000000000000185e+01 -4.756695964291064033e-02 +1.608999999999999986e+01 -4.468516511480546960e-02 +1.610000000000000142e+01 -4.084825046389571612e-02 +1.610999999999999943e+01 -3.592744260136932627e-02 +1.612000000000000099e+01 -2.981583224650790828e-02 +1.612999999999999901e+01 -2.243247853947472059e-02 +1.614000000000000057e+01 -1.372612630924919218e-02 +1.614999999999999858e+01 -3.678450114249891007e-03 +1.616000000000000014e+01 7.693263052127271781e-03 +1.617000000000000171e+01 2.033408282644982856e-02 +1.617999999999999972e+01 3.415014819357142795e-02 +1.619000000000000128e+01 4.900821516695702540e-02 +1.619999999999999929e+01 6.473612693808264429e-02 +1.621000000000000085e+01 8.112428581202066336e-02 +1.621999999999999886e+01 9.792819266373446740e-02 +1.623000000000000043e+01 1.148720999363765510e-01 +1.624000000000000199e+01 1.316537979850201379e-01 +1.625000000000000000e+01 1.479505219145849926e-01 +1.626000000000000156e+01 1.634259275306744474e-01 +1.626999999999999957e+01 1.777380416921986450e-01 +1.628000000000000114e+01 1.905480457995496757e-01 +1.628999999999999915e+01 2.015297033949682293e-01 +1.630000000000000071e+01 2.103791962786567549e-01 +1.630999999999999872e+01 2.168250907884180512e-01 +1.632000000000000028e+01 2.206381196886551266e-01 +1.633000000000000185e+01 2.216404381497134313e-01 +1.633999999999999986e+01 2.197139970287839694e-01 +1.635000000000000142e+01 2.148076751596628420e-01 +1.635999999999999943e+01 2.069428261452782858e-01 +1.637000000000000099e+01 1.962169250748339866e-01 +1.637999999999999901e+01 1.828050467297483439e-01 +1.639000000000000057e+01 1.669589684350740733e-01 +1.639999999999999858e+01 1.490037661371651778e-01 +1.641000000000000014e+01 1.293318591012109497e-01 +1.642000000000000171e+01 1.083945536374235630e-01 +1.642999999999999972e+01 8.669123567545282405e-02 +1.644000000000000128e+01 6.475646155262181070e-02 +1.644999999999999929e+01 4.314529154553885248e-02 +1.646000000000000085e+01 2.241729690389411556e-02 +1.646999999999999886e+01 3.119744083068336747e-03 +1.648000000000000043e+01 -1.422948441143123167e-02 +1.649000000000000199e+01 -2.915863794661840633e-02 +1.650000000000000000e+01 -4.125790758442279133e-02 +1.651000000000000156e+01 -5.019370311979860083e-02 +1.651999999999999957e+01 -5.572083963927236538e-02 +1.653000000000000114e+01 -5.769213693076941790e-02 +1.653999999999999915e+01 -5.606501823248592753e-02 +1.655000000000000071e+01 -5.090479711499133059e-02 +1.655999999999999872e+01 -4.238445881135709248e-02 +1.657000000000000028e+01 -3.078087032585649641e-02 +1.658000000000000185e+01 -1.646748687457507201e-02 +1.658999999999999986e+01 9.624497175297197634e-05 +1.660000000000000142e+01 1.837846033300787052e-02 +1.660999999999999943e+01 3.779098294281641596e-02 +1.662000000000000099e+01 5.770742496565098301e-02 +1.662999999999999901e+01 7.748266085292615513e-02 +1.664000000000000057e+01 9.647300267269949547e-02 +1.664999999999999858e+01 1.140563770789117665e-01 +1.666000000000000014e+01 1.296518043574009238e-01 +1.667000000000000171e+01 1.427375076657876052e-01 +1.667999999999999972e+01 1.528670343262001352e-01 +1.669000000000000128e+01 1.596828483465829451e-01 +1.669999999999999929e+01 1.629269507403441619e-01 +1.671000000000000085e+01 1.624481973559125658e-01 +1.671999999999999886e+01 1.582061078733066062e-01 +1.673000000000000043e+01 1.502710890583127956e-01 +1.674000000000000199e+01 1.388211248576101398e-01 +1.675000000000000000e+01 1.241351101836663806e-01 +1.676000000000000156e+01 1.065831193772235203e-01 +1.676999999999999957e+01 8.661400005314284778e-02 +1.678000000000000114e+01 6.474076482191372384e-02 +1.678999999999999915e+01 4.152431464589693977e-02 +1.680000000000000071e+01 1.755606675242513473e-02 +1.680999999999999872e+01 -6.559923462380888408e-03 +1.682000000000000028e+01 -3.022476277960549004e-02 +1.683000000000000185e+01 -5.286188545030430508e-02 +1.683999999999999986e+01 -7.393307114532710056e-02 +1.685000000000000142e+01 -9.295286395135926583e-02 +1.685999999999999943e+01 -1.095010137699344716e-01 +1.687000000000000099e+01 -1.232326430660608679e-01 +1.687999999999999901e+01 -1.338859283685948087e-01 +1.689000000000000057e+01 -1.412871735898341696e-01 +1.689999999999999858e+01 -1.453532377245607132e-01 +1.691000000000000014e+01 -1.460913598462034724e-01 +1.692000000000000171e+01 -1.435964971050869565e-01 +1.692999999999999972e+01 -1.380463548194657275e-01 +1.694000000000000128e+01 -1.296943405327004584e-01 +1.694999999999999929e+01 -1.188607155121373798e-01 +1.696000000000000085e+01 -1.059222475847387129e-01 +1.696999999999999886e+01 -9.130068893722914636e-02 +1.698000000000000043e+01 -7.545041244543243542e-02 +1.699000000000000199e+01 -5.884554140722077914e-02 +1.700000000000000000e+01 -4.196690155594975241e-02 +1.701000000000000156e+01 -2.528911227772797504e-02 +1.701999999999999957e+01 -9.268117316345966111e-03 +1.703000000000000114e+01 5.670564976671316204e-03 +1.703999999999999915e+01 1.914261474159959994e-02 +1.705000000000000071e+01 3.081447504605152113e-02 +1.705999999999999872e+01 4.041150256908069421e-02 +1.707000000000000028e+01 4.772452815929554421e-02 +1.708000000000000185e+01 5.261468155067037383e-02 +1.708999999999999986e+01 5.501636741470536385e-02 +1.710000000000000142e+01 5.493831539494733324e-02 +1.710999999999999943e+01 5.246266509170668252e-02 +1.712000000000000099e+01 4.774208827460357796e-02 +1.712999999999999901e+01 4.099499479487638681e-02 +1.714000000000000057e+01 3.249891533866295507e-02 +1.715000000000000213e+01 2.258220254407117614e-02 +1.716000000000000014e+01 1.161424096653033457e-02 +1.717000000000000171e+01 -5.595569456255840799e-06 +1.717999999999999972e+01 -1.185995534367279523e-02 +1.719000000000000128e+01 -2.352616432754192979e-02 +1.719999999999999929e+01 -3.458916772617062763e-02 +1.721000000000000085e+01 -4.465437448408808574e-02 +1.721999999999999886e+01 -5.336000804474885090e-02 +1.723000000000000043e+01 -6.038856565306593288e-02 +1.724000000000000199e+01 -6.547700148284162081e-02 +1.725000000000000000e+01 -6.842527657779089167e-02 +1.726000000000000156e+01 -6.910296108311173024e-02 +1.726999999999999957e+01 -6.745363086210288961e-02 +1.728000000000000114e+01 -6.349686993929747059e-02 +1.728999999999999915e+01 -5.732777015808671051e-02 +1.730000000000000071e+01 -4.911390718587181625e-02 +1.730999999999999872e+01 -3.908986417698522009e-02 +1.732000000000000028e+01 -2.754946722264014700e-02 +1.733000000000000185e+01 -1.483598614083640049e-02 +1.733999999999999986e+01 -1.330636101241181512e-03 +1.735000000000000142e+01 1.256021388174429106e-02 +1.735999999999999943e+01 2.641866396684892926e-02 +1.737000000000000099e+01 3.982923872562730422e-02 +1.737999999999999901e+01 5.239265778026729742e-02 +1.739000000000000057e+01 6.373890893053231477e-02 +1.740000000000000213e+01 7.353913654369098607e-02 +1.741000000000000014e+01 8.151590470521628828e-02 +1.742000000000000171e+01 8.745146062797103104e-02 +1.742999999999999972e+01 9.119370635332239849e-02 +1.744000000000000128e+01 9.265968225165266414e-02 +1.744999999999999929e+01 9.183646995437677596e-02 +1.746000000000000085e+01 8.877953035348860877e-02 +1.746999999999999886e+01 8.360859917182988932e-02 +1.748000000000000043e+01 7.650136333022318491e-02 +1.749000000000000199e+01 6.768523117786338916e-02 +1.750000000000000000e+01 5.742758438642963509e-02 +1.751000000000000156e+01 4.602495545229814966e-02 +1.751999999999999957e+01 3.379160974572393422e-02 +1.753000000000000114e+01 2.104802339406193490e-02 +1.753999999999999915e+01 8.109737635491356261e-03 +1.755000000000000071e+01 -4.722962557912879777e-03 +1.755999999999999872e+01 -1.717415088007497384e-02 +1.757000000000000028e+01 -2.899981879876887408e-02 +1.758000000000000185e+01 -3.999365093960072226e-02 +1.758999999999999986e+01 -4.999086922347020095e-02 +1.760000000000000142e+01 -5.887009529386477702e-02 +1.760999999999999943e+01 -6.655327695491405904e-02 +1.762000000000000099e+01 -7.300381475035973289e-02 +1.762999999999999901e+01 -7.822310493305291434e-02 +1.764000000000000057e+01 -8.224578101793016127e-02 +1.765000000000000213e+01 -8.513398482443898518e-02 +1.766000000000000014e+01 -8.697102733339667768e-02 +1.767000000000000171e+01 -8.785480883493597404e-02 +1.767999999999999972e+01 -8.789135688570463845e-02 +1.769000000000000128e+01 -8.718881078650758676e-02 +1.769999999999999929e+01 -8.585213491619081427e-02 +1.771000000000000085e+01 -8.397878346678384898e-02 +1.771999999999999886e+01 -8.165546975382416417e-02 +1.773000000000000043e+01 -7.895611860949962313e-02 +1.774000000000000199e+01 -7.594100488910970892e-02 +1.775000000000000000e+01 -7.265700925261536769e-02 +1.776000000000000156e+01 -6.913885822256868319e-02 +1.776999999999999957e+01 -6.541116261297227896e-02 +1.778000000000000114e+01 -6.149102956283695326e-02 +1.778999999999999915e+01 -5.739100047862602527e-02 +1.780000000000000071e+01 -5.312206107294248358e-02 +1.780999999999999872e+01 -4.869648022217012290e-02 +1.782000000000000028e+01 -4.413026037711387239e-02 +1.783000000000000185e+01 -3.944502164060773031e-02 +1.783999999999999986e+01 -3.466919147852810107e-02 +1.785000000000000142e+01 -2.983842885683849963e-02 +1.785999999999999943e+01 -2.499527151929556781e-02 +1.787000000000000099e+01 -2.018805412435889859e-02 +1.787999999999999901e+01 -1.546919914689331467e-02 +1.789000000000000057e+01 -1.089302827860057568e-02 +1.790000000000000213e+01 -6.513276565349139166e-03 +1.791000000000000014e+01 -2.380512493246998360e-03 +1.792000000000000171e+01 1.460326633391159472e-03 +1.792999999999999972e+01 4.972083727391670739e-03 +1.794000000000000128e+01 8.127038643732561671e-03 +1.794999999999999929e+01 1.090793235555202051e-02 +1.796000000000000085e+01 1.330826528127766056e-02 +1.796999999999999886e+01 1.533183069874633278e-02 +1.798000000000000043e+01 1.699150205902824617e-02 +1.799000000000000199e+01 1.830735060543921613e-02 +1.800000000000000000e+01 1.930422306513260647e-02 +1.801000000000000156e+01 2.000895459361687334e-02 +1.801999999999999957e+01 2.044742636542969810e-02 +1.803000000000000114e+01 2.064169764375224300e-02 +1.803999999999999915e+01 2.060744710385773587e-02 +1.805000000000000071e+01 2.035194687519025283e-02 +1.805999999999999872e+01 1.987276548122132724e-02 +1.807000000000000028e+01 1.915735390232515406e-02 +1.808000000000000185e+01 1.818361463881564347e-02 +1.808999999999999986e+01 1.692149002604948632e-02 +1.810000000000000142e+01 1.533553693417449154e-02 +1.810999999999999943e+01 1.338838460110528331e-02 +1.812000000000000099e+01 1.104490512406439140e-02 +1.812999999999999901e+01 8.276866428552321145e-03 +1.814000000000000057e+01 5.067789364537872605e-03 +1.815000000000000213e+01 1.417697383610692355e-03 +1.816000000000000014e+01 -2.652568340680977466e-03 +1.817000000000000171e+01 -7.097791821652424046e-03 +1.817999999999999972e+01 -1.184588319391044475e-02 +1.819000000000000128e+01 -1.679669498620803628e-02 +1.819999999999999929e+01 -2.182235090378537370e-02 +1.821000000000000085e+01 -2.676920951118910708e-02 +1.821999999999999886e+01 -3.146149953859919690e-02 +1.823000000000000043e+01 -3.570657146386103237e-02 +1.824000000000000199e+01 -3.930161652722610754e-02 +1.825000000000000000e+01 -4.204161461507929798e-02 +1.826000000000000156e+01 -4.372819163176475121e-02 +1.826999999999999957e+01 -4.417899983428527633e-02 +1.828000000000000114e+01 -4.323718526828731340e-02 +1.828999999999999915e+01 -4.078047817413855969e-02 +1.830000000000000071e+01 -3.672943721520514210e-02 +1.830999999999999872e+01 -3.105439759051376036e-02 +1.832000000000000028e+01 -2.378071621957196860e-02 +1.833000000000000185e+01 -1.499197262772450183e-02 +1.833999999999999986e+01 -4.830869094520381761e-03 +1.835000000000000142e+01 6.502325852493613667e-03 +1.835999999999999943e+01 1.875383520816024246e-02 +1.837000000000000099e+01 3.162286047981621023e-02 +1.837999999999999901e+01 4.477030965597811329e-02 +1.839000000000000057e+01 5.782946803383623435e-02 +1.840000000000000213e+01 7.041821583405988294e-02 +1.841000000000000014e+01 8.215231556673689706e-02 +1.842000000000000171e+01 9.265923237690781855e-02 +1.842999999999999972e+01 1.015919152910663287e-01 +1.844000000000000128e+01 1.086419583913533354e-01 +1.844999999999999929e+01 1.135515791255634205e-01 +1.846000000000000085e+01 1.161238955236690157e-01 +1.846999999999999886e+01 1.162310530191255215e-01 +1.848000000000000043e+01 1.138198416304412736e-01 +1.849000000000000199e+01 1.089145511616935874e-01 +1.850000000000000000e+01 1.016169307187487353e-01 +1.851000000000000156e+01 9.210324353794036023e-02 +1.851999999999999957e+01 8.061853294322197938e-02 +1.853000000000000114e+01 6.746833427750305312e-02 +1.853999999999999915e+01 5.300817531925081788e-02 +1.855000000000000071e+01 3.763129903344213795e-02 +1.855999999999999872e+01 2.175511341058930168e-02 +1.857000000000000028e+01 5.806920564137485995e-03 +1.858000000000000185e+01 -9.790500677876600930e-03 +1.858999999999999986e+01 -2.463288833446179021e-02 +1.860000000000000142e+01 -3.834752579098461844e-02 +1.860999999999999943e+01 -5.060481662046732027e-02 +1.862000000000000099e+01 -6.112798998956456981e-02 +1.862999999999999901e+01 -6.970061036412515676e-02 +1.864000000000000057e+01 -7.617166655004073417e-02 +1.865000000000000213e+01 -8.045812325740560322e-02 +1.866000000000000014e+01 -8.254492811929119156e-02 +1.867000000000000171e+01 -8.248257327542422856e-02 +1.867999999999999972e+01 -8.038240843419583448e-02 +1.869000000000000128e+01 -7.640998751783331655e-02 +1.869999999999999929e+01 -7.077680011080711431e-02 +1.871000000000000085e+01 -6.373078942473572872e-02 +1.871999999999999886e+01 -5.554608883469741576e-02 +1.873000000000000043e+01 -4.651241875362606415e-02 +1.874000000000000199e+01 -3.692457525155158626e-02 +1.875000000000000000e+01 -2.707241291355958965e-02 +1.876000000000000156e+01 -1.723167932477255235e-02 +1.876999999999999957e+01 -7.656000312434931704e-03 +1.878000000000000114e+01 1.429752806347693974e-03 +1.878999999999999915e+01 9.834556417075559359e-03 +1.880000000000000071e+01 1.740470631677791535e-02 +1.880999999999999872e+01 2.402565984587306733e-02 +1.882000000000000028e+01 2.962230897425522508e-02 +1.883000000000000185e+01 3.415780537977496784e-02 +1.883999999999999986e+01 3.763110865271878519e-02 +1.885000000000000142e+01 4.007346685411888182e-02 +1.885999999999999943e+01 4.154406390362012924e-02 +1.887000000000000099e+01 4.212508056885260616e-02 +1.887999999999999901e+01 4.191641576204183789e-02 +1.889000000000000057e+01 4.103030361988099090e-02 +1.890000000000000213e+01 3.958604114487057624e-02 +1.891000000000000014e+01 3.770501307507753003e-02 +1.892000000000000171e+01 3.550616738969404607e-02 +1.892999999999999972e+01 3.310205877335936631e-02 +1.894000000000000128e+01 3.059554068876135444e-02 +1.894999999999999929e+01 2.807715146320821295e-02 +1.896000000000000085e+01 2.562320767424728848e-02 +1.896999999999999886e+01 2.329459041203364375e-02 +1.898000000000000043e+01 2.113618754165432628e-02 +1.899000000000000199e+01 1.917693826329953943e-02 +1.900000000000000000e+01 1.743041500457764154e-02 +1.901000000000000156e+01 1.589587151559988115e-02 +1.901999999999999957e+01 1.455968419236264126e-02 +1.903000000000000114e+01 1.339711511911808456e-02 +1.903999999999999915e+01 1.237432896568394121e-02 +1.905000000000000071e+01 1.145060055601492856e-02 +1.905999999999999872e+01 1.058065458388679492e-02 +1.907000000000000028e+01 9.717082713945916425e-03 +1.908000000000000185e+01 8.812785548272500380e-03 +1.908999999999999986e+01 7.823387338490498874e-03 +1.910000000000000142e+01 6.709569884947118486e-03 +1.910999999999999943e+01 5.439269110622846001e-03 +1.912000000000000099e+01 3.989673938647510416e-03 +1.912999999999999901e+01 2.348963179005756317e-03 +1.914000000000000057e+01 5.177131352093348798e-04 +1.915000000000000213e+01 -1.490092370859442050e-03 +1.916000000000000014e+01 -3.646515873443041764e-03 +1.917000000000000171e+01 -5.909644497275432125e-03 +1.917999999999999972e+01 -8.224142638417293247e-03 +1.919000000000000128e+01 -1.052241395285687803e-02 +1.919999999999999929e+01 -1.272638747073610854e-02 +1.921000000000000085e+01 -1.474991822594359445e-02 +1.921999999999999886e+01 -1.650176481558707914e-02 +1.923000000000000043e+01 -1.788907599748136221e-02 +1.924000000000000199e+01 -1.882128733571200238e-02 +1.925000000000000000e+01 -1.921429879620868350e-02 +1.926000000000000156e+01 -1.899477699689568894e-02 +1.926999999999999957e+01 -1.810440347143224202e-02 +1.928000000000000114e+01 -1.650387464599765985e-02 +1.928999999999999915e+01 -1.417645185430489729e-02 +1.930000000000000071e+01 -1.113086187233227817e-02 +1.930999999999999872e+01 -7.403360927909766707e-03 +1.932000000000000028e+01 -3.058798179655554048e-03 +1.933000000000000185e+01 1.809452076942918855e-03 +1.933999999999999986e+01 7.080777680802178425e-03 +1.935000000000000142e+01 1.260987328530951794e-02 +1.935999999999999943e+01 1.823052444440426481e-02 +1.937000000000000099e+01 2.376055402719607149e-02 +1.937999999999999901e+01 2.900779451646515530e-02 +1.939000000000000057e+01 3.377689311925374804e-02 +1.940000000000000213e+01 3.787670578742526745e-02 +1.941000000000000014e+01 4.112799412610197020e-02 +1.942000000000000171e+01 4.337110836253250251e-02 +1.942999999999999972e+01 4.447332219626361910e-02 +1.944000000000000128e+01 4.433548299392591624e-02 +1.944999999999999929e+01 4.289765426217157646e-02 +1.946000000000000085e+01 4.014345668758795976e-02 +1.946999999999999886e+01 3.610285852147786939e-02 +1.948000000000000043e+01 3.085322416258712286e-02 +1.949000000000000199e+01 2.451849916279548458e-02 +1.950000000000000000e+01 1.726648761461148721e-02 +1.951000000000000156e+01 9.304260527043237139e-03 +1.951999999999999957e+01 8.718175605100255375e-04 +1.953000000000000114e+01 -7.765794590360570668e-03 +1.953999999999999915e+01 -1.632762973407391599e-02 +1.955000000000000071e+01 -2.452691453588769915e-02 +1.955999999999999872e+01 -3.208165465491029378e-02 +1.957000000000000028e+01 -3.872535012037424396e-02 +1.958000000000000185e+01 -4.421738024128765016e-02 +1.958999999999999986e+01 -4.835262261394274869e-02 +1.960000000000000142e+01 -5.096989465825319671e-02 +1.960999999999999943e+01 -5.195884880267676031e-02 +1.962000000000000099e+01 -5.126501226306859338e-02 +1.962999999999999901e+01 -4.889273679896189578e-02 +1.964000000000000057e+01 -4.490590963423148063e-02 +1.965000000000000213e+01 -3.942637008038877428e-02 +1.966000000000000014e+01 -3.263007309448161253e-02 +1.967000000000000171e+01 -2.474113664884145317e-02 +1.967999999999999972e+01 -1.602400002172816099e-02 +1.969000000000000128e+01 -6.774000809728096713e-03 +1.969999999999999929e+01 2.693254075812801743e-03 +1.971000000000000085e+01 1.205329700990285906e-02 +1.971999999999999886e+01 2.098452889696322474e-02 +1.973000000000000043e+01 2.917979762458242088e-02 +1.974000000000000199e+01 3.635736238862802283e-02 +1.975000000000000000e+01 4.227080875949804778e-02 +1.976000000000000156e+01 4.671752630655426342e-02 +1.976999999999999957e+01 4.954542404680387091e-02 +1.978000000000000114e+01 5.065763595575598771e-02 +1.978999999999999915e+01 5.001505569837162712e-02 +1.980000000000000071e+01 4.763663261217952055e-02 +1.980999999999999872e+01 4.359745558298187829e-02 +1.982000000000000028e+01 3.802474355113658055e-02 +1.983000000000000185e+01 3.109194690491836124e-02 +1.983999999999999986e+01 2.301123925089580691e-02 +1.985000000000000142e+01 1.402474082691579881e-02 +1.985999999999999943e+01 4.394860636800368078e-03 +1.987000000000000099e+01 -5.605827490711450499e-03 +1.987999999999999901e+01 -1.570475017261525538e-02 +1.989000000000000057e+01 -2.563912538739281446e-02 +1.990000000000000213e+01 -3.516499019930960368e-02 +1.991000000000000014e+01 -4.406511948212138430e-02 +1.992000000000000171e+01 -5.215554673956752235e-02 +1.992999999999999972e+01 -5.929046603567155599e-02 +1.994000000000000128e+01 -6.536536968061974762e-02 +1.994999999999999929e+01 -7.031835611700278099e-02 +1.996000000000000085e+01 -7.412962277786659671e-02 +1.996999999999999886e+01 -7.681923598492589045e-02 +1.998000000000000043e+01 -7.844334090716598151e-02 +1.999000000000000199e+01 -7.908903627699155614e-02 +2.000000000000000000e+01 -7.886818854018284863e-02 +2.001000000000000156e+01 -7.791049657285541163e-02 +2.001999999999999957e+01 -7.635613987232048316e-02 +2.003000000000000114e+01 -7.434834974592352541e-02 +2.003999999999999915e+01 -7.202623469887642349e-02 +2.005000000000000071e+01 -6.951816882308065049e-02 +2.005999999999999872e+01 -6.693601696785368704e-02 +2.007000000000000028e+01 -6.437042478212325058e-02 +2.008000000000000185e+01 -6.188734770137294811e-02 +2.008999999999999986e+01 -5.952593322886621380e-02 +2.010000000000000142e+01 -5.729780819380041884e-02 +2.010999999999999943e+01 -5.518775984160407405e-02 +2.012000000000000099e+01 -5.315573930387625101e-02 +2.012999999999999901e+01 -5.114006067257916704e-02 +2.014000000000000057e+01 -4.906162071980862266e-02 +2.015000000000000213e+01 -4.682892502702319659e-02 +2.016000000000000014e+01 -4.434367723630145558e-02 +2.017000000000000171e+01 -4.150667015266785304e-02 +2.017999999999999972e+01 -3.822371085919377270e-02 +2.019000000000000128e+01 -3.441131672288848947e-02 +2.019999999999999929e+01 -3.000193458293865661e-02 +2.021000000000000085e+01 -2.494846053047244244e-02 +2.021999999999999886e+01 -1.922787117207873028e-02 +2.023000000000000043e+01 -1.284381750234770032e-02 +2.024000000000000199e+01 -5.828077681106685892e-03 +2.025000000000000000e+01 1.759186811882063137e-03 +2.026000000000000156e+01 9.830377956583803006e-03 +2.026999999999999957e+01 1.827256889439020024e-02 +2.028000000000000114e+01 2.695068492747029754e-02 +2.028999999999999915e+01 3.571162894212361050e-02 +2.030000000000000071e+01 4.438918692469676769e-02 +2.030999999999999872e+01 5.280952073924377599e-02 +2.032000000000000028e+01 6.079703467059037469e-02 +2.033000000000000185e+01 6.818038997271735902e-02 +2.033999999999999986e+01 7.479843805314524696e-02 +2.035000000000000142e+01 8.050584791292472731e-02 +2.035999999999999943e+01 8.517821669511303762e-02 +2.037000000000000099e+01 8.871647304491236952e-02 +2.037999999999999901e+01 9.105041057800672410e-02 +2.039000000000000057e+01 9.214122200632185455e-02 +2.040000000000000213e+01 9.198294212616309196e-02 +2.041000000000000014e+01 9.060274854823456570e-02 +2.042000000000000171e+01 8.806011127379922976e-02 +2.042999999999999972e+01 8.444482449175105820e-02 +2.044000000000000128e+01 7.987399479120818602e-02 +2.044999999999999929e+01 7.448809791574155514e-02 +2.046000000000000085e+01 6.844624988967626389e-02 +2.046999999999999886e+01 6.192086663107584932e-02 +2.048000000000000043e+01 5.509190801834713130e-02 +2.049000000000000199e+01 4.814091700520376632e-02 +2.050000000000000000e+01 4.124507123387349122e-02 +2.051000000000000156e+01 3.457146340186954825e-02 +2.051999999999999957e+01 2.827181739738607660e-02 +2.053000000000000114e+01 2.247783022787398430e-02 +2.053999999999999915e+01 1.729730560550812868e-02 +2.055000000000000071e+01 1.281121457540529245e-02 +2.055999999999999872e+01 9.071782879415939832e-03 +2.057000000000000028e+01 6.101665157082554469e-03 +2.058000000000000185e+01 3.894224085102047320e-03 +2.058999999999999986e+01 2.414889756428146173e-03 +2.060000000000000142e+01 1.603532670802154019e-03 +2.060999999999999943e+01 1.377744318277863891e-03 +2.062000000000000099e+01 1.636884085557967087e-03 +2.062999999999999901e+01 2.266721565359358474e-03 +2.064000000000000057e+01 3.144480565458916948e-03 +2.065000000000000213e+01 4.144076202503489681e-03 +2.066000000000000014e+01 5.141330124233210036e-03 +2.067000000000000171e+01 6.018951484420461892e-03 +2.067999999999999972e+01 6.671082778354735753e-03 +2.069000000000000128e+01 7.007229633256228073e-03 +2.069999999999999929e+01 6.955421364110236579e-03 +2.071000000000000085e+01 6.464483428064286309e-03 +2.071999999999999886e+01 5.505342407703758649e-03 +2.073000000000000043e+01 4.071327140536085826e-03 +2.074000000000000199e+01 2.177474220624414994e-03 +2.075000000000000000e+01 -1.411096427563507416e-04 +2.076000000000000156e+01 -2.831734002620598430e-03 +2.076999999999999957e+01 -5.827327708607280693e-03 +2.078000000000000114e+01 -9.050194843828629487e-03 +2.078999999999999915e+01 -1.241613563157832091e-02 +2.080000000000000071e+01 -1.583872887292333415e-02 +2.080999999999999872e+01 -1.923356643218477463e-02 +2.082000000000000028e+01 -2.252223406579380652e-02 +2.083000000000000185e+01 -2.563584639662469175e-02 +2.083999999999999986e+01 -2.851796651708388142e-02 +2.085000000000000142e+01 -3.112677156572959958e-02 +2.085999999999999943e+01 -3.343636326881906790e-02 +2.087000000000000099e+01 -3.543716513303218907e-02 +2.087999999999999901e+01 -3.713539371855447552e-02 +2.089000000000000057e+01 -3.855163804023142848e-02 +2.090000000000000213e+01 -3.971862639660110605e-02 +2.091000000000000014e+01 -4.067830160672895184e-02 +2.092000000000000171e+01 -4.147836168201507467e-02 +2.092999999999999972e+01 -4.216845155965737169e-02 +2.094000000000000128e+01 -4.279621119857483086e-02 +2.094999999999999929e+01 -4.340339502398168903e-02 +2.096000000000000085e+01 -4.402227681159558842e-02 +2.096999999999999886e+01 -4.467254254062157093e-02 +2.098000000000000043e+01 -4.535885194792224628e-02 +2.099000000000000199e+01 -4.606921841872821388e-02 +2.100000000000000000e+01 -4.677431784976573276e-02 +2.101000000000000156e+01 -4.742779201855788773e-02 +2.101999999999999957e+01 -4.796756290629033970e-02 +2.103000000000000114e+01 -4.831812368848160955e-02 +2.103999999999999915e+01 -4.839372217423384970e-02 +2.105000000000000071e+01 -4.810230577809813252e-02 +2.105999999999999872e+01 -4.735005595789319732e-02 +2.107000000000000028e+01 -4.604630651645107847e-02 +2.108000000000000185e+01 -4.410861597097260473e-02 +2.108999999999999986e+01 -4.146775063579843934e-02 +2.110000000000000142e+01 -3.807233294283239589e-02 +2.110999999999999943e+01 -3.389291909750681564e-02 +2.112000000000000099e+01 -2.892529114023724077e-02 +2.112999999999999901e+01 -2.319278000924712702e-02 +2.114000000000000057e+01 -1.674747692478961367e-02 +2.115000000000000213e+01 -9.670238531827737502e-03 +2.116000000000000014e+01 -2.069444575384151060e-03 +2.117000000000000171e+01 5.921476998530938660e-03 +2.117999999999999972e+01 1.414768631332105446e-02 +2.119000000000000128e+01 2.243760411853740200e-02 +2.119999999999999929e+01 3.060844661944864611e-02 +2.121000000000000085e+01 3.847240690164151211e-02 +2.121999999999999886e+01 4.584323485937524117e-02 +2.123000000000000043e+01 5.254294594080138187e-02 +2.124000000000000199e+01 5.840837931870845878e-02 +2.125000000000000000e+01 6.329732880889712976e-02 +2.126000000000000156e+01 6.709398494454178741e-02 +2.126999999999999957e+01 6.971345345774954128e-02 +2.128000000000000114e+01 7.110515285957577647e-02 +2.128999999999999915e+01 7.125494019807317170e-02 +2.130000000000000071e+01 7.018586734783706371e-02 +2.130999999999999872e+01 6.795752796453222166e-02 +2.132000000000000028e+01 6.466401493657904231e-02 +2.133000000000000185e+01 6.043056710921634878e-02 +2.133999999999999986e+01 5.540903960504051790e-02 +2.135000000000000142e+01 4.977238173954356276e-02 +2.135999999999999943e+01 4.370834812081641346e-02 +2.137000000000000099e+01 3.741270019232831312e-02 +2.137999999999999901e+01 3.108217584481645646e-02 +2.139000000000000057e+01 2.490751292260372923e-02 +2.140000000000000213e+01 1.906680816988331334e-02 +2.141000000000000014e+01 1.371947665805828102e-02 +2.142000000000000171e+01 9.001048811455825485e-03 +2.142999999999999972e+01 5.019004122196261443e-03 +2.144000000000000128e+01 1.849794279774823191e-03 +2.144999999999999929e+01 -4.628441339789520804e-04 +2.146000000000000085e+01 -1.908243624667794926e-03 +2.146999999999999886e+01 -2.507840338696520812e-03 +2.148000000000000043e+01 -2.312959431206696500e-03 +2.149000000000000199e+01 -1.401474011484326720e-03 +2.150000000000000000e+01 1.264931781957192582e-04 +2.151000000000000156e+01 2.153617940746575289e-03 +2.151999999999999957e+01 4.550936758903591228e-03 +2.153000000000000114e+01 7.183669422396917088e-03 +2.153999999999999915e+01 9.917042705820404772e-03 +2.155000000000000071e+01 1.262186138786207390e-02 +2.155999999999999872e+01 1.517958993663909989e-02 +2.157000000000000028e+01 1.748673560226556706e-02 +2.158000000000000185e+01 1.945836007338341139e-02 +2.158999999999999986e+01 2.103059048956373508e-02 +2.160000000000000142e+01 2.216204936520797461e-02 +2.160999999999999943e+01 2.283417456889664382e-02 +2.162000000000000099e+01 2.305045250554120517e-02 +2.162999999999999901e+01 2.283463766397752018e-02 +2.164000000000000057e+01 2.222807743330985214e-02 +2.165000000000000213e+01 2.128630049092114854e-02 +2.166000000000000014e+01 2.007505837271105625e-02 +2.167000000000000171e+01 1.866603169186772243e-02 +2.167999999999999972e+01 1.713242397002185877e-02 +2.169000000000000128e+01 1.554466676776300980e-02 +2.169999999999999929e+01 1.396644984082312003e-02 +2.171000000000000085e+01 1.245126999351775510e-02 +2.171999999999999886e+01 1.103966320988896375e-02 +2.173000000000000043e+01 9.757247989390678902e-03 +2.174000000000000199e+01 8.613665416601301583e-03 +2.175000000000000000e+01 7.602455429975999400e-03 +2.176000000000000156e+01 6.701861259312904412e-03 +2.176999999999999957e+01 5.876507365390153462e-03 +2.178000000000000114e+01 5.079852674351114164e-03 +2.178999999999999915e+01 4.257282531107157639e-03 +2.180000000000000071e+01 3.349671421338708526e-03 +2.180999999999999872e+01 2.297225610327828602e-03 +2.182000000000000028e+01 1.043401487904603011e-03 +2.183000000000000185e+01 -4.613077987931293996e-04 +2.183999999999999986e+01 -2.255917778731928412e-03 +2.185000000000000142e+01 -4.366013547285120186e-03 +2.185999999999999943e+01 -6.801483490096618331e-03 +2.187000000000000099e+01 -9.555049435274968334e-03 +2.187999999999999901e+01 -1.260167693515427609e-02 +2.189000000000000057e+01 -1.589890532437952808e-02 +2.190000000000000213e+01 -1.938809113724735550e-02 +2.191000000000000014e+01 -2.299651264409393117e-02 +2.192000000000000171e+01 -2.664023992398106139e-02 +2.192999999999999972e+01 -3.022763615147900859e-02 +2.194000000000000128e+01 -3.366332354124714626e-02 +2.194999999999999929e+01 -3.685242325519245271e-02 +2.196000000000000085e+01 -3.970486373279534520e-02 +2.196999999999999886e+01 -4.213954710578095980e-02 +2.198000000000000043e+01 -4.408816886683600278e-02 +2.199000000000000199e+01 -4.549850153937417402e-02 +2.200000000000000000e+01 -4.633697801067766797e-02 +2.201000000000000156e+01 -4.659044325513354151e-02 +2.201999999999999957e+01 -4.626698279609301606e-02 +2.203000000000000114e+01 -4.539578051673483217e-02 +2.203999999999999915e+01 -4.402600518091313864e-02 +2.205000000000000071e+01 -4.222477198282616195e-02 +2.205999999999999872e+01 -4.007427031140119167e-02 +2.207000000000000028e+01 -3.766818948521308968e-02 +2.208000000000000185e+01 -3.510760848697477149e-02 +2.208999999999999986e+01 -3.249654200334434195e-02 +2.210000000000000142e+01 -2.993735204665793487e-02 +2.210999999999999943e+01 -2.752624124368369118e-02 +2.212000000000000099e+01 -2.534904016636629551e-02 +2.212999999999999901e+01 -2.347748701232468815e-02 +2.214000000000000057e+01 -2.196617419392414908e-02 +2.215000000000000213e+01 -2.085030412073836034e-02 +2.216000000000000014e+01 -2.014435724411673886e-02 +2.217000000000000171e+01 -1.984173120579666230e-02 +2.217999999999999972e+01 -1.991536288055975601e-02 +2.219000000000000128e+01 -2.031929755617133473e-02 +2.219999999999999929e+01 -2.099112381120229326e-02 +2.221000000000000085e+01 -2.185515110234865013e-02 +2.221999999999999886e+01 -2.282617172219604182e-02 +2.223000000000000043e+01 -2.381362139166287931e-02 +2.224000000000000199e+01 -2.472593466498961348e-02 +2.225000000000000000e+01 -2.547488343685203396e-02 +2.226000000000000156e+01 -2.597968952268288334e-02 +2.226999999999999957e+01 -2.617071537191655375e-02 +2.228000000000000114e+01 -2.599255977704659909e-02 +2.228999999999999915e+01 -2.540641677357259945e-02 +2.230000000000000071e+01 -2.439159416583859888e-02 +2.230999999999999872e+01 -2.294613128947415107e-02 +2.232000000000000028e+01 -2.108650150791905112e-02 +2.233000000000000185e+01 -1.884643117846320631e-02 +2.233999999999999986e+01 -1.627491103647816725e-02 +2.235000000000000142e+01 -1.343351586833047354e-02 +2.235999999999999943e+01 -1.039318193257177635e-02 +2.237000000000000099e+01 -7.230617138221084698e-03 +2.237999999999999901e+01 -4.024535212153104204e-03 +2.239000000000000057e+01 -8.519111902528061402e-04 +2.240000000000000213e+01 2.215548714171764605e-03 +2.241000000000000014e+01 5.114544192186752138e-03 +2.242000000000000171e+01 7.792769863548237863e-03 +2.242999999999999972e+01 1.021083287922979095e-02 +2.244000000000000128e+01 1.234341363387339921e-02 +2.244999999999999929e+01 1.417962621340019061e-02 +2.246000000000000085e+01 1.572257921887190366e-02 +2.246999999999999886e+01 1.698818117213108866e-02 +2.248000000000000043e+01 1.800327547575577419e-02 +2.249000000000000199e+01 1.880322567819510057e-02 +2.250000000000000000e+01 1.942910066440831779e-02 +2.251000000000000156e+01 1.992462980923541405e-02 +2.251999999999999957e+01 2.033310901031925091e-02 +2.253000000000000114e+01 2.069443929423907258e-02 +2.253999999999999915e+01 2.104247034816394968e-02 +2.255000000000000071e+01 2.140280240654580599e-02 +2.255999999999999872e+01 2.179117247945978539e-02 +2.257000000000000028e+01 2.221251647380664135e-02 +2.258000000000000185e+01 2.266075924493186552e-02 +2.258999999999999986e+01 2.311934221844660561e-02 +2.260000000000000142e+01 2.356245529839285160e-02 +2.260999999999999943e+01 2.395689871827653278e-02 +2.262000000000000099e+01 2.426446359067385705e-02 +2.262999999999999901e+01 2.444468923808481089e-02 +2.264000000000000057e+01 2.445783267548588477e-02 +2.265000000000000213e+01 2.426787216040566381e-02 +2.266000000000000014e+01 2.384536331948485660e-02 +2.267000000000000171e+01 2.316997323801144731e-02 +2.267999999999999972e+01 2.223253472834178443e-02 +2.269000000000000128e+01 2.103648888980707080e-02 +2.269999999999999929e+01 1.959861764422147698e-02 +2.271000000000000085e+01 1.794900735348389093e-02 +2.271999999999999886e+01 1.613022773989249148e-02 +2.273000000000000043e+01 1.419575476068016262e-02 +2.274000000000000199e+01 1.220770937304012892e-02 +2.275000000000000000e+01 1.023402385038542882e-02 +2.276000000000000156e+01 8.345181241972315575e-03 +2.276999999999999957e+01 6.610699778659903311e-03 +2.278000000000000114e+01 5.095551003557080225e-03 +2.278999999999999915e+01 3.856707132239367911e-03 +2.280000000000000071e+01 2.940009165281444719e-03 +2.280999999999999872e+01 2.377532714084841514e-03 +2.282000000000000028e+01 2.185604069338664430e-03 +2.283000000000000185e+01 2.363585995959793448e-03 +2.283999999999999986e+01 2.893512815391156064e-03 +2.285000000000000142e+01 3.740609659462419776e-03 +2.285999999999999943e+01 4.854683746655215348e-03 +2.287000000000000099e+01 6.172328681850893818e-03 +2.287999999999999901e+01 7.619838659811623179e-03 +2.289000000000000057e+01 9.116690472043921523e-03 +2.290000000000000213e+01 1.057941952104474344e-02 +2.291000000000000014e+01 1.192569339545680555e-02 +2.292000000000000171e+01 1.307837423221813386e-02 +2.292999999999999972e+01 1.396935981141467914e-02 +2.294000000000000128e+01 1.454300322515403483e-02 +2.294999999999999929e+01 1.475893155790399501e-02 +2.296000000000000085e+01 1.459411425677080779e-02 +2.296999999999999886e+01 1.404407017609707146e-02 +2.298000000000000043e+01 1.312314663142967290e-02 +2.299000000000000199e+01 1.186385184257293841e-02 +2.300000000000000000e+01 1.031527132868909763e-02 +2.301000000000000156e+01 8.540646519686346735e-03 +2.301999999999999957e+01 6.614237522623622571e-03 +2.303000000000000114e+01 4.617629299884136451e-03 +2.303999999999999915e+01 2.635669487529339588e-03 +2.305000000000000071e+01 7.522451671498883502e-04 +2.305999999999999872e+01 -9.538859066265140086e-04 +2.307000000000000028e+01 -2.412997250872394965e-03 +2.308000000000000185e+01 -3.567830662858520376e-03 +2.308999999999999986e+01 -4.376394798441031637e-03 +2.310000000000000142e+01 -4.813985455746256498e-03 +2.310999999999999943e+01 -4.874328527239190495e-03 +2.312000000000000099e+01 -4.569792412785166763e-03 +2.312999999999999901e+01 -3.930665061268566463e-03 +2.314000000000000057e+01 -3.003539146175277126e-03 +2.315000000000000213e+01 -1.848894613596374897e-03 +2.316000000000000014e+01 -5.380085553428526259e-04 +2.317000000000000171e+01 8.506440746928450175e-04 +2.317999999999999972e+01 2.235310697855832918e-03 +2.319000000000000128e+01 3.534999536073147285e-03 +2.319999999999999929e+01 4.673429706737778321e-03 +2.321000000000000085e+01 5.582693624713303340e-03 +2.321999999999999886e+01 6.206449923731332911e-03 +2.323000000000000043e+01 6.502492053966833080e-03 +2.324000000000000199e+01 6.444572481205146017e-03 +2.325000000000000000e+01 6.023403051635423458e-03 +2.326000000000000156e+01 5.246796342362146197e-03 +2.326999999999999957e+01 4.138958266608578837e-03 +2.328000000000000114e+01 2.738986381468762506e-03 +2.328999999999999915e+01 1.098668889830913724e-03 +2.330000000000000071e+01 -7.202859019346376322e-04 +2.330999999999999872e+01 -2.649432709850650658e-03 +2.332000000000000028e+01 -4.617009752608767018e-03 +2.333000000000000185e+01 -6.551412871729940350e-03 +2.333999999999999986e+01 -8.384541178395816044e-03 +2.335000000000000142e+01 -1.005484354592703355e-02 +2.335999999999999943e+01 -1.150991573541678900e-02 +2.337000000000000099e+01 -1.270852616419033444e-02 +2.337999999999999901e+01 -1.362198260888185589e-02 +2.339000000000000057e+01 -1.423479047186851192e-02 +2.340000000000000213e+01 -1.454459343067064821e-02 +2.341000000000000014e+01 -1.456142706368286632e-02 +2.342000000000000171e+01 -1.430635318961018081e-02 +2.342999999999999972e+01 -1.380957514040107720e-02 +2.344000000000000128e+01 -1.310816027120730379e-02 +2.344999999999999929e+01 -1.224351434502875778e-02 +2.346000000000000085e+01 -1.125876212379474210e-02 +2.346999999999999886e+01 -1.019618916331922233e-02 +2.348000000000000043e+01 -9.094891578239576793e-03 +2.349000000000000199e+01 -7.988764050213332385e-03 +2.350000000000000000e+01 -6.904932696311070345e-03 +2.351000000000000156e+01 -5.862710085636995902e-03 +2.351999999999999957e+01 -4.873116485614763932e-03 +2.353000000000000114e+01 -3.938976326283610656e-03 +2.353999999999999915e+01 -3.055563963017426075e-03 +2.355000000000000071e+01 -2.211740127189695208e-03 +2.355999999999999872e+01 -1.391491856188925439e-03 +2.357000000000000028e+01 -5.757658023155310702e-04 +2.358000000000000185e+01 2.555311044807852738e-04 +2.358999999999999986e+01 1.121497782389937938e-03 +2.360000000000000142e+01 2.038305989740100445e-03 +2.360999999999999943e+01 3.017494121176170566e-03 +2.362000000000000099e+01 4.064598108745259321e-03 +2.362999999999999901e+01 5.178207603561526054e-03 +2.364000000000000057e+01 6.349508379798804621e-03 +2.365000000000000213e+01 7.562341224678921503e-03 +2.366000000000000014e+01 8.793775306434388483e-03 +2.367000000000000171e+01 1.001516207480317167e-02 +2.367999999999999972e+01 1.119360603683364729e-02 +2.369000000000000128e+01 1.229376301063760460e-02 +2.369999999999999929e+01 1.327985619091920887e-02 +2.371000000000000085e+01 1.411778673061800382e-02 +2.371999999999999886e+01 1.477720932431687839e-02 +2.373000000000000043e+01 1.523344480307200523e-02 +2.374000000000000199e+01 1.546911089479803547e-02 +2.375000000000000000e+01 1.547536850130768610e-02 +2.376000000000000156e+01 1.525270311674325856e-02 +2.376999999999999957e+01 1.481118803706332233e-02 +2.378000000000000114e+01 1.417020619091734560e-02 +2.378999999999999915e+01 1.335763898782858609e-02 +2.380000000000000071e+01 1.240856168724947806e-02 +2.380999999999999872e+01 1.136351363456255051e-02 +2.382000000000000028e+01 1.026643661988838746e-02 +2.383000000000000185e+01 9.162394161343767260e-03 +2.383999999999999986e+01 8.095197581190854280e-03 +2.385000000000000142e+01 7.105070596464679519e-03 +2.385999999999999943e+01 6.226482469655328714e-03 +2.387000000000000099e+01 5.486270680099189327e-03 +2.387999999999999901e+01 4.902158128854555708e-03 +2.389000000000000057e+01 4.481748016542188434e-03 +2.390000000000000213e+01 4.222053007762560477e-03 +2.391000000000000014e+01 4.109585649773276651e-03 +2.392000000000000171e+01 4.121005949625632103e-03 +2.392999999999999972e+01 4.224291306117642329e-03 +2.394000000000000128e+01 4.380365382477672577e-03 +2.394999999999999929e+01 4.545097602873666466e-03 +2.396000000000000085e+01 4.671565147895272337e-03 +2.396999999999999886e+01 4.712455697222792464e-03 +2.398000000000000043e+01 4.622482446851836589e-03 +2.399000000000000199e+01 4.360683438278722089e-03 +2.400000000000000000e+01 3.892484887450000514e-03 +2.401000000000000156e+01 3.191422494039887307e-03 +2.401999999999999957e+01 2.240434773858540965e-03 +2.403000000000000114e+01 1.032667093700078429e-03 +2.403999999999999915e+01 -4.282471469995349214e-04 +2.405000000000000071e+01 -2.128432461049360562e-03 +2.406000000000000227e+01 -4.044519501560483142e-03 +2.407000000000000028e+01 -6.144843435592063814e-03 +2.408000000000000185e+01 -8.391016390064421140e-03 +2.408999999999999986e+01 -1.073977864727952009e-02 +2.410000000000000142e+01 -1.314501974924011177e-02 +2.410999999999999943e+01 -1.555985358806490429e-02 +2.412000000000000099e+01 -1.793863124035757067e-02 +2.412999999999999901e+01 -2.023878168052420379e-02 +2.414000000000000057e+01 -2.242238312867017927e-02 +2.415000000000000213e+01 -2.445738584474348859e-02 +2.416000000000000014e+01 -2.631842955656258851e-02 +2.417000000000000171e+01 -2.798722405158461310e-02 +2.417999999999999972e+01 -2.945248825712929938e-02 +2.419000000000000128e+01 -3.070946979915609165e-02 +2.419999999999999929e+01 -3.175909200452693704e-02 +2.421000000000000085e+01 -3.260679714829961551e-02 +2.421999999999999886e+01 -3.326117219244945078e-02 +2.423000000000000043e+01 -3.373245533007034752e-02 +2.424000000000000199e+01 -3.403102767269673007e-02 +2.425000000000000000e+01 -3.416599409082134164e-02 +2.426000000000000156e+01 -3.414395060240797697e-02 +2.426999999999999957e+01 -3.396802323110926364e-02 +2.428000000000000114e+01 -3.363724569340564852e-02 +2.428999999999999915e+01 -3.314632168107701365e-02 +2.430000000000000071e+01 -3.248579317080518142e-02 +2.431000000000000227e+01 -3.164261055610541329e-02 +2.432000000000000028e+01 -3.060107496718260378e-02 +2.433000000000000185e+01 -2.934409941148856393e-02 +2.433999999999999986e+01 -2.785471471683922257e-02 +2.435000000000000142e+01 -2.611772989198584902e-02 +2.435999999999999943e+01 -2.412144538752015663e-02 +2.437000000000000099e+01 -2.185931248878617700e-02 +2.437999999999999901e+01 -1.933143301066538033e-02 +2.439000000000000057e+01 -1.654580054352989063e-02 +2.440000000000000213e+01 -1.351919732423363836e-02 +2.441000000000000014e+01 -1.027767865346041788e-02 +2.442000000000000171e+01 -6.856598647592422602e-03 +2.442999999999999972e+01 -3.300155772568951450e-03 +2.444000000000000128e+01 3.395373202977270874e-04 +2.444999999999999929e+01 4.003829103604663459e-03 +2.446000000000000085e+01 7.629294525851390216e-03 +2.446999999999999886e+01 1.114981359191550420e-02 +2.448000000000000043e+01 1.449886867291916813e-02 +2.449000000000000199e+01 1.761195334770851786e-02 +2.450000000000000000e+01 2.042897854336172409e-02 +2.451000000000000156e+01 2.289656073256286090e-02 +2.451999999999999957e+01 2.497008198925768779e-02 +2.453000000000000114e+01 2.661542249653966671e-02 +2.453999999999999915e+01 2.781028202889863563e-02 +2.455000000000000071e+01 2.854502710555714001e-02 +2.456000000000000227e+01 2.882302382555855524e-02 +2.457000000000000028e+01 2.866044158294524941e-02 +2.458000000000000185e+01 2.808553857137056214e-02 +2.458999999999999986e+01 2.713746486436330319e-02 +2.460000000000000142e+01 2.586464160453286198e-02 +2.460999999999999943e+01 2.432279429723582104e-02 +2.462000000000000099e+01 2.257273341818869655e-02 +2.462999999999999901e+01 2.067798579782833060e-02 +2.464000000000000057e+01 1.870238510231815587e-02 +2.465000000000000213e+01 1.670772905784593393e-02 +2.466000000000000014e+01 1.475160502604083365e-02 +2.467000000000000171e+01 1.288547458359014762e-02 +2.467999999999999972e+01 1.115309259163873093e-02 +2.469000000000000128e+01 9.589317771771627488e-03 +2.469999999999999929e+01 8.219351100328956689e-03 +2.471000000000000085e+01 7.058416546938372713e-03 +2.471999999999999886e+01 6.111876995740281489e-03 +2.473000000000000043e+01 5.375757736898541424e-03 +2.474000000000000199e+01 4.837631734755623754e-03 +2.475000000000000000e+01 4.477805842406871323e-03 +2.476000000000000156e+01 4.270735912666281421e-03 +2.476999999999999957e+01 4.186591789732254341e-03 +2.478000000000000114e+01 4.192890640476317279e-03 +2.478999999999999915e+01 4.256118931121094864e-03 +2.480000000000000071e+01 4.343269264352705820e-03 +2.481000000000000227e+01 4.423227737999844457e-03 +2.482000000000000028e+01 4.467959765467232648e-03 +2.483000000000000185e+01 4.453456574616082748e-03 +2.483999999999999986e+01 4.360419962343833021e-03 +2.485000000000000142e+01 4.174678390555787606e-03 +2.485999999999999943e+01 3.887342263732742470e-03 +2.487000000000000099e+01 3.494719411928017168e-03 +2.487999999999999901e+01 2.998022730881873613e-03 +2.489000000000000057e+01 2.402910084659189670e-03 +2.490000000000000213e+01 1.718901630984753922e-03 +2.491000000000000014e+01 9.587215651258593554e-04 +2.492000000000000171e+01 1.376099805852859742e-04 +2.492999999999999972e+01 -7.273536073677620145e-04 +2.494000000000000128e+01 -1.617880088551059640e-03 +2.494999999999999929e+01 -2.515027331425402288e-03 +2.496000000000000085e+01 -3.399666429383094157e-03 +2.496999999999999886e+01 -4.252850496451172566e-03 +2.498000000000000043e+01 -5.056088534455626705e-03 +2.499000000000000199e+01 -5.791535554045451444e-03 +2.500000000000000000e+01 -6.442117215922481960e-03 +2.501000000000000156e+01 -6.991612300946668107e-03 +2.501999999999999957e+01 -7.424719005287012778e-03 +2.503000000000000114e+01 -7.727131247214657529e-03 +2.503999999999999915e+01 -7.885648899880035381e-03 +2.505000000000000071e+01 -7.888341335839483062e-03 +2.506000000000000227e+01 -7.724777245988347259e-03 +2.507000000000000028e+01 -7.386325871663422006e-03 +2.508000000000000185e+01 -6.866526152933133571e-03 +2.508999999999999986e+01 -6.161511496518729501e-03 +2.510000000000000142e+01 -5.270469565814190488e-03 +2.510999999999999943e+01 -4.196109326324234945e-03 +2.512000000000000099e+01 -2.945102107108292944e-03 +2.512999999999999901e+01 -1.528460118879787456e-03 +2.514000000000000057e+01 3.818497710276868288e-05 +2.515000000000000213e+01 1.734439066681937695e-03 +2.516000000000000014e+01 3.535169348663267860e-03 +2.517000000000000171e+01 5.410719206692694676e-03 +2.517999999999999972e+01 7.327329553179104567e-03 +2.519000000000000128e+01 9.247771413827050868e-03 +2.519999999999999929e+01 1.113218289400984100e-02 +2.521000000000000085e+01 1.293909168540063187e-02 +2.521999999999999886e+01 1.462659264556484366e-02 +2.523000000000000043e+01 1.615363942297253635e-02 +2.524000000000000199e+01 1.748140026677610925e-02 +2.525000000000000000e+01 1.857462162931031863e-02 +2.526000000000000156e+01 1.940293939313443225e-02 +2.526999999999999957e+01 1.994207683652676061e-02 +2.528000000000000114e+01 2.017487092677454005e-02 +2.528999999999999915e+01 2.009207415485045681e-02 +2.530000000000000071e+01 1.969288767685980698e-02 +2.531000000000000227e+01 1.898519261789757481e-02 +2.532000000000000028e+01 1.798545948847617149e-02 +2.533000000000000185e+01 1.671833011023367635e-02 +2.533999999999999986e+01 1.521588151197120903e-02 +2.535000000000000142e+01 1.351659616499069523e-02 +2.535999999999999943e+01 1.166407690336255902e-02 +2.537000000000000099e+01 9.705557190291298417e-03 +2.537999999999999901e+01 7.690267398716908211e-03 +2.539000000000000057e+01 5.667724945646991121e-03 +2.540000000000000213e+01 3.686020073805446919e-03 +2.541000000000000014e+01 1.790169598596036979e-03 +2.542000000000000171e+01 2.060799889073028712e-05 +2.542999999999999972e+01 -1.588121027961163180e-03 +2.544000000000000128e+01 -3.008418686060307205e-03 +2.544999999999999929e+01 -4.220388805902889826e-03 +2.546000000000000085e+01 -5.212270829062412222e-03 +2.546999999999999886e+01 -5.980534673317357622e-03 +2.548000000000000043e+01 -6.529639556615389473e-03 +2.549000000000000199e+01 -6.871474040705704243e-03 +2.550000000000000000e+01 -7.024508718233535634e-03 +2.551000000000000156e+01 -7.012705428936158447e-03 +2.551999999999999957e+01 -6.864237064553468937e-03 +2.553000000000000114e+01 -6.610079448775145125e-03 +2.553999999999999915e+01 -6.282541143800168815e-03 +2.555000000000000071e+01 -5.913798186859739112e-03 +2.556000000000000227e+01 -5.534498711332844732e-03 +2.557000000000000028e+01 -5.172497331850129700e-03 +2.558000000000000185e+01 -4.851771394162067083e-03 +2.558999999999999986e+01 -4.591561160010717429e-03 +2.560000000000000142e+01 -4.405764267661854000e-03 +2.560999999999999943e+01 -4.302602004119439154e-03 +2.562000000000000099e+01 -4.284561705219147934e-03 +2.562999999999999901e+01 -4.348606625658367648e-03 +2.564000000000000057e+01 -4.486632520669282809e-03 +2.565000000000000213e+01 -4.686139517096326451e-03 +2.566000000000000014e+01 -4.931079095534706552e-03 +2.567000000000000171e+01 -5.202829514874465940e-03 +2.567999999999999972e+01 -5.481249015962250289e-03 +2.569000000000000128e+01 -5.745754737383248698e-03 +2.569999999999999929e+01 -5.976376423242145582e-03 +2.571000000000000085e+01 -6.154737532673946153e-03 +2.571999999999999886e+01 -6.264921991801456619e-03 +2.573000000000000043e+01 -6.294192185334434100e-03 +2.574000000000000199e+01 -6.233532419794018085e-03 +2.575000000000000000e+01 -6.078001513395156659e-03 +2.576000000000000156e+01 -5.826887871132672286e-03 +2.576999999999999957e+01 -5.483669892465225897e-03 +2.578000000000000114e+01 -5.055793373515410707e-03 +2.578999999999999915e+01 -4.554285306879401161e-03 +2.580000000000000071e+01 -3.993229827247704415e-03 +2.581000000000000227e+01 -3.389136769066512355e-03 +2.582000000000000028e+01 -2.760236259714183866e-03 +2.583000000000000185e+01 -2.125733934821166099e-03 +2.583999999999999986e+01 -1.505060793717137059e-03 +2.585000000000000142e+01 -9.171495618966674567e-04 +2.585999999999999943e+01 -3.797659169069432820e-04 +2.587000000000000099e+01 9.108165622483220937e-05 +2.587999999999999901e+01 4.816349662831529289e-04 +2.589000000000000057e+01 7.807695393494091607e-04 +2.590000000000000213e+01 9.802616027961216782e-04 +2.591000000000000014e+01 1.074937522153237082e-03 +2.592000000000000171e+01 1.062709743061770540e-03 +2.592999999999999972e+01 9.445077309503793544e-04 +2.594000000000000128e+01 7.241159563644909659e-04 +2.594999999999999929e+01 4.079335430983611769e-04 +2.596000000000000085e+01 4.671744466678857769e-06 +2.596999999999999886e+01 -4.749940319606894791e-04 +2.598000000000000043e+01 -1.018801284796472164e-03 +2.599000000000000199e+01 -1.613291329990310672e-03 +2.600000000000000000e+01 -2.244200572243769745e-03 +2.601000000000000156e+01 -2.896840814868126019e-03 +2.601999999999999957e+01 -3.556459684085423387e-03 +2.603000000000000114e+01 -4.208574681095255364e-03 +2.603999999999999915e+01 -4.839276679607564663e-03 +2.605000000000000071e+01 -5.435500713930255419e-03 +2.606000000000000227e+01 -5.985263544102805561e-03 +2.607000000000000028e+01 -6.477868671939139220e-03 +2.608000000000000185e+01 -6.904080189314097324e-03 +2.608999999999999986e+01 -7.256267082971075595e-03 +2.610000000000000142e+01 -7.528519451335542734e-03 +2.610999999999999943e+01 -7.716737592267109910e-03 +2.612000000000000099e+01 -7.818694203193388495e-03 +2.612999999999999901e+01 -7.834069117002981017e-03 +2.614000000000000057e+01 -7.764455202749005053e-03 +2.615000000000000213e+01 -7.613333407953194569e-03 +2.616000000000000014e+01 -7.386014511495503712e-03 +2.617000000000000171e+01 -7.089545074051201851e-03 +2.617999999999999972e+01 -6.732575368044934130e-03 +2.619000000000000128e+01 -6.325187761304875388e-03 +2.619999999999999929e+01 -5.878685104679382163e-03 +2.621000000000000085e+01 -5.405340088025188498e-03 +2.621999999999999886e+01 -4.918108206180789484e-03 +2.623000000000000043e+01 -4.430308819326898850e-03 +2.624000000000000199e+01 -3.955280684023798794e-03 +2.625000000000000000e+01 -3.506020148654834419e-03 +2.626000000000000156e+01 -3.094811824602953891e-03 +2.626999999999999957e+01 -2.732862844570904063e-03 +2.628000000000000114e+01 -2.429952700354833569e-03 +2.628999999999999915e+01 -2.194111033603958916e-03 +2.630000000000000071e+01 -2.031335582582621032e-03 +2.631000000000000227e+01 -1.945361743205590004e-03 +2.632000000000000028e+01 -1.937493894746766462e-03 +2.633000000000000185e+01 -2.006506811451159219e-03 +2.633999999999999986e+01 -2.148623202784438659e-03 +2.635000000000000142e+01 -2.357570794266086733e-03 +2.635999999999999943e+01 -2.624719494416080743e-03 +2.637000000000000099e+01 -2.939296221245887158e-03 +2.637999999999999901e+01 -3.288672019651607895e-03 +2.639000000000000057e+01 -3.658713323151307432e-03 +2.640000000000000213e+01 -4.034186725246457876e-03 +2.641000000000000014e+01 -4.399204537381696742e-03 +2.642000000000000171e+01 -4.737696812182386023e-03 +2.642999999999999972e+01 -5.033894467195673336e-03 +2.644000000000000128e+01 -5.272807694058417524e-03 +2.644999999999999929e+01 -5.440683990791647488e-03 +2.646000000000000085e+01 -5.525430892874107561e-03 +2.646999999999999886e+01 -5.516989759395796167e-03 +2.648000000000000043e+01 -5.407648728255292150e-03 +2.649000000000000199e+01 -5.192285106337484434e-03 +2.650000000000000000e+01 -4.868529911161354612e-03 +2.651000000000000156e+01 -4.436849926253515382e-03 +2.651999999999999957e+01 -3.900545367864537497e-03 +2.653000000000000114e+01 -3.265663983670797840e-03 +2.653999999999999915e+01 -2.540835018598715418e-03 +2.655000000000000071e+01 -1.737028905303198562e-03 +2.656000000000000227e+01 -8.672506959393977638e-04 +2.657000000000000028e+01 5.382290794659076223e-05 +2.658000000000000185e+01 1.010251588709937341e-03 +2.658999999999999986e+01 1.985272071251796729e-03 +2.660000000000000142e+01 2.961758262355062687e-03 +2.660999999999999943e+01 3.922687408536413255e-03 +2.662000000000000099e+01 4.851598868475889663e-03 +2.662999999999999901e+01 5.733032508331045544e-03 +2.664000000000000057e+01 6.552934466599336268e-03 +2.665000000000000213e+01 7.299019068395600288e-03 +2.666000000000000014e+01 7.961076962961787656e-03 +2.667000000000000171e+01 8.531221078607551314e-03 +2.667999999999999972e+01 9.004063700880783616e-03 +2.669000000000000128e+01 9.376819847716783701e-03 +2.669999999999999929e+01 9.649334103895476286e-03 +2.671000000000000085e+01 9.824030150193282379e-03 +2.671999999999999886e+01 9.905784340808456920e-03 +2.673000000000000043e+01 9.901726805635264680e-03 +2.674000000000000199e+01 9.820975635946291304e-03 +2.675000000000000000e+01 9.674311704883574795e-03 +2.676000000000000156e+01 9.473803525052780158e-03 +2.676999999999999957e+01 9.232393198742349164e-03 +2.678000000000000114e+01 8.963455915069088592e-03 +2.678999999999999915e+01 8.680346535010737344e-03 +2.680000000000000071e+01 8.395947526345193951e-03 +2.681000000000000227e+01 8.122232817224562390e-03 +2.682000000000000028e+01 7.869861991133869986e-03 +2.683000000000000185e+01 7.647818619851822451e-03 +2.683999999999999986e+01 7.463105415090513436e-03 +2.685000000000000142e+01 7.320507280321662986e-03 +2.685999999999999943e+01 7.222431290120010124e-03 +2.687000000000000099e+01 7.168830164299752790e-03 +2.687999999999999901e+01 7.157213008338229356e-03 +2.689000000000000057e+01 7.182744050105161794e-03 +2.690000000000000213e+01 7.238426923907505250e-03 +2.691000000000000014e+01 7.315368856281334077e-03 +2.692000000000000171e+01 7.403116024254335903e-03 +2.692999999999999972e+01 7.490048518342195573e-03 +2.694000000000000128e+01 7.563820877793708992e-03 +2.694999999999999929e+01 7.611832194278992866e-03 +2.696000000000000085e+01 7.621708403682138540e-03 +2.696999999999999886e+01 7.581778684671513883e-03 +2.698000000000000043e+01 7.481527907544384230e-03 +2.699000000000000199e+01 7.312007849327380703e-03 +2.700000000000000000e+01 7.066191395545521128e-03 +2.701000000000000156e+01 6.739256137253859212e-03 +2.701999999999999957e+01 6.328786561189604642e-03 +2.703000000000000114e+01 5.834887306705922351e-03 +2.703999999999999915e+01 5.260203586817471105e-03 +2.705000000000000071e+01 4.609848681761698902e-03 +2.706000000000000227e+01 3.891242240646462878e-03 +2.707000000000000028e+01 3.113866794009986956e-03 +2.708000000000000185e+01 2.288953216951681701e-03 +2.708999999999999986e+01 1.429108731783755885e-03 +2.710000000000000142e+01 5.479032665951651896e-04 +2.710999999999999943e+01 -3.405685141185688125e-04 +2.712000000000000099e+01 -1.222131488068680738e-03 +2.712999999999999901e+01 -2.082962770192359377e-03 +2.714000000000000057e+01 -2.909995874598300322e-03 +2.715000000000000213e+01 -3.691281103327246748e-03 +2.716000000000000014e+01 -4.416289306720627521e-03 +2.717000000000000171e+01 -5.076149096171560585e-03 +2.717999999999999972e+01 -5.663810924818311367e-03 +2.719000000000000128e+01 -6.174135013471972536e-03 +2.719999999999999929e+01 -6.603903705418908560e-03 +2.721000000000000085e+01 -6.951762300992907900e-03 +2.721999999999999886e+01 -7.218095577552723421e-03 +2.723000000000000043e+01 -7.404849886361935044e-03 +2.724000000000000199e+01 -7.515312805967728875e-03 +2.725000000000000000e+01 -7.553863727575383692e-03 +2.726000000000000156e+01 -7.525709393987289192e-03 +2.726999999999999957e+01 -7.436618296476176816e-03 +2.728000000000000114e+01 -7.292666979590656587e-03 +2.728999999999999915e+01 -7.100009781031914498e-03 +2.730000000000000071e+01 -6.864681445408136670e-03 +2.731000000000000227e+01 -6.592439530804789297e-03 +2.732000000000000028e+01 -6.288650732217657829e-03 +2.733000000000000185e+01 -5.958222343055288167e-03 +2.733999999999999986e+01 -5.605577239610197611e-03 +2.735000000000000142e+01 -5.234668166157565618e-03 +2.735999999999999943e+01 -4.849024871378497525e-03 +2.737000000000000099e+01 -4.451825922185345848e-03 +2.737999999999999901e+01 -4.045985891957568775e-03 +2.739000000000000057e+01 -3.634248141486161841e-03 +2.740000000000000213e+01 -3.219273596276537620e-03 +2.741000000000000014e+01 -2.803716749416446802e-03 +2.742000000000000171e+01 -2.390281518101289044e-03 +2.742999999999999972e+01 -1.981751456585146339e-03 +2.744000000000000128e+01 -1.580991049433955967e-03 +2.744999999999999929e+01 -1.190917228672189578e-03 +2.746000000000000085e+01 -8.144427160931099049e-04 +2.746999999999999886e+01 -4.543951256048772095e-04 +2.748000000000000043e+01 -1.134178163223446568e-04 +2.749000000000000199e+01 2.061398716459104106e-04 +2.750000000000000000e+01 5.023342501534464651e-04 +2.751000000000000156e+01 7.737315222784594626e-04 +2.751999999999999957e+01 1.019495494124777807e-03 +2.753000000000000114e+01 1.239450396483682704e-03 +2.753999999999999915e+01 1.434111826298522293e-03 +2.755000000000000071e+01 1.604680713061214714e-03 +2.756000000000000227e+01 1.752997519870848906e-03 +2.757000000000000028e+01 1.881456462998650154e-03 +2.758000000000000185e+01 1.992882218213275648e-03 +2.758999999999999986e+01 2.090374208339108430e-03 +2.760000000000000142e+01 2.177125966629926083e-03 +2.760999999999999943e+01 2.256229087562159133e-03 +2.762000000000000099e+01 2.330472773830235232e-03 +2.762999999999999901e+01 2.402150857984909713e-03 +2.764000000000000057e+01 2.472888347629730033e-03 +2.765000000000000213e+01 2.543498982807515865e-03 +2.766000000000000014e+01 2.613884015284963312e-03 +2.767000000000000171e+01 2.682980476870246590e-03 +2.767999999999999972e+01 2.748764693116447812e-03 +2.769000000000000128e+01 2.808313851049253854e-03 +2.769999999999999929e+01 2.857925204539831995e-03 +2.771000000000000085e+01 2.893289178160268933e-03 +2.771999999999999886e+01 2.909709398734231303e-03 +2.773000000000000043e+01 2.902359731630599175e-03 +2.774000000000000199e+01 2.866565901928538537e-03 +2.775000000000000000e+01 2.798097393456952173e-03 +2.776000000000000156e+01 2.693454163508368377e-03 +2.776999999999999957e+01 2.550132372764275270e-03 +2.778000000000000114e+01 2.366853847867140571e-03 +2.778999999999999915e+01 2.143745362161973006e-03 +2.780000000000000071e+01 1.882455983917371949e-03 +2.781000000000000227e+01 1.586203601999817189e-03 +2.782000000000000028e+01 1.259745157791185548e-03 +2.783000000000000185e+01 9.092689168040950665e-04 +2.783999999999999986e+01 5.422111084494895313e-04 +2.785000000000000142e+01 1.670032382291646532e-04 +2.785999999999999943e+01 -2.072398783864649494e-04 +2.787000000000000099e+01 -5.710779994113426589e-04 +2.787999999999999901e+01 -9.151331999819664739e-04 +2.789000000000000057e+01 -1.230489490488841358e-03 +2.790000000000000213e+01 -1.509085275974719493e-03 +2.791000000000000014e+01 -1.744079525307965688e-03 +2.792000000000000171e+01 -1.930173389036499501e-03 +2.792999999999999972e+01 -2.063870812295472406e-03 +2.794000000000000128e+01 -2.143664353883659775e-03 +2.794999999999999929e+01 -2.170135818048579083e-03 +2.796000000000000085e+01 -2.145965268161498327e-03 +2.796999999999999886e+01 -2.075846325102324082e-03 +2.798000000000000043e+01 -1.966310143404406165e-03 +2.799000000000000199e+01 -1.825464879399212471e-03 +2.800000000000000000e+01 -1.662661595782143845e-03 +2.801000000000000156e+01 -1.488101177625345559e-03 +2.801999999999999957e+01 -1.312399781657354629e-03 +2.803000000000000114e+01 -1.146132454067924763e-03 +2.803999999999999915e+01 -9.993757240070665852e-04 +2.805000000000000071e+01 -8.812701495705131715e-04 +2.806000000000000227e+01 -7.996229499357235563e-04 +2.807000000000000028e+01 -7.605690417096600334e-04 +2.808000000000000185e+01 -7.683060982238055668e-04 +2.808999999999999986e+01 -8.249158000759559657e-04 +2.810000000000000142e+01 -9.302794132435704411e-04 +2.810999999999999943e+01 -1.082091415326162870e-03 +2.812000000000000099e+01 -1.275970306796543217e-03 +2.812999999999999901e+01 -1.505661215519825446e-03 +2.814000000000000057e+01 -1.763320648277522237e-03 +2.815000000000000213e+01 -2.039869966447037126e-03 +2.816000000000000014e+01 -2.325401043578439412e-03 +2.817000000000000171e+01 -2.609615245480562985e-03 +2.817999999999999972e+01 -2.882275463805719640e-03 +2.819000000000000128e+01 -3.133650491334400660e-03 +2.819999999999999929e+01 -3.354931563515334454e-03 +2.821000000000000085e+01 -3.538602370569064650e-03 +2.821999999999999886e+01 -3.678746186850375115e-03 +2.823000000000000043e+01 -3.771276847666851263e-03 +2.824000000000000199e+01 -3.814083972806586384e-03 +2.825000000000000000e+01 -3.807086909204749573e-03 +2.826000000000000156e+01 -3.752196143924118460e-03 +2.826999999999999957e+01 -3.653185218389309440e-03 +2.828000000000000114e+01 -3.515480253178730665e-03 +2.828999999999999915e+01 -3.345877881726952441e-03 +2.830000000000000071e+01 -3.152205523113954435e-03 +2.831000000000000227e+01 -2.942940362377922166e-03 +2.832000000000000028e+01 -2.726805048441765036e-03 +2.833000000000000185e+01 -2.512358903425594443e-03 +2.833999999999999986e+01 -2.307603341671275992e-03 +2.835000000000000142e+01 -2.119619243629260533e-03 +2.835999999999999943e+01 -1.954252280042112835e-03 +2.837000000000000099e+01 -1.815859732520019431e-03 +2.837999999999999901e+01 -1.707129335219990159e-03 +2.839000000000000057e+01 -1.628977220180513998e-03 +2.840000000000000213e+01 -1.580528353316153559e-03 +2.841000000000000014e+01 -1.559179073710113697e-03 +2.842000000000000171e+01 -1.560737670346660968e-03 +2.842999999999999972e+01 -1.579635512614025253e-03 +2.844000000000000128e+01 -1.609198243279549335e-03 +2.844999999999999929e+01 -1.641964071024681893e-03 +2.846000000000000085e+01 -1.670034362630467683e-03 +2.846999999999999886e+01 -1.685440598814668062e-03 +2.848000000000000043e+01 -1.680511355819434014e-03 +2.849000000000000199e+01 -1.648223305107068826e-03 +2.850000000000000000e+01 -1.582521252250777269e-03 +2.851000000000000156e+01 -1.478593897843240778e-03 +2.851999999999999957e+01 -1.333094207052997306e-03 +2.853000000000000114e+01 -1.144295907349289054e-03 +2.853999999999999915e+01 -9.121805677588120352e-04 +2.855000000000000071e+01 -6.384528101267799693e-04 +2.856000000000000227e+01 -3.264843227086107426e-04 +2.857000000000000028e+01 1.880964750870202709e-05 +2.858000000000000185e+01 3.911548824179348401e-04 +2.858999999999999986e+01 7.831550075438116097e-04 +2.860000000000000142e+01 1.186569716127499263e-03 +2.860999999999999943e+01 1.592622136617693205e-03 +2.862000000000000099e+01 1.992322191824324584e-03 +2.862999999999999901e+01 2.376792494210804626e-03 +2.864000000000000057e+01 2.737583593514387841e-03 +2.865000000000000213e+01 3.066966209767236964e-03 +2.866000000000000014e+01 3.358189393468343550e-03 +2.867000000000000171e+01 3.605695283404699355e-03 +2.867999999999999972e+01 3.805283194011023409e-03 +2.869000000000000128e+01 3.954218059989049114e-03 +2.869999999999999929e+01 4.051280691953202187e-03 +2.871000000000000085e+01 4.096759746502785099e-03 +2.871999999999999886e+01 4.092387685144102324e-03 +2.873000000000000043e+01 4.041225191370271912e-03 +2.874000000000000199e+01 3.947500450658231706e-03 +2.875000000000000000e+01 3.816411301043909875e-03 +2.876000000000000156e+01 3.653899479552883897e-03 +2.876999999999999957e+01 3.466406983308267277e-03 +2.878000000000000114e+01 3.260624917914082578e-03 +2.878999999999999915e+01 3.043245118882735665e-03 +2.880000000000000071e+01 2.820724325130048900e-03 +2.881000000000000227e+01 2.599069791582382834e-03 +2.882000000000000028e+01 2.383654002196411263e-03 +2.883000000000000185e+01 2.179064646794019039e-03 +2.883999999999999986e+01 1.988994326932094683e-03 +2.885000000000000142e+01 1.816172635185049102e-03 +2.885999999999999943e+01 1.662341387559722501e-03 +2.887000000000000099e+01 1.528271960300073284e-03 +2.887999999999999901e+01 1.413821964101163271e-03 +2.889000000000000057e+01 1.318026948892225998e-03 +2.890000000000000213e+01 1.239221529599691778e-03 +2.891000000000000014e+01 1.175183303631990644e-03 +2.892000000000000171e+01 1.123292228678964997e-03 +2.892999999999999972e+01 1.080697763468022998e-03 +2.894000000000000128e+01 1.044486049234360147e-03 +2.894999999999999929e+01 1.011839716604155193e-03 +2.896000000000000085e+01 9.801835170683381553e-04 +2.896999999999999886e+01 9.473098655248183945e-04 +2.898000000000000043e+01 9.114794931137687635e-04 +2.899000000000000199e+01 8.714936941940946633e-04 +2.900000000000000000e+01 8.267360457768288410e-04 +2.901000000000000156e+01 7.771829197412261732e-04 +2.901999999999999957e+01 7.233835320082302985e-04 +2.903000000000000114e+01 6.664116175689605969e-04 +2.903999999999999915e+01 6.077920285385823157e-04 +2.905000000000000071e+01 5.494065744797861205e-04 +2.906000000000000227e+01 4.933842202116345494e-04 +2.907000000000000028e+01 4.419812966241489448e-04 +2.908000000000000185e+01 3.974576477231368853e-04 +2.908999999999999986e+01 3.619546275820959350e-04 +2.910000000000000142e+01 3.373805823216749554e-04 +2.910999999999999943e+01 3.253089247111798170e-04 +2.912000000000000099e+01 3.268931638470239770e-04 +2.912999999999999901e+01 3.428023297797732206e-04 +2.914000000000000057e+01 3.731791809911938875e-04 +2.915000000000000213e+01 4.176224537230566105e-04 +2.916000000000000014e+01 4.751932616886745298e-04 +2.917000000000000171e+01 5.444446373149550893e-04 +2.917999999999999972e+01 6.234721735654947909e-04 +2.919000000000000128e+01 7.099828252031554349e-04 +2.919999999999999929e+01 8.013781992426800230e-04 +2.921000000000000085e+01 8.948481364414578041e-04 +2.921999999999999886e+01 9.874700781841332705e-04 +2.923000000000000043e+01 1.076309634117479999e-03 +2.924000000000000199e+01 1.158517911981187800e-03 +2.925000000000000000e+01 1.231421527236384230e-03 +2.926000000000000156e+01 1.292601751858112871e-03 +2.926999999999999957e+01 1.339959954705711130e-03 +2.928000000000000114e+01 1.371767290300928343e-03 +2.928999999999999915e+01 1.386697463083649872e-03 +2.930000000000000071e+01 1.383842282463162163e-03 +2.931000000000000227e+01 1.362710584435698020e-03 +2.932000000000000028e+01 1.323211882257683712e-03 +2.933000000000000185e+01 1.265626784153812794e-03 +2.933999999999999986e+01 1.190566747411949712e-03 +2.935000000000000142e+01 1.098926102407487507e-03 +2.935999999999999943e+01 9.918294643402770106e-04 +2.937000000000000099e+01 8.705776509456371109e-04 +2.937999999999999901e+01 7.365950491690538560e-04 +2.939000000000000057e+01 5.913810396623016361e-04 +2.940000000000000213e+01 4.364676206124925022e-04 +2.941000000000000014e+01 2.733848045077385278e-04 +2.942000000000000171e+01 1.036347307504220238e-04 +2.942999999999999972e+01 -7.132521649047586791e-05 +2.944000000000000128e+01 -2.500906312647244796e-04 +2.944999999999999929e+01 -4.313105748010948124e-04 +2.946000000000000085e+01 -6.136817440791003447e-04 +2.946999999999999886e+01 -7.959381036455844601e-04 +2.948000000000000043e+01 -9.768379958385064229e-04 +2.949000000000000199e+01 -1.155150826658360441e-03 +2.950000000000000000e+01 -1.329645355440084008e-03 +2.951000000000000156e+01 -1.499081404657668466e-03 +2.951999999999999957e+01 -1.662206467922144231e-03 +2.953000000000000114e+01 -1.817758254832832401e-03 +2.953999999999999915e+01 -1.964473701387192250e-03 +2.955000000000000071e+01 -2.101104429221348907e-03 +2.956000000000000227e+01 -2.226438093563973264e-03 +2.957000000000000028e+01 -2.339324554910828489e-03 +2.958000000000000185e+01 -2.438705377421049054e-03 +2.958999999999999986e+01 -2.523644827446939760e-03 +2.960000000000000142e+01 -2.593360341393009631e-03 +2.960999999999999943e+01 -2.647250366745700512e-03 +2.962000000000000099e+01 -2.684917562080953168e-03 +2.962999999999999901e+01 -2.706185563565285859e-03 +2.964000000000000057e+01 -2.711107877053592873e-03 +2.965000000000000213e+01 -2.699967914126317776e-03 +2.966000000000000014e+01 -2.673269726633684465e-03 +2.967000000000000171e+01 -2.631719576543704517e-03 +2.967999999999999972e+01 -2.576199066330797996e-03 +2.969000000000000128e+01 -2.507731112253697246e-03 +2.969999999999999929e+01 -2.427440531542020795e-03 +2.971000000000000085e+01 -2.336511401839525080e-03 +2.971999999999999886e+01 -2.236143608929975352e-03 +2.973000000000000043e+01 -2.127511108733649153e-03 +2.974000000000000199e+01 -2.011724379853184821e-03 +2.975000000000000000e+01 -1.889799334003022238e-03 +2.976000000000000156e+01 -1.762634591999568626e-03 +2.976999999999999957e+01 -1.630998543147706972e-03 +2.978000000000000114e+01 -1.495527011447395083e-03 +2.978999999999999915e+01 -1.356731690343609010e-03 +2.980000000000000071e+01 -1.215018816465049866e-03 +2.981000000000000227e+01 -1.070716876058424357e-03 +2.982000000000000028e+01 -9.241115175196755807e-04 +2.983000000000000185e+01 -7.754853196535765230e-04 +2.983999999999999986e+01 -6.251596740843095527e-04 +2.985000000000000142e+01 -4.735358083143954237e-04 +2.985999999999999943e+01 -3.211319230330241989e-04 +2.987000000000000099e+01 -1.686135514144986090e-04 +2.987999999999999901e+01 -1.681456639518935769e-05 +2.989000000000000057e+01 1.332532494577941902e-04 +2.990000000000000213e+01 2.804035226710148996e-04 +2.991000000000000014e+01 4.232922016121870947e-04 +2.992000000000000171e+01 5.604479528681200699e-04 +2.992999999999999972e+01 6.903150916864903702e-04 +2.994000000000000128e+01 8.113072839063550663e-04 +2.994999999999999929e+01 9.218695187174466739e-04 +2.996000000000000085e+01 1.020545234394514738e-03 +2.996999999999999886e+01 1.106045022719563372e-03 +2.998000000000000043e+01 1.177313073495554622e-03 +2.999000000000000199e+01 1.233587469205456137e-03 +3.000000000000000000e+01 1.274450611241852377e-03 +3.001000000000000156e+01 1.299866448734053170e-03 +3.001999999999999957e+01 1.310201773961065146e-03 +3.003000000000000114e+01 1.306229615020872668e-03 +3.003999999999999915e+01 1.289113659944718165e-03 +3.005000000000000071e+01 1.260373637242881689e-03 +3.006000000000000227e+01 1.221832605134506909e-03 +3.007000000000000028e+01 1.175548106372403291e-03 +3.008000000000000185e+01 1.123730073597332740e-03 +3.008999999999999986e+01 1.068649166489159773e-03 +3.010000000000000142e+01 1.012539840826441042e-03 +3.010999999999999943e+01 9.575028523941961833e-04 +3.012000000000000099e+01 9.054120593685817441e-04 +3.012999999999999901e+01 8.578302909977873541e-04 +3.014000000000000057e+01 8.159386988991962136e-04 +3.015000000000000213e+01 7.804834140198205986e-04 +3.016000000000000014e+01 7.517425246679849613e-04 +3.017000000000000171e+01 7.295154096977198932e-04 +3.017999999999999972e+01 7.131353545849211531e-04 +3.019000000000000128e+01 7.015052049413937705e-04 +3.019999999999999929e+01 6.931546332158669728e-04 +3.021000000000000085e+01 6.863164724544509616e-04 +3.021999999999999886e+01 6.790185666691248012e-04 +3.023000000000000043e+01 6.691867545230470145e-04 +3.024000000000000199e+01 6.547539884051362721e-04 +3.025000000000000000e+01 6.337702282278802508e-04 +3.026000000000000156e+01 6.045076601595488841e-04 +3.026999999999999957e+01 5.655559822088209246e-04 +3.028000000000000114e+01 5.159029623754929307e-04 +3.028999999999999915e+01 4.549961888795867136e-04 +3.030000000000000071e+01 3.827828597317713111e-04 +3.031000000000000227e+01 2.997255528079880056e-04 +3.032000000000000028e+01 2.067931213769594106e-04 +3.033000000000000185e+01 1.054271111699714544e-04 +3.033999999999999986e+01 -2.514671800939117733e-06 +3.035000000000000142e+01 -1.148346624069779075e-04 +3.035999999999999943e+01 -2.290883175448212884e-04 +3.037000000000000099e+01 -3.426885742943579010e-04 +3.037999999999999901e+01 -4.530168052046143435e-04 +3.039000000000000057e+01 -5.575347807390859493e-04 +3.040000000000000213e+01 -6.538921212488711795e-04 +3.041000000000000014e+01 -7.400239762263605180e-04 +3.042000000000000171e+01 -8.142341932540028042e-04 +3.042999999999999972e+01 -8.752600041219830204e-04 +3.044000000000000128e+01 -9.223152209247616065e-04 +3.044999999999999929e+01 -9.551100489149244198e-04 +3.046000000000000085e+01 -9.738468271928022108e-04 +3.046999999999999886e+01 -9.791922396041434235e-04 +3.048000000000000043e+01 -9.722277326172058202e-04 +3.049000000000000199e+01 -9.543809724465448455e-04 +3.050000000000000000e+01 -9.273421143001513199e-04 +3.051000000000000156e+01 -8.929693946915808183e-04 +3.051999999999999957e+01 -8.531890563556955749e-04 +3.053000000000000114e+01 -8.098948508403372264e-04 +3.053999999999999915e+01 -7.648523265889638819e-04 +3.055000000000000071e+01 -7.196128034658540781e-04 +3.056000000000000227e+01 -6.754413787731201142e-04 +3.057000000000000028e+01 -6.332625335772324154e-04 +3.058000000000000185e+01 -5.936259559837763758e-04 +3.058999999999999986e+01 -5.566941194480448185e-04 +3.060000000000000142e+01 -5.222520071954097004e-04 +3.060999999999999943e+01 -4.897382178056962007e-04 +3.062000000000000099e+01 -4.582955814942281511e-04 +3.062999999999999901e+01 -4.268384185118582748e-04 +3.064000000000000057e+01 -3.941327295710394868e-04 +3.065000000000000213e+01 -3.588849653663388033e-04 +3.066000000000000014e+01 -3.198346080631650468e-04 +3.067000000000000171e+01 -2.758456307189257489e-04 +3.067999999999999972e+01 -2.259919864306780108e-04 +3.069000000000000128e+01 -1.696326097072177290e-04 +3.069999999999999929e+01 -1.064719686130665896e-04 +3.071000000000000085e+01 -3.660295624197949284e-05 +3.071999999999999886e+01 3.947018625745769247e-05 +3.073000000000000043e+01 1.208302130289856804e-04 +3.074000000000000199e+01 2.061667171860103180e-04 +3.075000000000000000e+01 2.938166444495441515e-04 +3.076000000000000156e+01 3.818236344829574317e-04 +3.076999999999999957e+01 4.680134373653766964e-04 +3.078000000000000114e+01 5.500818869925471269e-04 +3.078999999999999915e+01 6.256913271355317137e-04 +3.080000000000000071e+01 6.925710047068680403e-04 +3.081000000000000227e+01 7.486167835456427732e-04 +3.082000000000000028e+01 7.919855930489155729e-04 +3.083000000000000185e+01 8.211803034181803596e-04 +3.083999999999999986e+01 8.351211936620944742e-04 +3.085000000000000142e+01 8.332008237766499537e-04 +3.085999999999999943e+01 8.153199038810319838e-04 +3.087000000000000099e+01 7.819026300902139548e-04 +3.087999999999999901e+01 7.338908865538657563e-04 +3.089000000000000057e+01 6.727176502383494690e-04 +3.090000000000000213e+01 6.002608357299021955e-04 +3.091000000000000014e+01 5.187796420753706559e-04 +3.092000000000000171e+01 4.308361756961715666e-04 +3.092999999999999972e+01 3.392056944912146205e-04 +3.094000000000000128e+01 2.467792272979239484e-04 +3.094999999999999929e+01 1.564625561410629508e-04 +3.096000000000000085e+01 7.107560316831335707e-05 +3.097000000000000242e+01 -6.743856942842047956e-06 +3.098000000000000043e+01 -7.462852208205002734e-05 +3.099000000000000199e+01 -1.305587159105710791e-04 +3.100000000000000000e+01 -1.729257064490321281e-04 +3.101000000000000156e+01 -2.005791638479409575e-04 +3.101999999999999957e+01 -2.128574260358230465e-04 +3.103000000000000114e+01 -2.095999614391469478e-04 +3.103999999999999915e+01 -1.911421319895274828e-04 +3.105000000000000071e+01 -1.582930372838956944e-04 +3.106000000000000227e+01 -1.122978352275049146e-04 +3.107000000000000028e+01 -5.478646346581497490e-05 +3.108000000000000185e+01 1.228888770188749015e-05 +3.108999999999999986e+01 8.672488827744704546e-05 +3.110000000000000142e+01 1.661439130368120882e-04 +3.110999999999999943e+01 2.480736921876157863e-04 +3.112000000000000099e+01 3.300268878338761614e-04 +3.112999999999999901e+01 4.095778673285732185e-04 +3.114000000000000057e+01 4.844341898228840862e-04 +3.115000000000000213e+01 5.525006446056003823e-04 +3.116000000000000014e+01 6.119340623428539284e-04 +3.117000000000000171e+01 6.611875429613133176e-04 +3.117999999999999972e+01 6.990431890239910077e-04 +3.119000000000000128e+01 7.246328814559200920e-04 +3.119999999999999929e+01 7.374470703748687087e-04 +3.121000000000000085e+01 7.373319606870834108e-04 +3.122000000000000242e+01 7.244758401185293550e-04 +3.123000000000000043e+01 6.993856145692795402e-04 +3.124000000000000199e+01 6.628548768087450145e-04 +3.125000000000000000e+01 6.159250338136684679e-04 +3.126000000000000156e+01 5.598411551330506608e-04 +3.126999999999999957e+01 4.960042787022896299e-04 +3.128000000000000114e+01 4.259219243578998512e-04 +3.128999999999999915e+01 3.511585230327253808e-04 +3.130000000000000071e+01 2.732873762536719236e-04 +3.131000000000000227e+01 1.938456221225004592e-04 +3.132000000000000028e+01 1.142935072540858472e-04 +3.133000000000000185e+01 3.597905665528213225e-05 +3.133999999999999986e+01 -3.989099789820745907e-05 +3.135000000000000142e+01 -1.122734180829261492e-04 +3.135999999999999943e+01 -1.803034314663134270e-04 +3.137000000000000099e+01 -2.433023781090828984e-04 +3.137999999999999901e+01 -3.007781862368572880e-04 +3.139000000000000057e+01 -3.524190727972349572e-04 +3.140000000000000213e+01 -3.980810867840843667e-04 +3.141000000000000014e+01 -4.377703109704844751e-04 +3.142000000000000171e+01 -4.716207043490340815e-04 +3.142999999999999972e+01 -4.998686994667117566e-04 +3.144000000000000128e+01 -5.228257602024856876e-04 +3.144999999999999929e+01 -5.408501542513527395e-04 +3.146000000000000085e+01 -5.543191975628089432e-04 +3.147000000000000242e+01 -5.636031842866500450e-04 +3.148000000000000043e+01 -5.690421272349355502e-04 +3.149000000000000199e+01 -5.709263000523273060e-04 +3.150000000000000000e+01 -5.694814002189963354e-04 +3.151000000000000156e+01 -5.648589444105109542e-04 +3.151999999999999957e+01 -5.571322738042055502e-04 +3.153000000000000114e+01 -5.462982935502808373e-04 +3.153999999999999915e+01 -5.322848098724916079e-04 +3.155000000000000071e+01 -5.149630674223725987e-04 +3.156000000000000227e+01 -4.941648441603777291e-04 +3.157000000000000028e+01 -4.697032370973903579e-04 +3.158000000000000185e+01 -4.413960848898067593e-04 +3.158999999999999986e+01 -4.090908288390991622e-04 +3.160000000000000142e+01 -3.726895208814009412e-04 +3.160999999999999943e+01 -3.321726523155170223e-04 +3.162000000000000099e+01 -2.876205020985859485e-04 +3.162999999999999901e+01 -2.392307903526292884e-04 +3.164000000000000057e+01 -1.873315679692944794e-04 +3.165000000000000213e+01 -1.323884725061722032e-04 +3.166000000000000014e+01 -7.500572563775363796e-05 +3.167000000000000171e+01 -1.592052755981389871e-05 +3.167999999999999972e+01 4.400919249795540633e-05 +3.169000000000000128e+01 1.038233980861515523e-04 +3.169999999999999929e+01 1.624843607308304450e-04 +3.171000000000000085e+01 2.189060027057201094e-04 +3.172000000000000242e+01 2.719870488765315213e-04 +3.173000000000000043e+01 3.206466637578124458e-04 +3.174000000000000199e+01 3.638611021965910790e-04 +3.175000000000000000e+01 4.006998207681910628e-04 +3.176000000000000156e+01 4.303594860987813484e-04 +3.176999999999999957e+01 4.521943788863994691e-04 +3.178000000000000114e+01 4.657418250446070541e-04 +3.178999999999999915e+01 4.707414835010895865e-04 +3.180000000000000071e+01 4.671475754913836107e-04 +3.181000000000000227e+01 4.551334394958290335e-04 +3.182000000000000028e+01 4.350881274840946570e-04 +3.183000000000000185e+01 4.076051041948545789e-04 +3.183999999999999986e+01 3.734634571723170781e-04 +3.185000000000000142e+01 3.336023532755533509e-04 +3.185999999999999943e+01 2.890897723936580624e-04 +3.187000000000000099e+01 2.410867971244837183e-04 +3.187999999999999901e+01 1.908089256250894276e-04 +3.189000000000000057e+01 1.394859959321045103e-04 +3.190000000000000213e+01 8.832235689861381094e-05 +3.191000000000000014e+01 3.845889314074306181e-05 +3.192000000000000171e+01 -9.061590730803830695e-06 +3.192999999999999972e+01 -5.332429090049348560e-05 +3.194000000000000128e+01 -9.356652374103150609e-05 +3.194999999999999929e+01 -1.291952141183970568e-04 +3.196000000000000085e+01 -1.597972334260905651e-04 +3.197000000000000242e+01 -1.851423968235652560e-04 +3.198000000000000043e+01 -2.051792601033241550e-04 +3.199000000000000199e+01 -2.200241734066352487e-04 +3.200000000000000000e+01 -2.299443367366307324e-04 +3.200999999999999801e+01 -2.353358477278704136e-04 +3.202000000000000313e+01 -2.366979235951170940e-04 +3.203000000000000114e+01 -2.346046094370967815e-04 +3.203999999999999915e+01 -2.296753482896047975e-04 +3.204999999999999716e+01 -2.225457838205206057e-04 +3.206000000000000227e+01 -2.138400959396781302e-04 +3.207000000000000028e+01 -2.041460381901315246e-04 +3.207999999999999829e+01 -1.939936626466690333e-04 +3.209000000000000341e+01 -1.838384925788138081e-04 +3.210000000000000142e+01 -1.740496497194861793e-04 +3.210999999999999943e+01 -1.649031737664790600e-04 +3.211999999999999744e+01 -1.565805021998993910e-04 +3.213000000000000256e+01 -1.491718217702471181e-04 +3.214000000000000057e+01 -1.426837719627596418e-04 +3.214999999999999858e+01 -1.370507866432842548e-04 +3.216000000000000369e+01 -1.321492118367946858e-04 +3.217000000000000171e+01 -1.278132403884174281e-04 +3.217999999999999972e+01 -1.238516628096343164e-04 +3.218999999999999773e+01 -1.200644465811158044e-04 +3.220000000000000284e+01 -1.162582219707943763e-04 +3.221000000000000085e+01 -1.122598647194383170e-04 +3.221999999999999886e+01 -1.079275174979357511e-04 +3.223000000000000398e+01 -1.031585728838904631e-04 +3.224000000000000199e+01 -9.789434002976807672e-05 +3.225000000000000000e+01 -9.212132313864810382e-05 +3.225999999999999801e+01 -8.586924154372988307e-05 +3.227000000000000313e+01 -7.920610682411949668e-05 +3.228000000000000114e+01 -7.223083279248975874e-05 +3.228999999999999915e+01 -6.506398102906258861e-05 +3.229999999999999716e+01 -5.783733226390551211e-05 +3.231000000000000227e+01 -5.068301832502388062e-05 +3.232000000000000028e+01 -4.372294989373715318e-05 +3.232999999999999829e+01 -3.705923311163870812e-05 +3.234000000000000341e+01 -3.076618678834224305e-05 +3.235000000000000142e+01 -2.488445756842241254e-05 +3.235999999999999943e+01 -1.941759010529121101e-05 +3.236999999999999744e+01 -1.433125186857545026e-05 +3.238000000000000256e+01 -9.555146921275132880e-06 +3.239000000000000057e+01 -4.987489498014498577e-06 +3.239999999999999858e+01 -5.017555459163592062e-07 +3.241000000000000369e+01 4.044703101579275377e-06 +3.242000000000000171e+01 8.800704433432037372e-06 +3.242999999999999972e+01 1.391053999045540352e-05 +3.243999999999999773e+01 1.950317517012692135e-05 +3.245000000000000284e+01 2.568198848024490227e-05 +3.246000000000000085e+01 3.251565976829760162e-05 +3.246999999999999886e+01 4.003075164000556796e-05 +3.248000000000000398e+01 4.820643302350102744e-05 +3.249000000000000199e+01 5.697167518433241483e-05 +3.250000000000000000e+01 6.620511519298958095e-05 +3.250999999999999801e+01 7.573763741834779652e-05 +3.252000000000000313e+01 8.535757833263517530e-05 +3.253000000000000114e+01 9.481832119387474612e-05 +3.253999999999999915e+01 1.038479223855474145e-04 +3.254999999999999716e+01 1.121603067694174690e-04 +3.256000000000000227e+01 1.194674901794998682e-04 +3.257000000000000028e+01 1.254922371650067062e-04 +3.257999999999999829e+01 1.299805424442676441e-04 +3.259000000000000341e+01 1.327133371027259840e-04 +3.260000000000000142e+01 1.335168619994696337e-04 +3.260999999999999943e+01 1.322712205001323347e-04 +3.261999999999999744e+01 1.289167145427046245e-04 +3.263000000000000256e+01 1.234576782232928963e-04 +3.264000000000000057e+01 1.159636448026880374e-04 +3.264999999999999858e+01 1.065678110266823610e-04 +3.266000000000000369e+01 9.546288804448979323e-05 +3.267000000000000171e+01 8.289454862833896265e-05 +3.267999999999999972e+01 6.915278600431548519e-05 +3.268999999999999773e+01 5.456158880756196072e-05 +3.270000000000000284e+01 3.946740385728795733e-05 +3.271000000000000085e+01 2.422690189600035509e-05 +3.271999999999999886e+01 9.194579390869393783e-06 +3.273000000000000398e+01 -5.289277879306488100e-06 +3.274000000000000199e+01 -1.890977507884623949e-05 +3.275000000000000000e+01 -3.138729137892848196e-05 +3.275999999999999801e+01 -4.248569642026807640e-05 +3.277000000000000313e+01 -5.201861681672778290e-05 +3.278000000000000114e+01 -5.985356518447024703e-05 +3.278999999999999915e+01 -6.591384474452517521e-05 +3.279999999999999716e+01 -7.017824339316527330e-05 +3.281000000000000227e+01 -7.267862678900945919e-05 +3.282000000000000028e+01 -7.349562699448275471e-05 +3.282999999999999829e+01 -7.275269766177079958e-05 +3.284000000000000341e+01 -7.060886495052503436e-05 +3.285000000000000142e+01 -6.725054529674888480e-05 +3.285999999999999943e+01 -6.288282284968864009e-05 +3.286999999999999744e+01 -5.772058396915921241e-05 +3.288000000000000256e+01 -5.197989127091720882e-05 +3.289000000000000057e+01 -4.586994908980838271e-05 +3.289999999999999858e+01 -3.958596707469038258e-05 +3.291000000000000369e+01 -3.330317179828484308e-05 +3.292000000000000171e+01 -2.717215133105289998e-05 +3.292999999999999972e+01 -2.131564736701213383e-05 +3.293999999999999773e+01 -1.582683833498693077e-05 +3.295000000000000284e+01 -1.076908666115662375e-05 +3.296000000000000085e+01 -6.177058861031154999e-06 +3.296999999999999886e+01 -2.059069640031567534e-06 +3.298000000000000398e+01 1.599546188067358537e-06 +3.299000000000000199e+01 4.832266107320840269e-06 +3.300000000000000000e+01 7.686672241668708819e-06 +3.300999999999999801e+01 1.021946967853661111e-05 +3.302000000000000313e+01 1.249149448193302665e-05 +3.303000000000000114e+01 1.456296074559376540e-05 +3.303999999999999915e+01 1.648917077051498850e-05 +3.304999999999999716e+01 1.831687814472466320e-05 +3.306000000000000227e+01 2.008145193943015400e-05 +3.307000000000000028e+01 2.180494377176613101e-05 +3.307999999999999829e+01 2.349511042007403899e-05 +3.309000000000000341e+01 2.514539524171920619e-05 +3.310000000000000142e+01 2.673582431413384201e-05 +3.310999999999999943e+01 2.823472978377045375e-05 +3.311999999999999744e+01 2.960117544272298845e-05 +3.313000000000000256e+01 3.078792924071404772e-05 +3.314000000000000057e+01 3.174480568757163089e-05 +3.314999999999999858e+01 3.242218833516250404e-05 +3.316000000000000369e+01 3.277453905217198748e-05 +3.317000000000000171e+01 3.276370680583893895e-05 +3.317999999999999972e+01 3.236186287330853473e-05 +3.318999999999999773e+01 3.155391177268658152e-05 +3.320000000000000284e+01 3.033925582830405905e-05 +3.321000000000000085e+01 2.873282509857686309e-05 +3.321999999999999886e+01 2.676532140101027643e-05 +3.323000000000000398e+01 2.448266418870565249e-05 +3.324000000000000199e+01 2.194466443723889695e-05 +3.325000000000000000e+01 1.922298950361602435e-05 +3.325999999999999801e+01 1.639851523497496942e-05 +3.327000000000000313e+01 1.355818963178425195e-05 +3.328000000000000114e+01 1.079155463178603176e-05 +3.328999999999999915e+01 8.187087491427798625e-06 +3.329999999999999716e+01 5.828530647322938165e-06 +3.331000000000000227e+01 3.791378408773886836e-06 +3.332000000000000028e+01 2.139680653442144044e-06 +3.332999999999999829e+01 9.233081374962411266e-07 +3.334000000000000341e+01 1.758020628402072528e-07 +3.335000000000000142e+01 -8.709680960634248460e-08 +3.335999999999999943e+01 1.318243130133501924e-07 +3.336999999999999744e+01 8.112958542340534814e-07 +3.338000000000000256e+01 1.912379305858778643e-06 +3.339000000000000057e+01 3.380008777331556866e-06 +3.339999999999999858e+01 5.145188687146969142e-06 +3.341000000000000369e+01 7.127747061431540307e-06 +3.342000000000000171e+01 9.239520243394895298e-06 +3.342999999999999972e+01 1.138782721686280141e-05 +3.343999999999999773e+01 1.347908077113001793e-05 +3.345000000000000284e+01 1.542237905661052798e-05 +3.346000000000000085e+01 1.713292447226560724e-05 +3.346999999999999886e+01 1.853512742796090495e-05 +3.348000000000000398e+01 1.956526923171491485e-05 +3.349000000000000199e+01 2.017362088451592461e-05 +3.350000000000000000e+01 2.032594119492408733e-05 +3.350999999999999801e+01 2.000430726128067541e-05 +3.352000000000000313e+01 1.920726198483001018e-05 +3.353000000000000114e+01 1.794929411058487906e-05 +3.353999999999999915e+01 1.625969656691196393e-05 +3.354999999999999716e+01 1.418087540005238534e-05 +3.356000000000000227e+01 1.176620464064333931e-05 +3.357000000000000028e+01 9.077539871772603543e-06 +3.357999999999999829e+01 6.182515107444642694e-06 +3.359000000000000341e+01 3.151752822754488465e-06 +3.360000000000000142e+01 5.611595659711153204e-08 +3.360999999999999943e+01 -3.035876618850003609e-06 +3.361999999999999744e+01 -6.060362715948659101e-06 +3.363000000000000256e+01 -8.960086964913866093e-06 +3.364000000000000057e+01 -1.168591966896786472e-05 +3.364999999999999858e+01 -1.419789992547059593e-05 +3.366000000000000369e+01 -1.646578428810299046e-05 +3.367000000000000171e+01 -1.846910776532912653e-05 +3.367999999999999972e+01 -2.019678830442772055e-05 +3.368999999999999773e+01 -2.164632737466794493e-05 +3.370000000000000284e+01 -2.282267744272802244e-05 +3.371000000000000085e+01 -2.373686051708457829e-05 +3.371999999999999886e+01 -2.440443035063719478e-05 +3.373000000000000398e+01 -2.484387434460383153e-05 +3.374000000000000199e+01 -2.507504866524458360e-05 +3.375000000000000000e+01 -2.511773347834542319e-05 +3.375999999999999801e+01 -2.499038302782963065e-05 +3.377000000000000313e+01 -2.470913084399561148e-05 +3.378000000000000114e+01 -2.428709187887847091e-05 +3.378999999999999915e+01 -2.373398437309867347e-05 +3.379999999999999716e+01 -2.305607396123806802e-05 +3.381000000000000227e+01 -2.225642411399359396e-05 +3.382000000000000028e+01 -2.133541817587892572e-05 +3.382999999999999829e+01 -2.029150500681881593e-05 +3.384000000000000341e+01 -1.912210739531788648e-05 +3.385000000000000142e+01 -1.782462608499044214e-05 +3.385999999999999943e+01 -1.639746761691315019e-05 +3.386999999999999744e+01 -1.484102663783027846e-05 +3.388000000000000256e+01 -1.315855681331550245e-05 +3.389000000000000057e+01 -1.135687422961755739e-05 +3.389999999999999858e+01 -9.446848043692705892e-06 +3.391000000000000369e+01 -7.443647395525671459e-06 +3.392000000000000171e+01 -5.366728384803364430e-06 +3.392999999999999972e+01 -3.239561118970440206e-06 +3.393999999999999773e+01 -1.089111335621122922e-06 +3.395000000000000284e+01 1.054894450409085190e-06 +3.396000000000000085e+01 3.160879956719657633e-06 +3.396999999999999886e+01 5.196456668494862981e-06 +3.398000000000000398e+01 7.129532342552443248e-06 +3.399000000000000199e+01 8.929432201219975122e-06 +3.400000000000000000e+01 1.056797535051212631e-05 +3.400999999999999801e+01 1.202045262860175936e-05 +3.402000000000000313e+01 1.326645898441694374e-05 +3.403000000000000114e+01 1.429054276053401014e-05 +3.403999999999999915e+01 1.508264454856996216e-05 +3.404999999999999716e+01 1.563831077274570786e-05 +3.406000000000000227e+01 1.595867939117820523e-05 +3.407000000000000028e+01 1.605024623345100140e-05 +3.407999999999999829e+01 1.592443241503202622e-05 +3.409000000000000341e+01 1.559698178491757630e-05 +3.410000000000000142e+01 1.508722474823024953e-05 +3.410999999999999943e+01 1.441724992410348630e-05 +3.411999999999999744e+01 1.361102677145632420e-05 +3.413000000000000256e+01 1.269352315886827573e-05 +3.414000000000000057e+01 1.168985814752473478e-05 +3.414999999999999858e+01 1.062452656278000732e-05 +3.416000000000000369e+01 9.520725342366262114e-06 +3.417000000000000171e+01 8.399803082319185293e-06 +3.417999999999999972e+01 7.280848101973260045e-06 +3.418999999999999773e+01 6.180419181050523990e-06 +3.420000000000000284e+01 5.112417160184706496e-06 +3.421000000000000085e+01 4.088086881534951317e-06 +3.421999999999999886e+01 3.116133256427093967e-06 +3.423000000000000398e+01 2.202930368836290192e-06 +3.424000000000000199e+01 1.352799396743076299e-06 +3.425000000000000000e+01 5.683297009760791360e-07 +3.425999999999999801e+01 -1.492821861068540659e-07 +3.427000000000000313e+01 -7.998992512712665287e-07 +3.428000000000000114e+01 -1.384136726867042870e-06 +3.428999999999999915e+01 -1.903097084243035191e-06 +3.430000000000000426e+01 -2.358158781899520627e-06 +3.431000000000000227e+01 -2.750825039570752266e-06 +3.432000000000000028e+01 -3.082633902631991487e-06 +3.432999999999999829e+01 -3.355126150077640798e-06 +3.434000000000000341e+01 -3.569863592017642398e-06 +3.435000000000000142e+01 -3.728487169299041492e-06 +3.435999999999999943e+01 -3.832802036457009152e-06 +3.436999999999999744e+01 -3.884876025958187833e-06 +3.438000000000000256e+01 -3.887137866817799669e-06 +3.439000000000000057e+01 -3.842462285165584289e-06 +3.439999999999999858e+01 -3.754231933425460512e-06 +3.441000000000000369e+01 -3.626367611202411284e-06 +3.442000000000000171e+01 -3.463321977986780192e-06 +3.442999999999999972e+01 -3.270035174570039133e-06 +3.443999999999999773e+01 -3.051853542184851585e-06 +3.445000000000000284e+01 -2.814415921949668510e-06 +3.446000000000000085e+01 -2.563514168578440747e-06 +3.446999999999999886e+01 -2.304936606536295273e-06 +3.448000000000000398e+01 -2.044303746172721339e-06 +3.449000000000000199e+01 -1.786906801888591342e-06 +3.450000000000000000e+01 -1.537558199411324060e-06 +3.450999999999999801e+01 -1.300462898086104675e-06 +3.452000000000000313e+01 -1.079117485405599583e-06 +3.453000000000000114e+01 -8.762421868327658472e-07 +3.453999999999999915e+01 -6.937482736873225661e-07 +3.455000000000000426e+01 -5.327416874145780754e-07 +3.456000000000000227e+01 -3.935606944421768356e-07 +3.457000000000000028e+01 -2.758440537729225393e-07 +3.457999999999999829e+01 -1.786241294360830180e-07 +3.459000000000000341e+01 -1.004382900531979396e-07 +3.460000000000000142e+01 -3.945143099000779264e-08 +3.460999999999999943e+01 6.417936148465094699e-09 +3.461999999999999744e+01 3.937507225299001728e-08 +3.463000000000000256e+01 6.163618034684389956e-08 +3.464000000000000057e+01 7.533052006531242809e-08 +3.464999999999999858e+01 8.242122344280953723e-08 +3.466000000000000369e+01 8.464704229232951658e-08 +3.467000000000000171e+01 8.348570069469806293e-08 +3.467999999999999972e+01 8.013809939328622620e-08 +3.468999999999999773e+01 7.553134758261680750e-08 +3.470000000000000284e+01 7.033753773406452595e-08 +3.471000000000000085e+01 6.500462867457251877e-08 +3.471999999999999886e+01 5.979530049318684276e-08 +3.473000000000000398e+01 5.482975288784416824e-08 +3.474000000000000199e+01 5.012861221703238720e-08 +3.475000000000000000e+01 4.565270568205733985e-08 +3.475999999999999801e+01 4.133718099404713480e-08 +3.477000000000000313e+01 3.711821322922182642e-08 +3.478000000000000114e+01 3.295154383463905473e-08 +3.478999999999999915e+01 2.882275640867311894e-08 +3.480000000000000426e+01 2.475007210880393945e-08 +3.481000000000000227e+01 2.078092806756468432e-08 +3.482000000000000028e+01 1.698401912244888067e-08 +3.482999999999999829e+01 1.343862662512037722e-08 +3.484000000000000341e+01 1.022314639434855843e-08 +3.485000000000000142e+01 7.404406997618042797e-09 +3.485999999999999943e+01 5.029128559315473487e-09 +3.486999999999999744e+01 3.118437016003692143e-09 +3.488000000000000256e+01 1.665842036731200075e-09 +3.489000000000000057e+01 6.386699692754192504e-10 +3.489999999999999858e+01 -1.752312159834586523e-11 +3.491000000000000369e+01 -3.723121585046739003e-10 +3.492000000000000171e+01 -5.025220622460116840e-10 +3.492999999999999972e+01 -4.841801860688976499e-10 +3.493999999999999773e+01 -3.852920018457449041e-10 +3.495000000000000284e+01 -2.603125355732348463e-10 +3.496000000000000085e+01 -1.468803279010182202e-10 +3.496999999999999886e+01 -6.512107170779918740e-11 +3.498000000000000398e+01 -1.942177265911410204e-11 +3.499000000000000199e+01 -2.340930704936667819e-12 +3.500000000000000000e+01 -0.000000000000000000e+00 +3.500999999999999801e+01 -0.000000000000000000e+00 +3.502000000000000313e+01 -0.000000000000000000e+00 +3.503000000000000114e+01 -0.000000000000000000e+00 +3.503999999999999915e+01 -0.000000000000000000e+00 +3.505000000000000426e+01 -0.000000000000000000e+00 +3.506000000000000227e+01 0.000000000000000000e+00 +3.507000000000000028e+01 0.000000000000000000e+00 +3.507999999999999829e+01 0.000000000000000000e+00 +3.509000000000000341e+01 0.000000000000000000e+00 +3.510000000000000142e+01 0.000000000000000000e+00 +3.510999999999999943e+01 0.000000000000000000e+00 +3.511999999999999744e+01 0.000000000000000000e+00 +3.513000000000000256e+01 0.000000000000000000e+00 +3.514000000000000057e+01 0.000000000000000000e+00 +3.514999999999999858e+01 0.000000000000000000e+00 +3.516000000000000369e+01 0.000000000000000000e+00 +3.517000000000000171e+01 0.000000000000000000e+00 +3.517999999999999972e+01 0.000000000000000000e+00 +3.518999999999999773e+01 0.000000000000000000e+00 +3.520000000000000284e+01 0.000000000000000000e+00 +3.521000000000000085e+01 0.000000000000000000e+00 +3.521999999999999886e+01 0.000000000000000000e+00 +3.523000000000000398e+01 0.000000000000000000e+00 +3.524000000000000199e+01 0.000000000000000000e+00 +3.525000000000000000e+01 0.000000000000000000e+00 +3.525999999999999801e+01 0.000000000000000000e+00 +3.527000000000000313e+01 0.000000000000000000e+00 +3.528000000000000114e+01 0.000000000000000000e+00 +3.528999999999999915e+01 0.000000000000000000e+00 +3.530000000000000426e+01 0.000000000000000000e+00 +3.531000000000000227e+01 0.000000000000000000e+00 +3.532000000000000028e+01 0.000000000000000000e+00 +3.532999999999999829e+01 0.000000000000000000e+00 +3.534000000000000341e+01 0.000000000000000000e+00 +3.535000000000000142e+01 0.000000000000000000e+00 +3.535999999999999943e+01 0.000000000000000000e+00 +3.536999999999999744e+01 0.000000000000000000e+00 +3.538000000000000256e+01 0.000000000000000000e+00 +3.539000000000000057e+01 0.000000000000000000e+00 +3.539999999999999858e+01 0.000000000000000000e+00 +3.541000000000000369e+01 0.000000000000000000e+00 +3.542000000000000171e+01 0.000000000000000000e+00 +3.542999999999999972e+01 0.000000000000000000e+00 +3.543999999999999773e+01 0.000000000000000000e+00 +3.545000000000000284e+01 0.000000000000000000e+00 +3.546000000000000085e+01 0.000000000000000000e+00 +3.546999999999999886e+01 0.000000000000000000e+00 +3.548000000000000398e+01 0.000000000000000000e+00 +3.549000000000000199e+01 0.000000000000000000e+00 +3.550000000000000000e+01 0.000000000000000000e+00 +3.550999999999999801e+01 0.000000000000000000e+00 +3.552000000000000313e+01 0.000000000000000000e+00 +3.553000000000000114e+01 0.000000000000000000e+00 +3.553999999999999915e+01 0.000000000000000000e+00 +3.555000000000000426e+01 0.000000000000000000e+00 +3.556000000000000227e+01 0.000000000000000000e+00 +3.557000000000000028e+01 0.000000000000000000e+00 +3.557999999999999829e+01 0.000000000000000000e+00 +3.559000000000000341e+01 -0.000000000000000000e+00 +3.560000000000000142e+01 -0.000000000000000000e+00 +3.560999999999999943e+01 -0.000000000000000000e+00 +3.561999999999999744e+01 -0.000000000000000000e+00 +3.563000000000000256e+01 -0.000000000000000000e+00 +3.564000000000000057e+01 -0.000000000000000000e+00 +3.564999999999999858e+01 -0.000000000000000000e+00 +3.566000000000000369e+01 -0.000000000000000000e+00 +3.567000000000000171e+01 -0.000000000000000000e+00 +3.567999999999999972e+01 -0.000000000000000000e+00 +3.568999999999999773e+01 -0.000000000000000000e+00 +3.570000000000000284e+01 -0.000000000000000000e+00 +3.571000000000000085e+01 -0.000000000000000000e+00 +3.571999999999999886e+01 -0.000000000000000000e+00 +3.573000000000000398e+01 -0.000000000000000000e+00 +3.574000000000000199e+01 -0.000000000000000000e+00 +3.575000000000000000e+01 -0.000000000000000000e+00 +3.575999999999999801e+01 -0.000000000000000000e+00 +3.577000000000000313e+01 -0.000000000000000000e+00 +3.578000000000000114e+01 -0.000000000000000000e+00 +3.578999999999999915e+01 -0.000000000000000000e+00 +3.580000000000000426e+01 -0.000000000000000000e+00 +3.581000000000000227e+01 -0.000000000000000000e+00 +3.582000000000000028e+01 -0.000000000000000000e+00 +3.582999999999999829e+01 -0.000000000000000000e+00 +3.584000000000000341e+01 -0.000000000000000000e+00 +3.585000000000000142e+01 -0.000000000000000000e+00 +3.585999999999999943e+01 -0.000000000000000000e+00 +3.586999999999999744e+01 -0.000000000000000000e+00 +3.588000000000000256e+01 -0.000000000000000000e+00 +3.589000000000000057e+01 -0.000000000000000000e+00 +3.589999999999999858e+01 -0.000000000000000000e+00 +3.591000000000000369e+01 -0.000000000000000000e+00 +3.592000000000000171e+01 -0.000000000000000000e+00 +3.592999999999999972e+01 -0.000000000000000000e+00 +3.593999999999999773e+01 -0.000000000000000000e+00 +3.595000000000000284e+01 -0.000000000000000000e+00 +3.596000000000000085e+01 -0.000000000000000000e+00 +3.596999999999999886e+01 -0.000000000000000000e+00 +3.598000000000000398e+01 -0.000000000000000000e+00 +3.599000000000000199e+01 -0.000000000000000000e+00 +3.600000000000000000e+01 -0.000000000000000000e+00 +3.600999999999999801e+01 -0.000000000000000000e+00 +3.602000000000000313e+01 -0.000000000000000000e+00 +3.603000000000000114e+01 -0.000000000000000000e+00 +3.603999999999999915e+01 -0.000000000000000000e+00 +3.605000000000000426e+01 -0.000000000000000000e+00 +3.606000000000000227e+01 -0.000000000000000000e+00 +3.607000000000000028e+01 -0.000000000000000000e+00 +3.607999999999999829e+01 -0.000000000000000000e+00 +3.609000000000000341e+01 -0.000000000000000000e+00 +3.610000000000000142e+01 -0.000000000000000000e+00 +3.610999999999999943e+01 -0.000000000000000000e+00 +3.611999999999999744e+01 -0.000000000000000000e+00 +3.613000000000000256e+01 -0.000000000000000000e+00 +3.614000000000000057e+01 -0.000000000000000000e+00 +3.614999999999999858e+01 -0.000000000000000000e+00 +3.616000000000000369e+01 -0.000000000000000000e+00 +3.617000000000000171e+01 -0.000000000000000000e+00 +3.617999999999999972e+01 -0.000000000000000000e+00 +3.618999999999999773e+01 -0.000000000000000000e+00 +3.620000000000000284e+01 -0.000000000000000000e+00 +3.621000000000000085e+01 -0.000000000000000000e+00 +3.621999999999999886e+01 -0.000000000000000000e+00 +3.623000000000000398e+01 -0.000000000000000000e+00 +3.624000000000000199e+01 -0.000000000000000000e+00 +3.625000000000000000e+01 -0.000000000000000000e+00 +3.625999999999999801e+01 0.000000000000000000e+00 +3.627000000000000313e+01 0.000000000000000000e+00 +3.628000000000000114e+01 0.000000000000000000e+00 +3.628999999999999915e+01 0.000000000000000000e+00 +3.630000000000000426e+01 0.000000000000000000e+00 +3.631000000000000227e+01 0.000000000000000000e+00 +3.632000000000000028e+01 0.000000000000000000e+00 +3.632999999999999829e+01 0.000000000000000000e+00 +3.634000000000000341e+01 0.000000000000000000e+00 +3.635000000000000142e+01 0.000000000000000000e+00 +3.635999999999999943e+01 0.000000000000000000e+00 +3.636999999999999744e+01 0.000000000000000000e+00 +3.638000000000000256e+01 0.000000000000000000e+00 +3.639000000000000057e+01 0.000000000000000000e+00 +3.639999999999999858e+01 0.000000000000000000e+00 +3.641000000000000369e+01 0.000000000000000000e+00 +3.642000000000000171e+01 0.000000000000000000e+00 +3.642999999999999972e+01 0.000000000000000000e+00 +3.643999999999999773e+01 0.000000000000000000e+00 +3.645000000000000284e+01 0.000000000000000000e+00 +3.646000000000000085e+01 0.000000000000000000e+00 +3.646999999999999886e+01 0.000000000000000000e+00 +3.648000000000000398e+01 0.000000000000000000e+00 +3.649000000000000199e+01 -0.000000000000000000e+00 +3.650000000000000000e+01 -0.000000000000000000e+00 +3.650999999999999801e+01 -0.000000000000000000e+00 +3.652000000000000313e+01 -0.000000000000000000e+00 +3.653000000000000114e+01 -0.000000000000000000e+00 +3.653999999999999915e+01 -0.000000000000000000e+00 +3.655000000000000426e+01 -0.000000000000000000e+00 +3.656000000000000227e+01 -0.000000000000000000e+00 +3.657000000000000028e+01 -0.000000000000000000e+00 +3.657999999999999829e+01 -0.000000000000000000e+00 +3.659000000000000341e+01 -0.000000000000000000e+00 +3.660000000000000142e+01 -0.000000000000000000e+00 +3.660999999999999943e+01 -0.000000000000000000e+00 +3.661999999999999744e+01 0.000000000000000000e+00 +3.663000000000000256e+01 0.000000000000000000e+00 +3.664000000000000057e+01 0.000000000000000000e+00 +3.664999999999999858e+01 0.000000000000000000e+00 +3.666000000000000369e+01 0.000000000000000000e+00 +3.667000000000000171e+01 0.000000000000000000e+00 +3.667999999999999972e+01 0.000000000000000000e+00 +3.668999999999999773e+01 0.000000000000000000e+00 +3.670000000000000284e+01 0.000000000000000000e+00 +3.671000000000000085e+01 0.000000000000000000e+00 +3.671999999999999886e+01 0.000000000000000000e+00 +3.673000000000000398e+01 0.000000000000000000e+00 +3.674000000000000199e+01 0.000000000000000000e+00 +3.675000000000000000e+01 0.000000000000000000e+00 +3.675999999999999801e+01 0.000000000000000000e+00 +3.677000000000000313e+01 0.000000000000000000e+00 +3.678000000000000114e+01 0.000000000000000000e+00 +3.678999999999999915e+01 0.000000000000000000e+00 +3.680000000000000426e+01 -0.000000000000000000e+00 +3.681000000000000227e+01 -0.000000000000000000e+00 +3.682000000000000028e+01 -0.000000000000000000e+00 +3.682999999999999829e+01 -0.000000000000000000e+00 +3.684000000000000341e+01 -0.000000000000000000e+00 +3.685000000000000142e+01 -0.000000000000000000e+00 +3.685999999999999943e+01 -0.000000000000000000e+00 +3.686999999999999744e+01 -0.000000000000000000e+00 +3.688000000000000256e+01 -0.000000000000000000e+00 +3.689000000000000057e+01 -0.000000000000000000e+00 +3.689999999999999858e+01 -0.000000000000000000e+00 +3.691000000000000369e+01 -0.000000000000000000e+00 +3.692000000000000171e+01 -0.000000000000000000e+00 +3.692999999999999972e+01 -0.000000000000000000e+00 +3.693999999999999773e+01 -0.000000000000000000e+00 +3.695000000000000284e+01 -0.000000000000000000e+00 +3.696000000000000085e+01 -0.000000000000000000e+00 +3.696999999999999886e+01 -0.000000000000000000e+00 +3.698000000000000398e+01 -0.000000000000000000e+00 +3.699000000000000199e+01 -0.000000000000000000e+00 +3.700000000000000000e+01 -0.000000000000000000e+00 +3.700999999999999801e+01 -0.000000000000000000e+00 +3.702000000000000313e+01 -0.000000000000000000e+00 +3.703000000000000114e+01 -0.000000000000000000e+00 +3.703999999999999915e+01 -0.000000000000000000e+00 +3.705000000000000426e+01 -0.000000000000000000e+00 +3.706000000000000227e+01 -0.000000000000000000e+00 +3.707000000000000028e+01 -0.000000000000000000e+00 +3.707999999999999829e+01 -0.000000000000000000e+00 +3.709000000000000341e+01 -0.000000000000000000e+00 +3.710000000000000142e+01 -0.000000000000000000e+00 +3.710999999999999943e+01 -0.000000000000000000e+00 +3.711999999999999744e+01 -0.000000000000000000e+00 +3.713000000000000256e+01 0.000000000000000000e+00 +3.714000000000000057e+01 0.000000000000000000e+00 +3.714999999999999858e+01 0.000000000000000000e+00 +3.716000000000000369e+01 0.000000000000000000e+00 +3.717000000000000171e+01 0.000000000000000000e+00 +3.717999999999999972e+01 0.000000000000000000e+00 +3.718999999999999773e+01 0.000000000000000000e+00 +3.720000000000000284e+01 0.000000000000000000e+00 +3.721000000000000085e+01 0.000000000000000000e+00 +3.721999999999999886e+01 0.000000000000000000e+00 +3.723000000000000398e+01 0.000000000000000000e+00 +3.724000000000000199e+01 0.000000000000000000e+00 +3.725000000000000000e+01 0.000000000000000000e+00 +3.725999999999999801e+01 0.000000000000000000e+00 +3.727000000000000313e+01 0.000000000000000000e+00 +3.728000000000000114e+01 0.000000000000000000e+00 +3.728999999999999915e+01 0.000000000000000000e+00 +3.730000000000000426e+01 0.000000000000000000e+00 +3.731000000000000227e+01 0.000000000000000000e+00 +3.732000000000000028e+01 0.000000000000000000e+00 +3.732999999999999829e+01 0.000000000000000000e+00 +3.734000000000000341e+01 0.000000000000000000e+00 +3.735000000000000142e+01 0.000000000000000000e+00 +3.735999999999999943e+01 0.000000000000000000e+00 +3.736999999999999744e+01 0.000000000000000000e+00 +3.738000000000000256e+01 0.000000000000000000e+00 +3.739000000000000057e+01 0.000000000000000000e+00 +3.739999999999999858e+01 0.000000000000000000e+00 +3.741000000000000369e+01 0.000000000000000000e+00 +3.742000000000000171e+01 0.000000000000000000e+00 +3.742999999999999972e+01 0.000000000000000000e+00 +3.743999999999999773e+01 0.000000000000000000e+00 +3.745000000000000284e+01 0.000000000000000000e+00 +3.746000000000000085e+01 0.000000000000000000e+00 +3.746999999999999886e+01 0.000000000000000000e+00 +3.748000000000000398e+01 0.000000000000000000e+00 +3.749000000000000199e+01 0.000000000000000000e+00 +3.750000000000000000e+01 0.000000000000000000e+00 +3.750999999999999801e+01 0.000000000000000000e+00 +3.752000000000000313e+01 0.000000000000000000e+00 +3.753000000000000114e+01 0.000000000000000000e+00 +3.753999999999999915e+01 0.000000000000000000e+00 +3.755000000000000426e+01 0.000000000000000000e+00 +3.756000000000000227e+01 0.000000000000000000e+00 +3.757000000000000028e+01 0.000000000000000000e+00 +3.757999999999999829e+01 0.000000000000000000e+00 +3.759000000000000341e+01 0.000000000000000000e+00 +3.760000000000000142e+01 0.000000000000000000e+00 +3.760999999999999943e+01 0.000000000000000000e+00 +3.761999999999999744e+01 0.000000000000000000e+00 +3.763000000000000256e+01 0.000000000000000000e+00 +3.764000000000000057e+01 0.000000000000000000e+00 +3.764999999999999858e+01 0.000000000000000000e+00 +3.766000000000000369e+01 0.000000000000000000e+00 +3.767000000000000171e+01 0.000000000000000000e+00 +3.767999999999999972e+01 0.000000000000000000e+00 +3.768999999999999773e+01 0.000000000000000000e+00 +3.770000000000000284e+01 0.000000000000000000e+00 +3.771000000000000085e+01 0.000000000000000000e+00 +3.771999999999999886e+01 0.000000000000000000e+00 +3.773000000000000398e+01 0.000000000000000000e+00 +3.774000000000000199e+01 0.000000000000000000e+00 +3.775000000000000000e+01 0.000000000000000000e+00 +3.775999999999999801e+01 0.000000000000000000e+00 +3.777000000000000313e+01 0.000000000000000000e+00 +3.778000000000000114e+01 0.000000000000000000e+00 +3.778999999999999915e+01 -0.000000000000000000e+00 +3.780000000000000426e+01 -0.000000000000000000e+00 +3.781000000000000227e+01 -0.000000000000000000e+00 +3.782000000000000028e+01 -0.000000000000000000e+00 +3.782999999999999829e+01 -0.000000000000000000e+00 +3.784000000000000341e+01 -0.000000000000000000e+00 +3.785000000000000142e+01 -0.000000000000000000e+00 +3.785999999999999943e+01 -0.000000000000000000e+00 +3.786999999999999744e+01 -0.000000000000000000e+00 +3.788000000000000256e+01 -0.000000000000000000e+00 +3.789000000000000057e+01 -0.000000000000000000e+00 +3.789999999999999858e+01 -0.000000000000000000e+00 +3.791000000000000369e+01 -0.000000000000000000e+00 +3.792000000000000171e+01 -0.000000000000000000e+00 +3.792999999999999972e+01 -0.000000000000000000e+00 +3.793999999999999773e+01 -0.000000000000000000e+00 +3.795000000000000284e+01 -0.000000000000000000e+00 +3.796000000000000085e+01 -0.000000000000000000e+00 +3.796999999999999886e+01 -0.000000000000000000e+00 +3.798000000000000398e+01 -0.000000000000000000e+00 +3.799000000000000199e+01 -0.000000000000000000e+00 +3.800000000000000000e+01 -0.000000000000000000e+00 +3.800999999999999801e+01 -0.000000000000000000e+00 +3.802000000000000313e+01 -0.000000000000000000e+00 +3.803000000000000114e+01 -0.000000000000000000e+00 +3.803999999999999915e+01 -0.000000000000000000e+00 +3.805000000000000426e+01 -0.000000000000000000e+00 +3.806000000000000227e+01 -0.000000000000000000e+00 +3.807000000000000028e+01 -0.000000000000000000e+00 +3.807999999999999829e+01 -0.000000000000000000e+00 +3.809000000000000341e+01 -0.000000000000000000e+00 +3.810000000000000142e+01 -0.000000000000000000e+00 +3.810999999999999943e+01 -0.000000000000000000e+00 +3.811999999999999744e+01 0.000000000000000000e+00 +3.813000000000000256e+01 0.000000000000000000e+00 +3.814000000000000057e+01 0.000000000000000000e+00 +3.814999999999999858e+01 0.000000000000000000e+00 +3.816000000000000369e+01 0.000000000000000000e+00 +3.817000000000000171e+01 0.000000000000000000e+00 +3.817999999999999972e+01 0.000000000000000000e+00 +3.818999999999999773e+01 0.000000000000000000e+00 +3.820000000000000284e+01 0.000000000000000000e+00 +3.821000000000000085e+01 0.000000000000000000e+00 +3.821999999999999886e+01 0.000000000000000000e+00 +3.823000000000000398e+01 0.000000000000000000e+00 +3.824000000000000199e+01 0.000000000000000000e+00 +3.825000000000000000e+01 0.000000000000000000e+00 +3.825999999999999801e+01 0.000000000000000000e+00 +3.827000000000000313e+01 0.000000000000000000e+00 +3.828000000000000114e+01 0.000000000000000000e+00 +3.828999999999999915e+01 0.000000000000000000e+00 +3.830000000000000426e+01 0.000000000000000000e+00 +3.831000000000000227e+01 0.000000000000000000e+00 +3.832000000000000028e+01 0.000000000000000000e+00 +3.832999999999999829e+01 0.000000000000000000e+00 +3.834000000000000341e+01 -0.000000000000000000e+00 +3.835000000000000142e+01 -0.000000000000000000e+00 +3.835999999999999943e+01 -0.000000000000000000e+00 +3.836999999999999744e+01 -0.000000000000000000e+00 +3.838000000000000256e+01 -0.000000000000000000e+00 +3.839000000000000057e+01 -0.000000000000000000e+00 +3.839999999999999858e+01 -0.000000000000000000e+00 +3.841000000000000369e+01 -0.000000000000000000e+00 +3.842000000000000171e+01 -0.000000000000000000e+00 +3.842999999999999972e+01 -0.000000000000000000e+00 +3.843999999999999773e+01 -0.000000000000000000e+00 +3.845000000000000284e+01 -0.000000000000000000e+00 +3.846000000000000085e+01 -0.000000000000000000e+00 +3.846999999999999886e+01 -0.000000000000000000e+00 +3.848000000000000398e+01 -0.000000000000000000e+00 +3.849000000000000199e+01 -0.000000000000000000e+00 +3.850000000000000000e+01 -0.000000000000000000e+00 +3.850999999999999801e+01 -0.000000000000000000e+00 +3.852000000000000313e+01 -0.000000000000000000e+00 +3.853000000000000114e+01 -0.000000000000000000e+00 +3.853999999999999915e+01 -0.000000000000000000e+00 +3.855000000000000426e+01 -0.000000000000000000e+00 +3.856000000000000227e+01 -0.000000000000000000e+00 +3.857000000000000028e+01 -0.000000000000000000e+00 +3.857999999999999829e+01 -0.000000000000000000e+00 +3.859000000000000341e+01 -0.000000000000000000e+00 +3.860000000000000142e+01 -0.000000000000000000e+00 +3.860999999999999943e+01 -0.000000000000000000e+00 +3.861999999999999744e+01 -0.000000000000000000e+00 +3.863000000000000256e+01 -0.000000000000000000e+00 +3.864000000000000057e+01 -0.000000000000000000e+00 +3.864999999999999858e+01 -0.000000000000000000e+00 +3.866000000000000369e+01 -0.000000000000000000e+00 +3.867000000000000171e+01 0.000000000000000000e+00 +3.867999999999999972e+01 0.000000000000000000e+00 +3.868999999999999773e+01 0.000000000000000000e+00 +3.870000000000000284e+01 0.000000000000000000e+00 +3.871000000000000085e+01 0.000000000000000000e+00 +3.871999999999999886e+01 0.000000000000000000e+00 +3.873000000000000398e+01 0.000000000000000000e+00 +3.874000000000000199e+01 0.000000000000000000e+00 +3.875000000000000000e+01 0.000000000000000000e+00 +3.875999999999999801e+01 0.000000000000000000e+00 +3.877000000000000313e+01 0.000000000000000000e+00 +3.878000000000000114e+01 0.000000000000000000e+00 +3.878999999999999915e+01 0.000000000000000000e+00 +3.880000000000000426e+01 0.000000000000000000e+00 +3.881000000000000227e+01 0.000000000000000000e+00 +3.882000000000000028e+01 0.000000000000000000e+00 +3.882999999999999829e+01 0.000000000000000000e+00 +3.884000000000000341e+01 0.000000000000000000e+00 +3.885000000000000142e+01 0.000000000000000000e+00 +3.885999999999999943e+01 0.000000000000000000e+00 +3.886999999999999744e+01 0.000000000000000000e+00 +3.888000000000000256e+01 0.000000000000000000e+00 +3.889000000000000057e+01 0.000000000000000000e+00 +3.889999999999999858e+01 0.000000000000000000e+00 +3.891000000000000369e+01 0.000000000000000000e+00 +3.892000000000000171e+01 0.000000000000000000e+00 +3.892999999999999972e+01 0.000000000000000000e+00 +3.893999999999999773e+01 0.000000000000000000e+00 +3.895000000000000284e+01 0.000000000000000000e+00 +3.896000000000000085e+01 0.000000000000000000e+00 +3.896999999999999886e+01 0.000000000000000000e+00 +3.898000000000000398e+01 0.000000000000000000e+00 +3.899000000000000199e+01 0.000000000000000000e+00 +3.900000000000000000e+01 0.000000000000000000e+00 +3.900999999999999801e+01 0.000000000000000000e+00 +3.902000000000000313e+01 0.000000000000000000e+00 +3.903000000000000114e+01 0.000000000000000000e+00 +3.903999999999999915e+01 0.000000000000000000e+00 +3.905000000000000426e+01 0.000000000000000000e+00 +3.906000000000000227e+01 0.000000000000000000e+00 +3.907000000000000028e+01 0.000000000000000000e+00 +3.907999999999999829e+01 0.000000000000000000e+00 +3.909000000000000341e+01 0.000000000000000000e+00 +3.910000000000000142e+01 0.000000000000000000e+00 +3.910999999999999943e+01 0.000000000000000000e+00 +3.911999999999999744e+01 0.000000000000000000e+00 +3.913000000000000256e+01 0.000000000000000000e+00 +3.914000000000000057e+01 0.000000000000000000e+00 +3.914999999999999858e+01 0.000000000000000000e+00 +3.916000000000000369e+01 0.000000000000000000e+00 +3.917000000000000171e+01 0.000000000000000000e+00 +3.917999999999999972e+01 0.000000000000000000e+00 +3.918999999999999773e+01 -0.000000000000000000e+00 +3.920000000000000284e+01 -0.000000000000000000e+00 +3.921000000000000085e+01 -0.000000000000000000e+00 +3.921999999999999886e+01 -0.000000000000000000e+00 +3.923000000000000398e+01 -0.000000000000000000e+00 +3.924000000000000199e+01 -0.000000000000000000e+00 +3.925000000000000000e+01 -0.000000000000000000e+00 +3.925999999999999801e+01 -0.000000000000000000e+00 +3.927000000000000313e+01 -0.000000000000000000e+00 +3.928000000000000114e+01 -0.000000000000000000e+00 +3.928999999999999915e+01 -0.000000000000000000e+00 +3.930000000000000426e+01 -0.000000000000000000e+00 +3.931000000000000227e+01 -0.000000000000000000e+00 +3.932000000000000028e+01 -0.000000000000000000e+00 +3.932999999999999829e+01 -0.000000000000000000e+00 +3.934000000000000341e+01 -0.000000000000000000e+00 +3.935000000000000142e+01 -0.000000000000000000e+00 +3.935999999999999943e+01 -0.000000000000000000e+00 +3.936999999999999744e+01 -0.000000000000000000e+00 +3.938000000000000256e+01 -0.000000000000000000e+00 +3.939000000000000057e+01 -0.000000000000000000e+00 +3.939999999999999858e+01 -0.000000000000000000e+00 +3.941000000000000369e+01 -0.000000000000000000e+00 +3.942000000000000171e+01 -0.000000000000000000e+00 +3.942999999999999972e+01 0.000000000000000000e+00 +3.943999999999999773e+01 0.000000000000000000e+00 +3.945000000000000284e+01 0.000000000000000000e+00 +3.946000000000000085e+01 0.000000000000000000e+00 +3.946999999999999886e+01 0.000000000000000000e+00 +3.948000000000000398e+01 0.000000000000000000e+00 +3.949000000000000199e+01 0.000000000000000000e+00 +3.950000000000000000e+01 0.000000000000000000e+00 +3.950999999999999801e+01 0.000000000000000000e+00 +3.952000000000000313e+01 0.000000000000000000e+00 +3.953000000000000114e+01 0.000000000000000000e+00 +3.953999999999999915e+01 0.000000000000000000e+00 +3.955000000000000426e+01 0.000000000000000000e+00 +3.956000000000000227e+01 0.000000000000000000e+00 +3.957000000000000028e+01 0.000000000000000000e+00 +3.957999999999999829e+01 0.000000000000000000e+00 +3.959000000000000341e+01 0.000000000000000000e+00 +3.960000000000000142e+01 0.000000000000000000e+00 +3.960999999999999943e+01 0.000000000000000000e+00 +3.961999999999999744e+01 0.000000000000000000e+00 +3.963000000000000256e+01 0.000000000000000000e+00 +3.964000000000000057e+01 0.000000000000000000e+00 +3.964999999999999858e+01 0.000000000000000000e+00 +3.966000000000000369e+01 0.000000000000000000e+00 +3.967000000000000171e+01 0.000000000000000000e+00 +3.967999999999999972e+01 0.000000000000000000e+00 +3.968999999999999773e+01 0.000000000000000000e+00 +3.970000000000000284e+01 0.000000000000000000e+00 +3.971000000000000085e+01 0.000000000000000000e+00 +3.971999999999999886e+01 -0.000000000000000000e+00 +3.973000000000000398e+01 -0.000000000000000000e+00 +3.974000000000000199e+01 -0.000000000000000000e+00 +3.975000000000000000e+01 -0.000000000000000000e+00 +3.975999999999999801e+01 -0.000000000000000000e+00 +3.977000000000000313e+01 -0.000000000000000000e+00 +3.978000000000000114e+01 -0.000000000000000000e+00 +3.978999999999999915e+01 -0.000000000000000000e+00 +3.980000000000000426e+01 -0.000000000000000000e+00 +3.981000000000000227e+01 -0.000000000000000000e+00 +3.982000000000000028e+01 -0.000000000000000000e+00 +3.982999999999999829e+01 -0.000000000000000000e+00 +3.984000000000000341e+01 -0.000000000000000000e+00 +3.985000000000000142e+01 -0.000000000000000000e+00 +3.985999999999999943e+01 -0.000000000000000000e+00 +3.986999999999999744e+01 -0.000000000000000000e+00 +3.988000000000000256e+01 -0.000000000000000000e+00 +3.989000000000000057e+01 -0.000000000000000000e+00 +3.989999999999999858e+01 -0.000000000000000000e+00 +3.991000000000000369e+01 -0.000000000000000000e+00 +3.992000000000000171e+01 -0.000000000000000000e+00 +3.992999999999999972e+01 -0.000000000000000000e+00 +3.993999999999999773e+01 -0.000000000000000000e+00 +3.995000000000000284e+01 -0.000000000000000000e+00 +3.996000000000000085e+01 -0.000000000000000000e+00 +3.996999999999999886e+01 -0.000000000000000000e+00 +3.998000000000000398e+01 -0.000000000000000000e+00 +3.999000000000000199e+01 -0.000000000000000000e+00 diff --git a/tests/testdata/squeeze_morph.cgr b/tests/testdata/squeeze_morph.cgr new file mode 100644 index 00000000..cc7799b9 --- /dev/null +++ b/tests/testdata/squeeze_morph.cgr @@ -0,0 +1,105 @@ +# PDF created by diffpy.morph +# from PATH + +# Labels: [r] [gr] +0.000000000000000000e+00 0.000000000000000000e+00 +1.000000000000000056e-01 2.016607210740701817e-01 +2.000000000000000111e-01 4.012816425967311584e-01 +3.000000000000000444e-01 5.968384836782407721e-01 +4.000000000000000222e-01 7.863460390718853832e-01 +5.000000000000000000e-01 9.678774221035963965e-01 +6.000000000000000888e-01 1.139582805695501078e+00 +7.000000000000000666e-01 1.299707497430252046e+00 +8.000000000000000444e-01 1.446609189174991705e+00 +9.000000000000000222e-01 1.578774227495413296e+00 +1.000000000000000000e+00 1.694832757920656352e+00 +1.100000000000000089e+00 1.793572604043012886e+00 +1.200000000000000178e+00 1.873951751421987222e+00 +1.300000000000000044e+00 1.935109316274401969e+00 +1.400000000000000133e+00 1.976374889929940482e+00 +1.500000000000000000e+00 1.997276161968231323e+00 +1.600000000000000089e+00 1.997544737777092294e+00 +1.700000000000000178e+00 1.977120079923743390e+00 +1.800000000000000044e+00 1.936151517147448820e+00 +1.900000000000000133e+00 1.874998279892714503e+00 +2.000000000000000000e+00 1.794227537029879693e+00 +2.100000000000000089e+00 1.694610424671280313e+00 +2.200000000000000178e+00 1.577116074695904757e+00 +2.300000000000000266e+00 1.442903667646756372e+00 +2.400000000000000355e+00 1.293312551959283851e+00 +2.500000000000000000e+00 1.129850488905959738e+00 +2.600000000000000089e+00 9.541801000842509151e-01 +2.700000000000000178e+00 7.681036116097271771e-01 +2.800000000000000266e+00 5.735460062730138864e-01 +2.900000000000000355e+00 3.725367116437122150e-01 +3.000000000000000000e+00 1.671899683154590699e-01 +3.100000000000000089e+00 -4.031596196150075834e-02 +3.200000000000000178e+00 -2.477605737698468646e-01 +3.300000000000000266e+00 -4.529036928636547832e-01 +3.400000000000000355e+00 -6.535086474160737291e-01 +3.500000000000000000e+00 -8.473658233427887598e-01 +3.600000000000000089e+00 -1.032316381403495242e+00 +3.700000000000000178e+00 -1.206275905404040172e+00 +3.800000000000000266e+00 -1.367257744179736667e+00 +3.900000000000000355e+00 -1.513395805283929141e+00 +4.000000000000000000e+00 -1.642966555577477061e+00 +4.100000000000000533e+00 -1.754409983348725222e+00 +4.200000000000000178e+00 -1.846349278313989206e+00 +4.299999999999999822e+00 -1.917608989968017763e+00 +4.400000000000000355e+00 -1.967231431369953931e+00 +4.500000000000000000e+00 -1.994491104644685819e+00 +4.600000000000000533e+00 -1.998906936314116090e+00 +4.700000000000000178e+00 -1.980252125089067672e+00 +4.800000000000000711e+00 -1.938561421967258891e+00 +4.900000000000000355e+00 -1.874135682387076951e+00 +5.000000000000000000e+00 -1.787543552743151798e+00 +5.100000000000000533e+00 -1.679620178709657630e+00 +5.200000000000000178e+00 -1.551462850439542906e+00 +5.300000000000000711e+00 -1.404423529676374072e+00 +5.400000000000000355e+00 -1.240098235957646233e+00 +5.500000000000000000e+00 -1.060313303193321621e+00 +5.600000000000000533e+00 -8.671085537216786099e-01 +5.700000000000000178e+00 -6.627174741864847451e-01 +5.800000000000000711e+00 -4.495445159157776538e-01 +5.900000000000000355e+00 -2.301396815438895571e-01 +6.000000000000000000e+00 -7.170598996826864358e-03 +6.100000000000000533e+00 2.166076767888532317e-01 +6.200000000000000178e+00 4.383848554024750710e-01 +6.300000000000000711e+00 6.553292792208245121e-01 +6.400000000000000355e+00 8.646231160092439083e-01 +6.500000000000000000e+00 1.063498489850685624e+00 +6.600000000000000533e+00 1.249274133578965218e+00 +6.700000000000000178e+00 1.419392118491213939e+00 +6.800000000000000711e+00 1.571454193726408821e+00 +6.900000000000000355e+00 1.703257248921869360e+00 +7.000000000000000000e+00 1.812827400185563764e+00 +7.100000000000000533e+00 1.898452191616431639e+00 +7.200000000000000178e+00 1.958710403102522868e+00 +7.300000000000000711e+00 1.992498960420514109e+00 +7.400000000000000355e+00 1.999056456187634501e+00 +7.500000000000000000e+00 1.977982810349711684e+00 +7.600000000000000533e+00 1.929254626918742277e+00 +7.700000000000000178e+00 1.853235839800372542e+00 +7.800000000000000711e+00 1.750683284871877854e+00 +7.900000000000000355e+00 1.622746887964007678e+00 +8.000000000000000000e+00 1.470964218916802180e+00 +8.099999999999999645e+00 1.297249230133007636e+00 +8.200000000000001066e+00 1.103875073606781942e+00 +8.300000000000000711e+00 8.934509726687409614e-01 +8.400000000000000355e+00 6.688932129054430131e-01 +8.500000000000000000e+00 4.333904099623434036e-01 +8.599999999999999645e+00 1.903633091336342231e-01 +8.700000000000001066e+00 -5.658052847403799435e-02 +8.800000000000000711e+00 -3.036966972619735139e-01 +8.900000000000000355e+00 -5.471580191460774234e-01 +9.000000000000000000e+00 -7.831120606064566614e-01 +9.099999999999999645e+00 -1.007741344138793016e+00 +9.200000000000001066e+00 -1.217325414256249960e+00 +9.300000000000000711e+00 -1.408303836788730168e+00 +9.400000000000000355e+00 -1.577339138701817634e+00 +9.500000000000000000e+00 -1.721378636094831327e+00 +9.600000000000001421e+00 -1.837714052498993222e+00 +9.700000000000001066e+00 -1.924037800077388338e+00 +9.800000000000000711e+00 -1.978494784713575205e+00 +9.900000000000000355e+00 -1.999728603987454667e+00 +1.000000000000000000e+01 -1.986921036185803846e+00 diff --git a/tests/testdata/squeeze_target.cgr b/tests/testdata/squeeze_target.cgr new file mode 100644 index 00000000..1474409a --- /dev/null +++ b/tests/testdata/squeeze_target.cgr @@ -0,0 +1,128 @@ +# PDF created by diffpy.morph +# from PATH + +# Input morphing parameters: +# scale = 2.0 +# stretch = None +# smear = None +# hshift = None +# vshift = None +# squeeze a0 = 0.0 +# squeeze a1 = -0.001 +# squeeze a2 = -0.0001 +# squeeze a3 = 0.0001 + +# Optimized morphing parameters: +# xmin = 0.000000 +# xmax = 10.100000 +# xstep = 0.100000 +# scale = 0.500000 +# squeeze a0 = 0.000000 +# squeeze a1 = 0.010000 +# squeeze a2 = 0.000100 +# squeeze a3 = 0.001000 +# Rw = 0.000000 +# Pearson = 1.000000 + +# Labels: [r] [gr] +0.000000000000000000e+00 -8.357788796904224253e-08 +1.000000000000000056e-01 9.983335989539958433e-02 +2.000000000000000111e-01 1.986692882755068390e-01 +3.000000000000000444e-01 2.955201900777184587e-01 +4.000000000000000222e-01 3.894183455897525792e-01 +5.000000000000000000e-01 4.794255628338816577e-01 +6.000000000000000888e-01 5.646425163401342928e-01 +7.000000000000000666e-01 6.442177472575285613e-01 +8.000000000000000444e-01 7.173561656390742280e-01 +9.000000000000000222e-01 7.833269965082827468e-01 +1.000000000000000000e+00 8.414710809423141535e-01 +1.100000000000000089e+00 8.912074623687431529e-01 +1.200000000000000178e+00 9.320391912438557025e-01 +1.300000000000000044e+00 9.635582904389520253e-01 +1.400000000000000133e+00 9.854498316195489105e-01 +1.500000000000000000e+00 9.974950819180453676e-01 +1.600000000000000089e+00 9.995736894484723578e-01 +1.700000000000000178e+00 9.916648858278295231e-01 +1.800000000000000044e+00 9.738476936863433853e-01 +1.900000000000000133e+00 9.463001370918723287e-01 +2.000000000000000000e+00 9.092974627759751183e-01 +2.100000000000000089e+00 8.632093899332391462e-01 +2.200000000000000178e+00 8.084964160720563564e-01 +2.300000000000000266e+00 7.457052158273517195e-01 +2.400000000000000355e+00 6.754631787095541906e-01 +2.500000000000000000e+00 5.984721403688244568e-01 +2.600000000000000089e+00 5.155013700132252685e-01 +2.700000000000000178e+00 4.273798840535988908e-01 +2.800000000000000266e+00 3.349881627820611163e-01 +2.900000000000000355e+00 2.392493528578337192e-01 +3.000000000000000000e+00 1.411200435139138010e-01 +3.100000000000000089e+00 4.158070865920206888e-02 +3.200000000000000178e+00 -5.837408960958168080e-02 +3.300000000000000266e+00 -1.577456381872548441e-01 +3.400000000000000355e+00 -2.555410515265202354e-01 +3.500000000000000000e+00 -3.507831918753864797e-01 +3.600000000000000089e+00 -4.425204320563480009e-01 +3.700000000000000178e+00 -5.298361632374190000e-01 +3.800000000000000266e+00 -6.118579527020228115e-01 +3.900000000000000355e+00 -6.877662601339329385e-01 +4.000000000000000000e+00 -7.568026253602615494e-01 +4.100000000000000533e+00 -8.182772483416952403e-01 +4.200000000000000178e+00 -8.715758921842486906e-01 +4.299999999999999822e+00 -9.161660173828498621e-01 +4.400000000000000355e+00 -9.516021002227514902e-01 +4.500000000000000000e+00 -9.775300836040233809e-01 +4.600000000000000533e+00 -9.936909136186475866e-01 +4.700000000000000178e+00 -9.999231265841722616e-01 +4.800000000000000711e+00 -9.961644607670143703e-01 +4.900000000000000355e+00 -9.824524768209257353e-01 +5.000000000000000000e+00 -9.589241809225684809e-01 +5.100000000000000533e+00 -9.258146546047605341e-01 +5.200000000000000178e+00 -8.834547052655963295e-01 +5.300000000000000711e+00 -8.322675611647437632e-01 +5.400000000000000355e+00 -7.727646443038580504e-01 +5.500000000000000000e+00 -7.055404651441096187e-01 +5.600000000000000533e+00 -6.312667151091209128e-01 +5.700000000000000178e+00 -5.506855493720435035e-01 +5.800000000000000711e+00 -4.646021351237333841e-01 +5.900000000000000355e+00 -3.738766024924461973e-01 +6.000000000000000000e+00 -2.794154497218503952e-01 +6.100000000000000533e+00 -1.821624876417017036e-01 +6.200000000000000178e+00 -8.308941446470229086e-02 +6.300000000000000711e+00 1.681388447947275780e-02 +6.400000000000000355e+00 1.165492148948801265e-01 +6.500000000000000000e+00 2.151200311503978224e-01 +6.600000000000000533e+00 3.115414025443001833e-01 +6.700000000000000178e+00 4.048499089995918898e-01 +6.800000000000000711e+00 4.941132660497548068e-01 +6.900000000000000355e+00 5.784396255563073463e-01 +7.000000000000000000e+00 6.569864681520779515e-01 +7.100000000000000533e+00 7.289689982084295305e-01 +7.200000000000000178e+00 7.936679588809117947e-01 +7.300000000000000711e+00 8.504367914640226234e-01 +7.400000000000000355e+00 8.987081693992005071e-01 +7.500000000000000000e+00 9.379998675576307621e-01 +7.600000000000000533e+00 9.679194196440626952e-01 +7.700000000000000178e+00 9.881679699685518292e-01 +7.800000000000000711e+00 9.985432236313553922e-01 +7.900000000000000355e+00 9.989414376611046587e-01 +8.000000000000000000e+00 9.893584389332742424e-01 +8.099999999999999645e+00 9.698898327615692594e-01 +8.200000000000001066e+00 9.407303515736493704e-01 +8.300000000000000711e+00 9.021715336418995035e-01 +8.400000000000000355e+00 8.545987062144498880e-01 +8.500000000000000000e+00 7.984871238128524729e-01 +8.599999999999999645e+00 7.343972374542593329e-01 +8.700000000000001066e+00 6.629692383579551818e-01 +8.800000000000000711e+00 5.849170287654014144e-01 +8.900000000000000355e+00 5.010206616413290792e-01 +9.000000000000000000e+00 4.121183976640565572e-01 +9.099999999999999645e+00 3.190983923437636927e-01 +9.200000000000001066e+00 2.228899358017164267e-01 +9.300000000000000711e+00 1.244543754116841927e-01 +9.400000000000000355e+00 2.477539551689142416e-02 +9.500000000000000000e+00 -7.515108859995893453e-02 +9.600000000000001421e+00 -1.743267637418187965e-01 +9.700000000000001066e+00 -2.717606916786979854e-01 +9.800000000000000711e+00 -3.664791265996873437e-01 +9.900000000000000355e+00 -4.575357200218788112e-01 +1.000000000000000000e+01 -5.440208946101240395e-01 diff --git a/tests/testdata/testsequence/a_210K.gr b/tests/testdata/testsequence/a_210K.gr index a9932c9b..8b73d5bc 100644 --- a/tests/testdata/testsequence/a_210K.gr +++ b/tests/testdata/testsequence/a_210K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/b_204K.gr b/tests/testdata/testsequence/b_204K.gr index bfce0df5..75584763 100644 --- a/tests/testdata/testsequence/b_204K.gr +++ b/tests/testdata/testsequence/b_204K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/c_198K.gr b/tests/testdata/testsequence/c_198K.gr index 9f884651..a8fda3b3 100644 --- a/tests/testdata/testsequence/c_198K.gr +++ b/tests/testdata/testsequence/c_198K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/d_192K.gr b/tests/testdata/testsequence/d_192K.gr index bcbe7330..38083694 100644 --- a/tests/testdata/testsequence/d_192K.gr +++ b/tests/testdata/testsequence/d_192K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/e_186K.gr b/tests/testdata/testsequence/e_186K.gr index 0bcb4646..bde9e2a9 100644 --- a/tests/testdata/testsequence/e_186K.gr +++ b/tests/testdata/testsequence/e_186K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/f_180K.gr b/tests/testdata/testsequence/f_180K.gr index e0800537..af5b64f8 100644 --- a/tests/testdata/testsequence/f_180K.gr +++ b/tests/testdata/testsequence/f_180K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/g_174K.gr b/tests/testdata/testsequence/g_174K.gr index 88a2ad0b..9deb50ca 100644 --- a/tests/testdata/testsequence/g_174K.gr +++ b/tests/testdata/testsequence/g_174K.gr @@ -12,9 +12,9 @@ outputtype = gr qmaxinst = 25.0 qmin = 0.4 qmax = 25.0 -rmax = 100.0 -rmin = 0.0 -rstep = 0.01 +xmax = 100.0 +xmin = 0.0 +xstep = 0.01 rpoly = 0.7 [Misc] diff --git a/tests/testdata/testsequence/testsaving/verbose/Morph_Reference_Table.txt b/tests/testdata/testsequence/testsaving/verbose/Morph_Reference_Table.txt index c849e35f..83445d1e 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morph_Reference_Table.txt +++ b/tests/testdata/testsequence/testsaving/verbose/Morph_Reference_Table.txt @@ -11,49 +11,49 @@ # Target: f_180K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.020141 # Pearson = 0.999810 # Target: e_186K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.034859 # Pearson = 0.999424 # Target: d_192K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.062392 # Pearson = 0.998077 # Target: c_198K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.105918 # Pearson = 0.994409 # Target: b_204K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.117595 # Pearson = 0.993160 # Target: a_210K.gr # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.127100 # Pearson = 0.992111 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_a.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_a.cgr index d4ab20ff..95cba1f9 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_a.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_a.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.127100 # Pearson = 0.992111 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_b.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_b.cgr index fd039d17..ef8cf023 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_b.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_b.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.117595 # Pearson = 0.993160 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_c.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_c.cgr index 0321f80e..27ebcd00 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_c.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_c.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.105918 # Pearson = 0.994409 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_d.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_d.cgr index fa694073..8a30b321 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_d.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_d.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.062392 # Pearson = 0.998077 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_e.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_e.cgr index 5ea8d806..1ad1a45f 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_e.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_e.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.034859 # Pearson = 0.999424 diff --git a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_f.cgr b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_f.cgr index 1cf81646..32ce202b 100644 --- a/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_f.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/Morphs/mwt_f.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.020141 # Pearson = 0.999810 diff --git a/tests/testdata/testsequence/testsaving/verbose/single_verbose_morph.cgr b/tests/testdata/testsequence/testsaving/verbose/single_verbose_morph.cgr index d4ab20ff..95cba1f9 100644 --- a/tests/testdata/testsequence/testsaving/verbose/single_verbose_morph.cgr +++ b/tests/testdata/testsequence/testsaving/verbose/single_verbose_morph.cgr @@ -9,9 +9,9 @@ # vshift = None # Optimized morphing parameters: -# rmin = 0.000000 -# rmax = 100.010000 -# rstep = 0.010000 +# xmin = 0.000000 +# xmax = 100.010000 +# xstep = 0.010000 # Rw = 0.127100 # Pearson = 0.992111 diff --git a/tests/testdata/testsequence_serialfile.json b/tests/testdata/testsequence_serialfile.json index bc49ce93..834f3c1e 100644 --- a/tests/testdata/testsequence_serialfile.json +++ b/tests/testdata/testsequence_serialfile.json @@ -13,9 +13,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "b_204K.gr": { @@ -32,9 +32,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "c_198K.gr": { @@ -51,9 +51,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "d_192K.gr": { @@ -70,9 +70,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "e_186K.gr": { @@ -89,9 +89,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "f_180K.gr": { @@ -108,9 +108,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 }, "g_174K.gr": { @@ -127,9 +127,9 @@ "qmaxinst": 25.0, "qmin": 0.4, "qmax": 25.0, - "rmax": 100.0, - "rmin": 0.0, - "rstep": 0.01, + "xmax": 100.0, + "xmin": 0.0, + "xstep": 0.01, "rpoly": 0.7 } } diff --git a/tutorial/additionalData.zip b/tutorial/additionalData.zip index 66520ccf..6ea6621b 100644 Binary files a/tutorial/additionalData.zip and b/tutorial/additionalData.zip differ diff --git a/tutorial/diffpy.morph_manual.pdf b/tutorial/diffpy.morph_manual.pdf deleted file mode 100644 index 779e49f4..00000000 Binary files a/tutorial/diffpy.morph_manual.pdf and /dev/null differ diff --git a/tutorial/tutorialData.zip b/tutorial/quickstartData.zip similarity index 100% rename from tutorial/tutorialData.zip rename to tutorial/quickstartData.zip