diff --git a/.flake8 b/.flake8 index 7b2865c..88077af 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/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index fa94779..56c5fca 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -11,32 +11,33 @@ assignees: "" - [ ] All PRs/issues attached to the release are merged. - [ ] All the badges on the README are passing. - [ ] License information is verified as correct. If you are unsure, please comment below. -- [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are - missing), tutorials, and other human-written text is up-to-date with any changes in the code. -- [ ] Installation instructions in the README, documentation, and the website (e.g., diffpy.org) are updated. +- [ ] Locally rendered documentation contains all appropriate pages, tutorials, and other human-written text is up-to-date with any changes in the code. +- [ ] All API references are included. To check this, run `conda install scikit-package` and then `package build api-doc`. Review any edits made by rerendering the docs locally. +- [ ] Installation instructions in the README, documentation, and the website are updated. - [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. - [ ] Grammar and writing quality are checked (no typos). - [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. +- [ ] Dispatch matrix testing to test the release on all Python versions and systems. If you do not have permission to run this workflow, tag the maintainer and say `@maintainer, please dispatch matrix testing workflow`. -Please mention @sbillinge here when you are ready for PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: +Please tag the maintainer (e.g., @username) in the comment here when you are ready for the PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: ### PyPI/GitHub full-release preparation checklist: - [ ] Create a new conda environment and install the rc from PyPI (`pip install ==??`) - [ ] License information on PyPI is correct. -- [ ] Docs are deployed successfully to `https://www.diffpy.org/`. +- [ ] Docs are deployed successfully to `https:///`. - [ ] Successfully run all tests, tutorial examples or do functional testing. -Please let @sbillinge know that all checks are done and the package is ready for full release. +Please let the maintainer know that all checks are done and the package is ready for full release. ### conda-forge release preparation checklist: - + - [ ] Ensure that the full release has appeared on PyPI successfully. -- [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. -- [ ] Close any open issues on the feedstock. Reach out to @bobleesj if you have questions. -- [ ] Tag @sbillinge and @bobleesj for conda-forge release. +- [ ] New package dependencies listed in `conda.txt` and `tests.txt` are added to `meta.yaml` in the feedstock. +- [ ] Close any open issues on the feedstock. Reach out to the maintainer if you have questions. +- [ ] Tag the maintainer for conda-forge release. ### Post-release checklist diff --git a/.github/workflows/build-and-publish-docs-on-dispatch.yml b/.github/workflows/build-and-publish-docs-on-dispatch.yml new file mode 100644 index 0000000..a059aea --- /dev/null +++ b/.github/workflows/build-and-publish-docs-on-dispatch.yml @@ -0,0 +1,18 @@ +name: Build and Publish Docs on Dispatch + +on: + workflow_dispatch: + +jobs: + get-python-version: + uses: scikit-package/release-scripts/.github/workflows/_get-python-version-latest.yml@v0 + with: + python_version: 0 + + docs: + uses: scikit-package/release-scripts/.github/workflows/_release-docs.yml@v0 + with: + project: diffpy.labpdfproc + c_extension: false + headless: false + python_version: ${{ fromJSON(needs.get-python-version.outputs.latest_python_version) }} diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index b60acca..7f42d6d 100644 --- a/.github/workflows/build-wheel-release-upload.yml +++ b/.github/workflows/build-wheel-release-upload.yml @@ -1,4 +1,4 @@ -name: Release (GitHub/PyPI) and Deploy Docs +name: Build Wheel, Release on GitHub/PyPI, and Deploy Docs on: workflow_dispatch: @@ -7,12 +7,12 @@ on: - "*" # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml jobs: - release: - uses: Billingegroup/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 + build-release: + uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 with: project: diffpy.labpdfproc c_extension: false - github_admin_username: sbillinge + maintainer_GITHUB_username: sbillinge secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml index 3588c8a..1f2a0cc 100644 --- a/.github/workflows/check-news-item.yml +++ b/.github/workflows/check-news-item.yml @@ -7,6 +7,6 @@ on: jobs: check-news-item: - uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + uses: scikit-package/release-scripts/.github/workflows/_check-news-item.yml@v0 with: project: diffpy.labpdfproc diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml deleted file mode 100644 index 3114aa2..0000000 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: CI - -on: - push: - branches: - - main - release: - types: - - prereleased - - published - workflow_dispatch: - -jobs: - matrix-coverage: - defaults: - run: - shell: bash -l {0} - - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, windows-latest, macos-13, macos-14] - python-version: ["3.11", "3.12", "3.13"] - env: - LATEST_PYTHON_VERSION: "3.13" - steps: - - name: Check out diffpy.labpdfproc - uses: actions/checkout@v4 - - - name: Initialize miniconda - uses: conda-incubator/setup-miniconda@v3 - with: - activate-environment: test - auto-update-conda: true - environment-file: environment.yml - auto-activate-base: false - python-version: ${{ matrix.python-version }} - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.labpdfproc and requirements - run: | - conda install --file requirements/tests.txt - conda install --file requirements/conda.txt - pip install gooey - python -m pip install . --no-deps - - - name: Validate diffpy.labpdfproc - run: | - pytest --cov - coverage report -m - codecov - - - name: Upload coverage to Codecov - if: matrix.os == 'ubuntu-latest' && matrix.python-version == env.LATEST_PYTHON_VERSION - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/matrix-and-codecov.yml b/.github/workflows/matrix-and-codecov.yml new file mode 100644 index 0000000..5fb55d6 --- /dev/null +++ b/.github/workflows/matrix-and-codecov.yml @@ -0,0 +1,21 @@ +name: Matrix and Codecov + +on: + # push: + # branches: + # - main + release: + types: + - prereleased + - published + workflow_dispatch: + +jobs: + matrix-coverage: + uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.labpdfproc + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index db5cacf..7dc796d 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -1,53 +1,15 @@ name: Tests on PR on: - push: - branches: - - main pull_request: workflow_dispatch: jobs: - validate: - defaults: - run: - shell: bash -l {0} - - runs-on: ubuntu-latest - steps: - - name: Check out diffpy.labpdfproc repository - uses: actions/checkout@v4 - - - name: Initialize miniconda - uses: conda-incubator/setup-miniconda@v3 - with: - activate-environment: test - auto-update-conda: true - environment-file: environment.yml - auto-activate-base: false - python-version: 3.13 - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.labpdfproc and requirements - run: | - conda install --file requirements/tests.txt - conda install --file requirements/conda.txt - pip install gooey - python -m pip install . --no-deps - - - name: Validate diffpy.labpdfproc - run: | - pytest --cov - coverage report -m - codecov - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - verbose: true - fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} + tests-on-pr: + uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + with: + project: diffpy.labpdfproc + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index d418364..099e294 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ .Python env/ build/ +_build/ develop-eggs/ dist/ downloads/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 47f7a01..aaa8889 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/AUTHORS.rst b/AUTHORS.rst index 251218d..30b069c 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,7 +1,7 @@ Authors ======= -Billinge Group and community contributors. +Yucong Chen, Till Schertenleib, Caden Myers, Billinge Group members Contributors ------------ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 94114aa..3e10213 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,9 +1,67 @@ ============= -Release Notes +Release notes ============= .. current developments +0.3.1 +===== + +**Added:** + +* Add back support for Python 3.10 and 3.11. + + +0.3.0 +===== + +**Added:** + +* Functionalities to estimate mu*D theoretically. +* Added published reference to ``README.rst``. +* Fast calculation supports values up to muD = 7 +* Recookiecut with updated ``scikit-package`` to enable docs preview in PRs. +* Updated package standards to scikit-package 0.3.0. +* Added ``cookiecutter.json`` file for the ``package update`` command. +* Functionality to read wavelength and anode type directly from a diffpy configuration file. +* Utility and example documentation for ``tools`` module. +* Gooey support so that the app can be run with GUI +* Coverage report in each PR +* doi in Readme for papers. +* Support for independent variables other than two-theta. +* new subcommand ``applymud`` to run the original absorption correction process through CLI. +* Utility and example documentation for the main module. +* Added documentation for new CLI updates. +* Documentation for functions module. +* Spelling check via Codespell in pre-commit +* Python 3.13 support +* Functionality in `load_user_info` to enable user to enter an ORCID. + +**Changed:** + +* Default to brute-force computation when muD < 0.5 or > 7. +* Print a warning message instead of error, explicitly stating the input muD value +* Functions that use DiffractionObject` in `diffpy.utils` to follow the new API. +* Workflow for loading wavelength - raise an error when both wavelength and anode type are specified. +* Readme: muD now requires the ``--mud`` flag instead of a required argument. +* Made muD an optional argument and provided different options (manually entry / z-scan file path) for users to specify muD +* Increased the number of significant figures for wavelength and separated values for Ka1 and Ka2. +* hyphens / underscores format according to new scikit-package group standard. +* GitHub workflows for renamed test file. +* Return a ``ValueError`` if no wavelength is found on config file or if its not specified. +* Compartmentalize commands into the subcommands ``mud``, ``zscan``, and ``sample``. See documentation for more info. +* Changed ``doc`` to ``docs`` and ``CODE_OF_CONDUCT.rst`` to ``CODE-OF-CONDUCT.rst`` to comply with scikit-package standards. +* All function docstrings and tests to be more informative, incorporating new ORCID function and improving overall clarity. + +**Fixed:** + +* duplicated wavelength information in output files + +**Removed:** + +* Remove the import of extend_path from pkgutil in diffpy/__init__.py since we are not strictly following the Python namespace package convention. + + 0.2.0 ===== diff --git a/CODE_OF_CONDUCT.rst b/CODE-OF-CONDUCT.rst similarity index 98% rename from CODE_OF_CONDUCT.rst rename to CODE-OF-CONDUCT.rst index e8199ca..25fafe2 100644 --- a/CODE_OF_CONDUCT.rst +++ b/CODE-OF-CONDUCT.rst @@ -67,7 +67,7 @@ Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -sb2896@columbia.edu. All complaints will be reviewed and investigated promptly and fairly. +sbillinge@ucsb.edu. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. diff --git a/LICENSE.rst b/LICENSE.rst index 9cc6a9d..d5f6da9 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -1,6 +1,9 @@ BSD 3-Clause License -Copyright (c) 2025, The Trustees of Columbia University in the City of New York. +Copyright (c) 2025-2026, The Trustees of Columbia University in the City of New York. +All rights reserved. + +Copyright (c) 2026-present, diffpy.labpdfproc developers and contributors. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.rst b/README.rst index 358c54d..48b6c98 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ :target: https://diffpy.github.io/diffpy.labpdfproc :height: 100px -|PyPi| |Forge| |PythonVersion| |PR| +|PyPI| |Forge| |PythonVersion| |PR| |CI| |Codecov| |Black| |Tracking| @@ -25,8 +25,9 @@ :target: https://anaconda.org/conda-forge/diffpy.labpdfproc .. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + :target: https://github.com/diffpy/diffpy.labpdfproc/pulls -.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.labpdfproc +.. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.labpdfproc :target: https://pypi.org/project/diffpy.labpdfproc/ .. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.labpdfproc @@ -48,15 +49,19 @@ which is the most common geometry for lab PDF measurements. The theory is described in the following paper: -Chen, Y., Schertenleib, T., Yang, A., Schouwink, P., Queen, W.L. and Billinge, S.J.L., -An Absorption Correction for Reliable Pair-Distribution Functions from Low Energy x-ray Sources. -Arxiv.org. https://doi.org/10.48550/arXiv.2504.12499 + Chen, Y., Schertenleib, T., Yang, A., Schouwink, P., Queen, W. L., and Billinge, S. J. L., + *Absorption Correction for Reliable Pair Distribution Functions from Low Energy X-ray Sources*. + Crystal Growth & Design, 2026, 26 (3), 1036–1047. + https://doi.org/10.1021/acs.cgd.5c00551 + The related experimental data acquisition protocols are described in the following paper: -Schertenleib, T., Schmuckler, D., Chen, Y., Jin, G.B., Queen, W.L. and Billinge, S.J.L. (2025), -Testing Protocols for Obtaining Reliable Pair Distribution Functions from Laboratory X-Ray Sources Using PDFgetX3. -Chem. Methods 2500001. https://doi.org/10.1002/cmtd.202500001 + Schertenleib, T., Schmuckler, D., Chen, Y., Jin, G. B., Queen, W. L., and Billinge, S. J. L. (2025). + *Testing Protocols for Obtaining Reliable Pair Distribution Functions from Laboratory X-Ray Sources Using PDFgetX3*. + Chem. Methods, 2500001. + https://doi.org/10.1002/cmtd.202500001 + For more information about the diffpy.labpdfproc library, please consult our `online documentation `_. @@ -65,7 +70,10 @@ Citation If you use diffpy.labpdfproc in a scientific publication, we would like you to cite this package as - diffpy.labpdfproc Package, https://github.com/diffpy/diffpy.labpdfproc + Chen, Y., Schertenleib, T., Yang, A., Schouwink, P., Queen, W. L., and Billinge, S. J. L., + *Absorption Correction for Reliable Pair Distribution Functions from Low Energy X-ray Sources*. + Crystal Growth & Design, 2026, 26 (3), 1036–1047. + https://doi.org/10.1021/acs.cgd.5c00551 Installation ------------ @@ -84,10 +92,6 @@ The following creates and activates a new environment named ``diffpy.labpdfproc_ conda create -n diffpy.labpdfproc_env diffpy.labpdfproc conda activate diffpy.labpdfproc_env -To confirm that the installation was successful, type :: - - python -c "import diffpy.labpdfproc; print(diffpy.labpdfproc.__version__)" - The output should print the latest version displayed on the badges above. If the above does not work, you can use ``pip`` to download and install the latest release from @@ -102,26 +106,18 @@ and run the following :: pip install . -Example -------- +This package also provides command-line utilities. To check the software has been installed correctly, type :: -Navigate to the directory that contains 1D diffraction patterns that you would like to process. -Activate the conda environment (`conda activate diffpy.labpdfproc_env`) that contains the package and run the following command :: + labpdfproc --version - labpdfproc --mud +You can also type the following command to verify the installation. :: -Here replace with the value of muD for your sample -and with the path and filename of your input file. -For example, if the uncorrected data case is called zro2_mo.xy and is in the current directory -and it has a muD of 2.5 then the command would be :: - - labpdfproc zro2_mo.xy --mud 2.5 + python -c "import diffpy.labpdfproc; print(diffpy.labpdfproc.__version__)" -Please type :: - labpdfproc --help +To view the basic usage and available commands, type :: -for more information on the available options. + labpdfproc -h Getting Started --------------- @@ -131,9 +127,7 @@ You may consult our `online documentation `_ is the discussion forum for general questions and discussions about the use of diffpy.labpdfproc. Please join the diffpy.labpdfproc users community by joining the Google group. The diffpy.labpdfproc project welcomes your expertise and enthusiasm! - -If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. You can also post it to the `Diffpy user group `_. +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. Feel free to fork the project and contribute. To install diffpy.labpdfproc in a development mode, with its sources being directly used by Python @@ -156,9 +150,14 @@ 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 ------- -For more information on diffpy.labpdfproc please visit the project `web-page `_ or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.labpdfproc please visit the project `web-page `_ or email the maintainers ``Simon Billinge(sbillinge@ucsb.edu)``. + +Acknowledgements +---------------- + +``diffpy.labpdfproc`` is built and maintained with `scikit-package `_. diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 0000000..7c013d4 --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,20 @@ +{ + "author_names": "Yucong Chen, Till Schertenleib, Caden Myers, Simon Billinge", + "author_emails": "yc4372@columbia.edu, ts@chem.ku.dk, cjm2304@columbia.edu, sbillinge@ucsb.edu", + "maintainer_names": "Simon Billinge", + "maintainer_emails": "sbillinge@ucsb.edu", + "maintainer_github_usernames": "sbillinge", + "contributors": "Yucong Chen, Till Schertenleib, Caden Myers, Billinge Group members", + "license_holders": "The Trustees of Columbia University in the City of New York", + "project_name": "diffpy.labpdfproc", + "github_username_or_orgname": "diffpy", + "github_repo_name": "diffpy.labpdfproc", + "conda_pypi_package_dist_name": "diffpy.labpdfproc", + "package_dir_name": "diffpy.labpdfproc", + "project_short_description": "Tools for processing x-ray powder diffraction data from laboratory sources.", + "project_keywords": "powder XRD, absorption correction, PDF, diffpy", + "minimum_supported_python_version": "3.12", + "maximum_supported_python_version": "3.14", + "project_needs_c_code_compiled": "No", + "project_has_gui_tests": "No" +} diff --git a/doc/source/examples/labpdfprocapp-example.rst b/doc/source/examples/labpdfprocapp-example.rst deleted file mode 100644 index a553c8f..0000000 --- a/doc/source/examples/labpdfprocapp-example.rst +++ /dev/null @@ -1,130 +0,0 @@ -.. _labpdfprocapp Example: - -:tocdepth: -1 - -labpdfprocapp Example -##################### - -This example provides a quick-start tutorial for using ``diffpy.labpdfproc`` -to apply absorption correction to your 1D diffraction data using the command-line (CLI). -Check ``labpdfproc --help`` for more information. -A graphical user interface (GUI) is also available and is designed to be intuitive and easy to use. - - -1. To use this application, you will need: -(1) your input diffraction data file(s), and (2) information required to compute the muD value. -To launch the GUI, use ``labpdfproc`` or ``labpdfproc --gui``. -Note that the GUI is currently not supported on Python 3.13. - - -2. Here we first provide a basic CLI example. -Assume you have an uncorrected diffraction data file named ``zro2_mo.xy`` in the current directory -with a muD of 2.5 on the two-theta x-axis. Then the minimum command would be: - -.. code-block:: python - - labpdfproc zro2_mo.xy --mud 2.5 - - -3. You must provide at least one file path, and filepath(s) should immediately follow ``labpdfproc``. - -To process multiple files at once in the CLI, separate each file path with a whitespace. -In general, avoid spaces in filenames, but if necessary, enclose them in quotes; otherwise, quotes are optional. -For example, the following is a valid and more complex CLI command: - -.. code-block:: python - - labpdfproc "SiO2 uncorrected.xy" input_dir file_list.txt ./*.chi data* --mud 2.5 - -This command will process ``"SiO2 uncorrected.xy"``, -all files in the ``input_dir`` directory, all files listed in ``file_list.txt``, -all ``.chi`` files in the current directory, and all files matching the pattern ``data``, -using a muD value of 2.5. -Check ``labpdfproc --help`` to see all supported file types. - -In the GUI, you can select multiple individual files via the file browser, but not entire directories. -To include directories, you can either: -(1) create a text file named ``file_list.txt`` containing the desired paths and load it, -(2) manually select all files in a folder, or -(3) enter paths manually separated by a colon with no spaces. - -We will now continue using ``zro2_mo.xy`` as the example input throughout the rest of this tutorial. - - -4. The muD value is required for absorption correction, and you can specify it in one of the four ways: - -.. code-block:: python - - # Option 1: Manual value - labpdfproc zro2_mo.xy --mud 2.5 - # Option 2: From a z-scan file - labpdfproc zro2_mo.xy -z zscan.xy - # Option 3: Using sample mass density - labpdfproc zro2_mo.xy -d ZrO2,17.45,1.2 - # Option 4: Using packing fraction - labpdfproc zro2_mo.xy -p ZrO2,17.45,0.2 - -Note that you can only use one method at a time. The following examples are not allowed: - -.. code-block:: python - - labpdfproc zro2_mo.xy --mud 2.5 -z zscan.xy - labpdfproc zro2_mo.xy --mud 2.5 -d ZrO2,17.45,1.2 - -If the packing fraction option is not supported at the moment, you can approximate the sample mass density as: -``mass density = packing fraction * material density``, where the material density can be looked up manually. - - -5. You can specify the wavelength in two ways: - -.. code-block:: python - - # Option 1: Manually enter wavelength - labpdfproc zro2_mo.xy --mud 2.5 -w 0.71303 - # Option 2: Use a known anode type - labpdfproc zro2_mo.xy --mud 2.5 -a Mo - -Do not use both ``-w`` and ``-a`` at the same time. For example: - -.. code-block:: python - - labpdfproc zro2_mo.xy --mud 2.5 -w 0.71303 -a Mo - -is not valid. This is to avoid confusion when wavelength conflicts with anode type. -To avoid retyping, you can save your wavelength or anode type in a diffpy configuration file. -See full instructions at https://www.diffpy.org/diffpy.labpdfproc/examples/tools_example.html. - - -6. You are also encouraged to provide your information (name, email, and orcid) for reproducibility: - -.. code-block:: python - - labpdfproc zro2_mo.xy --mud 2.5 -n Joe -e Joe@email.com --orcid 0000-0000-0000-0000 - - -Alternatively, you can enter this information during the interactive prompts -or save it in your diffpy configuration file. -For more details, refer to https://www.diffpy.org/diffpy.utils/examples/tools_example.html. - - -7. You can further customize the diffraction correction process using the following options: - -- Choose xtype: use ``-x`` to specify your input data's xtype, which will be used for the output. -- Select correction method: use ``-m`` to choose between "brute_force" or "polynomial_interpolation" (faster and preferred for muD 0.5-7). -- Specify output directory: use ``-o`` to save the corrected file(s) to a specific folder. -- Add custom metadata: use ``-u`` to provide key-value pair for information tracking (e.g., experimental details). -- Output the cve file: use ``-c`` to export the cve file along with the corrected data. -- Overwrite existing files: use ``-f`` to replace any previous corrected files with the same names. - - -8. To summarize, a full command might look like this: - -.. code-block:: python - - labpdfproc zro2_mo.xy --mud 2.5 -w 0.71303 -n Joe -x q -m brute_force -o results -u "facility=NSLS II" beamline=28ID-2 -c -f - -After running the command, check your output folder (in this case, ``results``) -for the corrected data file and cve file (if ``-c`` was used). -In this example, the corrected and cve files are called ``zro2_mo_corrected.chi`` and ``zro2_mo_cve.chi``. -The headers include all the arguments you provided -—such as diffraction settings, personal information, and metadata—making it easy to track your analysis. 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 95% rename from doc/make.bat rename to docs/make.bat index ac53d5b..2be8306 100644 --- a/doc/make.bat +++ b/docs/make.bat @@ -1,36 +1,36 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build -set SPHINXPROJ=PackagingScientificPython - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=PackagingScientificPython + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd 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.labpdfproc.data.rst b/docs/source/api/diffpy.labpdfproc.data.rst similarity index 100% rename from doc/source/api/diffpy.labpdfproc.data.rst rename to docs/source/api/diffpy.labpdfproc.data.rst diff --git a/doc/source/api/diffpy.labpdfproc.rst b/docs/source/api/diffpy.labpdfproc.rst similarity index 100% rename from doc/source/api/diffpy.labpdfproc.rst rename to docs/source/api/diffpy.labpdfproc.rst diff --git a/doc/source/conf.py b/docs/source/conf.py similarity index 91% rename from doc/source/conf.py rename to docs/source/conf.py index 12c7366..4ef7771 100644 --- a/doc/source/conf.py +++ b/docs/source/conf.py @@ -18,15 +18,26 @@ from importlib.metadata import version from pathlib import Path +# Attempt to import the version dynamically from GitHub tag. +try: + fullversion = version("diffpy.labpdfproc") +except Exception: + fullversion = ( + "No version found. " + "The correct version will appear in the released version." + ) + # 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. +# documentation root, use Path().resolve() to make it absolute, like shown here # sys.path.insert(0, str(Path(".").resolve())) sys.path.insert(0, str(Path("../..").resolve())) sys.path.insert(0, str(Path("../../src").resolve())) # abbreviations -ab_authors = "Billinge Group members and community contributors" +ab_authors = ( + "Yucong Chen, Till Schertenleib, Caden Myers, Billinge Group members" +) # -- General configuration ------------------------------------------------ @@ -43,7 +54,8 @@ "sphinx.ext.viewcode", "sphinx.ext.intersphinx", "sphinx_rtd_theme", - "m2r", + "sphinx_copybutton", + "m2r2", ] # Add any paths that contain templates here, relative to this directory. @@ -68,7 +80,6 @@ # |version| and |release|, also used in various other places throughout the # built documents. -fullversion = version(project) # The short X.Y version. version = "".join(fullversion.split(".post")[:1]) # The full version, including alpha/beta/rc tags. @@ -88,10 +99,18 @@ # substitute YEAR in the copyright string copyright = copyright.replace("%Y", year) +# For sphinx_copybutton extension. +# Do not copy "$" for shell commands in code-blocks. +copybutton_prompt_text = r"^\$ " +copybutton_prompt_is_regexp = True + # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ["build"] +# Mock imports so API docs render without installing dependencies. +autodoc_mock_imports = ["diffpy.utils"] + # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None @@ -123,6 +142,14 @@ # html_theme = "sphinx_rtd_theme" +html_context = { + "display_github": True, + "github_user": "diffpy", + "github_repo": "diffpy.labpdfproc", + "github_version": "main", + "conf_py_path": "/docs/source/", +} + # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. diff --git a/docs/source/examples/example-data/CeO2_635um_accum_0.xy b/docs/source/examples/example-data/CeO2_635um_accum_0.xy new file mode 100644 index 0000000..97b1f9e --- /dev/null +++ b/docs/source/examples/example-data/CeO2_635um_accum_0.xy @@ -0,0 +1,5631 @@ +2.00009989738464 22.6381633008874 +2.02462468668818 21.8208275836126 +2.04914947599173 21.0965692433941 +2.07367426529527 20.3054115384164 +2.09819905459881 19.2641083826002 +2.12272384390235 18.4351379931934 +2.14724863320589 18.0337418046386 +2.17177342250943 17.0477033414494 +2.19629821181297 16.5503211078054 +2.22082300111651 15.5206526241212 +2.24534779042006 15.439209919197 +2.2698725797236 14.7847596117706 +2.29439736902714 14.2088433412354 +2.31892215833068 13.6329270707001 +2.34344694763422 12.7806873370293 +2.36797173693776 12.3618391402764 +2.3924965262413 12.2076797345271 +2.41702131554484 11.7393841812131 +2.44154610484838 11.0965685459187 +2.46607089415193 11.0267605131266 +2.49059568345547 10.2385114761819 +2.51512047275901 10.28505016471 +2.53964526206255 9.7294945704058 +2.56417005136609 9.2641076851248 +2.58869484066963 9.09540493921044 +2.61321962997317 8.42350262358601 +2.63774441927671 8.28097788996871 +2.66226920858026 8.10645780798833 +2.6867939978838 7.60907557434427 +2.71131878718734 7.16114069726131 +2.73584357649088 7.11751067676621 +2.76036836579442 7.03897663987505 +2.78489315509796 6.5968590988581 +2.8094179444015 6.37289166031662 +2.83394273370504 6.27981428326042 +2.85846752300859 5.73298469305526 +2.88299231231213 5.62827264386703 +2.90751710161567 5.8464227463425 +2.93204189091921 5.45084389385365 +2.95656668022275 5.03781303316677 +2.98109146952629 5.15997709055303 +3.00561625882983 4.78475891429523 +3.03014104813337 4.89237963151646 +3.05466583743691 4.5375221314897 +3.07919062674046 4.18557329949595 +3.103715416044 4.03432256177963 +3.12824020534754 3.89470649619533 +3.15276499465108 3.85107647570023 +3.17728978395462 3.67073905765385 +3.20181457325816 3.47294963140942 +3.2263393625617 3.56311834043262 +3.25086415186524 3.40605026665028 +3.27538894116879 3.3187902256601 +3.29991373047233 3.01628875022745 +3.32443851977587 3.04537543055751 +3.34896330907941 2.81559065595002 +3.37348809838295 2.69051793053075 +3.39801288768649 2.4345551436262 +3.42253767699003 2.32402575837197 +3.44706246629357 2.23094838131577 +3.47158725559711 2.35892977476804 +3.49611204490066 2.19313569688669 +3.5206368342042 2.0564282993354 +3.54516162350774 2.1029669878635 +3.56968641281128 1.93135557391613 +3.59421120211482 1.81210018456287 +3.61873599141836 1.91099489768509 +3.6432607807219 1.67248411897858 +3.66778557002544 1.76556149603477 +3.69231035932899 1.6841187911106 +3.71683514863253 1.67539278701158 +3.74135993793607 1.72484014357269 +3.76588472723961 1.63176276651649 +3.79040951654315 1.73356614767171 +3.81493430584669 1.62594543045048 +3.83945909515023 1.60849342225244 +3.86398388445377 1.6375801025825 +3.88850867375731 1.68702745914361 +3.91303346306086 1.58522407798839 +3.9375582523644 1.53577672142728 +3.96208304166794 1.63467143454949 +3.98660783097148 1.52995938536127 +4.01113262027502 1.62885409848348 +4.03565740957856 1.51832471322925 +4.0601821988821 1.65794077881354 +4.08470698818564 1.56777206979035 +4.10923177748919 1.60267608618643 +4.13375656679273 1.39906932387599 +4.15828135609627 1.49214670093219 +4.18280614539981 1.50959870913023 +4.20733093470335 1.53286805339428 +4.23185572400689 1.53577672142728 +4.25638051331043 1.52123338126225 +4.28090530261397 1.52414204929526 +4.30543009191751 1.50087270503121 +4.32995488122106 1.52123338126225 +4.3544796705246 1.61721942635146 +4.37900445982814 1.46596868863513 +4.40352924913168 1.52123338126225 +4.42805403843522 1.46887735666814 +4.45257882773876 1.50087270503121 +4.4771036170423 1.43688200830507 +4.50162840634584 1.43979067633808 +4.52615319564939 1.52414204929526 +4.55067798495293 1.33798729518286 +4.57520277425647 1.39034331977697 +4.59972756356001 1.46596868863513 +4.62425235286355 1.43106467223906 +4.64877714216709 1.30017461075378 +4.67330193147063 1.41361266404102 +4.69782672077417 1.34671329928188 +4.72235151007771 1.50378137306421 +4.74687629938126 1.43106467223906 +4.7714010886848 1.48051202880016 +4.79592587798834 1.46306002060213 +4.82045066729188 1.4979640369982 +4.84497545659542 1.42524733617305 +4.86950024589896 1.27108793042372 +4.8940250352025 1.401977991909 +4.91854982450604 1.55322872962532 +4.94307461380959 1.37579997961194 +4.96759940311313 1.3089006148528 +4.99212419241667 1.43688200830507 +5.01664898172021 1.39906932387599 +5.04117377102375 1.3554393033809 +5.06569856032729 1.38452598371096 +5.09022334963083 1.45433401650311 +5.11474813893437 1.37579997961194 +5.13927292823792 1.34962196731489 +5.16379771754146 1.404886659942 +5.188322506845 1.36998264354593 +5.21284729614854 1.33507862714985 +5.23737208545208 1.27399659845672 +5.26189687475562 1.30017461075378 +5.28642166405916 1.38452598371096 +5.3109464533627 1.32635262305084 +5.33547124266624 1.31762661895182 +5.35999603196979 1.1692845492685 +5.38452082127333 1.36707397551292 +5.40904561057687 1.28272260255574 +5.43357039988041 1.33798729518286 +5.45809518918395 1.21000590173059 +5.48261997848749 1.32344395501783 +5.50714476779103 1.3089006148528 +5.53166955709457 1.3089006148528 +5.55619434639812 1.15183254107046 +5.58071913570166 1.29435727468777 +5.6052439250052 1.25363592222568 +5.62976871430874 1.2158232377966 +5.65429350361228 1.30308327878679 +5.67881829291582 1.2623619263247 +5.70334308221936 1.28563127058875 +5.7278678715229 1.29726594272077 +5.75239266082644 1.38161731567795 +5.77691745012999 1.18382788943353 +5.80144223943353 1.14601520500445 +5.82596702873707 1.31471795091881 +5.85049181804061 1.25072725419267 +5.87501660734415 1.23327524599464 +5.89954139664769 1.19255389353255 +5.92406618595123 1.19546256156556 +5.94859097525477 1.21000590173059 +5.97311576455832 1.25654459025869 +5.99764055386186 1.22164057386261 +6.0221653431654 1.25654459025869 +6.04669013246894 1.15183254107046 +6.07121492177248 1.36707397551292 +6.09573971107602 1.15183254107046 +6.12026450037956 1.2652705943577 +6.1447892896831 1.29144860665476 +6.16931407898664 1.25654459025869 +6.19383886829019 1.29435727468777 +6.21836365759373 1.24490991812666 +6.24288844689727 1.21291456976359 +6.26741323620081 1.18964522549954 +6.29193802550435 1.27690526648973 +6.31646281480789 1.17219321730151 +6.34098760411143 1.15764987713647 +6.36551239341497 1.3118092828858 +6.39003718271852 1.21873190582961 +6.41456197202206 1.13438053287243 +6.4390867613256 1.21873190582961 +6.46361155062914 1.19255389353255 +6.48813633993268 1.13728920090543 +6.51266112923622 1.21000590173059 +6.53718591853976 1.24490991812666 +6.5617107078433 1.28563127058875 +6.58623549714684 1.20127989763157 +6.61076028645039 1.15474120910347 +6.63528507575393 1.2158232377966 +6.65980986505747 1.10820252057537 +6.68433465436101 1.10238518450936 +6.70885944366455 1.15474120910347 +6.73338423296809 1.25654459025869 +6.75790902227163 1.17219321730151 +6.78243381157517 1.16346721320249 +6.80695860087872 1.25363592222568 +6.83148339018226 1.14601520500445 +6.8560081794858 1.17510188533451 +6.88053296878934 1.17801055336752 +6.90505775809288 1.30017461075378 +6.92958254739642 1.22745790992862 +6.95410733669996 1.07911584024531 +6.9786321260035 1.21873190582961 +7.00315691530705 1.25654459025869 +7.02768170461059 1.21873190582961 +7.05220649391413 1.20418856566457 +7.07673128321767 1.1692845492685 +7.10125607252121 1.14019786893844 +7.12578086182475 1.13728920090543 +7.15030565112829 1.17219321730151 +7.17483044043183 1.19546256156556 +7.19935522973537 1.09656784844334 +7.22388001903892 1.15474120910347 +7.24840480834246 1.10529385254236 +7.272929597646 1.2158232377966 +7.29745438694954 1.05875516401426 +7.32197917625308 1.18382788943353 +7.34650396555662 1.18382788943353 +7.37102875486016 1.19255389353255 +7.3955535441637 1.15474120910347 +7.42007833346725 1.09947651647635 +7.44460312277079 1.19255389353255 +7.46912791207433 1.15474120910347 +7.49365270137787 1.14892387303746 +7.51817749068141 1.15474120910347 +7.54270227998495 1.0267598156512 +7.56722706928849 1.1692845492685 +7.59175185859203 1.04130315581623 +7.61627664789557 1.16637588123549 +7.64080143719912 1.10820252057537 +7.66532622650266 1.29144860665476 +7.6898510158062 1.13438053287243 +7.71437580510974 1.11401985664138 +7.73890059441328 1.16055854516948 +7.76342538371682 1.20709723369758 +7.78795017302036 1.1227458607404 +7.8124749623239 1.18091922140052 +7.83699975162745 1.21873190582961 +7.86152454093099 1.06166383204727 +7.88604933023453 1.15764987713647 +7.91057411953807 1.04421182384923 +7.93509890884161 1.21000590173059 +7.95962369814515 1.13728920090543 +7.98414848744869 1.17801055336752 +8.00867327675223 1.17219321730151 +8.03319806605577 1.03548581975021 +8.05772285535932 1.02094247958518 +8.08224764466286 1.17801055336752 +8.1067724339664 1.15474120910347 +8.13129722326994 1.22454924189562 +8.15582201257348 1.05875516401426 +8.18034680187702 1.14310653697144 +8.20487159118056 1.11692852467439 +8.2293963804841 1.10820252057537 +8.25392116978765 1.05875516401426 +8.27844595909119 1.16346721320249 +8.30297074839473 1.18091922140052 +8.32749553769827 0.983129795156102 +8.35202032700181 1.10820252057537 +8.37654511630535 1.15183254107046 +8.40106990560889 1.1692845492685 +8.42559469491243 1.17510188533451 +8.45011948421597 1.07038983614629 +8.47464427351952 1.17219321730151 +8.49916906282306 1.15183254107046 +8.5236938521266 1.12856319680641 +8.54821864143014 1.24490991812666 +8.57274343073368 1.09365918041034 +8.59726822003722 1.13438053287243 +8.62179300934076 1.17219321730151 +8.6463177986443 1.17801055336752 +8.67084258794785 1.09947651647635 +8.69536737725139 1.0296684836842 +8.71989216655493 1.11983719270739 +8.74441695585847 1.00930780745316 +8.76894174516201 1.08493317631132 +8.79346653446555 1.05002915991524 +8.81799132376909 1.19255389353255 +8.84251611307263 1.00930780745316 +8.86704090237617 1.08493317631132 +8.89156569167972 1.13438053287243 +8.91609048098326 1.17219321730151 +8.9406152702868 1.07038983614629 +8.96514005959034 1.10529385254236 +8.98966484889388 1.04130315581623 +9.01418963819742 1.0296684836842 +9.03871442750096 1.07329850417929 +9.0632392168045 1.07038983614629 +9.08776400610805 1.08202450827831 +9.11228879541159 1.08784184434433 +9.13681358471513 1.11111118860838 +9.16133837401867 1.05002915991524 +9.18586316332221 1.10238518450936 +9.21038795262575 1.00930780745316 +9.23491274192929 1.08784184434433 +9.25943753123283 1.17510188533451 +9.28396232053638 1.08202450827831 +9.30848710983992 1.0296684836842 +9.33301189914346 0.980221127123096 +9.357536688447 1.0296684836842 +9.38206147775054 1.05584649598126 +9.40658626705408 1.11401985664138 +9.43111105635762 0.924956434495977 +9.45563584566116 1.03839448778322 +9.4801606349647 1.01221647548616 +9.50468542426825 1.05002915991524 +9.52921021357179 0.994764467288127 +9.55373500287533 1.10238518450936 +9.57825979217887 1.05584649598126 +9.60278458148241 1.07038983614629 +9.62730937078595 1.06748116811328 +9.65183416008949 1.10238518450936 +9.67635894939303 0.997673135321133 +9.70088373869658 1.01803381155218 +9.72540852800012 1.07329850417929 +9.74993331730366 1.06166383204727 +9.7744581066072 1.06166383204727 +9.79898289591074 0.948225778760027 +9.82350768521428 1.03839448778322 +9.84803247451782 0.968586454991071 +9.87255726382136 0.986038463189108 +9.8970820531249 0.933682438594996 +9.92160684242845 1.06457250008028 +9.94613163173199 1.11401985664138 +9.97065642103553 1.06457250008028 +9.99518121033907 0.90750442629794 +10.0197059996426 1.1227458607404 +10.0442307889462 0.988947131222114 +10.0687555782497 0.994764467288127 +10.0932803675532 0.93077377056199 +10.1178051568568 0.922047766462971 +10.1423299461603 1.00349047138715 +10.1668547354639 0.913321762363952 +10.1913795247674 0.983129795156102 +10.2159043140709 0.977312459090089 +10.2404291033745 0.997673135321133 +10.264953892678 1.0267598156512 +10.2894786819816 0.927865102528984 +10.3140034712851 0.951134446793033 +10.3385282605886 1.03839448778322 +10.3630530498922 1.15764987713647 +10.3875778391957 0.974403791057083 +10.4121026284993 0.887143750066897 +10.4366274178028 1.05293782794825 +10.4611522071064 0.971495123024077 +10.4856769964099 0.878417745967878 +10.5102017857134 0.942408442694015 +10.534726575017 1.01803381155218 +10.5592513643205 1.05002915991524 +10.5837761536241 0.988947131222114 +10.6083009429276 0.922047766462971 +10.6328257322311 1.02385114761819 +10.6573505215347 0.878417745967878 +10.6818753108382 0.924956434495977 +10.7064001001418 0.95404311482604 +10.7309248894453 0.922047766462971 +10.7554496787488 0.90750442629794 +10.7799744680524 0.933682438594996 +10.8044992573559 1.03257715171721 +10.8290240466595 0.977312459090089 +10.853548835963 1.00639913942015 +10.8780736252666 1.01803381155218 +10.9025984145701 0.927865102528984 +10.9271232038736 1.02385114761819 +10.9516479931772 0.99185579925512 +10.9761727824807 0.977312459090089 +11.0006975717843 0.922047766462971 +11.0252223610878 0.93077377056199 +11.0497471503913 0.88423508203389 +11.0742719396949 0.90750442629794 +11.0987967289984 0.951134446793033 +11.123321518302 0.951134446793033 +11.1478463076055 0.99185579925512 +11.172371096909 0.878417745967878 +11.1968958862126 0.913321762363952 +11.2214206755161 0.919139098429965 +11.2459454648197 0.962769118925058 +11.2704702541232 0.922047766462971 +11.2949950434268 0.945317110727021 +11.3195198327303 1.06748116811328 +11.3440446220338 0.898778422198921 +11.3685694113374 0.968586454991071 +11.3930942006409 0.956951782859046 +11.4176189899445 0.997673135321133 +11.442143779248 1.03257715171721 +11.4666685685515 1.10529385254236 +11.4911933578551 1.15183254107046 +11.5157181471586 1.16055854516948 +11.5402429364622 1.06748116811328 +11.5647677257657 1.09947651647635 +11.5892925150692 1.23909258206065 +11.6138173043728 1.18964522549954 +11.6383420936763 1.30017461075378 +11.6628668829799 1.31762661895182 +11.6873916722834 1.20127989763157 +11.711916461587 1.25363592222568 +11.7364412508905 1.25363592222568 +11.760966040194 1.14892387303746 +11.7854908294976 1.17219321730151 +11.8100156188011 1.20709723369758 +11.8345404081047 1.13147186483942 +11.8590651974082 1.36125663944691 +11.8835899867117 1.21291456976359 +11.9081147760153 1.33216995911685 +11.9326395653188 1.27690526648973 +11.9571643546224 1.27108793042372 +11.9816891439259 1.28853993862175 +12.0062139332294 1.22164057386261 +12.030738722533 1.28563127058875 +12.0552635118365 1.27981393452274 +12.0797883011401 1.25654459025869 +12.1043130904436 1.37579997961194 +12.1288378797472 1.37870864764495 +12.1533626690507 1.35253063534789 +12.1778874583542 1.33798729518286 +12.2024122476578 1.404886659942 +12.2269370369613 1.50087270503121 +12.2514618262649 1.64921477471453 +12.2759866155684 1.65794077881354 +12.3005114048719 1.62594543045048 +12.3250361941755 1.72193147553968 +12.349560983479 1.7306574796387 +12.3740857727826 1.97498559441122 +12.3986105620861 1.91099489768509 +12.4231353513896 2.12914500016055 +12.4476601406932 2.11460165999552 +12.4721849299967 2.28330440590988 +12.4967097193003 2.32984309443798 +12.5212345086038 2.55671920101247 +12.5457592979074 2.46655049198927 +12.5702840872109 2.9464807174353 +12.5948088765144 2.95520672153432 +12.619333665818 3.01628875022745 +12.6438584551215 3.77545110684207 +12.6683832444251 3.94124518472343 +12.6929080337286 4.50261811509363 +12.7174328230321 4.4909834429616 +12.7419576123357 5.11343840202493 +12.7664824016392 5.92786545126667 +12.7910071909428 6.56777241852804 +12.8155319802463 8.03374110716317 +12.8400567695498 9.33682438594996 +12.8645815588534 11.6404894680909 +12.8891063481569 14.6684128904504 +12.9136311374605 18.2926132595761 +12.938155926764 23.4700423583272 +12.9626807160676 29.1448536907223 +12.9872055053711 36.8411893060568 +13.0117302946746 43.6794678516544 +13.0362550839782 49.6451459873501 +13.0607798732817 52.4549193072341 +13.0853046625853 51.0238546349951 +13.1098294518888 45.6224580977025 +13.1343542411923 38.9645169701513 +13.1588790304959 31.7713809245269 +13.1834038197994 24.3979074608562 +13.207928609103 18.5951147350088 +13.2324533984065 14.2611993658295 +13.25697818771 10.9220484639383 +13.2815029770136 8.60965737769841 +13.3060277663171 7.26876141448254 +13.3305525556207 6.27108827916141 +13.3550773449242 5.20651577908113 +13.3796021342278 4.70040754133805 +13.4041269235313 4.22047731589202 +13.4286517128348 3.68819106585188 +13.4531765021384 3.23734752073592 +13.4777012914419 3.02501475432647 +13.5022260807455 2.85631200841211 +13.526750870049 2.49854584035234 +13.5512756593525 2.40546846329614 +13.5758004486561 2.26294372967884 +13.6003252379596 1.9633509222792 +13.6248500272632 1.92844690588312 +13.6493748165667 1.77137883210079 +13.6738996058702 1.66666678291256 +13.6984243951738 1.66375811487956 +13.7229491844773 1.53577672142728 +13.7474739737809 1.37870864764495 +13.7719987630844 1.4514253484701 +13.796523552388 1.45433401650311 +13.8210483416915 1.2652705943577 +13.845573130995 1.31762661895182 +13.8700979202986 1.27690526648973 +13.8946227096021 1.18673655746654 +13.9191474989057 1.2158232377966 +13.9436722882092 1.28272260255574 +13.9681970775127 1.27108793042372 +13.9927218668163 1.14601520500445 +14.0172466561198 1.14019786893844 +14.0417714454234 1.21000590173059 +14.0662962347269 1.14601520500445 +14.0908210240304 1.04712049188224 +14.115345813334 1.11692852467439 +14.1398706026375 0.994764467288127 +14.1643953919411 1.11111118860838 +14.1889201812446 1.08202450827831 +14.2134449705482 1.08493317631132 +14.2379697598517 1.04130315581623 +14.2624945491552 1.09365918041034 +14.2870193384588 1.09075051237733 +14.3115441277623 1.10238518450936 +14.3360689170659 1.05002915991524 +14.3605937063694 1.04712049188224 +14.3851184956729 1.06457250008028 +14.4096432849765 1.16637588123549 +14.43416807428 1.12565452877341 +14.4586928635836 1.15764987713647 +14.4832176528871 1.18964522549954 +14.5077424421906 1.22745790992862 +14.5322672314942 1.21873190582961 +14.5567920207977 1.18382788943353 +14.5813168101013 1.37870864764495 +14.6058415994048 1.39906932387599 +14.6303663887084 1.43397334027207 +14.6548911780119 1.28853993862175 +14.6794159673154 1.56777206979035 +14.703940756619 1.48923803289918 +14.7284655459225 1.57649807388937 +14.7529903352261 1.85863887309097 +14.7775151245296 1.95753358621318 +14.8020399138331 2.13205366819356 +14.8265647031367 2.26876106574485 +14.8510894924402 2.69342659856376 +14.8756142817438 2.96102405760033 +14.9001390710473 3.31588155762709 +14.9246638603508 4.28155934458515 +14.9491886496544 5.34031450859942 +14.9737134389579 6.58522442672608 +14.9982382282615 8.61547471376442 +15.022763017565 10.779523730321 +15.0472878068686 12.5538112304548 +15.0718125961721 14.1826653289383 +15.0963373854756 14.8254809642327 +15.1208621747792 13.9790585666279 +15.1453869640827 12.8650387099865 +15.1699117533863 11.1547419065788 +15.1944365426898 9.36881973431303 +15.2189613319933 7.45782483662794 +15.2434861212969 5.78824938568237 +15.2680109106004 4.41826674213644 +15.292535699904 3.56602700846562 +15.3170604892075 3.05410143465653 +15.341585278511 2.52181518461639 +15.3661100678146 2.1058756558965 +15.3906348571181 2.03897629113736 +15.4151596464217 1.73356614767171 +15.4396844357252 1.61140209028544 +15.4642092250288 1.56486340175735 +15.4887340143323 1.4514253484701 +15.5132588036358 1.27690526648973 +15.5377835929394 1.27399659845672 +15.5623083822429 1.23618391402764 +15.5868331715465 1.14019786893844 +15.61135796085 0.986038463189108 +15.6358827501535 0.988947131222114 +15.6604075394571 1.04421182384923 +15.6849323287606 0.956951782859046 +15.7094571180642 0.933682438594996 +15.7339819073677 0.904595758264934 +15.7585066966712 0.817335717274747 +15.7830314859748 0.794066373010698 +15.8075562752783 0.788249036944685 +15.8320810645819 0.756253688581617 +15.8566058538854 0.767888360713642 +15.881130643189 0.782431700878673 +15.9056554324925 0.747527684482598 +15.930180221796 0.750436352515604 +15.9547050110996 0.674810983657443 +15.9792298004031 0.767888360713642 +16.0037545897067 0.66899364759143 +16.0282793790102 0.651541639393393 +16.0528041683137 0.712623668086523 +16.0773289576173 0.593368278733268 +16.1018537469208 0.730075676284561 +16.1263785362244 0.639906967261368 +16.1509033255279 0.703897663987505 +16.1754281148314 0.64572430332738 +16.199952904135 0.703897663987505 +16.2244776934385 0.651541639393393 +16.2490024827421 0.677719651690449 +16.2735272720456 0.622454959063331 +16.2980520613492 0.602094282832287 +16.3225768506527 0.695171659888486 +16.3471016399562 0.631180963162349 +16.3716264292598 0.671902315624436 +16.3961512185633 0.570098934469219 +16.4206760078669 0.622454959063331 +16.4452007971704 0.567190266436213 +16.4697255864739 0.613728954964312 +16.4942503757775 0.53810358610615 +16.518775165081 0.64572430332738 +16.5432999543846 0.66899364759143 +16.5678247436881 0.660267643492411 +16.5923495329916 0.578824938568237 +16.6168743222952 0.642815635294374 +16.6413991115987 0.558464262337194 +16.6659239009023 0.6079116188983 +16.6904486902058 0.622454959063331 +16.7149734795094 0.680628319723455 +16.7394982688129 0.575916270535231 +16.7640230581164 0.654450307426399 +16.78854784742 0.593368278733268 +16.8130726367235 0.541012254139157 +16.8375974260271 0.578824938568237 +16.8621222153306 0.628272295129343 +16.8866470046341 0.573007602502225 +16.9111717939377 0.590459610700262 +16.9356965832412 0.567190266436213 +16.9602213725448 0.532286250040138 +16.9847461618483 0.602094282832287 +17.0092709511518 0.5613729303702 +17.0337957404554 0.546829590205169 +17.0583205297589 0.570098934469219 +17.0828453190625 0.546829590205169 +17.107370108366 0.517742909875107 +17.1318948976696 0.613728954964312 +17.1564196869731 0.546829590205169 +17.1809444762766 0.53810358610615 +17.2054692655802 0.517742909875107 +17.2299940548837 0.555555594304188 +17.2545188441873 0.5613729303702 +17.2790436334908 0.520651577908113 +17.3035684227943 0.543920922172163 +17.3280932120979 0.497382233644063 +17.3526180014014 0.491564897578051 +17.377142790705 0.5613729303702 +17.4016675800085 0.575916270535231 +17.426192369312 0.546829590205169 +17.4507171586156 0.541012254139157 +17.4752419479191 0.546829590205169 +17.4997667372227 0.488656229545045 +17.5242915265262 0.514834241842101 +17.5488163158298 0.503199569710076 +17.5733411051333 0.485747561512038 +17.5978658944368 0.596276946766275 +17.6223906837404 0.555555594304188 +17.6469154730439 0.517742909875107 +17.6714402623475 0.526468913974126 +17.695965051651 0.532286250040138 +17.7204898409545 0.596276946766275 +17.7450146302581 0.573007602502225 +17.7695394195616 0.471204221347007 +17.7940642088652 0.447934877082958 +17.8185889981687 0.555555594304188 +17.8431137874722 0.555555594304188 +17.8676385767758 0.526468913974126 +17.8921633660793 0.485747561512038 +17.9166881553829 0.541012254139157 +17.9412129446864 0.482838893479032 +17.96573773399 0.546829590205169 +17.9902625232935 0.526468913974126 +18.014787312597 0.541012254139157 +18.0393121019006 0.450843545115964 +18.0638368912041 0.491564897578051 +18.0883616805077 0.500290901677069 +18.1128864698112 0.546829590205169 +18.1374112591147 0.465386885280995 +18.1619360484183 0.497382233644063 +18.1864608377218 0.485747561512038 +18.2109856270254 0.570098934469219 +18.2355104163289 0.552646926271182 +18.2600352056324 0.558464262337194 +18.284559994936 0.517742909875107 +18.3090847842395 0.552646926271182 +18.3336095735431 0.529377582007132 +18.3581343628466 0.567190266436213 +18.3826591521502 0.543920922172163 +18.4071839414537 0.535194918073144 +18.4317087307572 0.482838893479032 +18.4562335200608 0.509016905776088 +18.4807583093643 0.465386885280995 +18.5052830986679 0.468295553314001 +18.5298078879714 0.482838893479032 +18.5543326772749 0.497382233644063 +18.5788574665785 0.474112889380014 +18.603382255882 0.47702155741302 +18.6279070451856 0.511925573809094 +18.6524318344891 0.500290901677069 +18.6769566237926 0.526468913974126 +18.7014814130962 0.450843545115964 +18.7260062023997 0.514834241842101 +18.7505309917033 0.494473565611057 +18.7750557810068 0.494473565611057 +18.7995805703104 0.529377582007132 +18.8241053596139 0.491564897578051 +18.8486301489174 0.511925573809094 +18.873154938221 0.514834241842101 +18.8976797275245 0.593368278733268 +18.9222045168281 0.53810358610615 +18.9467293061316 0.587550942667256 +18.9712540954351 0.535194918073144 +18.9957788847387 0.625363627096337 +19.0203036740422 0.683536987756461 +19.0448284633458 0.6079116188983 +19.0693532526493 0.567190266436213 +19.0938780419528 0.671902315624436 +19.1184028312564 0.622454959063331 +19.1429276205599 0.660267643492411 +19.1674524098635 0.64572430332738 +19.191977199167 0.671902315624436 +19.2165019884706 0.625363627096337 +19.2410267777741 0.573007602502225 +19.2655515670776 0.619546291030324 +19.2900763563812 0.58464227463425 +19.3146011456847 0.666084979558424 +19.3391259349883 0.654450307426399 +19.3636507242918 0.535194918073144 +19.3881755135953 0.610820286931306 +19.4127003028989 0.567190266436213 +19.4372250922024 0.599185614799281 +19.461749881506 0.555555594304188 +19.4862746708095 0.546829590205169 +19.510799460113 0.555555594304188 +19.5353242494166 0.549738258238175 +19.5598490387201 0.593368278733268 +19.5843738280237 0.657358975459405 +19.6088986173272 0.543920922172163 +19.6334234066308 0.590459610700262 +19.6579481959343 0.53810358610615 +19.6824729852378 0.546829590205169 +19.7069977745414 0.573007602502225 +19.7315225638449 0.541012254139157 +19.7560473531485 0.5613729303702 +19.780572142452 0.613728954964312 +19.8050969317555 0.570098934469219 +19.8296217210591 0.613728954964312 +19.8541465103626 0.596276946766275 +19.8786712996662 0.628272295129343 +19.9031960889697 0.610820286931306 +19.9277208782732 0.514834241842101 +19.9522456675768 0.596276946766275 +19.9767704568803 0.64572430332738 +20.0012952461839 0.590459610700262 +20.0258200354874 0.596276946766275 +20.050344824791 0.570098934469219 +20.0748696140945 0.666084979558424 +20.099394403398 0.657358975459405 +20.1239191927016 0.558464262337194 +20.1484439820051 0.654450307426399 +20.1729687713087 0.703897663987505 +20.1974935606122 0.700988995954499 +20.2220183499157 0.625363627096337 +20.2465431392193 0.663176311525418 +20.2710679285228 0.724258340218548 +20.2955927178264 0.69226299185548 +20.3201175071299 0.802792377109716 +20.3446422964334 0.875509077934872 +20.369167085737 0.750436352515604 +20.3936918750405 0.732984344317567 +20.4182166643441 0.852239733670822 +20.4427414536476 0.875509077934872 +20.4672662429512 0.817335717274747 +20.4917910322547 0.881326414000884 +20.5163158215582 0.945317110727021 +20.5408406108618 0.927865102528984 +20.5653654001653 0.974403791057083 +20.5898901894689 0.90750442629794 +20.6144149787724 1.06166383204727 +20.6389397680759 1.11692852467439 +20.6634645573795 1.15183254107046 +20.687989346683 1.21873190582961 +20.7125141359866 1.29726594272077 +20.7370389252901 1.11401985664138 +20.7615637145936 1.2158232377966 +20.7860885038972 1.34962196731489 +20.8106132932007 1.36998264354593 +20.8351380825043 1.52995938536127 +20.8596628718078 1.47178602470115 +20.8841876611114 1.57068073782336 +20.9087124504149 1.63176276651649 +20.9332372397184 1.75392682390275 +20.957762029022 1.79464817636484 +20.9822868183255 1.77428750013379 +21.0068116076291 1.9662595903122 +21.0313363969326 2.18440969278767 +21.0558611862361 2.4781851641213 +21.0803859755397 2.68179192643173 +21.1049107648432 2.88539868874217 +21.1294355541468 3.27806887319801 +21.1539603434503 3.67946506175287 +21.1784851327538 4.3979060659054 +21.2030099220574 5.39267053319353 +21.2275347113609 6.38743500048165 +21.2520595006645 8.53112334080724 +21.276584289968 10.3635842016012 +21.3011090792716 13.3478776034655 +21.3256338685751 16.9982559848883 +21.3501586578786 20.6922643868062 +21.3746834471822 23.9586985878722 +21.3992082364857 26.4805137724886 +21.4237330257893 26.5474131372478 +21.4482578150928 25.3228638953521 +21.4727826043963 23.374056313238 +21.4973073936999 20.9278664974797 +21.5218321830034 19.173939673577 +21.546356972307 16.6928458414227 +21.5708817616105 13.586388382172 +21.595406550914 11.2623626238001 +21.6199313402176 8.92670219329608 +21.6444561295211 6.82373520543259 +21.6689809188247 5.73880202912127 +21.6935057081282 4.43571875033448 +21.7180304974318 3.94997118882244 +21.7425552867353 3.23734752073592 +21.7670800760388 2.95811538956732 +21.7916048653424 2.54217586084743 +21.8161296546459 2.2920304100089 +21.8406544439495 2.06515430343442 +21.865179233253 1.89063422145404 +21.8897040225565 1.74520081980373 +21.9142288118601 1.53577672142728 +21.9387536011636 1.50669004109722 +21.9632783904672 1.48342069683317 +21.9878031797707 1.25654459025869 +22.0123279690742 1.16637588123549 +22.0368527583778 1.13728920090543 +22.0613775476813 1.12856319680641 +22.0859023369849 1.05293782794825 +22.1104271262884 0.988947131222114 +22.134951915592 0.983129795156102 +22.1594767048955 0.974403791057083 +22.184001494199 0.933682438594996 +22.2085262835026 0.788249036944685 +22.2330510728061 0.863874405802847 +22.2575758621097 0.849331065637816 +22.2821006514132 0.814427049241741 +22.3066254407167 0.869691741868859 +22.3311502300203 0.802792377109716 +22.3556750193238 0.750436352515604 +22.3801998086274 0.846422397604809 +22.4047245979309 0.762071024647629 +22.4292493872344 0.709715000053517 +22.453774176538 0.759162356614623 +22.4782989658415 0.703897663987505 +22.5028237551451 0.738801680383579 +22.5273485444486 0.700988995954499 +22.5518733337522 0.712623668086523 +22.5763981230557 0.654450307426399 +22.6009229123592 0.747527684482598 +22.6254477016628 0.66899364759143 +22.6499724909663 0.654450307426399 +22.6744972802699 0.69226299185548 +22.6990220695734 0.686445655789467 +22.7235468588769 0.6079116188983 +22.7480716481805 0.674810983657443 +22.772596437484 0.53810358610615 +22.7971212267876 0.674810983657443 +22.8216460160911 0.6079116188983 +22.8461708053947 0.526468913974126 +22.8706955946982 0.575916270535231 +22.8952203840017 0.53810358610615 +22.9197451733053 0.605002950865293 +22.9442699626088 0.497382233644063 +22.9687947519124 0.546829590205169 +22.9933195412159 0.625363627096337 +23.0178443305194 0.570098934469219 +23.042369119823 0.529377582007132 +23.0668939091265 0.570098934469219 +23.0914186984301 0.567190266436213 +23.1159434877336 0.491564897578051 +23.1404682770371 0.558464262337194 +23.1649930663407 0.549738258238175 +23.1895178556442 0.509016905776088 +23.2140426449478 0.529377582007132 +23.2385674342513 0.546829590205169 +23.2630922235549 0.482838893479032 +23.2876170128584 0.494473565611057 +23.3121418021619 0.543920922172163 +23.3366665914655 0.605002950865293 +23.361191380769 0.503199569710076 +23.3857161700726 0.514834241842101 +23.4102409593761 0.58464227463425 +23.4347657486796 0.53810358610615 +23.4592905379832 0.541012254139157 +23.4838153272867 0.555555594304188 +23.5083401165903 0.596276946766275 +23.5328649058938 0.587550942667256 +23.5573896951973 0.529377582007132 +23.5819144845009 0.578824938568237 +23.6064392738044 0.628272295129343 +23.630964063108 0.593368278733268 +23.6554888524115 0.485747561512038 +23.6800136417151 0.625363627096337 +23.7045384310186 0.605002950865293 +23.7290632203221 0.634089631195356 +23.7535880096257 0.651541639393393 +23.7781127989292 0.590459610700262 +23.8026375882328 0.625363627096337 +23.8271623775363 0.605002950865293 +23.8516871668398 0.703897663987505 +23.8762119561434 0.596276946766275 +23.9007367454469 0.651541639393393 +23.9252615347505 0.674810983657443 +23.949786324054 0.619546291030324 +23.9743111133575 0.666084979558424 +23.9988359026611 0.689354323822474 +24.0233606919646 0.709715000053517 +24.0478854812682 0.634089631195356 +24.0724102705717 0.759162356614623 +24.0969350598753 0.718441004152536 +24.1214598491788 0.796975041043704 +24.1459846384823 0.895869754165915 +24.1705094277859 0.744619016449592 +24.1950342170894 0.866783073835853 +24.219559006393 0.843513729571803 +24.2440837956965 0.919139098429965 +24.268608585 0.828970389406772 +24.2931333743036 0.828970389406772 +24.3176581636071 0.892961086132909 +24.3421829529107 0.924956434495977 +24.3667077422142 0.95404311482604 +24.3912325315177 0.942408442694015 +24.4157573208213 0.95404311482604 +24.4402821101248 0.939499774661008 +24.4648068994284 1.0762071722123 +24.4893316887319 1.16346721320249 +24.5138564780355 1.21000590173059 +24.538381267339 1.10529385254236 +24.5629060566425 1.25654459025869 +24.5874308459461 1.24490991812666 +24.6119556352496 1.31762661895182 +24.6364804245532 1.41652133207403 +24.6610052138567 1.37870864764495 +24.6855300031602 1.56195473372434 +24.7100547924638 1.62885409848348 +24.7345795817673 1.61431075831845 +24.7591043710709 1.74810948783674 +24.7836291603744 1.93426424194913 +24.8081539496779 1.95753358621318 +24.8326787389815 2.28621307394289 +24.857203528285 2.42582913952719 +24.8817283175886 2.57707987724351 +24.9062531068921 2.94066338136929 +24.9307778961957 3.81326379127115 +24.9553026854992 4.60442149624884 +24.9798274748027 5.38685319712752 +25.0043522641063 6.80919186526756 +25.0288770534098 8.66492207032552 +25.0534018427134 10.8638751032782 +25.0779266320169 13.577662378073 +25.1024514213204 16.4979650832113 +25.126976210624 19.2553823785012 +25.1515009999275 20.4886576244958 +25.1760257892311 20.5410136490899 +25.2005505785346 19.2175696940721 +25.2250753678381 17.751601005437 +25.2496001571417 16.3118103290989 +25.2741249464452 14.9214670093219 +25.2986497357488 14.5317054928991 +25.3231745250523 12.4607338533986 +25.3476993143559 10.7038983614629 +25.3722241036594 8.79872079984381 +25.3967488929629 7.17277536939333 +25.4212736822665 5.87841809470557 +25.44579847157 4.41826674213644 +25.4703232608736 3.85689381176624 +25.4948480501771 3.39441559451826 +25.5193728394806 2.79813864775198 +25.5438976287842 2.3880164550981 +25.5684224180877 2.1495056763916 +25.5929472073913 1.98371159851024 +25.6174719966948 1.90226889358607 +25.6419967859983 1.60267608618643 +25.6665215753019 1.54741139355931 +25.6910463646054 1.5415940574933 +25.715571153909 1.4514253484701 +25.7400959432125 1.33798729518286 +25.7646207325161 1.36998264354593 +25.7891455218196 1.31471795091881 +25.8136703111231 1.21291456976359 +25.8381951004267 1.14601520500445 +25.8627198897302 1.15764987713647 +25.8872446790338 1.14892387303746 +25.9117694683373 1.08202450827831 +25.9362942576408 1.18091922140052 +25.9608190469444 1.04421182384923 +25.9853438362479 1.23327524599464 +26.0098686255515 1.11692852467439 +26.034393414855 1.27981393452274 +26.0589182041585 1.24781858615967 +26.0834429934621 1.44560801240409 +26.1079677827656 1.58231540995538 +26.1324925720692 1.72774881160569 +26.1570173613727 1.92553823785012 +26.1815421506763 2.41128579936216 +26.2060669399798 2.76905196742192 +26.2305917292833 3.19662616827383 +26.2551165185869 3.96160586095447 +26.2796413078904 3.98487520521852 +26.304166097194 4.17393862736392 +26.3286908864975 3.98196653718551 +26.353215675801 3.9296105125914 +26.3777404651046 3.48749297157446 +26.4022652544081 3.46422362731041 +26.4267900437117 3.06573610678855 +26.4513148330152 2.82431666004904 +26.4758396223187 2.60325788954057 +26.5003644116223 2.32111709033896 +26.5248892009258 1.86445620915699 +26.5494139902294 1.46015135256912 +26.5739387795329 1.45433401650311 +26.5984635688365 1.23909258206065 +26.62298835814 1.19255389353255 +26.6475131474435 1.07911584024531 +26.6720379367471 0.869691741868859 +26.6965627260506 0.875509077934872 +26.7210875153542 0.770797028746648 +26.7456123046577 0.689354323822474 +26.7701370939612 0.683536987756461 +26.7946618832648 0.654450307426399 +26.8191866725683 0.651541639393393 +26.8437114618719 0.581733606601244 +26.8682362511754 0.58464227463425 +26.8927610404789 0.631180963162349 +26.9172858297825 0.555555594304188 +26.941810619086 0.514834241842101 +26.9663354083896 0.552646926271182 +26.9908601976931 0.573007602502225 +27.0153849869967 0.532286250040138 +27.0399097763002 0.407213524620871 +27.0644345656037 0.578824938568237 +27.0889593549073 0.514834241842101 +27.1134841442108 0.47702155741302 +27.1380089335144 0.506108237743082 +27.1625337228179 0.511925573809094 +27.1870585121214 0.488656229545045 +27.211583301425 0.494473565611057 +27.2361080907285 0.511925573809094 +27.2606328800321 0.497382233644063 +27.2851576693356 0.488656229545045 +27.3096824586391 0.506108237743082 +27.3342072479427 0.47702155741302 +27.3587320372462 0.459569549214982 +27.3832568265498 0.482838893479032 +27.4077816158533 0.340314159861727 +27.4323064051569 0.474112889380014 +27.4568311944604 0.43048286888492 +27.4813559837639 0.398487520521852 +27.5058807730675 0.506108237743082 +27.530405562371 0.404304856587864 +27.5549303516746 0.398487520521852 +27.5794551409781 0.398487520521852 +27.6039799302816 0.413030860686883 +27.6285047195852 0.488656229545045 +27.6530295088887 0.482838893479032 +27.6775542981923 0.389761516422833 +27.7020790874958 0.395578852488846 +27.7266038767993 0.363583504125777 +27.7511286661029 0.383944180356821 +27.7756534554064 0.418848196752895 +27.80017824471 0.354857500026759 +27.8247030340135 0.401396188554858 +27.8492278233171 0.375218176257802 +27.8737526126206 0.436300204950933 +27.8982774019241 0.340314159861727 +27.9228021912277 0.363583504125777 +27.9473269805312 0.392670184455839 +27.9718517698348 0.357766168059765 +27.9963765591383 0.395578852488846 +28.0209013484418 0.351948831993752 +28.0454261377454 0.459569549214982 +28.0699509270489 0.407213524620871 +28.0944757163525 0.389761516422833 +28.119000505656 0.389761516422833 +28.1435252949595 0.340314159861727 +28.1680500842631 0.410122192653877 +28.1925748735666 0.36940084019179 +28.2170996628702 0.360674836092771 +28.2416244521737 0.363583504125777 +28.2661492414773 0.381035512323815 +28.2906740307808 0.378126844290808 +28.3151988200843 0.337405491828721 +28.3397236093879 0.410122192653877 +28.3642483986914 0.389761516422833 +28.388773187995 0.36940084019179 +28.4132979772985 0.372309508224796 +28.437822766602 0.407213524620871 +28.4623475559056 0.340314159861727 +28.4868723452091 0.366492172158783 +28.5113971345127 0.407213524620871 +28.5359219238162 0.375218176257802 +28.5604467131197 0.424665532818908 +28.5849715024233 0.378126844290808 +28.6094962917268 0.36940084019179 +28.6340210810304 0.363583504125777 +28.6585458703339 0.386852848389827 +28.6830706596375 0.386852848389827 +28.707595448941 0.343222827894734 +28.7321202382445 0.410122192653877 +28.7566450275481 0.354857500026759 +28.7811698168516 0.395578852488846 +28.8056946061552 0.404304856587864 +28.8302193954587 0.378126844290808 +28.8547441847622 0.343222827894734 +28.8792689740658 0.381035512323815 +28.9037937633693 0.410122192653877 +28.9283185526729 0.340314159861727 +28.9528433419764 0.410122192653877 +28.9773681312799 0.354857500026759 +29.0018929205835 0.418848196752895 +29.026417709887 0.29959280739964 +29.0509424991906 0.424665532818908 +29.0754672884941 0.378126844290808 +29.0999920777977 0.351948831993752 +29.1245168671012 0.383944180356821 +29.1490416564047 0.36940084019179 +29.1735664457083 0.415939528719889 +29.1980912350118 0.421756864785902 +29.2226160243154 0.45375221314897 +29.2471408136189 0.424665532818908 +29.2716656029224 0.418848196752895 +29.296190392226 0.424665532818908 +29.3207151815295 0.424665532818908 +29.3452399708331 0.343222827894734 +29.3697647601366 0.398487520521852 +29.3942895494401 0.450843545115964 +29.4188143387437 0.479930225446026 +29.4433391280472 0.462478217247989 +29.4678639173508 0.386852848389827 +29.4923887066543 0.462478217247989 +29.5169134959579 0.450843545115964 +29.5414382852614 0.482838893479032 +29.5659630745649 0.47702155741302 +29.5904878638685 0.433391536917926 +29.615012653172 0.459569549214982 +29.6395374424756 0.421756864785902 +29.6640622317791 0.491564897578051 +29.6885870210826 0.450843545115964 +29.7131118103862 0.456660881181976 +29.7376365996897 0.523560245941119 +29.7621613889933 0.520651577908113 +29.7866861782968 0.503199569710076 +29.8112109676003 0.485747561512038 +29.8357357569039 0.526468913974126 +29.8602605462074 0.541012254139157 +29.884785335511 0.485747561512038 +29.9093101248145 0.514834241842101 +29.9338349141181 0.497382233644063 +29.9583597034216 0.543920922172163 +29.9828844927251 0.570098934469219 +30.0074092820287 0.575916270535231 +30.0319340713322 0.564281598403206 +30.0564588606358 0.590459610700262 +30.0809836499393 0.590459610700262 +30.1055084392428 0.654450307426399 +30.1300332285464 0.732984344317567 +30.1545580178499 0.735893012350573 +30.1790828071535 0.796975041043704 +30.203607596457 0.834787725472785 +30.2281323857605 1.01512514351917 +30.2526571750641 1.09365918041034 +30.2771819643676 1.15474120910347 +30.3017067536712 1.4950553689652 +30.3262315429747 1.84118686489294 +30.3507563322783 2.22222237721675 +30.3752811215818 2.7574172952899 +30.3998059108853 3.35660291008918 +30.4243307001889 4.00814454948257 +30.4488554894924 3.99941854538355 +30.473380278796 4.09831325850576 +30.4979050680995 3.68819106585188 +30.522429857403 3.42641094288132 +30.5469546467066 3.08318811498659 +30.5714794360101 2.87376401661014 +30.5960042253137 2.6207098977386 +30.6205290146172 2.73705661905885 +30.6450538039207 2.62361856577161 +30.6695785932243 2.24840038951381 +30.6941033825278 2.10005831983049 +30.7186281718314 1.64339743864851 +30.7431529611349 1.50087270503121 +30.7676777504385 1.21291456976359 +30.792202539742 1.0267598156512 +30.8167273290455 0.878417745967878 +30.8412521183491 0.817335717274747 +30.8657769076526 0.773705696779654 +30.8903016969562 0.738801680383579 +30.9148264862597 0.657358975459405 +30.9393512755632 0.552646926271182 +30.9638760648668 0.634089631195356 +30.9884008541703 0.660267643492411 +31.0129256434739 0.573007602502225 +31.0374504327774 0.552646926271182 +31.0619752220809 0.578824938568237 +31.0865000113845 0.494473565611057 +31.111024800688 0.555555594304188 +31.1355495899916 0.523560245941119 +31.1600743792951 0.485747561512038 +31.1845991685987 0.526468913974126 +31.2091239579022 0.485747561512038 +31.2336487472057 0.47702155741302 +31.2581735365093 0.520651577908113 +31.2826983258128 0.465386885280995 +31.3072231151164 0.389761516422833 +31.3317479044199 0.465386885280995 +31.3562726937234 0.471204221347007 +31.380797483027 0.520651577908113 +31.4053222723305 0.424665532818908 +31.4298470616341 0.439208872983939 +31.4543718509376 0.415939528719889 +31.4788966402411 0.468295553314001 +31.5034214295447 0.433391536917926 +31.5279462188482 0.442117541016945 +31.5524710081518 0.418848196752895 +31.5769957974553 0.53810358610615 +31.6015205867589 0.45375221314897 +31.6260453760624 0.36940084019179 +31.6505701653659 0.450843545115964 +31.6750949546695 0.462478217247989 +31.699619743973 0.447934877082958 +31.7241445332766 0.418848196752895 +31.7486693225801 0.456660881181976 +31.7731941118836 0.424665532818908 +31.7977189011872 0.447934877082958 +31.8222436904907 0.410122192653877 +31.8467684797943 0.445026209049951 +31.8712932690978 0.47702155741302 +31.8958180584013 0.471204221347007 +31.9203428477049 0.535194918073144 +31.9448676370084 0.564281598403206 +31.969392426312 0.479930225446026 +31.9939172156155 0.514834241842101 +32.0184420049191 0.532286250040138 +32.0429667942226 0.503199569710076 +32.0674915835261 0.5613729303702 +32.0920163728297 0.462478217247989 +32.1165411621332 0.520651577908113 +32.1410659514368 0.564281598403206 +32.1655907407403 0.555555594304188 +32.1901155300438 0.573007602502225 +32.2146403193474 0.581733606601244 +32.2391651086509 0.549738258238175 +32.2636898979545 0.529377582007132 +32.288214687258 0.6079116188983 +32.3127394765615 0.596276946766275 +32.3372642658651 0.605002950865293 +32.3617890551686 0.523560245941119 +32.3863138444722 0.610820286931306 +32.4108386337757 0.642815635294374 +32.4353634230793 0.709715000053517 +32.4598882123828 0.5613729303702 +32.4844130016863 0.66899364759143 +32.5089377909899 0.610820286931306 +32.5334625802934 0.619546291030324 +32.557987369597 0.698080327921492 +32.5825121589005 0.698080327921492 +32.607036948204 0.762071024647629 +32.6315617375076 0.747527684482598 +32.6560865268111 0.680628319723455 +32.6806113161147 0.721349672185542 +32.7051361054182 0.817335717274747 +32.7296608947217 0.671902315624436 +32.7541856840253 0.741710348416586 +32.7787104733288 0.814427049241741 +32.8032352626324 0.843513729571803 +32.8277600519359 0.933682438594996 +32.8522848412395 0.916230430396959 +32.876809630543 1.13147186483942 +32.9013344198465 1.05584649598126 +32.9258592091501 1.1227458607404 +32.9503839984536 1.18382788943353 +32.9749087877572 1.38743465174397 +32.9994335770607 1.55613739765833 +33.0239583663642 1.69575346324262 +33.0484831556678 1.93717290998214 +33.0730079449713 2.36183844280105 +33.0975327342749 2.71669594282781 +33.1220575235784 3.21116950843887 +33.1465823128819 4.01396188554858 +33.1711071021855 5.23269379137819 +33.195631891489 6.06748151685097 +33.2201566807926 7.24258340218548 +33.2446814700961 7.59744090221224 +33.2692062593997 7.92321172190894 +33.2937310487032 7.9988370907671 +33.3182558380067 7.26294407841653 +33.3427806273103 6.50669038983491 +33.3673054166138 6.2216409226003 +33.3918302059174 5.72135002092323 +33.4163549952209 5.45666122991967 +33.4408797845244 5.39267053319353 +33.465404573828 5.2414197954772 +33.4899293631315 4.8632929511864 +33.5144541524351 4.38918006180638 +33.5389789417386 3.80453778717213 +33.5635037310421 3.01628875022745 +33.5880285203457 2.77777797152094 +33.6125533096492 2.1495056763916 +33.6370780989528 1.9197209017841 +33.6616028882563 1.68993612717661 +33.6861276775599 1.50959870913023 +33.7106524668634 1.43106467223906 +33.7351772561669 1.5445027255263 +33.7597020454705 1.34380463124887 +33.784226834774 1.29435727468777 +33.8087516240776 1.23327524599464 +33.8332764133811 1.29726594272077 +33.8578012026846 1.35253063534789 +33.8823259919882 1.40779532797501 +33.9068507812917 1.5445027255263 +33.9313755705953 1.61431075831845 +33.9559003598988 1.81210018456287 +33.9804251492023 1.93426424194913 +34.0049499385059 2.29493907804191 +34.0294747278094 2.81849932398303 +34.053999517113 3.33624223385813 +34.0785243064165 3.93833651669042 +34.1030490957201 4.73822022576713 +34.1275738850236 5.30831916023635 +34.1520986743271 5.27632381187328 +34.1766234636307 5.40139653729255 +34.2011482529342 5.18615510285009 +34.2256730422378 4.46480543066455 +34.2501978315413 4.0692265781757 +34.2747226208448 3.9296105125914 +34.2992474101484 3.7870857789741 +34.3237721994519 3.51657965190452 +34.3482969887555 3.31006422156108 +34.372821778059 3.30133821746206 +34.3973465673625 3.2286215166369 +34.4218713566661 2.63234456987063 +34.4463961459696 2.13205366819356 +34.4709209352732 1.86736487718999 +34.4954457245767 1.55613739765833 +34.5199705138803 1.38161731567795 +34.5444953031838 1.34962196731489 +34.5690200924873 1.19255389353255 +34.5935448817909 0.901687090231928 +34.6180696710944 0.872600409901865 +34.642594460398 0.791157704977691 +34.6671192497015 0.860965737769841 +34.691644039005 0.782431700878673 +34.7161688283086 0.747527684482598 +34.7406936176121 0.680628319723455 +34.7652184069157 0.599185614799281 +34.7897431962192 0.66899364759143 +34.8142679855227 0.639906967261368 +34.8387927748263 0.622454959063331 +34.8633175641298 0.634089631195356 +34.8878423534334 0.596276946766275 +34.9123671427369 0.610820286931306 +34.9368919320405 0.500290901677069 +34.961416721344 0.532286250040138 +34.9859415106475 0.634089631195356 +35.0104662999511 0.567190266436213 +35.0349910892546 0.526468913974126 +35.0595158785582 0.526468913974126 +35.0840406678617 0.520651577908113 +35.1085654571652 0.526468913974126 +35.1330902464688 0.541012254139157 +35.1576150357723 0.488656229545045 +35.1821398250759 0.482838893479032 +35.2066646143794 0.488656229545045 +35.2311894036829 0.465386885280995 +35.2557141929865 0.445026209049951 +35.28023898229 0.456660881181976 +35.3047637715936 0.450843545115964 +35.3292885608971 0.479930225446026 +35.3538133502007 0.514834241842101 +35.3783381395042 0.459569549214982 +35.4028629288077 0.442117541016945 +35.4273877181113 0.494473565611057 +35.4519125074148 0.520651577908113 +35.4764372967184 0.491564897578051 +35.5009620860219 0.500290901677069 +35.5254868753254 0.439208872983939 +35.550011664629 0.43048286888492 +35.5745364539325 0.436300204950933 +35.5990612432361 0.479930225446026 +35.6235860325396 0.424665532818908 +35.6481108218431 0.482838893479032 +35.6726356111467 0.482838893479032 +35.6971604004502 0.509016905776088 +35.7216851897538 0.433391536917926 +35.7462099790573 0.43048286888492 +35.7707347683609 0.479930225446026 +35.7952595576644 0.43048286888492 +35.8197843469679 0.523560245941119 +35.8443091362715 0.485747561512038 +35.868833925575 0.445026209049951 +35.8933587148786 0.415939528719889 +35.9178835041821 0.459569549214982 +35.9424082934856 0.471204221347007 +35.9669330827892 0.415939528719889 +35.9914578720927 0.413030860686883 +36.0159826613963 0.445026209049951 +36.0405074506998 0.479930225446026 +36.0650322400033 0.462478217247989 +36.0895570293069 0.468295553314001 +36.1140818186104 0.523560245941119 +36.138606607914 0.413030860686883 +36.1631313972175 0.47702155741302 +36.1876561865211 0.485747561512038 +36.2121809758246 0.491564897578051 +36.2367057651281 0.506108237743082 +36.2612305544317 0.494473565611057 +36.2857553437352 0.462478217247989 +36.3102801330388 0.47702155741302 +36.3348049223423 0.43048286888492 +36.3593297116458 0.511925573809094 +36.3838545009494 0.503199569710076 +36.4083792902529 0.474112889380014 +36.4329040795565 0.491564897578051 +36.45742886886 0.552646926271182 +36.4819536581635 0.532286250040138 +36.5064784474671 0.494473565611057 +36.5310032367706 0.58464227463425 +36.5555280260742 0.500290901677069 +36.5800528153777 0.532286250040138 +36.6045776046813 0.555555594304188 +36.6291023939848 0.578824938568237 +36.6536271832883 0.619546291030324 +36.6781519725919 0.541012254139157 +36.7026767618954 0.543920922172163 +36.727201551199 0.5613729303702 +36.7517263405025 0.58464227463425 +36.776251129806 0.570098934469219 +36.8007759191096 0.511925573809094 +36.8253007084131 0.590459610700262 +36.8498254977167 0.648632971360387 +36.8743502870202 0.628272295129343 +36.8988750763237 0.66899364759143 +36.9233998656273 0.625363627096337 +36.9479246549308 0.703897663987505 +36.9724494442344 0.764979692680635 +36.9969742335379 0.703897663987505 +37.0214990228415 0.756253688581617 +37.046023812145 0.721349672185542 +37.0705486014485 0.788249036944685 +37.0950733907521 0.869691741868859 +37.1195981800556 0.805701045142722 +37.1441229693592 0.901687090231928 +37.1686477586627 0.945317110727021 +37.1931725479662 1.10529385254236 +37.2176973372698 1.14019786893844 +37.2422221265733 1.27981393452274 +37.2667469158769 1.37579997961194 +37.2912717051804 1.41652133207403 +37.3157964944839 1.80046551243085 +37.3403212837875 1.97789426244423 +37.364846073091 2.39674245919712 +37.3893708623946 2.85049467234609 +37.4138956516981 3.65328704945581 +37.4384204410017 4.40663207000442 +37.4629452303052 5.29377582007132 +37.4874700196087 6.08784219308201 +37.5119948089123 6.67248446771626 +37.5365195982158 6.9691686070829 +37.5610443875194 6.62012844312215 +37.5855691768229 6.06166418078496 +37.6100939661264 5.30541049220334 +37.63461875543 4.89819696758247 +37.6591435447335 4.54915680362172 +37.6836683340371 4.35718471344331 +37.7081931233406 4.34555004131129 +37.7327179126441 4.2553813322881 +37.7572427019477 4.49680077902761 +37.7817674912512 3.81617245930416 +37.8062922805548 3.61256569699372 +37.8308170698583 3.06864477482156 +37.8553418591619 2.68179192643173 +37.8798666484654 2.16114034852362 +37.9043914377689 1.93135557391613 +37.9289162270725 1.70157079930864 +37.953441016376 1.27690526648973 +37.9779658056796 1.13728920090543 +38.0024905949831 1.13147186483942 +38.0270153842866 0.866783073835853 +38.0515401735902 0.965677786958064 +38.0760649628937 0.898778422198921 +38.1005897521973 0.959860450892052 +38.1251145415008 0.875509077934872 +38.1496393308043 0.759162356614623 +38.1741641201079 0.709715000053517 +38.1986889094114 0.660267643492411 +38.223213698715 0.66899364759143 +38.2477384880185 0.666084979558424 +38.2722632773221 0.695171659888486 +38.2967880666256 0.587550942667256 +38.3213128559291 0.619546291030324 +38.3458376452327 0.698080327921492 +38.3703624345362 0.674810983657443 +38.3948872238398 0.689354323822474 +38.4194120131433 0.616637622997318 +38.4439368024468 0.541012254139157 +38.4684615917504 0.593368278733268 +38.4929863810539 0.497382233644063 +38.5175111703575 0.58464227463425 +38.542035959661 0.546829590205169 +38.5665607489645 0.660267643492411 +38.5910855382681 0.581733606601244 +38.6156103275716 0.590459610700262 +38.6401351168752 0.509016905776088 +38.6646599061787 0.558464262337194 +38.6891846954823 0.506108237743082 +38.7137094847858 0.575916270535231 +38.7382342740893 0.58464227463425 +38.7627590633929 0.520651577908113 +38.7872838526964 0.532286250040138 +38.811808642 0.549738258238175 +38.8363334313035 0.549738258238175 +38.860858220607 0.546829590205169 +38.8853830099106 0.514834241842101 +38.9099077992141 0.509016905776088 +38.9344325885177 0.541012254139157 +38.9589573778212 0.575916270535231 +38.9834821671247 0.45375221314897 +39.0080069564283 0.532286250040138 +39.0325317457318 0.567190266436213 +39.0570565350354 0.599185614799281 +39.0815813243389 0.53810358610615 +39.1061061136425 0.602094282832287 +39.130630902946 0.497382233644063 +39.1551556922495 0.581733606601244 +39.1796804815531 0.657358975459405 +39.2042052708566 0.564281598403206 +39.2287300601602 0.549738258238175 +39.2532548494637 0.596276946766275 +39.2777796387672 0.596276946766275 +39.3023044280708 0.587550942667256 +39.3268292173743 0.599185614799281 +39.3513540066779 0.657358975459405 +39.3758787959814 0.610820286931306 +39.4004035852849 0.634089631195356 +39.4249283745885 0.671902315624436 +39.449453163892 0.721349672185542 +39.4739779531956 0.66899364759143 +39.4985027424991 0.730075676284561 +39.5230275318027 0.791157704977691 +39.5475523211062 0.90750442629794 +39.5720771104097 0.968586454991071 +39.5966018997133 1.07038983614629 +39.6211266890168 1.08493317631132 +39.6456514783204 1.1227458607404 +39.6701762676239 1.44560801240409 +39.6947010569274 1.55613739765833 +39.719225846231 1.97789426244423 +39.7437506355345 2.19313569688669 +39.7682754248381 2.42582913952719 +39.7928002141416 3.17335682400978 +39.8173250034451 3.93542784865741 +39.8418497927487 4.68586420117302 +39.8663745820522 5.3315885045004 +39.8908993713558 5.76788870945133 +39.9154241606593 5.44793522582065 +39.9399489499629 5.33740584056641 +39.9644737392664 4.7236768856021 +39.9889985285699 4.31937202901423 +40.0135233178735 3.5573010043666 +40.038048107177 3.53112299206955 +40.0625728964806 3.43804561501335 +40.0870976857841 3.48458430354145 +40.1116224750876 3.56020967239961 +40.1361472643912 3.26352553303298 +40.1606720536947 3.35951157812218 +40.1851968429983 2.98720206989739 +40.2097216323018 2.53054118871541 +40.2342464216053 2.2454917214808 +40.2587712109089 1.83827819685993 +40.2832960002124 1.56486340175735 +40.307820789516 1.37289131157893 +40.3323455788195 1.16346721320249 +40.3568703681231 1.06166383204727 +40.3813951574266 0.968586454991071 +40.4059199467301 0.933682438594996 +40.4304447360337 0.794066373010698 +40.4549695253372 0.79988370907671 +40.4794943146408 0.782431700878673 +40.5040191039443 0.703897663987505 +40.5285438932478 0.689354323822474 +40.5530686825514 0.642815635294374 +40.5775934718549 0.642815635294374 +40.6021182611585 0.628272295129343 +40.626643050462 0.570098934469219 +40.6511678397655 0.570098934469219 +40.6756926290691 0.532286250040138 +40.7002174183726 0.543920922172163 +40.7247422076762 0.450843545115964 +40.7492669969797 0.497382233644063 +40.7737917862833 0.511925573809094 +40.7983165755868 0.546829590205169 +40.8228413648903 0.450843545115964 +40.8473661541939 0.506108237743082 +40.8718909434974 0.474112889380014 +40.896415732801 0.535194918073144 +40.9209405221045 0.485747561512038 +40.945465311408 0.413030860686883 +40.9699901007116 0.485747561512038 +40.9945148900151 0.407213524620871 +41.0190396793187 0.445026209049951 +41.0435644686222 0.433391536917926 +41.0680892579257 0.439208872983939 +41.0926140472293 0.462478217247989 +41.1171388365328 0.479930225446026 +41.1416636258364 0.407213524620871 +41.1661884151399 0.401396188554858 +41.1907132044435 0.418848196752895 +41.215237993747 0.413030860686883 +41.2397627830505 0.43048286888492 +41.2642875723541 0.407213524620871 +41.2888123616576 0.45375221314897 +41.3133371509612 0.459569549214982 +41.3378619402647 0.447934877082958 +41.3623867295682 0.418848196752895 +41.3869115188718 0.392670184455839 +41.4114363081753 0.427574200851914 +41.4359610974789 0.386852848389827 +41.4604858867824 0.404304856587864 +41.4850106760859 0.421756864785902 +41.5095354653895 0.395578852488846 +41.534060254693 0.407213524620871 +41.5585850439966 0.392670184455839 +41.5831098333001 0.439208872983939 +41.6076346226037 0.398487520521852 +41.6321594119072 0.395578852488846 +41.6566842012107 0.415939528719889 +41.6812089905143 0.445026209049951 +41.7057337798178 0.418848196752895 +41.7302585691214 0.407213524620871 +41.7547833584249 0.349040163960746 +41.7793081477284 0.363583504125777 +41.803832937032 0.413030860686883 +41.8283577263355 0.360674836092771 +41.8528825156391 0.375218176257802 +41.8774073049426 0.410122192653877 +41.9019320942461 0.36940084019179 +41.9264568835497 0.398487520521852 +41.9509816728532 0.372309508224796 +41.9755064621568 0.381035512323815 +42.0000312514603 0.401396188554858 +42.0245560407639 0.445026209049951 +42.0490808300674 0.366492172158783 +42.0736056193709 0.334496823795715 +42.0981304086745 0.404304856587864 +42.122655197978 0.378126844290808 +42.1471799872816 0.366492172158783 +42.1717047765851 0.360674836092771 +42.1962295658886 0.381035512323815 +42.2207543551922 0.354857500026759 +42.2452791444957 0.366492172158783 +42.2698039337993 0.354857500026759 +42.2943287231028 0.378126844290808 +42.3188535124063 0.418848196752895 +42.3433783017099 0.386852848389827 +42.3679030910134 0.360674836092771 +42.392427880317 0.404304856587864 +42.4169526696205 0.442117541016945 +42.4414774589241 0.381035512323815 +42.4660022482276 0.32286215166369 +42.4905270375311 0.378126844290808 +42.5150518268347 0.418848196752895 +42.5395766161382 0.462478217247989 +42.5641014054418 0.354857500026759 +42.5886261947453 0.366492172158783 +42.6131509840488 0.404304856587864 +42.6376757733524 0.372309508224796 +42.6622005626559 0.415939528719889 +42.6867253519595 0.447934877082958 +42.711250141263 0.383944180356821 +42.7357749305665 0.395578852488846 +42.7602997198701 0.509016905776088 +42.7848245091736 0.427574200851914 +42.8093492984772 0.418848196752895 +42.8338740877807 0.450843545115964 +42.8583988770843 0.386852848389827 +42.8829236663878 0.378126844290808 +42.9074484556913 0.433391536917926 +42.9319732449949 0.43048286888492 +42.9564980342984 0.474112889380014 +42.981022823602 0.479930225446026 +43.0055476129055 0.45375221314897 +43.030072402209 0.482838893479032 +43.0545971915126 0.410122192653877 +43.0791219808161 0.474112889380014 +43.1036467701197 0.482838893479032 +43.1281715594232 0.494473565611057 +43.1526963487267 0.529377582007132 +43.1772211380303 0.427574200851914 +43.2017459273338 0.474112889380014 +43.2262707166374 0.541012254139157 +43.2507955059409 0.573007602502225 +43.2753202952445 0.587550942667256 +43.299845084548 0.66899364759143 +43.3243698738515 0.613728954964312 +43.3488946631551 0.671902315624436 +43.3734194524586 0.759162356614623 +43.3979442417622 0.802792377109716 +43.4224690310657 0.866783073835853 +43.4469938203692 1.00639913942015 +43.4715186096728 1.23618391402764 +43.4960433989763 1.42524733617305 +43.5205681882799 1.6375801025825 +43.5450929775834 1.92262956981711 +43.569617766887 2.1029669878635 +43.5941425561905 2.13787100425957 +43.618667345494 2.13205366819356 +43.6431921347976 2.07678897556644 +43.6677169241011 1.90808622965208 +43.6922417134047 1.9168122337511 +43.7167665027082 1.51541604519624 +43.7412912920117 1.50669004109722 +43.7658160813153 1.4485166804371 +43.7903408706188 1.36998264354593 +43.8148656599224 1.47760336076716 +43.8393904492259 1.53577672142728 +43.8639152385294 1.401977991909 +43.888440027833 1.46306002060213 +43.9129648171365 1.28272260255574 +43.9374896064401 1.33507862714985 +43.9620143957436 1.09656784844334 +43.9865391850472 0.956951782859046 +44.0110639743507 0.837696393505791 +44.0355887636542 0.892961086132909 +44.0601135529578 0.718441004152536 +44.0846383422613 0.680628319723455 +44.1091631315649 0.636998299228362 +44.1336879208684 0.64572430332738 +44.1582127101719 0.573007602502225 +44.1827374994755 0.593368278733268 +44.207262288779 0.58464227463425 +44.2317870780826 0.532286250040138 +44.2563118673861 0.575916270535231 +44.2808366566896 0.500290901677069 +44.3053614459932 0.625363627096337 +44.3298862352967 0.599185614799281 +44.3544110246003 0.555555594304188 +44.3789358139038 0.43048286888492 +44.4034606032074 0.47702155741302 +44.4279853925109 0.497382233644063 +44.4525101818144 0.459569549214982 +44.477034971118 0.506108237743082 +44.5015597604215 0.570098934469219 +44.5260845497251 0.511925573809094 +44.5506093390286 0.622454959063331 +44.5751341283321 0.520651577908113 +44.5996589176357 0.509016905776088 +44.6241837069392 0.517742909875107 +44.6487084962428 0.529377582007132 +44.6732332855463 0.529377582007132 +44.6977580748498 0.541012254139157 +44.7222828641534 0.590459610700262 +44.7468076534569 0.58464227463425 +44.7713324427605 0.593368278733268 +44.795857232064 0.494473565611057 +44.8203820213676 0.503199569710076 +44.8449068106711 0.570098934469219 +44.8694315999746 0.526468913974126 +44.8939563892782 0.610820286931306 +44.9184811785817 0.66899364759143 +44.9430059678853 0.619546291030324 +44.9675307571888 0.575916270535231 +44.9920555464923 0.552646926271182 +45.0165803357959 0.642815635294374 +45.0411051250994 0.660267643492411 +45.065629914403 0.610820286931306 +45.0901547037065 0.703897663987505 +45.11467949301 0.642815635294374 +45.1392042823136 0.674810983657443 +45.1637290716171 0.66899364759143 +45.1882538609207 0.721349672185542 +45.2127786502242 0.695171659888486 +45.2373034395278 0.738801680383579 +45.2618282288313 0.71553233611953 +45.2863530181348 0.794066373010698 +45.3108778074384 0.82315305334076 +45.3354025967419 0.913321762363952 +45.3599273860455 0.866783073835853 +45.384452175349 0.869691741868859 +45.4089769646525 1.09365918041034 +45.4335017539561 1.25072725419267 +45.4580265432596 1.15474120910347 +45.4825513325632 1.43688200830507 +45.5070761218667 1.53286805339428 +45.5316009111702 1.83536952882692 +45.5561257004738 2.30075641410792 +45.5806504897773 2.46364182395627 +45.6051752790809 3.01628875022745 +45.6297000683844 3.6009310248617 +45.654224857688 4.09831325850576 +45.6787496469915 4.76439823806419 +45.703274436295 4.92728364791253 +45.7277992255986 5.27632381187328 +45.7523240149021 5.24432846351021 +45.7768488042057 4.40954073803743 +45.8013735935092 4.1623039552319 +45.8258983828127 3.6969170699509 +45.8504231721163 3.25770819696696 +45.8749479614198 3.26352553303298 +45.8994727507234 2.91739403710524 +45.9239975400269 3.15008747974573 +45.9485223293304 3.28097754123101 +45.973047118634 3.275160205165 +45.9975719079375 3.09191411908561 +46.0220966972411 3.1820828281088 +46.0466214865446 2.92612004120426 +46.0711462758482 2.82431666004904 +46.0956710651517 2.35020377066902 +46.1201958544552 2.05351963130239 +46.1447206437588 1.97789426244423 +46.1692454330623 1.88772555342104 +46.1937702223659 1.67539278701158 +46.2182950116694 1.75974415996876 +46.2428198009729 1.71611413947367 +46.2673445902765 1.72774881160569 +46.29186937958 1.88481688538803 +46.3163941688836 2.12332766409454 +46.3409189581871 2.35602110673504 +46.3654437474906 2.63525323790363 +46.3899685367942 2.79522997971898 +46.4144933260977 2.74287395512486 +46.4390181154013 2.48691116822032 +46.4635429047048 2.56253653707848 +46.4880676940084 2.16695768458963 +46.5125924833119 2.07388030753343 +46.5371172726154 1.89936022555306 +46.561642061919 1.67248411897858 +46.5861668512225 1.50087270503121 +46.6106916405261 1.55613739765833 +46.6352164298296 1.78301350423281 +46.6597412191331 1.64048877061551 +46.6842660084367 1.83827819685993 +46.7087907977402 1.59395008208741 +46.7333155870438 1.70738813537465 +46.7578403763473 1.42815600420605 +46.7823651656508 1.29435727468777 +46.8068899549544 1.09365918041034 +46.8314147442579 1.16055854516948 +46.8559395335615 1.00930780745316 +46.880464322865 0.826061721373766 +46.9049891121686 0.782431700878673 +46.9295139014721 0.744619016449592 +46.9540386907756 0.628272295129343 +46.9785634800792 0.625363627096337 +47.0030882693827 0.66899364759143 +47.0276130586863 0.686445655789467 +47.0521378479898 0.613728954964312 +47.0766626372933 0.671902315624436 +47.1011874265969 0.605002950865293 +47.1257122159004 0.596276946766275 +47.150237005204 0.529377582007132 +47.1747617945075 0.590459610700262 +47.199286583811 0.567190266436213 +47.2238113731146 0.58464227463425 +47.2483361624181 0.494473565611057 +47.2728609517217 0.506108237743082 +47.2973857410252 0.506108237743082 +47.3219105303288 0.506108237743082 +47.3464353196323 0.506108237743082 +47.3709601089358 0.488656229545045 +47.3954848982394 0.491564897578051 +47.4200096875429 0.474112889380014 +47.4445344768465 0.439208872983939 +47.46905926615 0.509016905776088 +47.4935840554535 0.491564897578051 +47.5181088447571 0.424665532818908 +47.5426336340606 0.526468913974126 +47.5671584233642 0.424665532818908 +47.5916832126677 0.485747561512038 +47.6162080019712 0.410122192653877 +47.6407327912748 0.497382233644063 +47.6652575805783 0.424665532818908 +47.6897823698819 0.47702155741302 +47.7143071591854 0.410122192653877 +47.738831948489 0.503199569710076 +47.7633567377925 0.494473565611057 +47.787881527096 0.447934877082958 +47.8124063163996 0.442117541016945 +47.8369311057031 0.509016905776088 +47.8614558950067 0.36940084019179 +47.8859806843102 0.436300204950933 +47.9105054736137 0.392670184455839 +47.9350302629173 0.421756864785902 +47.9595550522208 0.485747561512038 +47.9840798415244 0.433391536917926 +48.0086046308279 0.433391536917926 +48.0331294201314 0.450843545115964 +48.057654209435 0.43048286888492 +48.0821789987385 0.474112889380014 +48.1067037880421 0.47702155741302 +48.1312285773456 0.43048286888492 +48.1557533666492 0.459569549214982 +48.1802781559527 0.421756864785902 +48.2048029452562 0.479930225446026 +48.2293277345598 0.523560245941119 +48.2538525238633 0.407213524620871 +48.2783773131669 0.494473565611057 +48.3029021024704 0.468295553314001 +48.3274268917739 0.410122192653877 +48.3519516810775 0.45375221314897 +48.376476470381 0.503199569710076 +48.4010012596846 0.474112889380014 +48.4255260489881 0.45375221314897 +48.4500508382916 0.599185614799281 +48.4745756275952 0.506108237743082 +48.4991004168987 0.462478217247989 +48.5236252062023 0.468295553314001 +48.5481499955058 0.442117541016945 +48.5726747848094 0.529377582007132 +48.5971995741129 0.555555594304188 +48.6217243634164 0.546829590205169 +48.64624915272 0.619546291030324 +48.6707739420235 0.6079116188983 +48.6952987313271 0.599185614799281 +48.7198235206306 0.762071024647629 +48.7443483099341 0.680628319723455 +48.7688730992377 0.680628319723455 +48.7933978885412 0.727167008251555 +48.8179226778448 0.770797028746648 +48.8424474671483 0.852239733670822 +48.8669722564518 0.994764467288127 +48.8914970457554 1.10820252057537 +48.9160218350589 1.24200125009366 +48.9405466243625 1.45433401650311 +48.965071413666 1.83536952882692 +48.9895962029696 1.94008157801515 +49.0141209922731 2.48981983625332 +49.0386457815766 2.60616655757357 +49.0631705708802 2.73414795102584 +49.0876953601837 2.83013399611505 +49.1122201494873 2.52181518461639 +49.1367449387908 2.31820842230596 +49.1612697280943 2.17277502065564 +49.1857945173979 1.75101815586974 +49.2103193067014 1.80046551243085 +49.234844096005 1.72774881160569 +49.2593688853085 1.50669004109722 +49.283893674612 1.58522407798839 +49.3084184639156 1.64921477471453 +49.3329432532191 1.60267608618643 +49.3574680425227 1.81791752062889 +49.3819928318262 1.72193147553968 +49.4065176211298 1.67830145504459 +49.4310424104333 1.50378137306421 +49.4555671997368 1.37870864764495 +49.4800919890404 1.28853993862175 +49.5046167783439 1.01512514351917 +49.5291415676475 0.968586454991071 +49.553666356951 0.919139098429965 +49.5781911462545 0.794066373010698 +49.6027159355581 0.811518381208735 +49.6272407248616 0.677719651690449 +49.6517655141652 0.64572430332738 +49.6762903034687 0.657358975459405 +49.7008150927722 0.628272295129343 +49.7253398820758 0.648632971360387 +49.7498646713793 0.485747561512038 +49.7743894606829 0.529377582007132 +49.7989142499864 0.546829590205169 +49.82343903929 0.535194918073144 +49.8479638285935 0.575916270535231 +49.872488617897 0.491564897578051 +49.8970134072006 0.413030860686883 +49.9215381965041 0.465386885280995 +49.9460629858077 0.447934877082958 +49.9705877751112 0.439208872983939 +49.9951125644147 0.509016905776088 +50.0196373537183 0.465386885280995 +50.0441621430218 0.436300204950933 +50.0686869323254 0.494473565611057 +50.0932117216289 0.424665532818908 +50.1177365109324 0.511925573809094 +50.142261300236 0.506108237743082 +50.1667860895395 0.450843545115964 +50.1913108788431 0.532286250040138 +50.2158356681466 0.488656229545045 +50.2403604574502 0.418848196752895 +50.2648852467537 0.517742909875107 +50.2894100360572 0.488656229545045 +50.3139348253608 0.506108237743082 +50.3384596146643 0.509016905776088 +50.3629844039679 0.520651577908113 +50.3875091932714 0.535194918073144 +50.4120339825749 0.482838893479032 +50.4365587718785 0.552646926271182 +50.461083561182 0.616637622997318 +50.4856083504856 0.471204221347007 +50.5101331397891 0.53810358610615 +50.5346579290926 0.439208872983939 +50.5591827183962 0.479930225446026 +50.5837075076997 0.514834241842101 +50.6082322970033 0.511925573809094 +50.6327570863068 0.619546291030324 +50.6572818756104 0.5613729303702 +50.6818066649139 0.570098934469219 +50.7063314542174 0.69226299185548 +50.730856243521 0.727167008251555 +50.7553810328245 0.718441004152536 +50.7799058221281 0.796975041043704 +50.8044306114316 0.788249036944685 +50.8289554007351 0.852239733670822 +50.8534801900387 1.17510188533451 +50.8780049793422 1.05875516401426 +50.9025297686458 1.30308327878679 +50.9270545579493 1.55904606569133 +50.9515793472528 1.79173950833183 +50.9761041365564 1.88190821735502 +51.0006289258599 1.94299024604815 +51.0251537151635 2.01570694687331 +51.049678504467 1.81791752062889 +51.0742032937706 1.75683549193576 +51.0987280830741 1.50087270503121 +51.1232528723776 1.41652133207403 +51.1477776616812 1.29726594272077 +51.1723024509847 1.20127989763157 +51.1968272402883 1.23327524599464 +51.2213520295918 1.10529385254236 +51.2458768188953 1.27108793042372 +51.2704016081989 1.27399659845672 +51.2949263975024 1.31762661895182 +51.319451186806 1.401977991909 +51.3439759761095 1.23618391402764 +51.368500765413 1.32344395501783 +51.3930255547166 1.27108793042372 +51.4175503440201 1.23618391402764 +51.4420751333237 1.30017461075378 +51.4665999226272 1.15474120910347 +51.4911247119308 1.2158232377966 +51.5156495012343 1.24781858615967 +51.5401742905378 1.33216995911685 +51.5646990798414 1.48923803289918 +51.5892238691449 1.50087270503121 +51.6137486584485 1.55613739765833 +51.638273447752 1.72484014357269 +51.6627982370555 1.68121012307759 +51.6873230263591 1.61721942635146 +51.7118478156626 1.36707397551292 +51.7363726049662 1.25654459025869 +51.7608973942697 1.24490991812666 +51.7854221835732 1.09656784844334 +51.8099469728768 1.00639913942015 +51.8344717621803 1.0296684836842 +51.8589965514839 0.872600409901865 +51.8835213407874 1.03839448778322 +51.908046130091 1.04712049188224 +51.9325709193945 1.11692852467439 +51.957095708698 1.15764987713647 +51.9816204980016 1.01221647548616 +52.0061452873051 1.01512514351917 +52.0306700766087 0.922047766462971 +52.0551948659122 0.895869754165915 +52.0797196552157 0.747527684482598 +52.1042444445193 0.767888360713642 +52.1287692338228 0.671902315624436 +52.1532940231264 0.706806332020511 +52.1778188124299 0.555555594304188 +52.2023436017334 0.488656229545045 +52.226868391037 0.447934877082958 +52.2513931803405 0.532286250040138 +52.2759179696441 0.471204221347007 +52.3004427589476 0.456660881181976 +52.3249675482512 0.462478217247989 +52.3494923375547 0.488656229545045 +52.3740171268582 0.439208872983939 +52.3985419161618 0.383944180356821 +52.4230667054653 0.459569549214982 +52.4475914947689 0.506108237743082 +52.4721162840724 0.401396188554858 +52.4966410733759 0.363583504125777 +52.5211658626795 0.509016905776088 +52.545690651983 0.488656229545045 +52.5702154412866 0.421756864785902 +52.5947402305901 0.468295553314001 +52.6192650198936 0.45375221314897 +52.6437898091972 0.378126844290808 +52.6683145985007 0.494473565611057 +52.6928393878043 0.395578852488846 +52.7173641771078 0.45375221314897 +52.7418889664114 0.413030860686883 +52.7664137557149 0.36940084019179 +52.7909385450184 0.398487520521852 +52.815463334322 0.418848196752895 +52.8399881236255 0.375218176257802 +52.8645129129291 0.413030860686883 +52.8890377022326 0.325770819696696 +52.9135624915361 0.410122192653877 +52.9380872808397 0.433391536917926 +52.9626120701432 0.363583504125777 +52.9871368594468 0.383944180356821 +53.0116616487503 0.357766168059765 +53.0361864380538 0.401396188554858 +53.0607112273574 0.343222827894734 +53.0852360166609 0.413030860686883 +53.1097608059645 0.375218176257802 +53.134285595268 0.407213524620871 +53.1588103845716 0.418848196752895 +53.1833351738751 0.386852848389827 +53.2078599631786 0.413030860686883 +53.2323847524822 0.395578852488846 +53.2569095417857 0.328679487729703 +53.2814343310893 0.287958135267616 +53.3059591203928 0.418848196752895 +53.3304839096963 0.372309508224796 +53.3550086989999 0.447934877082958 +53.3795334883034 0.447934877082958 +53.404058277607 0.410122192653877 +53.4285830669105 0.421756864785902 +53.453107856214 0.447934877082958 +53.4776326455176 0.418848196752895 +53.5021574348211 0.401396188554858 +53.5266822241247 0.372309508224796 +53.5512070134282 0.436300204950933 +53.5757318027318 0.424665532818908 +53.6002565920353 0.491564897578051 +53.6247813813388 0.392670184455839 +53.6493061706424 0.459569549214982 +53.6738309599459 0.407213524620871 +53.6983557492495 0.43048286888492 +53.722880538553 0.474112889380014 +53.7474053278565 0.439208872983939 +53.7719301171601 0.471204221347007 +53.7964549064636 0.450843545115964 +53.8209796957672 0.421756864785902 +53.8455044850707 0.500290901677069 +53.8700292743742 0.47702155741302 +53.8945540636778 0.474112889380014 +53.9190788529813 0.482838893479032 +53.9436036422849 0.602094282832287 +53.9681284315884 0.564281598403206 +53.992653220892 0.625363627096337 +54.0171780101955 0.625363627096337 +54.041702799499 0.730075676284561 +54.0662275888026 0.788249036944685 +54.0907523781061 0.939499774661008 +54.1152771674097 0.948225778760027 +54.1398019567132 0.90750442629794 +54.1643267460167 0.913321762363952 +54.1888515353203 0.817335717274747 +54.2133763246238 0.642815635294374 +54.2379011139274 0.738801680383579 +54.2624259032309 0.613728954964312 +54.2869506925344 0.721349672185542 +54.311475481838 0.602094282832287 +54.3360002711415 0.596276946766275 +54.3605250604451 0.619546291030324 +54.3850498497486 0.532286250040138 +54.4095746390522 0.671902315624436 +54.4340994283557 0.64572430332738 +54.4586242176592 0.689354323822474 +54.4831490069628 0.712623668086523 +54.5076737962663 0.654450307426399 +54.5321985855699 0.58464227463425 +54.5567233748734 0.634089631195356 +54.5812481641769 0.543920922172163 +54.6057729534805 0.535194918073144 +54.630297742784 0.573007602502225 +54.6548225320876 0.494473565611057 +54.6793473213911 0.485747561512038 +54.7038721106946 0.447934877082958 +54.7283968999982 0.514834241842101 +54.7529216893017 0.410122192653877 +54.7774464786053 0.436300204950933 +54.8019712679088 0.474112889380014 +54.8264960572124 0.479930225446026 +54.8510208465159 0.468295553314001 +54.8755456358194 0.494473565611057 +54.900070425123 0.401396188554858 +54.9245952144265 0.439208872983939 +54.9491200037301 0.456660881181976 +54.9736447930336 0.520651577908113 +54.9981695823371 0.488656229545045 +55.0226943716407 0.471204221347007 +55.0472191609442 0.506108237743082 +55.0717439502478 0.511925573809094 +55.0962687395513 0.491564897578051 +55.1207935288548 0.45375221314897 +55.1453183181584 0.526468913974126 +55.1698431074619 0.468295553314001 +55.1943678967655 0.543920922172163 +55.218892686069 0.47702155741302 +55.2434174753726 0.523560245941119 +55.2679422646761 0.535194918073144 +55.2924670539796 0.424665532818908 +55.3169918432832 0.47702155741302 +55.3415166325867 0.53810358610615 +55.3660414218903 0.549738258238175 +55.3905662111938 0.520651577908113 +55.4150910004973 0.506108237743082 +55.4396157898009 0.58464227463425 +55.4641405791044 0.567190266436213 +55.488665368408 0.587550942667256 +55.5131901577115 0.660267643492411 +55.537714947015 0.69226299185548 +55.5622397363186 0.69226299185548 +55.5867645256221 0.666084979558424 +55.6112893149257 0.709715000053517 +55.6358141042292 0.689354323822474 +55.6603388935328 0.866783073835853 +55.6848636828363 0.881326414000884 +55.7093884721398 1.03257715171721 +55.7339132614434 1.09365918041034 +55.7584380507469 1.26817926239071 +55.7829628400505 1.46015135256912 +55.807487629354 1.62012809438446 +55.8320124186575 1.90808622965208 +55.8565372079611 2.17859235672166 +55.8810619972646 2.38219911903209 +55.9055867865682 2.57998854527652 +55.9301115758717 2.7574172952899 +55.9546363651752 2.65561391413468 +55.9791611544788 2.35020377066902 +56.0036859437823 2.1495056763916 +56.0282107330859 1.98080293047723 +56.0527355223894 1.80337418046386 +56.077260311693 1.70738813537465 +56.1017851009965 1.41652133207403 +56.1263098903 1.41943000010703 +56.1508346796036 1.46887735666814 +56.1753594689071 1.50669004109722 +56.1998842582107 1.51832471322925 +56.2244090475142 1.61721942635146 +56.2489338368177 1.78592217226582 +56.2734586261213 1.68121012307759 +56.2979834154248 1.70447946734164 +56.3225082047284 1.68121012307759 +56.3470329940319 1.75101815586974 +56.3715577833354 1.73647481570471 +56.396082572639 1.62012809438446 +56.4206073619425 1.4514253484701 +56.4451321512461 1.47469469273415 +56.4696569405496 1.62012809438446 +56.4941817298532 1.48923803289918 +56.5187065191567 1.46015135256912 +56.5432313084602 1.51250737716323 +56.5677560977638 1.25654459025869 +56.5922808870673 1.27981393452274 +56.6168056763709 1.25363592222568 +56.6413304656744 1.05002915991524 +56.6658552549779 1.03548581975021 +56.6903800442815 0.974403791057083 +56.714904833585 0.88423508203389 +56.7394296228886 0.785340368911679 +56.7639544121921 0.831879057439778 +56.7884792014956 0.933682438594996 +56.8130039907992 0.945317110727021 +56.8375287801027 0.866783073835853 +56.8620535694063 0.95404311482604 +56.8865783587098 1.0267598156512 +56.9111031480134 1.01221647548616 +56.9356279373169 0.866783073835853 +56.9601527266204 0.820244385307754 +56.984677515924 0.738801680383579 +57.0092023052275 0.718441004152536 +57.0337270945311 0.648632971360387 +57.0582518838346 0.596276946766275 +57.0827766731381 0.575916270535231 +57.1073014624417 0.564281598403206 +57.1318262517452 0.6079116188983 +57.1563510410488 0.517742909875107 +57.1808758303523 0.5613729303702 +57.2054006196558 0.546829590205169 +57.2299254089594 0.439208872983939 +57.2544501982629 0.532286250040138 +57.2789749875665 0.482838893479032 +57.30349977687 0.479930225446026 +57.3280245661736 0.497382233644063 +57.3525493554771 0.535194918073144 +57.3770741447806 0.546829590205169 +57.4015989340842 0.459569549214982 +57.4261237233877 0.558464262337194 +57.4506485126913 0.500290901677069 +57.4751733019948 0.488656229545045 +57.4996980912983 0.491564897578051 +57.5242228806019 0.447934877082958 +57.5487476699054 0.433391536917926 +57.573272459209 0.488656229545045 +57.5977972485125 0.497382233644063 +57.622322037816 0.494473565611057 +57.6468468271196 0.491564897578051 +57.6713716164231 0.462478217247989 +57.6958964057267 0.526468913974126 +57.7204211950302 0.529377582007132 +57.7449459843338 0.552646926271182 +57.7694707736373 0.479930225446026 +57.7939955629408 0.506108237743082 +57.8185203522444 0.45375221314897 +57.8430451415479 0.485747561512038 +57.8675699308515 0.570098934469219 +57.892094720155 0.520651577908113 +57.9166195094585 0.503199569710076 +57.9411442987621 0.488656229545045 +57.9656690880656 0.462478217247989 +57.9901938773692 0.506108237743082 +58.0147186666727 0.485747561512038 +58.0392434559762 0.543920922172163 +58.0637682452798 0.526468913974126 +58.0882930345833 0.517742909875107 +58.1128178238869 0.468295553314001 +58.1373426131904 0.488656229545045 +58.161867402494 0.511925573809094 +58.1863921917975 0.500290901677069 +58.210916981101 0.509016905776088 +58.2354417704046 0.648632971360387 +58.2599665597081 0.602094282832287 +58.2844913490117 0.558464262337194 +58.3090161383152 0.567190266436213 +58.3335409276187 0.6079116188983 +58.3580657169223 0.590459610700262 +58.3825905062258 0.555555594304188 +58.4071152955294 0.636998299228362 +58.4316400848329 0.613728954964312 +58.4561648741364 0.634089631195356 +58.48068966344 0.700988995954499 +58.5052144527435 0.721349672185542 +58.5297392420471 0.753345020548611 +58.5542640313506 0.718441004152536 +58.5787888206542 0.840605061538797 +58.6033136099577 0.878417745967878 +58.6278383992612 1.0267598156512 +58.6523631885648 1.09365918041034 +58.6768879778683 1.29144860665476 +58.7014127671719 1.32926129108384 +58.7259375564754 1.4979640369982 +58.7504623457789 1.93717290998214 +58.7749871350825 2.12332766409454 +58.799511924386 2.27457840181086 +58.8240367136896 2.67888325839873 +58.8485615029931 2.58871454937553 +58.8730862922966 2.70506127069578 +58.8976110816002 2.47236782805529 +58.9221358709037 2.5247238526494 +58.9466606602073 2.1524143444246 +58.9711854495108 1.88772555342104 +58.9957102388144 1.67248411897858 +59.0202350281179 1.48923803289918 +59.0447598174214 1.36125663944691 +59.069284606725 1.55322872962532 +59.0938093960285 1.43106467223906 +59.1183341853321 1.3554393033809 +59.1428589746356 1.43979067633808 +59.1673837639391 1.60849342225244 +59.1919085532427 1.64921477471453 +59.2164333425462 1.73647481570471 +59.2409581318498 1.62012809438446 +59.2654829211533 1.51541604519624 +59.2900077104568 1.49214670093219 +59.3145324997604 1.41361266404102 +59.3390572890639 1.404886659942 +59.3635820783675 1.21000590173059 +59.388106867671 1.0762071722123 +59.4126316569746 1.00639913942015 +59.4371564462781 0.904595758264934 +59.4616812355816 0.922047766462971 +59.4862060248852 0.831879057439778 +59.5107308141887 0.706806332020511 +59.5352556034923 0.677719651690449 +59.5597803927958 0.794066373010698 +59.5843051820993 0.642815635294374 +59.6088299714029 0.590459610700262 +59.6333547607064 0.639906967261368 +59.65787955001 0.636998299228362 +59.6824043393135 0.663176311525418 +59.706929128617 0.613728954964312 +59.7314539179206 0.5613729303702 +59.7559787072241 0.58464227463425 +59.7805034965277 0.53810358610615 +59.8050282858312 0.564281598403206 +59.8295530751348 0.628272295129343 +59.8540778644383 0.622454959063331 +59.8786026537418 0.570098934469219 +59.9031274430454 0.575916270535231 +59.9276522323489 0.564281598403206 +59.9521770216525 0.564281598403206 +59.976701810956 0.610820286931306 +60.0012266002595 0.506108237743082 +60.0257513895631 0.634089631195356 +60.0502761788666 0.570098934469219 +60.0748009681702 0.66899364759143 +60.0993257574737 0.6079116188983 +60.1238505467772 0.619546291030324 +60.1483753360808 0.689354323822474 +60.1729001253843 0.753345020548611 +60.1974249146879 0.735893012350573 +60.2219497039914 0.703897663987505 +60.246474493295 0.730075676284561 +60.2709992825985 0.811518381208735 +60.295524071902 0.866783073835853 +60.3200488612056 1.01221647548616 +60.3445736505091 1.06457250008028 +60.3690984398127 1.27690526648973 +60.3936232291162 1.45724268453612 +60.4181480184197 1.56195473372434 +60.4426728077233 1.73647481570471 +60.4671975970268 2.06806297146742 +60.4917223863304 2.1495056763916 +60.5162471756339 2.51308918051737 +60.5407719649374 2.62943590183762 +60.565296754241 2.87958135267616 +60.5898215435445 2.81849932398303 +60.6143463328481 2.71669594282781 +60.6388711221516 2.46073315592326 +60.6633959114552 2.25421772557982 +60.6879207007587 1.9662595903122 +60.7124454900622 1.74520081980373 +60.7369702793658 1.5881327460214 +60.7614950686693 1.41652133207403 +60.7860198579729 1.404886659942 +60.8105446472764 1.49214670093219 +60.8350694365799 1.50378137306421 +60.8595942258835 1.44560801240409 +60.884119015187 1.48342069683317 +60.9086438044906 1.68993612717661 +60.9331685937941 1.66957545094557 +60.9576933830976 1.81210018456287 +60.9822181724012 1.70157079930864 +61.0067429617047 1.60558475421943 +61.0312677510083 1.46596868863513 +61.0557925403118 1.42233866814004 +61.0803173296154 1.28853993862175 +61.1048421189189 1.21291456976359 +61.1293669082224 0.93077377056199 +61.153891697526 0.988947131222114 +61.1784164868295 0.837696393505791 +61.2029412761331 0.788249036944685 +61.2274660654366 0.689354323822474 +61.2519908547401 0.703897663987505 +61.2765156440437 0.724258340218548 +61.3010404333472 0.634089631195356 +61.3255652226508 0.514834241842101 +61.3500900119543 0.5613729303702 +61.3746148012578 0.541012254139157 +61.3991395905614 0.677719651690449 +61.4236643798649 0.532286250040138 +61.4481891691685 0.555555594304188 +61.472713958472 0.570098934469219 +61.4972387477756 0.459569549214982 +61.5217635370791 0.546829590205169 +61.5462883263826 0.471204221347007 +61.5708131156862 0.462478217247989 +61.5953379049897 0.485747561512038 +61.6198626942933 0.459569549214982 +61.6443874835968 0.45375221314897 +61.6689122729003 0.392670184455839 +61.6934370622039 0.517742909875107 +61.7179618515074 0.511925573809094 +61.742486640811 0.456660881181976 +61.7670114301145 0.442117541016945 +61.791536219418 0.424665532818908 +61.8160610087216 0.378126844290808 +61.8405857980251 0.488656229545045 +61.8651105873287 0.357766168059765 +61.8896353766322 0.468295553314001 +61.9141601659358 0.392670184455839 +61.9386849552393 0.488656229545045 +61.9632097445428 0.386852848389827 +61.9877345338464 0.474112889380014 +62.0122593231499 0.407213524620871 +62.0367841124535 0.500290901677069 +62.061308901757 0.479930225446026 +62.0858336910605 0.366492172158783 +62.1103584803641 0.436300204950933 +62.1348832696676 0.445026209049951 +62.1594080589712 0.45375221314897 +62.1839328482747 0.372309508224796 +62.2084576375782 0.378126844290808 +62.2329824268818 0.398487520521852 +62.2575072161853 0.372309508224796 +62.2820320054889 0.424665532818908 +62.3065567947924 0.383944180356821 +62.331081584096 0.421756864785902 +62.3556063733995 0.456660881181976 +62.380131162703 0.43048286888492 +62.4046559520066 0.363583504125777 +62.4291807413101 0.395578852488846 +62.4537055306137 0.36940084019179 +62.4782303199172 0.383944180356821 +62.5027551092207 0.404304856587864 +62.5272798985243 0.372309508224796 +62.5518046878278 0.407213524620871 +62.5763294771314 0.319953483630684 +62.6008542664349 0.413030860686883 +62.6253790557384 0.395578852488846 +62.649903845042 0.418848196752895 +62.6744286343455 0.383944180356821 +62.6989534236491 0.311227479531665 +62.7234782129526 0.410122192653877 +62.7480030022562 0.386852848389827 +62.7725277915597 0.337405491828721 +62.7970525808632 0.415939528719889 +62.8215773701668 0.410122192653877 +62.8461021594703 0.389761516422833 +62.8706269487739 0.407213524620871 +62.8951517380774 0.34613149592774 +62.9196765273809 0.407213524620871 +62.9442013166845 0.45375221314897 +62.968726105988 0.375218176257802 +62.9932508952916 0.404304856587864 +63.0177756845951 0.378126844290808 +63.0423004738986 0.407213524620871 +63.0668252632022 0.392670184455839 +63.0913500525057 0.482838893479032 +63.1158748418093 0.398487520521852 +63.1403996311128 0.474112889380014 +63.1649244204164 0.47702155741302 +63.1894492097199 0.479930225446026 +63.2139739990234 0.447934877082958 +63.238498788327 0.500290901677069 +63.2630235776305 0.558464262337194 +63.2875483669341 0.541012254139157 +63.3120731562376 0.639906967261368 +63.3365979455411 0.634089631195356 +63.3611227348447 0.581733606601244 +63.3856475241482 0.613728954964312 +63.4101723134518 0.596276946766275 +63.4346971027553 0.578824938568237 +63.4592218920588 0.5613729303702 +63.4837466813624 0.593368278733268 +63.5082714706659 0.488656229545045 +63.5327962599695 0.541012254139157 +63.557321049273 0.497382233644063 +63.5818458385766 0.439208872983939 +63.6063706278801 0.494473565611057 +63.6308954171836 0.462478217247989 +63.6554202064872 0.517742909875107 +63.6799449957907 0.462478217247989 +63.7044697850943 0.517742909875107 +63.7289945743978 0.555555594304188 +63.7535193637013 0.541012254139157 +63.7780441530049 0.558464262337194 +63.8025689423084 0.570098934469219 +63.827093731612 0.503199569710076 +63.8516185209155 0.450843545115964 +63.876143310219 0.541012254139157 +63.9006680995226 0.474112889380014 +63.9251928888261 0.465386885280995 +63.9497176781297 0.395578852488846 +63.9742424674332 0.47702155741302 +63.9987672567368 0.47702155741302 +64.0232920460403 0.424665532818908 +64.0478168353438 0.474112889380014 +64.0723416246474 0.482838893479032 +64.0968664139509 0.43048286888492 +64.1213912032545 0.436300204950933 +64.145915992558 0.442117541016945 +64.1704407818615 0.433391536917926 +64.1949655711651 0.433391536917926 +64.2194903604686 0.418848196752895 +64.2440151497722 0.410122192653877 +64.2685399390757 0.459569549214982 +64.2930647283793 0.43048286888492 +64.3175895176828 0.439208872983939 +64.3421143069863 0.450843545115964 +64.3666390962899 0.43048286888492 +64.3911638855934 0.445026209049951 +64.415688674897 0.482838893479032 +64.4402134642005 0.450843545115964 +64.464738253504 0.445026209049951 +64.4892630428076 0.491564897578051 +64.5137878321111 0.520651577908113 +64.5383126214147 0.517742909875107 +64.5628374107182 0.43048286888492 +64.5873622000217 0.415939528719889 +64.6118869893253 0.5613729303702 +64.6364117786288 0.45375221314897 +64.6609365679324 0.503199569710076 +64.6854613572359 0.445026209049951 +64.7099861465395 0.555555594304188 +64.734510935843 0.523560245941119 +64.7590357251465 0.610820286931306 +64.7835605144501 0.570098934469219 +64.8080853037536 0.660267643492411 +64.8326100930572 0.64572430332738 +64.8571348823607 0.631180963162349 +64.8816596716642 0.744619016449592 +64.9061844609678 0.869691741868859 +64.9307092502713 0.919139098429965 +64.9552340395749 0.942408442694015 +64.9797588288784 1.1227458607404 +65.0042836181819 1.0267598156512 +65.0288084074855 1.03548581975021 +65.053333196789 1.0267598156512 +65.0778579860926 0.956951782859046 +65.1023827753961 0.956951782859046 +65.1269075646997 0.922047766462971 +65.1514323540032 0.852239733670822 +65.1759571433067 0.927865102528984 +65.2004819326103 0.773705696779654 +65.2250067219138 0.782431700878673 +65.2495315112174 0.855148401703828 +65.2740563005209 0.741710348416586 +65.2985810898244 0.936591106628002 +65.323105879128 0.951134446793033 +65.3476306684315 0.933682438594996 +65.3721554577351 1.03257715171721 +65.3966802470386 1.08202450827831 +65.4212050363421 1.23327524599464 +65.4457298256457 1.29726594272077 +65.4702546149492 1.39906932387599 +65.4947794042528 1.44560801240409 +65.5193041935563 1.60267608618643 +65.5438289828599 1.60558475421943 +65.5683537721634 1.46887735666814 +65.5928785614669 1.401977991909 +65.6174033507705 1.32344395501783 +65.641928140074 1.25654459025869 +65.6664529293776 1.14601520500445 +65.6909777186811 0.962769118925058 +65.7155025079846 0.980221127123096 +65.7400272972882 0.878417745967878 +65.7645520865917 0.924956434495977 +65.7890768758953 0.782431700878673 +65.8136016651988 0.855148401703828 +65.8381264545023 0.747527684482598 +65.8626512438059 0.785340368911679 +65.8871760331094 0.753345020548611 +65.911700822413 0.933682438594996 +65.9362256117165 0.939499774661008 +65.9607504010201 0.90750442629794 +65.9852751903236 0.910413094330946 +66.0097999796271 0.898778422198921 +66.0343247689307 0.922047766462971 +66.0588495582342 0.88423508203389 +66.0833743475378 0.869691741868859 +66.1078991368413 0.762071024647629 +66.1324239261448 0.695171659888486 +66.1569487154484 0.689354323822474 +66.1814735047519 0.602094282832287 +66.2059982940555 0.616637622997318 +66.230523083359 0.549738258238175 +66.2550478726625 0.462478217247989 +66.2795726619661 0.555555594304188 +66.3040974512696 0.491564897578051 +66.3286222405732 0.532286250040138 +66.3531470298767 0.523560245941119 +66.3776718191803 0.506108237743082 +66.4021966084838 0.546829590205169 +66.4267213977873 0.43048286888492 +66.4512461870909 0.450843545115964 +66.4757709763944 0.482838893479032 +66.500295765698 0.456660881181976 +66.5248205550015 0.45375221314897 +66.549345344305 0.442117541016945 +66.5738701336086 0.488656229545045 +66.5983949229121 0.442117541016945 +66.6229197122157 0.497382233644063 +66.6474445015192 0.404304856587864 +66.6719692908227 0.401396188554858 +66.6964940801263 0.436300204950933 +66.7210188694298 0.514834241842101 +66.7455436587334 0.465386885280995 +66.7700684480369 0.427574200851914 +66.7945932373405 0.479930225446026 +66.819118026644 0.462478217247989 +66.8436428159475 0.415939528719889 +66.8681676052511 0.450843545115964 +66.8926923945546 0.482838893479032 +66.9172171838582 0.442117541016945 +66.9417419731617 0.447934877082958 +66.9662667624652 0.488656229545045 +66.9907915517688 0.415939528719889 +67.0153163410723 0.427574200851914 +67.0398411303759 0.456660881181976 +67.0643659196794 0.45375221314897 +67.0888907089829 0.485747561512038 +67.1134154982865 0.433391536917926 +67.13794028759 0.517742909875107 +67.1624650768936 0.494473565611057 +67.1869898661971 0.523560245941119 +67.2115146555007 0.511925573809094 +67.2360394448042 0.506108237743082 +67.2605642341077 0.479930225446026 +67.2850890234113 0.509016905776088 +67.3096138127148 0.564281598403206 +67.3341386020184 0.485747561512038 +67.3586633913219 0.564281598403206 +67.3831881806254 0.602094282832287 +67.407712969929 0.532286250040138 +67.4322377592325 0.654450307426399 +67.4567625485361 0.700988995954499 +67.4812873378396 0.686445655789467 +67.5058121271431 0.846422397604809 +67.5303369164467 0.791157704977691 +67.5548617057502 0.890052418099903 +67.5793864950538 1.05584649598126 +67.6039112843573 1.06166383204727 +67.6284360736609 1.16055854516948 +67.6529608629644 1.4514253484701 +67.6774856522679 1.34380463124887 +67.7020104415715 1.48342069683317 +67.726535230875 1.51832471322925 +67.7510600201786 1.43979067633808 +67.7755848094821 1.2652705943577 +67.8001095987856 1.18382788943353 +67.8246343880892 1.08493317631132 +67.8491591773927 0.956951782859046 +67.8736839666963 0.956951782859046 +67.8982087559998 0.942408442694015 +67.9227335453033 0.756253688581617 +67.9472583346069 0.878417745967878 +67.9717831239104 0.834787725472785 +67.996307913214 0.802792377109716 +68.0208327025175 0.840605061538797 +68.0453574918211 0.820244385307754 +68.0698822811246 0.875509077934872 +68.0944070704281 0.881326414000884 +68.1189318597317 1.01803381155218 +68.1434566490352 0.988947131222114 +68.1679814383388 1.01512514351917 +68.1925062276423 0.913321762363952 +68.2170310169458 0.890052418099903 +68.2415558062494 0.898778422198921 +68.2660805955529 0.805701045142722 +68.2906053848565 0.802792377109716 +68.31513017416 0.796975041043704 +68.3396549634635 0.721349672185542 +68.3641797527671 0.695171659888486 +68.3887045420706 0.663176311525418 +68.4132293313742 0.581733606601244 +68.4377541206777 0.578824938568237 +68.4622789099813 0.520651577908113 +68.4868036992848 0.570098934469219 +68.5113284885883 0.593368278733268 +68.5358532778919 0.526468913974126 +68.5603780671954 0.456660881181976 +68.584902856499 0.578824938568237 +68.6094276458025 0.541012254139157 +68.633952435106 0.570098934469219 +68.6584772244096 0.581733606601244 +68.6830020137131 0.567190266436213 +68.7075268030167 0.5613729303702 +68.7320515923202 0.546829590205169 +68.7565763816237 0.509016905776088 +68.7811011709273 0.482838893479032 +68.8056259602308 0.526468913974126 +68.8301507495344 0.541012254139157 +68.8546755388379 0.520651577908113 +68.8792003281415 0.567190266436213 +68.903725117445 0.610820286931306 +68.9282499067485 0.674810983657443 +68.9527746960521 0.639906967261368 +68.9772994853556 0.680628319723455 +69.0018242746592 0.703897663987505 +69.0263490639627 0.706806332020511 +69.0508738532662 0.718441004152536 +69.0753986425698 0.817335717274747 +69.0999234318733 0.808609713175729 +69.1244482211769 0.997673135321133 +69.1489730104804 1.05293782794825 +69.1734977997839 1.12856319680641 +69.1980225890875 1.15474120910347 +69.222547378391 1.32344395501783 +69.2470721676946 1.39034331977697 +69.2715969569981 1.68702745914361 +69.2961217463017 1.56486340175735 +69.3206465356052 1.62594543045048 +69.3451713249087 1.52414204929526 +69.3696961142123 1.36998264354593 +69.3942209035158 1.41652133207403 +69.4187456928194 1.2158232377966 +69.4432704821229 1.20709723369758 +69.4677952714264 1.14892387303746 +69.49232006073 1.05293782794825 +69.5168448500335 0.927865102528984 +69.5413696393371 1.0267598156512 +69.5658944286406 0.922047766462971 +69.5904192179441 0.939499774661008 +69.6149440072477 0.968586454991071 +69.6394687965512 1.04130315581623 +69.6639935858548 1.18382788943353 +69.6885183751583 1.13147186483942 +69.7130431644619 1.19546256156556 +69.7375679537654 1.28853993862175 +69.7620927430689 1.36707397551292 +69.7866175323725 1.38452598371096 +69.811142321676 1.41361266404102 +69.8356671109796 1.26817926239071 +69.8601919002831 1.2158232377966 +69.8847166895866 1.18091922140052 +69.9092414788902 1.01221647548616 +69.9337662681937 0.924956434495977 +69.9582910574973 0.927865102528984 +69.9828158468008 0.750436352515604 +70.0073406361043 0.738801680383579 +70.0318654254079 0.639906967261368 +70.0563902147114 0.721349672185542 +70.080915004015 0.735893012350573 +70.1054397933185 0.636998299228362 +70.1299645826221 0.64572430332738 +70.1544893719256 0.622454959063331 +70.1790141612291 0.616637622997318 +70.2035389505327 0.648632971360387 +70.2280637398362 0.605002950865293 +70.2525885291398 0.767888360713642 +70.2771133184433 0.686445655789467 +70.3016381077468 0.724258340218548 +70.3261628970504 0.622454959063331 +70.3506876863539 0.703897663987505 +70.3752124756575 0.616637622997318 +70.399737264961 0.599185614799281 +70.4242620542645 0.69226299185548 +70.4487868435681 0.587550942667256 +70.4733116328716 0.541012254139157 +70.4978364221752 0.587550942667256 +70.5223612114787 0.570098934469219 +70.5468860007823 0.509016905776088 +70.5714107900858 0.58464227463425 +70.5959355793893 0.459569549214982 +70.6204603686929 0.450843545115964 +70.6449851579964 0.445026209049951 +70.6695099473 0.517742909875107 +70.6940347366035 0.459569549214982 +70.718559525907 0.381035512323815 +70.7430843152106 0.503199569710076 +70.7676091045141 0.494473565611057 +70.7921338938177 0.497382233644063 +70.8166586831212 0.494473565611057 +70.8411834724247 0.45375221314897 +70.8657082617283 0.488656229545045 +70.8902330510318 0.474112889380014 +70.9147578403354 0.442117541016945 +70.9392826296389 0.491564897578051 +70.9638074189425 0.456660881181976 +70.988332208246 0.442117541016945 +71.0128569975495 0.485747561512038 +71.0373817868531 0.471204221347007 +71.0619065761566 0.517742909875107 +71.0864313654602 0.418848196752895 +71.1109561547637 0.465386885280995 +71.1354809440672 0.471204221347007 +71.1600057333708 0.523560245941119 +71.1845305226743 0.506108237743082 +71.2090553119779 0.529377582007132 +71.2335801012814 0.471204221347007 +71.2581048905849 0.433391536917926 +71.2826296798885 0.468295553314001 +71.307154469192 0.471204221347007 +71.3316792584956 0.468295553314001 +71.3562040477991 0.488656229545045 +71.3807288371027 0.552646926271182 +71.4052536264062 0.459569549214982 +71.4297784157097 0.456660881181976 +71.4543032050133 0.511925573809094 +71.4788279943168 0.45375221314897 +71.5033527836204 0.485747561512038 +71.5278775729239 0.517742909875107 +71.5524023622274 0.541012254139157 +71.576927151531 0.5613729303702 +71.6014519408345 0.450843545115964 +71.6259767301381 0.503199569710076 +71.6505015194416 0.581733606601244 +71.6750263087451 0.535194918073144 +71.6995510980487 0.628272295129343 +71.7240758873522 0.564281598403206 +71.7486006766558 0.66899364759143 +71.7731254659593 0.764979692680635 +71.7976502552629 0.82315305334076 +71.8221750445664 0.828970389406772 +71.8466998338699 0.895869754165915 +71.8712246231735 0.968586454991071 +71.895749412477 0.99185579925512 +71.9202742017806 0.99185579925512 +71.9447989910841 1.06748116811328 +71.9693237803876 0.945317110727021 +71.9938485696912 0.919139098429965 +72.0183733589947 0.82315305334076 +72.0428981482983 0.808609713175729 +72.0674229376018 0.770797028746648 +72.0919477269053 0.677719651690449 +72.1164725162089 0.648632971360387 +72.1409973055124 0.636998299228362 +72.165522094816 0.613728954964312 +72.1900468841195 0.599185614799281 +72.2145716734231 0.619546291030324 +72.2390964627266 0.674810983657443 +72.2636212520301 0.654450307426399 +72.2881460413337 0.622454959063331 +72.3126708306372 0.654450307426399 +72.3371956199408 0.686445655789467 +72.3617204092443 0.79988370907671 +72.3862451985478 0.660267643492411 +72.4107699878514 0.791157704977691 +72.4352947771549 0.712623668086523 +72.4598195664585 0.770797028746648 +72.484344355762 0.613728954964312 +72.5088691450655 0.732984344317567 +72.5333939343691 0.642815635294374 +72.5579187236726 0.666084979558424 +72.5824435129762 0.602094282832287 +72.6069683022797 0.58464227463425 +72.6314930915833 0.570098934469219 +72.6560178808868 0.587550942667256 +72.6805426701903 0.625363627096337 +72.7050674594939 0.602094282832287 +72.7295922487974 0.529377582007132 +72.754117038101 0.58464227463425 +72.7786418274045 0.575916270535231 +72.803166616708 0.509016905776088 +72.8276914060116 0.552646926271182 +72.8522161953151 0.450843545115964 +72.8767409846187 0.552646926271182 +72.9012657739222 0.494473565611057 +72.9257905632257 0.517742909875107 +72.9503153525293 0.587550942667256 +72.9748401418328 0.622454959063331 +72.9993649311364 0.53810358610615 +73.0238897204399 0.58464227463425 +73.0484145097435 0.616637622997318 +73.072939299047 0.605002950865293 +73.0974640883505 0.709715000053517 +73.1219888776541 0.587550942667256 +73.1465136669576 0.712623668086523 +73.1710384562612 0.666084979558424 +73.1955632455647 0.756253688581617 +73.2200880348682 0.79988370907671 +73.2446128241718 0.90750442629794 +73.2691376134753 0.913321762363952 +73.2936624027789 1.05293782794825 +73.3181871920824 1.14601520500445 +73.3427119813859 1.22454924189562 +73.3672367706895 1.37289131157893 +73.391761559993 1.55904606569133 +73.4162863492966 1.55904606569133 +73.4408111386001 1.8266435247279 +73.4653359279037 1.57068073782336 +73.4898607172072 1.71320547144066 +73.5143855065107 1.81210018456287 +73.5389102958143 1.53577672142728 +73.5634350851178 1.49214670093219 +73.5879598744214 1.27399659845672 +73.6124846637249 1.43106467223906 +73.6370094530284 1.16637588123549 +73.661534242332 1.0296684836842 +73.6860590316355 1.05002915991524 +73.7105838209391 1.17219321730151 +73.7351086102426 1.06748116811328 +73.7596333995461 0.994764467288127 +73.7841581888497 1.07038983614629 +73.8086829781532 1.14601520500445 +73.8332077674568 1.22164057386261 +73.8577325567603 1.28853993862175 +73.8822573460639 1.36998264354593 +73.9067821353674 1.43688200830507 +73.9313069246709 1.71320547144066 +73.9558317139745 1.70157079930864 +73.980356503278 1.6841187911106 +74.0048812925816 1.61721942635146 +74.0294060818851 1.64048877061551 +74.0539308711886 1.37870864764495 +74.0784556604922 1.4979640369982 +74.1029804497957 1.15183254107046 +74.1275052390993 1.04712049188224 +74.1520300284028 1.03257715171721 +74.1765548177063 0.983129795156102 +74.2010796070099 0.892961086132909 +74.2256043963134 0.933682438594996 +74.250129185617 0.779523032845666 +74.2746539749205 0.764979692680635 +74.2991787642241 0.759162356614623 +74.3237035535276 0.767888360713642 +74.3482283428311 0.759162356614623 +74.3727531321347 0.826061721373766 +74.3972779214382 0.820244385307754 +74.4218027107418 0.741710348416586 +74.4463275000453 0.863874405802847 +74.4708522893488 0.895869754165915 +74.4953770786524 0.788249036944685 +74.5199018679559 0.820244385307754 +74.5444266572595 0.770797028746648 +74.568951446563 0.779523032845666 +74.5934762358665 0.712623668086523 +74.6180010251701 0.732984344317567 +74.6425258144736 0.636998299228362 +74.6670506037772 0.636998299228362 +74.6915753930807 0.53810358610615 +74.7161001823843 0.581733606601244 +74.7406249716878 0.488656229545045 +74.7651497609913 0.593368278733268 +74.7896745502949 0.570098934469219 +74.8141993395984 0.546829590205169 +74.838724128902 0.526468913974126 +74.8632489182055 0.491564897578051 +74.887773707509 0.541012254139157 +74.9122984968126 0.541012254139157 +74.9368232861161 0.497382233644063 +74.9613480754197 0.514834241842101 +74.9858728647232 0.45375221314897 +75.0103976540267 0.503392714112542 +75.0349224433303 0.521717706120348 +75.0594472326338 0.496433525672776 +75.0839720219374 0.485264700505873 +75.1084968112409 0.477390832176908 +75.1330216005445 0.471707930392888 +75.157546389848 0.47940566836043 +75.1820711791515 0.475838008959836 +75.2065959684551 0.521541575758926 +75.2311207577586 0.506981221552851 +75.2556455470622 0.469092812962252 +75.2801703363657 0.465349023200236 +75.3046951256692 0.486116836275927 +75.3292199149728 0.458092450159429 +75.3537447042763 0.501554008290442 +75.3782694935799 0.465890594326875 +75.4027942828834 0.489235662752443 +75.4273190721869 0.497969334848804 +75.4518438614905 0.445622656298394 +75.476368650794 0.486368690798867 +75.5008934400976 0.486717117523041 +75.5254182294011 0.488286954781156 +75.5499430187047 0.49055747948629 +75.5744678080082 0.499476627987775 +75.5989925973117 0.499048643103412 +75.6235173866153 0.522939116654291 +75.6480421759188 0.517159642669037 +75.6725669652224 0.513012550061045 +75.6970917545259 0.498158645252599 +75.7216165438294 0.562393528504334 +75.746141333133 0.600293439090946 +75.7706661224365 0.577683086194484 +75.7951909117401 0.596932104135191 +75.8197157010436 0.659256391401979 +75.8442404903471 0.662345023795079 +75.8687652796507 0.672443886751076 +75.8932900689542 0.705232660763724 +75.9178148582578 0.72739801473478 +75.9423396475613 0.77979190140965 +75.9668644368649 0.84362731581408 +75.9913892261684 0.867849202048088 +76.0159140154719 0.853419448125334 +76.0404388047755 0.918677085463515 +76.064963594079 0.872638271982624 +76.0894883833826 0.85561424866895 +76.1140131726861 0.813578747470359 +76.1385379619896 0.752030871812106 +76.1630627512932 0.680221182878808 +76.1875875405967 0.668821351228679 +76.2121123299003 0.621720243534225 +76.2366371192038 0.584680136715009 +76.2611619085073 0.642542932731719 +76.2856866978109 0.602425695515417 +76.3102114871144 0.626643747750753 +76.334736276418 0.609985165202296 +76.3592610657215 0.629166126978827 +76.3837858550251 0.638374992084011 +76.4083106443286 0.613200563880045 +76.4328354336321 0.67312756015705 +76.4573602229357 0.627281891078626 +76.4818850122392 0.647701277430144 +76.5064098015428 0.704090808389971 +76.5309345908463 0.67768178960969 +76.5554593801498 0.669069371752948 +76.5799841694534 0.666709942843924 +76.6045089587569 0.687256095480091 +76.6290337480605 0.666533812482502 +76.653558537364 0.650144098498028 +76.6780833266675 0.619919399792884 +76.7026081159711 0.601376581344225 +76.7271329052746 0.586736668977961 +76.7516576945782 0.558464262337194 +76.7761824838817 0.53141710022904 +76.8007072731853 0.502851142985902 +76.8252320624888 0.518750327966868 +76.8497568517923 0.574749736123092 +76.8742816410959 0.540684675454698 +76.8988064303994 0.519799442138059 +76.923331219703 0.512508841015164 +76.9478560090065 0.493852436324228 +76.97238079831 0.516907788146097 +76.9969055876136 0.512294848572983 +77.0214303769171 0.522628552010876 +77.0459551662207 0.497226951322356 +77.0704799555242 0.5265276240946 +77.0950047448277 0.510393598631738 +77.1195295341313 0.525281531522271 +77.1440543234348 0.564595997045292 +77.1685791127384 0.508068197804801 +77.1931039020419 0.538275882468901 +77.2176286913455 0.572327763094922 +77.242153480649 0.59592468604343 +77.2666782699525 0.6233279428731 +77.2912030592561 0.671142918056944 +77.3157278485596 0.679738321872642 +77.3402526378632 0.705073544443346 +77.3647774271667 0.767481223868994 +77.3893022164702 0.792589273955144 +77.4138270057738 0.878917621015087 +77.4383517950773 0.947038396308173 +77.4628765843809 1.04033359980522 +77.4874013736844 1.06376757243468 +77.5119261629879 1.14305166084964 +77.5364509522915 1.14779520070608 +77.560975741595 1.12436122807662 +77.5855005308986 1.12379114091292 +77.6100253202021 1.04792158552916 +77.6345501095057 0.952808524249725 +77.6590748988092 0.873884364554953 +77.6835996881127 0.800215121759839 +77.7081244774163 0.783325532728157 +77.7326492667198 0.765735256249456 +77.7571740560234 0.719490118323727 +77.7816988453269 0.689727432585033 +77.8062236346304 0.657258569259501 +77.830748423934 0.680493885441463 +77.8552732132375 0.667927519379195 +77.8797980025411 0.667810099138247 +77.9043227918446 0.673182436278853 +77.9288475811481 0.67814380257614 +77.9533723704517 0.698021617801018 +77.9778971597552 0.756211992502187 +78.0024219490588 0.753310992466523 +78.0269467383623 0.738038448817416 +78.0514715276659 0.821835070605584 +78.0759963169694 0.804072497764133 +78.1005211062729 0.78994012844242 +78.1250458955765 0.768950654927205 +78.14957068488 0.784043234216219 +78.1740954741836 0.754725547402931 +78.1986202634871 0.646017853929751 +78.2231450527906 0.650437649100399 +78.2476698420942 0.616113065911723 +78.2721946313977 0.62195125001745 +78.2967194207013 0.570161478588364 +78.3212442100048 0.587143805822609 +78.3457689993083 0.546926162406402 +78.3702937886119 0.563135912030782 +78.3948185779154 0.547299271168962 +78.419343367219 0.525226655400468 +78.4438681565225 0.493894132403659 +78.4683929458261 0.49594683066794 +78.4929177351296 0.468820110399597 +78.5174425244331 0.470486519858946 +78.5419673137367 0.462730071770929 +78.5664921030402 0.472484342001424 +78.5910168923438 0.487686673534043 +78.6155416816473 0.476924985211787 +78.6400664709508 0.446247619583894 +78.6645912602544 0.46916853712377 +78.6891160495579 0.46482446611464 +78.7136408388615 0.44318366922918 +78.738165628165 0.466318579211238 +78.7626904174685 0.452413382374079 +78.7872152067721 0.461684791598409 +78.8117399960756 0.435699923703819 +78.8362647853792 0.447448182078121 +78.8607895746827 0.468954544681589 +78.8853143639863 0.454683907079213 +78.9098391532898 0.46398934438563 +78.9343639425933 0.464534749510941 +78.9588887318969 0.459745679576405 +78.9834135212004 0.468467849676752 +79.007938310504 0.458734427485972 +79.0324630998075 0.478498656468574 +79.056987889111 0.432556415188916 +79.0815126784146 0.43917101090318 +79.1060374677181 0.456446888739795 +79.1305622570217 0.471456075869948 +79.1550870463252 0.425034807582796 +79.1796118356287 0.439788306191337 +79.2041366249323 0.465676601884694 +79.2286614142358 0.473533456172615 +79.2531862035394 0.439443713465835 +79.2777109928429 0.43670734179558 +79.3022357821465 0.438974032502043 +79.32676057145 0.436476335312355 +79.3512853607535 0.454680073080542 +79.3758101500571 0.465525153561658 +79.4003349393606 0.434923512095283 +79.4248597286642 0.45751301695203 +79.4493845179677 0.467947126589828 +79.4739093072712 0.444791368568055 +79.4984340965748 0.470158941174487 +79.5229588858783 0.470348251578282 +79.5474836751819 0.478477808428858 +79.5720084644854 0.506553236668488 +79.5965332537889 0.515103110406085 +79.6210580430925 0.499770178590145 +79.645582832396 0.508454486609734 +79.6701076216996 0.501453602090538 +79.6946324110031 0.486058126155453 +79.7191572003067 0.503120011549887 +79.7436819896102 0.538628143191746 +79.7682067789137 0.50564239077796 +79.7927315682173 0.546943176447446 +79.8172563575208 0.57516070696641 +79.8417811468244 0.601759036150486 +79.8663059361279 0.635059187206358 +79.8908307254314 0.647701277430144 +79.915355514735 0.694743675004123 +79.9398803040385 0.71574249456304 +79.9644050933421 0.745084863414713 +79.9889298826456 0.77799105766831 +80.0134546719491 0.797164351447499 +80.0379794612527 0.848420219747288 +80.0625042505562 0.811753221690631 +80.0870290398598 0.825226599644756 +80.1115538291633 0.801612662655204 +80.1360786184669 0.738956962705287 +80.1606034077704 0.76203316256687 +80.1851281970739 0.719628386604391 +80.2096529863775 0.654840430230003 +80.234177775681 0.639730836899946 +80.2587025649846 0.619084278063874 +80.2832273542881 0.597771059862872 +80.3077521435916 0.581905902963995 +80.3322769328952 0.629959552628407 +80.3568017221987 0.61380467912583 +80.3813265115023 0.576675668102723 +80.4058513008058 0.591232188310127 +80.4303760901093 0.625577619538518 +80.4549008794129 0.60925044967319 +80.4794256687164 0.606434519842746 +80.50395045802 0.65524756707465 +80.5284752473235 0.629703864106796 +80.5530000366271 0.67287570563411 +80.5775248259306 0.680137790719947 +80.6020496152341 0.680321589078712 +80.6265744045377 0.655650869920626 +80.6510991938412 0.681849730257397 +80.6756239831448 0.670198044084329 +80.7001487724483 0.64651772897696 +80.7246735617518 0.634811166682089 +80.7491983510554 0.614967379539298 +80.7737231403589 0.608049887178963 +80.7982479296625 0.580650464347965 +80.822772718966 0.565058010011742 +80.8472975082695 0.572789776061372 +80.8718222975731 0.576365103459309 +80.8963470868766 0.55276434651213 +80.9208718761802 0.571047642440506 +80.9453966654837 0.570237202749882 +80.9699214547873 0.558346842096246 +80.9944462440908 0.567362562798964 +81.0189710333943 0.594513965105693 +81.0434958226979 0.565192444293734 +81.0680206120014 0.576730544224526 +81.092545401305 0.613338832160709 +81.1170701906085 0.661778770630053 +81.141594979912 0.626316169066295 +81.1661197692156 0.626622899711038 +81.1906445585191 0.615084799780247 +81.2151693478227 0.662341189796408 +81.2396941371262 0.659998774928427 +81.2642189264297 0.702903425938117 +81.2887437157333 0.747040989477761 +81.3132685050368 0.760870462153402 +81.3377932943404 0.7962496715583 +81.3623180836439 0.861645577177143 +81.3868428729475 0.891287008676218 +81.411367662251 1.01659457457738 +81.4358924515545 1.11861194817478 +81.4604172408581 1.20061707226531 +81.4849420301616 1.24565781369814 +81.5094668194652 1.31435251015359 +81.5339916087687 1.29978448795018 +81.5585163980722 1.31999371585818 +81.5830411873758 1.354234906888 +81.6075659766793 1.29988872814875 +81.6320907659829 1.19482441823768 +81.6566155552864 1.18127148212337 +81.6811403445899 1.13374622354322 +81.7056651338935 0.964909043346871 +81.730189923197 0.965014961591806 +81.7547147125006 0.925929824505651 +81.7792395018041 0.921585753496521 +81.8037642911077 0.898409147435033 +81.8282890804112 0.8918362478002 +81.8528138697147 0.875685208296294 +81.8773386590183 0.875488229895157 +81.9018634483218 0.901120837066902 +81.9263882376254 0.925111716817685 +81.9509130269289 0.963193269810749 +81.9754378162324 0.999201276499818 +81.999962605536 1.03921259547119 +82.0244873948395 1.08511865271644 +82.0490121841431 1.17285220866909 +82.0735369734466 1.16387435004713 +82.0980617627501 1.17979821706649 +82.1225865520537 1.11075892788553 +82.1471113413572 1.1440590789414 +82.1716361306608 1.09307974720294 +82.1961609199643 1.03256013767616 +82.2206857092679 0.967776015300447 +82.2452104985714 0.902018502915057 +82.2697352878749 0.93265417246352 +82.2942600771785 0.896763586015399 +82.318784866482 0.800378072078889 +82.3433096557856 0.717568020342767 +82.3678344450891 0.715435763918297 +82.3923592343926 0.699653999178279 +82.4168840236962 0.665850139076528 +82.4414088129997 0.674462556933269 +82.4659336023033 0.690013315190061 +82.4904583916068 0.679990176395582 +82.5149831809103 0.669963203602432 +82.5395079702139 0.669224654074655 +82.5640327595174 0.672175018187092 +82.588557548821 0.657745264264338 +82.6130823381245 0.696741497146602 +82.6376071274281 0.71929313992259 +82.6621319167316 0.69852916084557 +82.6866567060351 0.67814380257614 +82.7111814953387 0.677530341286654 +82.7357062846422 0.629359271381294 +82.7602310739458 0.639827409101179 +82.7847558632493 0.621254396569103 +82.8092806525528 0.594883239869581 +82.8338054418564 0.599999888488576 +82.8583302311599 0.588289492195033 +82.8828550204635 0.558308980015487 +82.907379809767 0.565075024052786 +82.9319045990705 0.565313698533354 +82.9564293883741 0.516110528497846 +82.9809541776776 0.554099343288349 +83.0054789669812 0.578921510769471 +83.0300037562847 0.596453077127697 +83.0545285455883 0.561607770852096 +83.0790533348918 0.539186728359429 +83.1035781241953 0.548944832588596 +83.1281029134989 0.575546995771343 +83.1526277028024 0.578980220889945 +83.177152492106 0.558871399181841 +83.2016772814095 0.562321638341487 +83.226202070713 0.534909035468116 +83.2507268600166 0.549910554600926 +83.2752516493201 0.541226246581338 +83.2997764386237 0.548651281986225 +83.3243012279272 0.580743202550526 +83.3488260172307 0.595345252836032 +83.3733508065343 0.606010368957055 +83.3978755958378 0.570954904237944 +83.4224003851414 0.566569137149384 +83.4469251744449 0.583089451417178 +83.4714499637485 0.58869662903968 +83.495974753052 0.566451716908436 +83.5204995423555 0.614967379539298 +83.5450243316591 0.646794265538287 +83.5695491209626 0.622782537747789 +83.5940739102662 0.60490637866406 +83.6185986995697 0.647235430465022 +83.6431234888732 0.661778770630053 +83.6676482781768 0.686345249589563 +83.6921730674803 0.693101947583161 +83.7166978567839 0.698152218084339 +83.7412226460874 0.778839359439692 +83.7657474353909 0.8218559186453 +83.7902722246945 0.82198651892862 +83.814797013998 0.905116481351858 +83.8393218033016 0.939285782218827 +83.8638465926051 0.982504831870602 +83.8883713819087 1.08015728641916 +83.9128961712122 1.20276250873215 +83.9374209605157 1.27863038606955 +83.9619457498193 1.39097762910617 +83.9864705391228 1.44816441971425 +84.0109953284264 1.47014046328151 +84.0355201177299 1.4538890175777 +84.0600449070334 1.52554893623432 +84.084569696337 1.49599473089278 +84.1090944856405 1.38030316694145 +84.1336192749441 1.28282684275432 +84.1581440642476 1.17103435088671 +84.1826688535511 1.11076659588287 +84.2071936428547 1.0240064299399 +84.2317184321582 0.972220492509481 +84.2562432214618 0.931856912815269 +84.2807680107653 0.891760523638682 +84.3052928000689 0.894513909349981 +84.3298175893724 0.82674539477974 +84.3543423786759 0.809789427630241 +84.3788671679795 0.839794621848173 +84.403391957283 0.783573553252426 +84.4279167465866 0.826196155655758 +84.4524415358901 0.833893893623301 +84.4769663251936 0.853889129089127 +84.5014911144972 0.848571668070324 +84.5260159038007 0.91393905765211 +84.5505406931043 0.959025329163042 +84.5750654824078 0.96536722231465 +84.5995902717113 1.01467631059509 +84.6241150610149 1.0607908482375 +84.6486398503184 1.04921488622595 +84.673164639622 1.05714363067672 +84.6976894289255 1.03765977225411 +84.7222142182291 0.957580580143217 +84.7467390075326 0.933930459119265 +84.7712637968361 0.912280316190104 +84.7957885861397 0.850917916936975 +84.8203133754432 0.827487778306188 +84.8448381647468 0.770541340225036 +84.8693629540503 0.770473284060861 +84.8938877433538 0.719679428727522 +84.9184125326574 0.707876294231417 +84.9429373219609 0.689295613702 +84.9674621112645 0.6695769147975 +84.991986900568 0.684544405848222 +85.0165116898716 0.682101584780338 +85.0410364791751 0.688888476857352 +85.0655612684786 0.689492592103137 +85.0900860577822 0.669417798477122 +85.1146108470857 0.688905490898396 +85.1391356363893 0.701748393521991 +85.1636604256928 0.689782308706836 +85.1881852149963 0.702441412971666 +85.2127100042999 0.694957667446305 +85.2372347936034 0.712909550691551 +85.261759582907 0.803237376035123 +85.2862843722105 0.82068938423316 +85.310809161514 0.840080504453201 +85.3353339508176 0.887295198389932 +85.3598587401211 0.976339069080416 +85.3843835294247 0.995751037340173 +85.4089083187282 1.09508691538912 +85.4334331080318 1.18109151776328 +85.4579578973353 1.24238370489992 +85.4824826866388 1.22967355851195 +85.5070074759424 1.25466035435849 +85.5315322652459 1.27878566839126 +85.5560570545495 1.23442476636573 +85.580581843853 1.22371795416528 +85.6051066331565 1.14333754345467 +85.6296314224601 1.13657533341604 +85.6541562117636 1.07927495656569 +85.6786810010672 0.97112968225886 +85.7032057903707 0.96164811459102 +85.7277305796742 0.925653287944324 +85.7522553689778 0.906945841130257 +85.7767801582813 0.823870754828822 +85.8013049475849 0.851366749861053 +85.8258297368884 0.901179547187376 +85.850354526192 0.885750043170203 +85.8748793154955 0.922316635026955 +85.899404104799 0.919991234200019 +85.9239288941026 0.923483169439095 +85.9484536834061 0.948729487805908 +85.9729784727097 1.01971723505257 +85.9975032620132 1.03530968938879 +86.0220280513167 1.06550419401052 +86.0465528406203 1.02489642779071 +86.0710776299238 1.06110141288092 +86.0956024192274 1.07927112256701 +86.1201272085309 1.07862914524047 +86.1446519978344 1.06139496348329 +86.169176787138 1.0573576231189 +86.1937015764415 1.02780892982239 +86.2182263657451 0.981429357614665 +86.2427511550486 0.946131384416316 +86.2672759443522 0.883348918181749 +86.2918007336557 0.853264165803627 +86.3163255229592 0.799190689627035 +86.3408503122628 0.736731968078254 +86.3653751015663 0.734743491979478 +86.3898998908699 0.757050948229868 +86.4144246801734 0.727540117014114 +86.4389494694769 0.682508721624985 +86.4634742587805 0.655012726592754 +86.487999048084 0.693967263395588 +86.5125238373876 0.709425283449818 +86.5370486266911 0.683398719475798 +86.5615734159946 0.674252398489759 +86.5860982052982 0.681169890850094 +86.6106229946017 0.668469090505835 +86.6351477839053 0.712061248920169 +86.6596725732088 0.675045824139339 +86.6841973625124 0.634576326200192 +86.7087221518159 0.663155463485703 +86.7332469411194 0.642429346489442 +86.757771730423 0.574291557155313 +86.7822965197265 0.576302559340164 +86.8068213090301 0.608394479904465 +86.8313460983336 0.577683086194484 +86.8558708876371 0.556663418595853 +86.8803956769407 0.563232484232015 +86.9049204662442 0.531009963384393 +86.9294452555478 0.504865979169425 +86.9539700448513 0.52456766403288 +86.9784948341548 0.527400607904368 +87.0030196234584 0.5262379074909 +87.0275444127619 0.500307915718113 +87.0520692020655 0.526913912899532 +87.076593991369 0.512995536020001 +87.1011187806726 0.516093514456802 +87.1256435699761 0.495871106506422 +87.1501683592796 0.501936463096703 +87.1746931485832 0.509407028579692 +87.1992179378867 0.478847083192747 +87.2237427271903 0.479788123166691 +87.2482675164938 0.513402672864648 +87.2727923057973 0.510120896069082 +87.2973170951009 0.485789257591469 +87.3218418844044 0.511925573809094 +87.346366673708 0.467363859383758 +87.3708914630115 0.484429578776863 +87.395416252315 0.490440059245342 +87.4199410416186 0.528425040037174 +87.4444658309221 0.497692798287478 +87.4689906202257 0.515203516605989 +87.4935154095292 0.489353082993391 +87.5180401988328 0.471770474512033 +87.5425649881363 0.47480974282836 +87.5670897774398 0.475875871040595 +87.5916145667434 0.488811511866752 +87.6161393560469 0.478553532590377 +87.6406641453505 0.516731657784674 +87.665188934654 0.513092108221234 +87.6897137239575 0.495522679782248 +87.7142385132611 0.488031266259545 +87.7387633025646 0.474410273981055 +87.7632880918682 0.4771900197771 +87.7878128811717 0.494960260615894 +87.8123376704752 0.504089567560889 +87.8368624597788 0.491724013898429 +87.8613872490823 0.4775252664589 +87.8859120383859 0.501180899527882 +87.9104368276894 0.484295144494871 +87.934961616993 0.500266219638683 +87.9594864062965 0.525385771720847 +87.9840111956 0.490481755324772 +88.0085359849036 0.468195147114097 +88.0330607742071 0.495018970736368 +88.0575855635107 0.513667707429961 +88.0821103528142 0.502309571859263 +88.1066351421177 0.505697266899763 +88.1311599314213 0.518191742799184 +88.1556847207248 0.495871106506422 +88.1802095100284 0.472757044564079 +88.2047342993319 0.474285185742765 +88.2292590886354 0.516286658859268 +88.253783877939 0.508651465010871 +88.2783086672425 0.496916386678942 +88.3028334565461 0.481890185507745 +88.3273582458496 0.458213704399048 +88.3518830351532 0.459062006170431 +88.3764078244567 0.510704163275152 +88.4009326137602 0.488597519424571 +88.4254574030638 0.481600468904046 +88.4499821923673 0.493579733761573 +88.4745069816709 0.498137797212884 +88.4990317709744 0.49916606334436 +88.5235565602779 0.497306509482545 +88.5480813495815 0.476362566045432 +88.572606138885 0.478456960389143 +88.5971309281886 0.525629958246444 +88.6216557174921 0.547005720566591 +88.6461805067956 0.519740732017585 +88.6707052960992 0.500290901677069 +88.6952300854027 0.532848669206493 +88.7197548747063 0.522939116654291 +88.7442796640098 0.536378466526327 +88.7688044533134 0.512895129820096 +88.7933292426169 0.482221598190875 +88.8178540319204 0.487393122931672 +88.842378821224 0.530246731818229 +88.8669036105275 0.549952250680357 +88.8914283998311 0.543455075207041 +88.9159531891346 0.564226722281403 +88.9404779784381 0.548706158108028 +88.9650027677417 0.554279307648443 +88.9895275570452 0.556349019953767 +89.0140523463488 0.551404667697524 +89.0385771356523 0.574888004403755 +89.0631019249558 0.587492232546782 +89.0876267142594 0.601548877706976 +89.1121515035629 0.629380119421008 +89.1366762928665 0.586929813380427 +89.16120108217 0.628696446015034 +89.1857258714736 0.642001361605079 +89.2102506607771 0.65921852932122 +89.2347754500806 0.69226299185548 +89.2593002393842 0.697186496072008 +89.2838250286877 0.744459900129213 +89.3083498179913 0.788072906583263 +89.3328746072948 0.815589749655209 +89.3573993965983 0.872248149179021 +89.3819241859019 0.915143454145008 +89.4064489752054 0.922803330031792 +89.430973764509 0.944671299401806 +89.4554985538125 0.986777012716885 +89.480023343116 1.02294030172766 +89.5045481324196 0.956565494054114 +89.5290729217231 0.983616490160938 +89.5535977110267 0.938958203534369 +89.5781225003302 0.870954848482232 +89.6026472896338 0.875081093050509 +89.6271720789373 0.876188917342175 +89.6516968682408 0.866552067352628 +89.6762216575444 0.826896843102776 +89.7007464468479 0.867924926209606 +89.7252712361515 0.849020500994401 +89.749796025455 0.859685617115424 +89.7743208147585 0.893637091541541 +89.7988456040621 0.909153821716245 +89.8233703933656 0.920066958361537 +89.8478951826692 0.976628785684115 +89.8724199719727 1.049097465985 +89.8969447612762 1.07767660327051 +89.9214695505798 1.10213332998642 +89.9459943398833 1.12235957193547 +89.9705191291869 1.11072489980344 +89.9950439184904 1.11056578348306 +90.019568707794 1.1429891167305 +90.0440934970975 1.15359552273104 +90.068618286401 1.11123627684667 +90.0931430757046 1.02255017892406 +90.1176678650081 0.992535638662423 +90.1421926543117 0.988623386536327 +90.1667174436152 0.946555535302007 +90.1912422329187 0.928293087413346 +90.2157670222223 0.894031048343815 +90.2402918115258 0.863311986636492 +90.2648166008294 0.866862631996042 +90.2893413901329 0.777084045776453 +90.3138661794364 0.803720237041288 +90.33839096874 0.785827063916516 +90.3629157580435 0.741848616697249 +90.3874405473471 0.734768174017864 +90.4119653366506 0.710491411662053 +90.4364901259542 0.728871279791662 +90.4610149152577 0.708904560362894 +90.4855397045612 0.737072726805085 +90.5100644938648 0.703880649946461 +90.5345892831683 0.75000453363257 +90.5591140724719 0.774209405825535 +90.5836388617754 0.784622667423617 +90.6081636510789 0.786368635043155 +90.6326884403825 0.75555683513327 +90.657213229686 0.785978512239552 +90.6817380189896 0.811421809007502 +90.7062628082931 0.748887363297204 +90.7307875975966 0.737890834493052 +90.7553123869002 0.727477572894969 +90.7798371762037 0.715087337194123 +90.8043619655073 0.682046708658535 +90.8288867548108 0.634790318642374 +90.8534115441144 0.625749915901269 +90.8779363334179 0.642232368088305 +90.9024611227214 0.614815931216262 +90.926985912025 0.634110479235071 +90.9515107013285 0.622727661625986 +90.9760354906321 0.595055536232332 +91.0005602799356 0.623735079717747 +91.0250850692391 0.580667478389009 +91.0496098585427 0.573066312622699 +91.0741346478462 0.566703571431376 +91.0986594371498 0.570837483996996 +91.1231842264533 0.564281598403206 +91.1477090157568 0.574833128281952 +91.1722338050604 0.550183257163582 +91.1967585943639 0.558926275303644 +91.2212833836675 0.578673490245202 +91.245808172971 0.558833537101082 +91.2703329622746 0.573835056233893 +91.2948577515781 0.595424810996221 +91.3193825408816 0.590459610700262 +91.3439073301852 0.599340897120988 +91.3684321194887 0.56985091394495 +91.3929569087923 0.563950185720077 +91.4174816980958 0.574791432202522 +91.4420064873993 0.559551238589144 +91.4665312767029 0.546094874676063 +91.4910560660064 0.54992756864197 +91.51558085531 0.594765819628633 +91.5401056446135 0.593444002894787 +91.564630433917 0.655222885036264 +91.5891552232206 0.653501599455112 +91.6136800125241 0.648863977843612 +91.6382048018277 0.655168008914461 +91.6627295911312 0.695868513336833 +91.6872543804348 0.705291370884198 +91.7117791697383 0.724455318619686 +91.7363039590418 0.737400305489544 +91.7608287483454 0.776169365887254 +91.7853535376489 0.816438051426592 +91.8098783269525 0.875681374297623 +91.834403116256 0.915219178306526 +91.8589279055595 0.958887060882379 +91.8834526948631 1.01570841072524 +91.9079774841666 1.03955335419802 +91.9325022734702 1.07388177138536 +91.9570270627737 1.04558851670488 +91.9815518520772 1.01237559180654 +92.0060766413808 0.961920817153675 +92.0306014306843 0.884738791079771 +92.0551262199879 0.877741740559246 +92.0796510092914 0.81697027650953 +92.104175798595 0.783111540285976 +92.1287005878985 0.764652113996177 +92.153225377202 0.745105711454429 +92.1777501665056 0.711922980639506 +92.2022749558091 0.71557403219896 +92.2267997451127 0.690596582396131 +92.2513245344162 0.656682970050774 +92.2758493237197 0.629707698105467 +92.3003741130233 0.624566367448086 +92.3248989023268 0.629048706737879 +92.3494236916304 0.661002359021517 +92.3739484809339 0.640431524346964 +92.3984732702374 0.680276059000611 +92.422998059541 0.732170070628272 +92.4475228488445 0.711578387914004 +92.4720476381481 0.696489642623662 +92.4965724274516 0.749639092867353 +92.5210972167552 0.753790019474017 +92.5456220060587 0.744463734127885 +92.5701467953622 0.781051174024352 +92.5946715846658 0.801322946051505 +92.6191963739693 0.798734188705614 +92.6437211632729 0.791278959217311 +92.6682459525764 0.770990173149114 +92.6927707418799 0.804165235966695 +92.7172955311835 0.815769714015303 +92.741820320487 0.7509609096012 +92.7663451097906 0.725907735636853 +92.7908698990941 0.718906851117658 +92.8153946883976 0.701807103642465 +92.8399194777012 0.680086748596816 +92.8644442670047 0.617006897761207 +92.8889690563083 0.626215762866391 +92.9134938456118 0.631084390961116 +92.9380186349154 0.608083915261051 +92.9625434242189 0.679155054666572 +92.9870682135224 0.638299267922493 +93.011593002826 0.646807445580659 +93.0361177921295 0.660909620818955 +93.0606425814331 0.656679136052102 +93.0851673707366 0.621812981736787 +93.1096921600401 0.69493681940659 +93.1342169493437 0.680556429560608 +93.1587417386472 0.654391597305925 +93.1832665279508 0.641162405877398 +93.2077913172543 0.705992058331216 +93.2323161065578 0.709597579812569 +93.2568408958614 0.770948477069684 +93.2813656851649 0.842112354677767 +93.3058904744685 0.856277074035209 +93.330415263772 0.875118955131268 +93.3549400530756 0.909557124562221 +93.3794648423791 0.919663655515561 +93.4039896316826 0.881674840725058 +93.4285144209862 0.942152754172403 +93.4530392102897 0.934521394322677 +93.4775639995933 0.904982047069866 +93.5020887888968 0.914139870051919 +93.5266135782003 0.812433061097934 +93.5511383675039 0.795153349262648 +93.5756631568074 0.758175786562577 +93.600187946111 0.686953198834019 +93.6247127354145 0.687780652565687 +93.649237524718 0.676543771234608 +93.6737623140216 0.636297611781344 +93.6982871033251 0.626761167991702 +93.7228118926287 0.621913387936691 +93.7473366819322 0.609867744961348 +93.7718614712358 0.625325765015578 +93.7963862605393 0.629628139945278 +93.8209110498428 0.614778069135503 +93.8454358391464 0.614581090734366 +93.8699606284499 0.614211815970477 +93.8944854177535 0.615437060503091 +93.919010207057 0.619659877272601 +93.9435349963605 0.657552119861871 +93.9680597856641 0.686718358352123 +93.9925845749676 0.668120663781661 +94.0171093642712 0.739108411028323 +94.0416341535747 0.71503246107232 +94.0661589428782 0.658718654274011 +94.0906837321818 0.67998250839824 +94.1152085214853 0.737366277407456 +94.1397333107889 0.721290962065068 +94.1642581000924 0.748518088533315 +94.188782889396 0.678848324021829 +94.2133076786995 0.673744855445207 +94.237832468003 0.63114310108159 +94.2623572573066 0.659021550920083 +94.2868820466101 0.684586101927653 +94.3114068359137 0.644368458511446 +94.3359316252172 0.60202239266944 +94.3604564145207 0.582778886773764 +94.3849812038243 0.565095872092501 +94.4095059931278 0.584235137789602 +94.4340307824314 0.562497768702909 +94.4585555717349 0.567269824596402 +94.4830803610384 0.534170485940339 +94.507605150342 0.537499470860366 +94.5321299396455 0.534749919147738 +94.5566547289491 0.521113590874563 +94.5811795182526 0.544428465216715 +94.6057043075562 0.556563012395949 +94.6302290968597 0.54382434997093 +94.6547538861632 0.551463377817998 +94.6792786754668 0.571047642440506 +94.7038034647703 0.569670949584856 +94.7283282540739 0.577082804947371 +94.7528530433774 0.511329126560652 +94.7773778326809 0.487644977454612 +94.8019026219845 0.513902547911858 +94.826427411288 0.529549878369883 +94.8509522005916 0.520168716901948 +94.8754769898951 0.513012550061045 +94.9000017791986 0.523425811659127 +94.9245265685022 0.480647926934088 +94.9490513578057 0.526620362297161 +94.9735761471093 0.528059599271956 +94.9981009364128 0.521331417315416 +95.0226257257164 0.524722946354587 +95.0471505150199 0.520282303144225 +95.0716753043234 0.557242851803252 +95.096200093627 0.540156284370431 +95.1207248829305 0.555169305499255 +95.1452496722341 0.550728662288892 +95.1697744615376 0.533759515097021 +95.1942992508411 0.555593456384947 +95.2188240401447 0.546753866043651 +95.2433488294482 0.488756635744949 +95.2678736187518 0.484329172576959 +95.2923984080553 0.511438878804258 +95.3169231973588 0.532151815758146 +95.3414479866624 0.517335773030459 +95.3659727759659 0.537986165865202 +95.3904975652695 0.543841364011974 +95.415022354573 0.565427284775631 +95.4395471438766 0.558502124417953 +95.4640719331801 0.562090631858262 +95.4885967224836 0.56922595065945 +95.5131215117872 0.566707405430047 +95.5376463010907 0.542972214200876 +95.5621710903943 0.542968380202205 +95.5866958796978 0.548013138658352 +95.6112206690013 0.571026794400791 +95.6357454583049 0.584411268151025 +95.6602702476084 0.583186023618411 +95.684795036912 0.574774418161478 +95.7093198262155 0.604184843177327 +95.733844615519 0.630987818759883 +95.7583694048226 0.612213993827999 +95.7828941941261 0.640259227984213 +95.8074189834297 0.64246337457153 +95.8319437727332 0.640490234467438 +95.8564685620368 0.621212700489673 +95.8809933513403 0.70930786320887 +95.9055181406438 0.67764009353026 +95.9300429299474 0.656896962492955 +95.9545677192509 0.653887888260045 +95.9790925085545 0.63711571946931 +96.003617297858 0.611479278298894 +96.0281420871615 0.611147865615764 +96.0526668764651 0.629900842507933 +96.0771916657686 0.604792792421783 +96.1017164550722 0.625498061378329 +96.1262412443757 0.592071144037808 +96.1507660336792 0.614446656452374 +96.1752908229828 0.577351673511355 +96.1998156122863 0.597670653662968 +96.2243404015899 0.609288311753949 +96.2488651908934 0.599924164327058 +96.273389980197 0.586018967489899 +96.2979147695005 0.580453485946827 +96.322439558804 0.583093285415849 +96.3469643481076 0.577599694035624 +96.3714891374111 0.611231257774625 +96.3960139267147 0.60753851013574 +96.4205387160182 0.645572855004344 +96.4450635053217 0.6224132629839 +96.4695882946253 0.609985165202296 +96.4941130839288 0.634362333758011 +96.5186378732324 0.61062714252884 +96.5431626625359 0.616385768474378 +96.5676874518394 0.603239969204712 +96.592212241143 0.659487397885204 +96.6167370304465 0.648943536003801 +96.6412618197501 0.699919033743592 +96.6657866090536 0.672506430870221 +96.6903113983572 0.725551640915337 +96.7148361876607 0.72585285951505 +96.7393609769642 0.656296681245841 +96.7638857662678 0.649695265573951 +96.7884105555713 0.664380708018316 +96.8129353448749 0.704107822431015 +96.8374601341784 0.698139038041967 +96.8619849234819 0.690151583470725 +96.8865097127855 0.678181664656899 +96.911034502089 0.733022206398326 +96.9355592913926 0.720497536415488 +96.9600840806961 0.739964380797048 +96.9846088699996 0.777424804503284 +97.0091336593032 0.782859685763035 +97.0336584486067 0.827879579156151 +97.0581832379103 0.856294088076253 +97.0827080272138 0.837230546540669 +97.1072328165174 0.934472030245905 +97.1317576058209 0.983302091518853 +97.1562823951244 1.06723865963404 +97.180807184428 1.17922812990279 +97.2053319737315 1.25156237592168 +97.2298567630351 1.26030539406175 +97.2543815523386 1.2866727167626 +97.2789063416421 1.41517866730047 +97.3034311309457 1.46904965303089 +97.3279559202492 1.5206709620959 +97.3524807095528 1.51225552264029 +97.3770054988563 1.53410647796926 +97.4015302881598 1.51268350752466 +97.4260550774634 1.45411067801723 +97.4505798667669 1.40682193796534 +97.4751046560705 1.34989850387621 +97.499629445374 1.29459211516966 +97.5241542346776 1.21908416655245 +97.5486790239811 1.13246610288881 +97.5732038132846 1.09961095075834 +97.5977286025882 1.05100254992492 +97.6222533918917 1.03994731100029 +97.6467781811953 1.04555065462412 +97.6713029704988 1.00600901661655 +97.6958277598023 1.02891675411405 +97.7203525491059 0.995343900495525 +97.7448773384094 1.03922577551356 +97.769402127713 1.0540248042002 +97.7939269170165 1.04482911913739 +97.81845170632 1.11196332437843 +97.8429764956236 1.12803863972082 +97.8675012849271 1.11175316593492 +97.8920260742307 1.11688682859496 +97.9165508635342 1.14927229976163 +97.9410756528378 1.13746533126685 +97.9656004421413 1.17166866021591 +97.9901252314448 1.14757186222019 +98.0146500207484 1.1408700403484 +98.0391748100519 1.15606302583732 +98.0636995993555 1.12373243079245 +98.088224388659 1.159530279038 +98.1127491779625 1.19793941071553 +98.1372739672661 1.2248636405377 +98.1617987565696 1.18390361359505 +98.1863235458732 1.20318498157148 +98.2108483351767 1.12152445020646 +98.2353731244802 1.1066952274364 +98.2598979137838 1.01923820804507 +98.2844227030873 1.00670970406357 +98.3089474923909 0.957228319420372 +98.3334722816944 0.926346307393999 +98.357997070998 0.927155069038264 +98.3825218603015 0.948570371485529 +98.407046649605 0.914084993930116 +98.4315714389086 0.80636003651031 +98.4560962282121 0.798548712300491 +98.4806210175157 0.785495651233386 +98.5051458068192 0.812601523462014 +98.5296705961227 0.829742967016637 +98.5541953854263 0.831186037990103 +98.5787201747298 0.789256455036446 +98.6032449640334 0.798079031336698 +98.6277697533369 0.830892487387732 +98.6522945426404 0.795094639142174 +98.676819331944 0.770041465177827 +98.7013441212475 0.76876134452341 +98.7258689105511 0.735893012350573 +98.7503936998546 0.753055303944911 +98.7749184891582 0.720925521299851 +98.7994432784617 0.720124427652929 +98.8239680677652 0.722650640879674 +98.8484928570688 0.711250809229545 +98.8730176463723 0.660322519614214 +98.8975424356759 0.690986705199735 +98.9220672249794 0.671394772579885 +98.9465920142829 0.711616249994762 +98.9711168035865 0.678886186102588 +98.99564159289 0.658248973310218 +99.0201663821936 0.620926817884645 +99.0446911714971 0.631974388811929 +99.0692159608006 0.637502008274242 +99.0937407501042 0.621544113172803 +99.1182655394077 0.653266758973216 +99.1427903287113 0.63653245226324 +99.1673151180148 0.655050588673513 +99.1918399073184 0.659784782486246 +99.2163646966219 0.640683378869904 +99.2408894859254 0.624587215487801 +99.265414275229 0.653887888260045 +99.2899390645325 0.652410789204491 +99.3144638538361 0.693912387273785 +99.3389886431396 0.657531271822156 +99.3635134324431 0.68390626252035 +99.3880382217467 0.678126788535096 +99.4125630110502 0.688053355128342 +99.4370878003538 0.704888068038222 +99.4616125896573 0.683923276561394 +99.4861373789608 0.719393546122494 +99.5106621682644 0.709480159571621 +99.5351869575679 0.715960321003892 +99.5597117468715 0.709110884807732 +99.584236536175 0.753382882629369 +99.6087613254786 0.734944304379286 +99.6332861147821 0.783359560810245 +99.6578109040856 0.79800330717518 +99.6823356933892 0.828869983206868 +99.7068604826927 0.861762997418092 +99.7313852719963 0.897918618431525 +99.7559100612998 0.92726482128187 +99.7804348506033 0.930673364362086 +99.8049596399069 1.01710211762193 +99.8294844292104 1.00349047138715 +99.854009218514 0.994823177408601 +99.8785340078175 0.999612247343137 +99.903058797121 0.973962626130348 +99.9275835864246 0.950668599827912 +99.9521083757281 0.923269176996913 +99.9766331650317 0.894979756315102 +100.001157954335 0.91343534860623 +100.025682743639 0.913694871126512 +100.050207532942 0.839635505527795 +100.074732322246 0.816407857343175 +100.099257111549 0.792089398907934 +100.123781900853 0.76963432833318 +100.148306690156 0.739208817228227 +100.17283147946 0.749739499067258 +100.197356268764 0.729475395037447 +100.221881058067 0.728333542663694 +100.246405847371 0.703738547667126 +100.270930636674 0.752703043222067 +100.295455425978 0.739968214795719 +100.319980215281 0.719351850043064 +100.344505004585 0.74068208228511 +100.369029793888 0.720594108616721 +100.393554583192 0.706344319054061 +100.418079372495 0.698832057491642 +100.442604161799 0.757685257559069 +100.467128951102 0.76048417334847 +100.491653740406 0.776127669807824 +100.51617852971 0.832538048807366 +100.540703319013 0.788483877426582 +100.565228108317 0.79984201299728 +100.58975289762 0.834204458266715 +100.614277686924 0.844114010818917 +100.638802476227 0.860323760443297 +100.663327265531 0.857553360690954 +100.687852054834 0.912818053318072 +100.712376844138 0.879328591858406 +100.736901633441 0.857401912367918 +100.761426422745 0.813457493230739 +100.785951212049 0.818439707567741 +100.810476001352 0.807547418962165 +100.835000790656 0.80197426942175 +100.859525579959 0.82047922578965 +100.884050369263 0.823770348628917 +100.908575158566 0.829301802089902 +100.93309994787 0.785461623151298 +100.957624737173 0.773177305695387 +100.982149526477 0.789801860161757 +101.00667431578 0.813902492156146 +101.031199105084 0.818687728092011 +101.055723894387 0.852046589268356 +101.080248683691 0.858136627897024 +101.104773472995 0.893813221902963 +101.129298262298 0.904751040586641 +101.153823051602 0.85448941033624 +101.178347840905 0.899744144211252 +101.202872630209 0.968448186710407 +101.227397419512 1.0323214631956 +101.251922208816 1.06788830495793 +101.276446998119 1.05041544872018 +101.300971787423 1.14889919099907 +101.325496576726 1.13866972775975 +101.35002136603 1.12441227019975 +101.374546155334 1.19827082339866 +101.399070944637 1.13834214907529 +101.423595733941 1.11136304313132 +101.448120523244 1.04597863950849 +101.472645312548 1.07318108393835 +101.497170101851 1.03448223565712 +101.521694891155 0.974151936534143 +101.546219680458 0.997031157994589 +101.570744469762 0.981097944931536 +101.595269259065 0.973572503326744 +101.619794048369 0.932729896625038 +101.644318837672 0.918887243907025 +101.668843626976 0.912293496232476 +101.69336841628 0.965132381832754 +101.717893205583 0.968200166186138 +101.742417994887 0.940565902873244 +101.76694278419 0.961933997196048 +101.791467573494 1.01948622856934 +101.815992362797 1.01729909602307 +101.840517152101 0.996275594425768 +101.865041941404 1.00389760823179 +101.889566730708 0.99996067406731 +101.914091520011 0.995133742052015 +101.938616309315 0.982491651828229 +101.963141098619 0.968200166186138 +101.987665887922 0.947470215191206 +102.012190677226 0.952645573930675 +102.036715466529 0.958017911071281 +102.061240255833 0.996082450023302 +102.085765045136 0.957165775301227 +102.11028983444 0.96966959724435 +102.134814623743 0.990499954439186 +102.159339413047 0.953635977981392 +102.18386420235 0.97133984070237 +102.208388991654 0.981715240219693 +102.232913780957 0.978164594860143 +102.257438570261 0.911117615776636 +102.281963359565 0.906765876770163 +102.306488148868 0.902870638685111 +102.331012938172 0.883114077699852 +102.355537727475 0.826993415304009 +102.380062516779 0.823812044708347 +102.404587306082 0.80640173258974 +102.429112095386 0.820765108394678 +102.453636884689 0.779833597489081 +102.478161673993 0.794590930096293 +102.502686463296 0.786855330047992 +102.5272112526 0.743183613473468 +102.551736041903 0.745509014300405 +102.576260831207 0.782607831240095 +102.600785620511 0.792202985150211 +102.625310409814 0.793600526045576 +102.649835199118 0.774171543744776 +102.674359988421 0.791098994857217 +102.698884777725 0.812059952335374 +102.723409567028 0.836882119816496 +102.747934356332 0.762889132335595 +102.772459145635 0.765521263807275 +102.796983934939 0.739057368905191 +102.821508724242 0.705933348210742 +102.846033513546 0.733139626639274 +102.87055830285 0.729005714073654 +102.895083092153 0.722730199039863 +102.919607881457 0.731255390739073 +102.94413267076 0.710457383579965 +102.968657460064 0.679192916747331 +102.993182249367 0.691003719240779 +103.017707038671 0.645199746241785 +103.042231827974 0.686525213949657 +103.066756617278 0.658366393551166 +103.091281406581 0.67225074234861 +103.115806195885 0.651310632910168 +103.140330985188 0.633468501908527 +103.164855774492 0.686324401549848 +103.189380563796 0.711464801671727 +103.213905353099 0.633216647385587 +103.238430142403 0.687008074955822 +103.262954931706 0.65954994200435 +103.28747972101 0.679096344546098 +103.312004510313 0.68299158263115 +103.336529299617 0.704556655355092 +103.36105408892 0.669694335038448 +103.385578878224 0.684426985607274 +103.410103667527 0.684061544842057 +103.434628456831 0.683264285193806 +103.459153246135 0.684195979124049 +103.483678035438 0.691586986446848 +103.508202824742 0.688515368094792 +103.532727614045 0.712917218688894 +103.557252403349 0.700233432385678 +103.581777192652 0.714210519385683 +103.606301981956 0.745899137104008 +103.630826771259 0.744698574609781 +103.655351560563 0.734495471455208 +103.679876349866 0.791775000265849 +103.70440113917 0.809054712101135 +103.728925928473 0.803627498838726 +103.753450717777 0.842095340636723 +103.777975507081 0.847992234862925 +103.802500296384 0.855441952306199 +103.827025085688 0.828597280644213 +103.851549874991 0.915067729983491 +103.876074664295 0.8499351808836 +103.900599453598 0.855920979313693 +103.925124242902 0.825931121090445 +103.949649032205 0.803044231632656 +103.974173821509 0.786948068250554 +103.998698610812 0.812491771218408 +104.023223400116 0.76691880470264 +104.04774818942 0.756056710180479 +104.072272978723 0.769075743165496 +104.096797768027 0.739091396987279 +104.12132255733 0.740199221278944 +104.145847346634 0.738491115740165 +104.170372135937 0.70630262297463 +104.194896925241 0.73228749086922 +104.219421714544 0.686155939185768 +104.243946503848 0.675415098903227 +104.268471293151 0.656423447530491 +104.292996082455 0.69635520834167 +104.317520871758 0.68227771514176 +104.342045661062 0.701568429161897 +104.366570450366 0.655986116602427 +104.391095239669 0.68921605554181 +104.415620028973 0.708628023801567 +104.440144818276 0.70930786320887 +104.46466960758 0.725051765868128 +104.489194396883 0.741534218055163 +104.513719186187 0.731380478977363 +104.53824397549 0.664339011938886 +104.562768764794 0.7130269709325 +104.587293554097 0.71803770130656 +104.611818343401 0.710798142306796 +104.636343132704 0.749114535781758 +104.660867922008 0.780592995056573 +104.685392711312 0.767905374754685 +104.709917500615 0.771376461954046 +104.734442289919 0.806788021394673 +104.758967079222 0.780261582373443 +104.783491868526 0.804496648649824 +104.808016657829 0.763917398467072 +104.832541447133 0.750453366556648 +104.857066236436 0.769672190413939 +104.88159102574 0.783342546769201 +104.906115815043 0.757244092632334 +104.930640604347 0.76249517553332 +104.955165393651 0.807136448118846 +104.979690182954 0.776383358329435 +105.004214972258 0.78906331063398 +105.028739761561 0.762088038688673 +105.053264550865 0.815417453292458 +105.077789340168 0.767577796070227 +105.102314129472 0.78128984850492 +105.126838918775 0.795577500148339 +105.151363708079 0.803485396559392 +105.175888497382 0.844021272616355 +105.200413286686 0.853730012768748 +105.224938075989 0.891777537679726 +105.249462865293 0.92120881073529 +105.273987654597 0.927634096045758 +105.2985124439 0.978047174619195 +105.323037233204 0.996527448948709 +105.347562022507 1.03387428641267 +105.372086811811 1.01252704012958 +105.396611601114 1.00477059204156 +105.421136390418 1.02008650981646 +105.445661179721 1.02019075001503 +105.470185969025 1.0055470036501 +105.494710758328 0.948015620316517 +105.519235547632 0.937153525794357 +105.543760336936 0.884449074476072 +105.568285126239 0.920809341887985 +105.592809915543 0.837641517383988 +105.617334704846 0.863438752921142 +105.64185949415 0.912804873275699 +105.666384283453 0.844810864267264 +105.690909072757 0.844369699340528 +105.71543386206 0.865364684900773 +105.739958651364 0.842006436432833 +105.764483440667 0.838040986231293 +105.789008229971 0.857649932892187 +105.813533019274 0.874401253643206 +105.838057808578 0.854258403853015 +105.862582597882 0.835139986195629 +105.887107387185 0.831610188875794 +105.911632176489 0.817021318632662 +105.936156965792 0.865985814187602 +105.960681755096 0.86183872157961 +105.985206544399 0.863063966112223 +106.009731333703 0.826175307616043 +106.034256123006 0.837251394580384 +106.05878091231 0.856504246519763 +106.083305701613 0.843534577611518 +106.107830490917 0.812912088105428 +106.132355280221 0.874673956205862 +106.156880069524 0.868474165333588 +106.181404858828 0.861175896213351 +106.205929648131 0.890556127145783 +106.230454437435 0.853481992244479 +106.254979226738 0.870409443356921 +106.279504016042 0.850069615165593 +106.304028805345 0.840622075579841 +106.328553594649 0.87696532895071 +106.353078383952 0.846695100167465 +106.377603173256 0.804869757412384 +106.402127962559 0.834939173795821 +106.426652751863 0.794649640216767 +106.451177541167 0.799635688552441 +106.47570233047 0.768895778805403 +106.500227119774 0.763582151785271 +106.524751909077 0.79854487830182 +106.549276698381 0.770335015780197 +106.573801487684 0.771842308919168 +106.598326276988 0.714994598991561 +106.622851066291 0.67893722822572 +106.647375855595 0.755867399776684 +106.671900644898 0.728539867108533 +106.696425434202 0.770624732383897 +106.720950223505 0.754121432157146 +106.745475012809 0.749949657510768 +106.769999802113 0.790457017530673 +106.794524591416 0.815396605252743 +106.81904938072 0.783442952969105 +106.843574170023 0.742583332226355 +106.868098959327 0.784639681464661 +106.89262374863 0.773419814174626 +106.917148537934 0.75576699357678 +106.941673327237 0.719020437359934 +106.966198116541 0.734889428257483 +106.990722905844 0.75225804429666 +107.015247695148 0.734461005420652 +107.039772484452 0.736866928340825 +107.064297273755 0.722087316395547 +107.088822063059 0.712182982601605 +107.113346852362 0.696046942780403 +107.137871641666 0.704852763527506 +107.162396430969 0.710657547067015 +107.186921220273 0.716186194337457 +107.211446009576 0.724073802394208 +107.23597079888 0.706375183236734 +107.260495588183 0.686649467667162 +107.285020377487 0.712519949913152 +107.30954516679 0.71536986271759 +107.334069956094 0.734236082512953 +107.358594745398 0.716346781152258 +107.383119534701 0.733003467330338 +107.407644324005 0.758494573060883 +107.432169113308 0.760161226743534 +107.456693902612 0.757853028532198 +107.481218691915 0.745913177356058 +107.505743481219 0.739408752187235 +107.530268270522 0.761845869593142 +107.554793059826 0.803823105314201 +107.579317849129 0.78472338403622 +107.603842638433 0.791560130929887 +107.628367427737 0.820476976317991 +107.65289221704 0.808224830211686 +107.677417006344 0.858307794137904 +107.701941795647 0.896750967404696 +107.726466584951 0.954799262107067 +107.750991374254 0.960976820180037 +107.775516163558 1.00467043071718 +107.800040952861 1.04386153302885 +107.824565742165 1.06707083509505 +107.849090531468 1.10407901918516 +107.873615320772 1.15783372521092 +107.898140110075 1.1834662497406 +107.922664899379 1.22757414231607 +107.947189688683 1.2321895244378 +107.971714477986 1.22842650869705 +107.99623926729 1.21263042733375 +108.020764056593 1.20557182296823 +108.045288845897 1.16334086709216 +108.0698136352 1.12604247729953 +108.094338424504 1.08893463899343 +108.118863213807 1.02654925756764 +108.143388003111 0.984888831520522 +108.167912792414 0.970627451933738 +108.192437581718 0.969160609289071 +108.216962371022 0.932538613247054 +108.241487160325 0.904197294840024 +108.266011949629 0.8992111195116 +108.290536738932 0.891452918519668 +108.315061528236 0.869046899631301 +108.339586317539 0.848712131057548 +108.364111106843 0.838739980925535 +108.388635896146 0.815784036024629 +108.41316068545 0.812661347777667 +108.437685474753 0.838597559123519 +108.462210264057 0.807355491173816 +108.48673505336 0.83214123675108 +108.511259842664 0.83954989979019 +108.535784631968 0.826449694705138 +108.560309421271 0.832661080756144 +108.584834210575 0.832669713675378 +108.609358999878 0.842354536396832 +108.633883789182 0.837686656153578 +108.658408578485 0.870382888112342 +108.682933367789 0.880232898106167 +108.707458157092 0.900905900889328 +108.731982946396 0.911194051526758 +108.756507735699 0.920879807442955 +108.781032525003 0.981929432534494 +108.805557314306 0.96425811391504 +108.83008210361 0.971455220349066 +108.854606892914 1.0047167911503 +108.879131682217 1.02427025777953 +108.903656471521 1.04767282728557 +108.928181260824 1.04001600488436 +108.952706050128 1.03939599067636 +108.977230839431 1.02971725811571 +109.001755628735 1.02370799788009 +109.026280418038 0.995567112535677 +109.050805207342 0.979294078779556 +109.075329996645 0.98953999593268 +109.099854785949 0.986542249617251 +109.124379575253 0.983274669268927 +109.148904364556 0.967962931125061 +109.17342915386 0.988300639151795 +109.197953943163 0.989721398513028 +109.222478732467 0.993093787960521 +109.24700352177 1.00389585686374 +109.271528311074 1.00835224361958 +109.296053100377 1.03301312180728 +109.320577889681 1.07619384870347 +109.345102678984 1.12101223611774 +109.369627468288 1.1400510451208 +109.394152257591 1.16847575282536 +109.418677046895 1.20415301539469 +109.443201836199 1.24257807534207 +109.467726625502 1.27168821770909 +109.492251414806 1.28037781275922 +109.516776204109 1.26200269393968 +109.541300993413 1.30250533768109 +109.565825782716 1.27153585133955 +109.59035057202 1.2224624052406 +109.614875361323 1.2148406009642 +109.639400150627 1.17883297988201 +109.66392493993 1.12715245194708 +109.688449729234 1.06690423013671 +109.712974518538 1.02871134651648 +109.737499307841 1.01206499270088 +109.762024097145 0.974188467968195 +109.786548886448 0.948217695974401 +109.811073675752 0.949343741579812 +109.835598465055 0.901448643290558 +109.860123254359 0.879910721599916 +109.884648043662 0.861831114280426 +109.909172832966 0.864847512624577 +109.933697622269 0.857934798881953 +109.958222411573 0.859778103520563 +109.982747200876 0.838852151564722 +110.00727199018 0.837950954325042 +110.031796779484 0.847286331624178 +110.056321568787 0.850882609354532 +110.080846358091 0.813622573708014 +110.105371147394 0.838153330401993 +110.129895936698 0.857238454835277 +110.154420726001 0.83614255520932 +110.178945515305 0.848214407775846 +110.203470304608 0.870775281574103 +110.227995093912 0.844277112283746 +110.252519883215 0.851724284990902 +110.277044672519 0.872098798634846 +110.301569461823 0.890832083718846 +110.326094251126 0.909792780250896 +110.35061904043 0.920832845182856 +110.375143829733 0.937713162818001 +110.399668619037 0.944983905291688 +110.42419340834 0.982376388633633 +110.448718197644 0.974043724698298 +110.473242986947 0.962661438224402 +110.497767776251 0.985895457674885 +110.522292565554 0.971056080681446 +110.546817354858 0.967209423298733 +110.571342144161 0.947507521331533 +110.595866933465 0.946139456009076 +110.620391722769 0.913424276883368 +110.644916512072 0.874110076433519 +110.669441301376 0.851265166243104 +110.693966090679 0.849281858408451 +110.718490879983 0.852235401463347 +110.743015669286 0.842770831257644 +110.76754045859 0.825228955806316 +110.792065247893 0.797391881430532 +110.816590037197 0.770193173419426 +110.8411148265 0.779370716086617 +110.865639615804 0.774881788195785 +110.890164405107 0.774562877776455 +110.914689194411 0.767707992758131 +110.939213983715 0.736797387754261 +110.963738773018 0.737567171797117 +110.988263562322 0.740455186403222 +111.012788351625 0.732697035021779 +111.037313140929 0.729373420005791 +111.061837930232 0.733551720787755 +111.086362719536 0.750027123930353 +111.110887508839 0.703326951622253 +111.135412298143 0.701597246606865 +111.159937087446 0.715289061055157 +111.18446187675 0.721801812580693 +111.208986666054 0.74010397368616 +111.233511455357 0.723700130769312 +111.258036244661 0.708307803038381 +111.282561033964 0.720585293161188 +111.307085823268 0.731830549470624 +111.331610612571 0.713327560817108 +111.356135401875 0.696494086023431 +111.380660191178 0.693634329955331 +111.405184980482 0.71578124165872 +111.429709769785 0.718903521913067 +111.454234559089 0.703821922594863 +111.478759348392 0.69887785659829 +111.503284137696 0.700824879410271 +111.527808927 0.726899775360934 +111.552333716303 0.711272343400405 +111.576858505607 0.693303482217422 +111.60138329491 0.740611328156155 +111.625908084214 0.712268831026649 +111.650432873517 0.708181006015426 +111.674957662821 0.714569969652897 +111.699482452124 0.727582444333356 +111.724007241428 0.745831724256159 +111.748532030731 0.745248723006909 +111.773056820035 0.722465270617431 +111.797581609339 0.71684950815032 +111.822106398642 0.743480438389096 +111.846631187946 0.772662823915045 +111.871155977249 0.75851878114869 +111.895680766553 0.754775866744591 +111.920205555856 0.781706954070116 +111.94473034516 0.788179246096562 +111.969255134463 0.781229388552257 +111.993779923767 0.821953637421076 +112.01830471307 0.844044602379714 +112.042829502374 0.867345678610234 +112.067354291677 0.876092976275557 +112.091879080981 0.848464460668031 +112.116403870285 0.871978853855435 +112.140928659588 0.890325513612129 +112.165453448892 0.868790670864518 +112.189978238195 0.874432710542874 +112.214503027499 0.854239806820823 +112.239027816802 0.83624730119082 +112.263552606106 0.810173126485766 +112.288077395409 0.819700953156632 +112.312602184713 0.836993278448011 +112.337126974016 0.811907909759481 +112.36165176332 0.793323073520631 +112.386176552624 0.794585094468011 +112.410701341927 0.785092610725483 +112.435226131231 0.763664885037741 +112.459750920534 0.768383437723936 +112.484275709838 0.757220224917079 +112.508800499141 0.754087573987825 +112.533325288445 0.744816602715964 +112.557850077748 0.730317082750331 +112.582374867052 0.738413957313767 +112.606899656355 0.734629379756622 +112.631424445659 0.747932957231037 +112.655949234962 0.724276203276403 +112.680474024266 0.730144175555815 +112.70499881357 0.737647509165974 +112.729523602873 0.724585489071678 +112.754048392177 0.734657669790345 +112.77857318148 0.740907214070215 +112.803097970784 0.773163882965576 +112.827622760087 0.750536622065754 +112.852147549391 0.725146168946495 +112.876672338694 0.745501591073384 +112.901197127998 0.748539057527524 +112.925721917301 0.744729938431925 +112.950246706605 0.751059073903565 +112.974771495908 0.775676582804497 +112.999296285212 0.777639437737084 +113.023821074516 0.778235561844098 +113.048345863819 0.790124625766256 +113.072870653123 0.797403110884449 +113.097395442426 0.822565913718397 +113.12192023173 0.81413566469051 +113.146445021033 0.824810296431373 +113.170969810337 0.851517570016004 +113.19549459964 0.843082348641238 +113.220019388944 0.842908206297049 +113.244544178247 0.843663062001208 +113.269068967551 0.815080224526485 +113.293593756855 0.831034239742708 +113.318118546158 0.852897818184775 +113.342643335462 0.839019773033132 +113.367168124765 0.823002059654297 +113.391692914069 0.843065037799874 +113.416217703372 0.838307910245079 +113.440742492676 0.851828604991251 +113.465267281979 0.844274177564589 +113.489792071283 0.827250534471755 +113.514316860586 0.826700883399784 +113.53884164989 0.857884300075719 +113.563366439193 0.870567250217091 +113.587891228497 0.867676508233373 +113.612416017801 0.89581101023541 +113.636940807104 0.900150400438176 +113.661465596408 0.887623955039455 +113.685990385711 0.915148112460442 +113.710515175015 0.93430393821423 +113.735039964318 0.949611794937017 +113.759564753622 0.923808207132418 +113.784089542925 0.943927589499613 +113.808614332229 0.932085336923207 +113.833139121532 0.935451356535503 +113.857663910836 0.940693922969357 +113.88218870014 0.957028678295155 +113.906713489443 0.947987268700988 +113.931238278747 0.953804460543126 +113.95576306805 0.97996437763554 +113.980287857354 0.991699551464503 +114.004812646657 0.992807562900058 +114.029337435961 0.98633053749023 +114.053862225264 1.01680146001207 +114.078387014568 1.04756981697686 +114.102911803871 1.08234306713222 +114.127436593175 1.0880106198562 +114.151961382478 1.12253767165233 +114.176486171782 1.14223645857319 +114.201010961086 1.16396763211361 +114.225535750389 1.19569808729495 +114.250060539693 1.20858582069495 +114.274585328996 1.23104531590248 +114.2991101183 1.22669532969473 +114.323634907603 1.20646913878683 +114.348159696907 1.18587067374236 +114.37268448621 1.18783968447813 +114.397209275514 1.17413124893836 +114.421734064817 1.131081101139 +114.446258854121 1.10561859408758 +114.470783643425 1.04776091398941 +114.495308432728 1.01863584801752 +114.519833222032 1.00585825419323 +114.544358011335 1.00361153858807 +114.568882800639 0.986964175079115 +114.593407589942 0.960225996811306 +114.617932379246 0.966417725747824 +114.642457168549 0.96886799627864 +114.666981957853 0.92910799377312 +114.691506747156 0.915079964754607 +114.71603153646 0.927843044797056 +114.740556325763 0.919012337636553 +114.765081115067 0.92455901907685 +114.789605904371 0.931277556990133 +114.814130693674 0.922891335503188 +114.838655482978 0.9126818857828 +114.863180272281 0.906260331399848 +114.887705061585 0.902412238216391 +114.912229850888 0.889785016180164 +114.936754640192 0.893984653448447 +114.961279429495 0.902265044718567 +114.985804218799 0.90607537889242 +115.010329008102 0.8828946171215 +115.034853797406 0.896512062860223 +115.059378586709 0.907903466744584 +115.083903376013 0.910073286913629 +115.108428165317 0.923194558025787 +115.13295295462 0.922221782698057 +115.157477743924 0.954640656619026 +115.182002533227 0.97299396127772 +115.206527322531 0.966691511009941 +115.231052111834 0.975853999103096 +115.255576901138 0.994389848961307 +115.280101690441 0.998483441980749 +115.304626479745 1.01676971466465 +115.329151269048 0.993172112506901 +115.353676058352 1.00389470282027 +115.378200847656 1.0104658352866 +115.402725636959 0.957502556352532 +115.427250426263 0.97829737238747 +115.451775215566 0.981930561772718 +115.47630000487 0.978426276846289 +115.500824794173 0.936705333009682 +115.525349583477 0.940195115578565 +115.54987437278 0.937429414873591 +115.574399162084 0.925479413745034 +115.598923951387 0.901217512886309 +115.623448740691 0.890858649504076 +115.647973529994 0.880725310856519 +115.672498319298 0.874393222550951 +115.697023108602 0.868308477874726 +115.721547897905 0.869864912705881 +115.746072687209 0.861776508723032 +115.770597476512 0.832829103526696 +115.795122265816 0.85645500240864 +115.819647055119 0.850803619989741 +115.844171844423 0.858169064530195 +115.868696633726 0.837745787879045 +115.89322142303 0.867677574353927 +115.917746212333 0.861571831375855 +115.942271001637 0.853919259949678 +115.966795790941 0.858566437029307 +115.991320580244 0.861118536937237 +116.015845369548 0.859968328246918 +116.040370158851 0.869413480175392 +116.064894948155 0.897406908253243 +116.089419737458 0.898587909024818 +116.113944526762 0.885791767126604 +116.138469316065 0.899195012324191 +116.162994105369 0.917784381421587 +116.187518894672 0.943766921578607 +116.212043683976 0.940341161849629 +116.236568473279 0.939506376642993 +116.261093262583 1.01108506973891 +116.285618051887 1.03046326017814 +116.31014284119 1.03147883932144 +116.334667630494 1.05364043579244 +116.359192419797 1.06235867717553 +116.383717209101 1.08931182223299 +116.408241998404 1.10927798418546 +116.432766787708 1.10124233066858 +116.457291577011 1.11798075839431 +116.481816366315 1.10913536185861 +116.506341155618 1.09053920142622 +116.530865944922 1.12103474002848 +116.555390734226 1.08155323817992 +116.579915523529 1.04882932470488 +116.604440312833 1.04177568599577 +116.628965102136 1.01931614786822 +116.65348989144 1.02582835386774 +116.678014680743 0.994762053289743 +116.702539470047 0.966414716612935 +116.72706425935 0.943060527052961 +116.751589048654 0.923359990952127 +116.776113837957 0.937325396828173 +116.800638627261 0.93046856671263 +116.825163416564 0.927813575914622 +116.849688205868 0.906965082909442 +116.874212995172 0.896915586554925 +116.898737784475 0.884675278419988 +116.923262573779 0.863440410222827 +116.947787363082 0.893415408379656 +116.972312152386 0.894364577572792 +116.996836941689 0.896254053417751 +117.021361730993 0.91072355228446 +117.045886520296 0.892769274691464 +117.0704113096 0.90222430806979 +117.094936098903 0.898624651524357 +117.119460888207 0.88986744078723 +117.143985677511 0.905875743574028 +117.168510466814 0.911602998354733 +117.193035256118 0.900105036317467 +117.217560045421 0.909012312153905 +117.242084834725 0.922608942127081 +117.266609624028 0.946263732995962 +117.291134413332 0.949161178265523 +117.315659202635 0.937453516923714 +117.340183991939 0.958349605511687 +117.364708781242 0.956931041509231 +117.389233570546 0.982361622633581 +117.413758359849 0.972751826875869 +117.438283149153 1.01247102488112 +117.462807938457 1.03471809814032 +117.48733272776 1.04160634684311 +117.511857517064 1.07376129700663 +117.536382306367 1.07890674945821 +117.560907095671 1.07510156808466 +117.585431884974 1.0795557165617 +117.609956674278 1.12378207519583 +117.634481463581 1.0885531167297 +117.659006252885 1.11537508755382 +117.683531042188 1.1111850299067 +117.708055831492 1.09513305783485 +117.732580620795 1.1378351033559 +117.757105410099 1.16529632217231 +117.781630199403 1.17546229656824 +117.806154988706 1.18687349970808 +117.83067977801 1.19647168964122 +117.855204567313 1.2127297366748 +117.879729356617 1.24850605163314 +117.90425414592 1.23970786749286 +117.928778935224 1.27916793824171 +117.953303724527 1.33872675156427 +117.977828513831 1.38677053545305 +118.002353303134 1.40298305615351 +118.026878092438 1.42729454730274 +118.051402881742 1.44727874134218 +118.075927671045 1.51816160637838 +118.100452460349 1.5535884759144 +118.124977249652 1.54644577912053 +118.149502038956 1.54067842113997 +118.174026828259 1.5134436106425 +118.198551617563 1.47614970409792 +118.223076406866 1.42166751719552 +118.24760119617 1.37600137749125 +118.272125985473 1.37315189275085 +118.296650774777 1.3121097962718 +118.32117556408 1.29236349695723 +118.345700353384 1.2733817391319 +118.370225142688 1.23583514693092 +118.394749931991 1.20719239336745 +118.419274721295 1.15700663985501 +118.443799510598 1.15517460285651 +118.468324299902 1.1519040944795 +118.492849089205 1.12203658779656 +118.517373878509 1.11850413894551 +118.541898667812 1.11351021428211 +118.566423457116 1.09263287902671 +118.590948246419 1.09177359728452 +118.615473035723 1.11044486566062 +118.639997825027 1.14011606427312 +118.66452261433 1.08613140669182 +118.689047403634 1.09085141525018 +118.713572192937 1.08408576416245 +118.738096982241 1.05817037539885 +118.762621771544 1.0681041397628 +118.787146560848 1.07877805234094 +118.811671350151 1.0699467681587 +118.836196139455 1.0634666390006 +118.860720928758 1.02253158639426 +118.885245718062 1.04168289740427 +118.909770507365 1.04367169609746 +118.934295296669 1.07023606547172 +118.958820085973 1.0530559289343 +118.983344875276 1.06240782128723 +119.00786966458 1.07286997004497 +119.032394453883 1.06519163531161 +119.056919243187 1.09166160918163 +119.08144403249 1.1236583685402 +119.105968821794 1.12983104218921 +119.130493611097 1.15408381433941 +119.155018400401 1.13169595377335 +119.179543189704 1.17328325295105 +119.204067979008 1.21724978328082 +119.228592768312 1.20653525555542 +119.253117557615 1.21557944882816 +119.277642346919 1.23020058612833 +119.302167136222 1.2210630588643 +119.326691925526 1.2067879860885 +119.351216714829 1.22105793560308 +119.375741504133 1.17184715277715 +119.400266293436 1.13516700112442 +119.42479108274 1.11518945880369 +119.449315872043 1.11590296934162 +119.473840661347 1.09502868822401 +119.49836545065 1.07168037940041 +119.522890239954 1.03854106133929 +119.547415029258 1.01786179475862 +119.571939818561 1.00110658139366 +119.596464607865 0.986445259661204 +119.620989397168 0.971375034020792 +119.645514186472 0.997136343464421 +119.670038975775 0.971400741027011 +119.694563765079 0.947754308010561 +119.719088554382 0.965754612586031 +119.743613343686 0.963411955030612 +119.768138132989 0.93914589099353 +119.792662922293 0.946334477236481 +119.817187711596 0.935923773986893 +119.8417125009 0.932160138304398 +119.866237290204 0.927727808722018 +119.890762079507 0.935689007689297 +119.915286868811 0.950615862869121 +119.939811658114 0.906163704433517 +119.964336447418 0.910255579768704 +119.988861236721 0.916142882528666 +120.013386026025 0.908677044285606 +120.037910815328 0.922816917183132 +120.062435604632 0.892899646446743 +120.086960393935 0.88458368679197 +120.111485183239 0.897407710731292 +120.136009972543 0.887069539088385 +120.160534761846 0.860787914655642 +120.18505955115 0.851504535081153 +120.209584340453 0.862887648712107 +120.234109129757 0.895856399161363 +120.25863391906 0.873626310109582 +120.283158708364 0.871014544374467 +120.307683497667 0.868826942380008 +120.332208286971 0.882423083254365 +120.356733076274 0.884703173968277 +120.381257865578 0.874527895017988 +120.405782654881 0.875300212604094 +120.430307444185 0.866509144349861 +120.454832233489 0.861268439697902 +120.479357022792 0.879616616361545 +120.503881812096 0.881647355357463 +120.528406601399 0.885227142839273 +120.552931390703 0.901077266245416 +120.577456180006 0.912000476765294 +120.60198096931 0.937459442662988 +120.626505758613 0.902781602439056 +120.651030547917 0.905582082557814 +120.67555533722 0.89755941897289 +120.700080126524 0.918157200957946 +120.724604915828 0.938018229133959 +120.749129705131 0.942202248313653 +120.773654494435 0.967417887453603 +120.798179283738 0.973088424507226 +120.822704073042 0.98853818439414 +120.847228862345 0.980023121566045 +120.871753651649 0.993269271492067 +120.896278440952 0.996013509727853 +120.920803230256 0.996041229430315 +120.945328019559 1.00668251768437 +120.969852808863 0.985049700092599 +120.994377598166 0.9719609249863 +121.01890238747 0.999870104987615 +121.043427176774 0.982981785799283 +121.067951966077 0.994339532691373 +121.092476755381 0.966619123627134 +121.117001544684 0.957996066719154 +121.141526333988 0.936577864351608 +121.166051123291 0.955308415367522 +121.190575912595 0.930226188739693 +121.215100701898 0.914385739568093 +121.239625491202 0.930250565856618 +121.264150280505 0.913092250296747 +121.288675069809 0.908939009564891 +121.313199859113 0.913102037259447 +121.337724648416 0.871398994666885 +121.36224943772 0.871138846166597 +121.386774227023 0.902215091438351 +121.411299016327 0.900003306161329 +121.43582380563 0.913746685536407 +121.460348594934 0.875840615422673 +121.484873384237 0.89155079205997 +121.509398173541 0.896294332463425 +121.533922962844 0.915419314568821 +121.558447752148 0.908935849515654 +121.582972541451 0.917712697169617 +121.607497330755 0.914658007797026 +121.632022120059 0.937858099922261 +121.656546909362 0.922101901036315 +121.681071698666 0.915532945813996 +121.705596487969 0.93529960998148 +121.730121277273 0.950455803465566 +121.754646066576 0.933027683285634 +121.77917085588 0.945911981569591 +121.803695645183 0.944584375746224 +121.828220434487 0.965929908973688 +121.85274522379 0.951335644021272 +121.877270013094 0.949115764534326 +121.901794802397 0.968852051429877 +121.926319591701 0.957412375720013 +121.950844381005 0.989492474765619 +121.975369170308 0.976072288533093 +121.999893959612 1.01107528277621 +122.024418748915 1.02763711136559 +122.048943538219 1.03844437794577 +122.073468327522 1.05078981524957 +122.097993116826 1.07990985718121 +122.122517906129 1.08560929291225 +122.147042695433 1.09424750557188 +122.171567484736 1.10026036338842 +122.19609227404 1.09865319968713 +122.220617063344 1.11390085856389 +122.245141852647 1.15276118755339 +122.269666641951 1.15715301276002 +122.294191431254 1.18263416041586 +122.318716220558 1.17487707515497 +122.343241009861 1.20010421408182 +122.367765799165 1.24326858826286 +122.392290588468 1.26131347928623 +122.416815377772 1.29309855132302 +122.441340167075 1.29165112695559 +122.465864956379 1.33087308894754 +122.490389745682 1.37413662351193 +122.514914534986 1.40966355525656 +122.53943932429 1.46812457677789 +122.563964113593 1.4899976469182 +122.588488902897 1.54156268169983 +122.6130136922 1.61651895743885 +122.637538481504 1.57334417439671 +122.662063270807 1.59735849278883 +122.686588060111 1.5857720678033 +122.711112849414 1.5747999881123 +122.735637638718 1.60806040487006 +122.760162428021 1.58756380764136 +122.784687217325 1.53810926734271 +122.809212006629 1.4819736106502 +122.833736795932 1.48467206534837 +122.858261585236 1.4728513632903 +122.882786374539 1.40470200938951 +122.907311163843 1.37992861568767 +122.931835953146 1.36524237131228 +122.95636074245 1.37206793167204 +122.980885531753 1.35047587553429 +123.005410321057 1.34671188828638 +123.02993511036 1.33888771474974 +123.054459899664 1.29405576972319 +123.078984688967 1.28296789713307 +123.103509478271 1.31610839391666 +123.128034267575 1.31260692429076 +123.152559056878 1.33394682691717 +123.177083846182 1.33741529124074 +123.201608635485 1.36940495270179 +123.226133424789 1.34245411573128 +123.250658214092 1.33241125954493 +123.275183003396 1.35527342427575 +123.299707792699 1.30358756113046 +123.324232582003 1.32481419537517 +123.348757371306 1.33459481121543 +123.37328216061 1.27983372248015 +123.397806949914 1.25850910644833 +123.422331739217 1.22749579978116 +123.446856528521 1.21787365871225 +123.471381317824 1.18292348253413 +123.495906107128 1.19111556637792 +123.520430896431 1.1961697901912 +123.544955685735 1.18386258761488 +123.569480475038 1.1930169003919 +123.594005264342 1.20791911468606 +123.618530053645 1.19266346763705 +123.643054842949 1.18872370159314 +123.667579632252 1.21278121367867 +123.692104421556 1.20572138085395 +123.71662921086 1.22327047362143 +123.741154000163 1.20905045731564 +123.765678789467 1.2450969578723 +123.79020357877 1.23746004284714 +123.814728368074 1.24229432739766 +123.839253157377 1.2573163556283 +123.863777946681 1.31382948205146 +123.888302735984 1.32608367260219 +123.912827525288 1.31342318149489 +123.937352314591 1.3103265337048 +123.961877103895 1.31464237855529 +123.986401893198 1.29494867210187 +124.010926682502 1.27275215329764 +124.035451471806 1.26407620193125 +124.059976261109 1.24719504457442 +124.084501050413 1.2195812938687 +124.109025839716 1.2058062331349 +124.13355062902 1.20618961777384 +124.158075418323 1.1859189836194 +124.182600207627 1.17812567665549 +124.20712499693 1.17607599451533 +124.231649786234 1.13630928224388 +124.256174575537 1.137873106694 +124.280699364841 1.14465000218612 +124.305224154145 1.10857734488039 +124.329748943448 1.12219401179336 +124.354273732752 1.13185117886837 +124.378798522055 1.11154082726825 +124.403323311359 1.12132117617126 +124.427848100662 1.13337570554639 +124.452372889966 1.12802836991215 +124.476897679269 1.12707178964425 +124.501422468573 1.13144171402527 +124.525947257876 1.13302360953542 +124.55047204718 1.13380136829383 +124.574996836483 1.10924000070417 +124.599521625787 1.11504711414829 +124.624046415091 1.11623071349956 +124.648571204394 1.09140394262801 +124.673095993698 1.07550744876566 +124.697620783001 1.08215306153359 +124.722145572305 1.05224879778354 +124.746670361608 1.03750708912224 +124.771195150912 1.03016077797952 +124.795719940215 1.02924961188464 +124.820244729519 1.02939261736941 +124.844769518822 1.01138972010101 +124.869294308126 1.0117691230838 +124.89381909743 1.01147504753598 +124.918343886733 1.00909918134255 +124.942868676037 1.0052173027392 +124.96739346534 1.00347734512944 +124.991918254644 1.00414155717407 +125.016443043947 0.990652520605602 +125.040967833251 0.990584935337111 +125.065492622554 0.996456911473258 +125.090017411858 1.00306085313953 +125.114542201161 1.00124399588161 +125.139066990465 0.994391148836046 +125.163591779768 0.996869175328321 +125.188116569072 1.01998975042926 +125.212641358376 1.01135279424465 +125.237166147679 1.00968366270957 +125.261690936983 1.02646113473946 +125.286215726286 1.03630992316233 +125.31074051559 1.03927088600643 +125.335265304893 1.03399003653063 +125.359790094197 1.05155522941212 +125.3843148835 1.07095753872864 +125.408839672804 1.09664967463179 +125.433364462107 1.12545609977674 +125.457889251411 1.13593964126707 +125.482414040715 1.1511987986305 +125.506938830018 1.15944987216397 +125.531463619322 1.17217696799835 +125.555988408625 1.21499204638382 +125.580513197929 1.18782802373697 +125.605037987232 1.17687103464756 +125.629562776536 1.1984485119544 +125.654087565839 1.18670922769662 +125.678612355143 1.19104741929905 +125.703137144446 1.20838676805363 +125.72766193375 1.19504618981059 +125.752186723053 1.18061942296941 +125.776711512357 1.17079008191681 +125.801236301661 1.1468520712301 +125.825761090964 1.11999324409686 +125.850285880268 1.08854021893271 +125.874810669571 1.09140824481251 +125.899335458875 1.09039775907999 +125.923860248178 1.05339930053488 +125.948385037482 1.02476141539715 +125.972909826785 1.02475842015657 +125.997434616089 1.02650083192017 +126.021959405392 1.01638925186466 +126.046484194696 1.0095465897387 +126.071008983999 1.0014088670144 +126.095533773303 0.982702404848601 +126.120058562607 0.975308961840186 +126.14458335191 0.970959154280684 +126.169108141214 1.00044420661602 +126.193632930517 0.981065082144692 +126.218157719821 0.966581535599087 +126.242682509124 0.981989051111792 +126.267207298428 0.981739699225483 +126.291732087731 0.95337963732802 +126.316256877035 0.94361410115318 +126.340781666338 0.958337369272033 +126.365306455642 0.953653722386444 +126.389831244946 0.953354103865936 +126.414356034249 0.963506226487599 +126.438880823553 0.979667814208001 +126.463405612856 0.98044107611439 +126.48793040216 0.968693090021298 +126.512455191463 0.973168845843623 +126.536979980767 0.981300089989401 +126.56150477007 0.978733449748126 +126.586029559374 0.977447908800731 +126.610554348677 0.979190601416925 +126.635079137981 0.993702637372347 +126.659603927284 0.982635418339569 +126.684128716588 0.985548600161169 +126.708653505892 1.00536140220887 +126.733178295195 1.01003928962817 +126.757703084499 1.02285910257539 +126.782227873802 1.05181257556784 +126.806752663106 1.04833694397623 +126.831277452409 1.07338294999928 +126.855802241713 1.08051767964331 +126.880327031016 1.08729595056202 +126.90485182032 1.08764568487812 +126.929376609623 1.09334215571554 +126.953901398927 1.11066433399403 +126.978426188231 1.12099816950775 +127.002950977534 1.12956200080905 +127.027475766838 1.12771308276264 +127.052000556141 1.11094272008822 +127.076525345445 1.11883367206019 +127.101050134748 1.13362700007254 +127.125574924052 1.1157705238511 +127.150099713355 1.11735172449041 +127.174624502659 1.13423882844059 +127.199149291962 1.13118341020199 +127.223674081266 1.15300933792754 +127.248198870569 1.12867636876535 +127.272723659873 1.13056318833264 +127.297248449177 1.15219652811793 +127.32177323848 1.1492926771413 +127.346298027784 1.14108874619511 +127.370822817087 1.17235133280287 +127.395347606391 1.18895720419504 +127.419872395694 1.19873094409317 +127.444397184998 1.20228311872232 +127.468921974301 1.19502120529971 +127.493446763605 1.16865574998139 +127.517971552908 1.16284336475597 +127.542496342212 1.16522392691662 +127.567021131516 1.14688217936408 +127.591545920819 1.13275038971505 +127.616070710123 1.11415917984973 +127.640595499426 1.09565456866395 +127.66512028873 1.08860154677016 +127.689645078033 1.09590549977539 +127.714169867337 1.09399775561506 +127.73869465664 1.05169654350746 +127.763219445944 1.02147764901062 +127.787744235247 1.01984672185184 +127.812269024551 1.02221228082886 +127.836793813854 1.0117845130988 +127.861318603158 1.01083934225012 +127.885843392462 1.00188662483918 +127.910368181765 0.988758170241945 +127.934892971069 0.981580703198967 +127.959417760372 0.986677484774103 +127.983942549676 0.97041745361134 +128.008467338979 0.963460720385796 +128.032992128283 0.975837771066389 +128.057516917586 0.968476651024639 +128.08204170689 0.955799933841486 +128.106566496193 0.948553062482993 +128.131091285497 0.93595566631853 +128.1556160748 0.963899622762891 +128.180140864104 0.961234691567335 +128.204665653408 0.948744023716807 +128.229190442711 0.946134217301425 +128.253715232015 0.940995551960156 +128.278240021318 0.923634504478538 +128.302764810622 0.938166543235508 +128.327289599925 0.960263983545255 +128.351814389229 0.950281943278398 +128.376339178532 0.942824372154014 +128.400863967836 0.944380198741228 +128.425388757139 0.944209208733297 +128.449913546443 0.939962050777646 +128.474438335747 0.942820227995116 +128.49896312505 0.950767474048368 +128.523487914354 0.967745484517927 +128.548012703657 0.950681909619174 +128.572537492961 0.951449604134752 +128.597062282264 0.972525450763781 +128.621587071568 0.992289384284156 +128.646111860871 0.98583564823817 +128.670636650175 0.985990007943657 +128.695161439478 1.00655986498021 +128.719686228782 0.997114334219486 +128.744211018085 1.00895517657043 +128.768735807389 1.01031498236516 +128.793260596693 1.0176815158369 +128.817785385996 1.01145557221301 +128.8423101753 1.03664334593704 +128.866834964603 1.03123768065143 +128.891359753907 1.02782673210634 +128.91588454321 1.03168855865953 +128.940409332514 1.03281748091584 +128.964934121817 1.00440861449658 +128.989458911121 1.01167315977452 +129.013983700424 0.993567350841919 +129.038508489728 0.999478463513975 +129.063033279032 0.979735279860092 +129.087558068335 0.979832795619989 +129.112082857639 0.973310123179226 +129.136607646942 0.972431000111523 +129.161132436246 0.958059636517259 +129.185657225549 0.952993007670842 +129.210182014853 0.961456396631051 +129.234706804156 0.969356144075497 +129.25923159346 0.96586107901634 +129.283756382763 0.947372808296666 +129.308281172067 0.943702295434772 +129.33280596137 0.937619441742883 +129.357330750674 0.927049244077037 +129.381855539978 0.936001568117626 +129.406380329281 0.941503124547985 +129.430905118585 0.931423641009771 +129.455429907888 0.924277592402553 +129.479954697192 0.926470812631209 +129.504479486495 0.926353916805521 +129.529004275799 0.90939023099623 +129.553529065102 0.918830281169773 +129.578053854406 0.920878737779395 +129.602578643709 0.912502737008191 +129.627103433013 0.916112990656858 +129.651628222317 0.926309564393727 +129.67615301162 0.926902309778235 +129.700677800924 0.919970639089636 +129.725202590227 0.931459888342778 +129.749727379531 0.929556909221446 +129.774252168834 0.906292024990776 +129.798776958138 0.903994078910949 +129.823301747441 0.930538786723035 +129.847826536745 0.934952409616791 +129.872351326048 0.936344254933566 +129.896876115352 0.931167341946736 +129.921400904655 0.933986932109688 +129.945925693959 0.929484203982264 +129.970450483263 0.914066770440914 +129.994975272566 0.914478841955399 +130.01950006187 0.912834388069926 +130.044024851173 0.933928911558168 +130.068549640477 0.924155096108188 +130.09307442978 0.924276680537375 +130.117599219084 0.93468725178267 +130.142124008387 0.923342495104458 +130.166648797691 0.917798247077539 +130.191173586994 0.943756490853549 +130.215698376298 0.9391551303305 +130.240223165601 0.933802624711127 +130.264747954905 0.930292335821592 +130.289272744209 0.942313852307652 +130.313797533512 0.942035922087145 +130.338322322816 0.936897104611255 +130.362847112119 0.93243811847202 +130.387371901423 0.942722841424465 +130.411896690726 0.941227137762598 +130.43642148003 0.927782446477839 +130.460946269333 0.9395336753506 +130.485471058637 0.941860136583837 +130.50999584794 0.962201794484869 +130.534520637244 0.973450544908534 +130.559045426548 0.961260269152878 +130.583570215851 0.949895554591858 +130.608095005155 0.962284476279607 +130.632619794458 0.960776565765673 +130.657144583762 0.968837645129007 +130.681669373065 0.967286475746356 +130.706194162369 0.975972727790162 +130.730718951672 0.966916891558613 +130.755243740976 0.94895569743883 +130.779768530279 0.972737290758785 +130.804293319583 0.962706580019432 +130.828818108886 0.957279298274352 +130.85334289819 0.955960944996379 +130.877867687494 0.964807102634396 +130.902392476797 0.962335237226145 +130.926917266101 0.955564557928193 +130.951442055404 0.957467065358558 +130.975966844708 0.955991402436167 +131.000491634011 0.955413885594824 +131.025016423315 0.958948143566591 +131.049541212618 0.947758876808308 +131.074066001922 0.963425382915033 +131.098590791225 0.979228294367577 +131.123115580529 0.962441268695763 +131.147640369833 0.940359207090324 +131.172165159136 0.964038953865158 +131.19668994844 0.965550239735323 +131.221214737743 0.964084455460359 +131.245739527047 0.98280890468078 +131.27026431635 0.964570129911392 +131.294789105654 0.955003888147995 +131.319313894957 0.952373700170345 +131.343838684261 0.961651775807175 +131.368363473564 0.975352828864479 +131.392888262868 0.988497678095401 +131.417413052171 0.977369432283835 +131.441937841475 0.977233007939597 +131.466462630779 0.972150524338578 +131.490987420082 0.981807955329604 +131.515512209386 0.986497771487683 +131.540036998689 0.990427028288161 +131.564561787993 0.99980897334513 +131.589086577296 1.00974191430542 +131.6136113666 1.00176854448419 +131.638136155903 1.00455661146971 +131.662660945207 1.0133177686812 +131.68718573451 1.00641594368331 +131.711710523814 1.0155898093423 +131.736235313118 1.00309281557806 +131.760760102421 1.02091169319293 +131.785284891725 1.03595220267692 +131.809809681028 1.05781263429921 +131.834334470332 1.04684751868785 +131.858859259635 1.05512651650918 +131.883384048939 1.06775969344084 +131.907908838242 1.079056333664 +131.932433627546 1.0879711279047 +131.956958416849 1.06983237936684 +131.981483206153 1.07212365190608 +132.006007995456 1.11601670957472 +132.03053278476 1.12178224301076 +132.055057574064 1.12147878479254 +132.079582363367 1.13248848224191 +132.104107152671 1.13901678653128 +132.128631941974 1.16015016175018 +132.153156731278 1.15206139540676 +132.177681520581 1.17897632722525 +132.202206309885 1.2059572072576 +132.226731099188 1.22461922049641 +132.251255888492 1.23951293250252 +132.275780677795 1.26813959282351 +132.300305467099 1.27712734803948 +132.324830256402 1.29779401842844 +132.349355045706 1.32349813383259 +132.37387983501 1.33072128059317 +132.398404624313 1.35676567662816 +132.422929413617 1.3831433420937 +132.44745420292 1.41493364551432 +132.471978992224 1.43310183239095 +132.496503781527 1.46205705563704 +132.521028570831 1.46513874822475 +132.545553360134 1.4926583198335 +132.570078149438 1.50974692203542 +132.594602938741 1.51334538414819 +132.619127728045 1.50990944744836 +132.643652517349 1.51672852884655 +132.668177306652 1.51232139068454 +132.692702095956 1.50907032622682 +132.717226885259 1.4927873745083 +132.741751674563 1.47050796838001 +132.766276463866 1.45777640251753 +132.79080125317 1.44017702067977 +132.815326042473 1.41963479489176 +132.839850831777 1.4026394108887 +132.86437562108 1.38324114539625 +132.888900410384 1.36093791741753 +132.913425199687 1.35336579899789 +132.937949988991 1.34848432146368 +132.962474778295 1.33552272386179 +132.986999567598 1.32636778708109 +133.011524356902 1.32880406501098 +133.036049146205 1.33522944702858 +133.060573935509 1.34083109839643 +133.085098724812 1.34347155432519 +133.109623514116 1.34336763183585 +133.134148303419 1.34986765755652 +133.158673092723 1.35823358236374 +133.183197882026 1.34617557192154 +133.20772267133 1.32903858706152 +133.232247460634 1.31155569162522 +133.256772249937 1.33953824507225 +133.281297039241 1.33019210444523 +133.305821828544 1.32786638780462 +133.330346617848 1.32890757285592 +133.354871407151 1.32000561237424 +133.379396196455 1.29430059180164 +133.403920985758 1.29063538978397 +133.428445775062 1.29620640581006 +133.452970564365 1.2941989037572 +133.477495353669 1.27677799612701 +133.502020142972 1.26502677271671 +133.526544932276 1.24907666100461 +133.55106972158 1.24758838981956 +133.575594510883 1.23034774368776 +133.600119300187 1.22595442304845 +133.62464408949 1.21867274985677 +133.649168878794 1.22518821368091 +133.673693668097 1.20711548209899 +133.698218457401 1.20219594564444 +133.722743246704 1.2084373279932 +133.747268036008 1.19829176755165 +133.771792825311 1.21725592865941 +133.796317614615 1.21384636900465 +133.820842403919 1.21080021196819 +133.845367193222 1.22403094929029 +133.869891982526 1.23311839500881 +133.894416771829 1.24791403337328 +133.918941561133 1.25717039358879 +133.943466350436 1.24828014967266 +133.96799113974 1.2777782062644 +133.992515929043 1.27588712267192 +134.017040718347 1.28790643950693 +134.04156550765 1.28471168378194 +134.066090296954 1.30167057129574 +134.090615086257 1.31949210567434 +134.115139875561 1.31781267084892 +134.139664664865 1.32137181089593 +134.164189454168 1.32082919585394 +134.188714243472 1.32934603499039 +134.213239032775 1.32686525146226 +134.237763822079 1.32112760311529 +134.262288611382 1.34228791826264 +134.286813400686 1.33355374653971 +134.311338189989 1.32746013119628 +134.335862979293 1.31174672142152 +134.360387768596 1.28556495601753 +134.3849125579 1.27324434192394 +134.409437347203 1.27035478601489 +134.433962136507 1.26399366863488 +134.458486925811 1.23856245935534 +134.483011715114 1.24596292618026 +134.507536504418 1.24030022112133 +134.532061293721 1.24002931420615 +134.556586083025 1.24038869416231 +134.581110872328 1.24239975127108 +134.605635661632 1.2356246182602 +134.630160450935 1.21490096082513 +134.654685240239 1.21406992261116 +134.679210029542 1.23586376985334 +134.703734818846 1.25099042356367 +134.72825960815 1.24156628971119 +134.752784397453 1.2262120964891 +134.777309186757 1.24236992830055 +134.80183397606 1.24699770183787 +134.826358765364 1.25110655194541 +134.850883554667 1.24533065560608 +134.875408343971 1.23687800491401 +134.899933133274 1.23602452953929 +134.924457922578 1.2271990892999 +134.948982711881 1.23994939666752 +134.973507501185 1.2306529486203 +134.998032290488 1.22357418438159 +135.022557079792 1.22369931419407 +135.047081869096 1.20883963682139 +135.071606658399 1.20996404036159 +135.096131447703 1.21308132793295 +135.120656237006 1.20455199194182 +135.14518102631 1.20822549173612 +135.169705815613 1.21011534419403 +135.194230604917 1.21706687405727 +135.21875539422 1.20675782697973 +135.243280183524 1.2055103909926 +135.267804972827 1.20728804875332 +135.292329762131 1.20343898540038 +135.316854551435 1.19340271829966 +135.341379340738 1.20588151514968 +135.365904130042 1.21857690912078 +135.390428919345 1.22650973960925 +135.414953708649 1.22593229999584 +135.439478497952 1.23003777136363 +135.464003287256 1.24588828243443 +135.488528076559 1.23837532506147 +135.513052865863 1.2525929537887 +135.537577655166 1.26284629543663 +135.56210244447 1.27345014824262 +135.586627233773 1.28352010569635 +135.611152023077 1.30892082074692 +135.635676812381 1.33212266494129 +135.660201601684 1.32711195119975 +135.684726390988 1.35583197590623 +135.709251180291 1.36222578652871 +135.733775969595 1.38383094029548 +135.758300758898 1.41413963159788 +135.782825548202 1.43132165986958 +135.807350337505 1.45787751855707 +135.831875126809 1.48036819693313 +135.856399916112 1.50046635682284 +135.880924705416 1.5046524733416 +135.90544949472 1.55082645860798 +135.929974284023 1.55600919644436 +135.954499073327 1.5864485079454 +135.97902386263 1.58453975233188 +136.003548651934 1.57500665177457 +136.028073441237 1.57689199443835 +136.052598230541 1.59143497584255 +136.077123019844 1.58434623207523 +136.101647809148 1.57158168073955 +136.126172598451 1.56114132014224 +136.150697387755 1.55224963167645 +136.175222177058 1.52888150749422 +136.199746966362 1.49232689384815 +136.224271755666 1.47493230119393 +136.248796544969 1.46312021521693 +136.273321334273 1.43626751033094 +136.297846123576 1.42645998266385 +136.32237091288 1.41069340173164 +136.346895702183 1.37841978535723 +136.371420491487 1.36127324534739 +136.39594528079 1.34057803473034 +136.420470070094 1.32935326104528 +136.444994859397 1.31268564824779 +136.469519648701 1.30237617920012 +136.494044438004 1.30222429169009 +136.518569227308 1.29219896679477 +136.543094016612 1.27067532653354 +136.567618805915 1.2569792229505 +136.592143595219 1.25509037239193 +136.616668384522 1.25434747590818 +136.641193173826 1.24513613047134 +136.665717963129 1.24501880947919 +136.690242752433 1.24216088767572 +136.714767541736 1.23653724906616 +136.73929233104 1.23833144303322 +136.763817120343 1.23649769739461 +136.788341909647 1.22355356023722 +136.812866698951 1.22007504383434 +136.837391488254 1.23375726101296 +136.861916277558 1.22517390262691 +136.886441066861 1.22203302968056 +136.910965856165 1.22273889716348 +136.935490645468 1.21379194567611 +136.960015434772 1.21087171830978 +136.984540224075 1.2255356517842 +137.009065013379 1.22860259983186 +137.033589802682 1.22039898831945 +137.058114591986 1.22448483712866 +137.082639381289 1.22600326443355 +137.107164170593 1.23952187528471 +137.131688959897 1.23272833296309 +137.1562137492 1.24618816599974 +137.180738538504 1.25310988202824 +137.205263327807 1.23411461993932 +137.229788117111 1.24316495243972 +137.254312906414 1.27585946141642 +137.278837695718 1.2708036529974 +137.303362485021 1.29664031413907 +137.327887274325 1.31445681323841 +137.352412063628 1.32579098819754 +137.376936852932 1.34037797931702 +137.401461642236 1.32721976381837 +137.425986431539 1.35046931463784 +137.450511220843 1.38981892416131 +137.475036010146 1.40440982068863 +137.49956079945 1.4224004005008 +137.524085588753 1.43254477769576 +137.548610378057 1.44033423353345 +137.57313516736 1.43285530453712 +137.597659956664 1.46878054481794 +137.622184745967 1.49015397531619 +137.646709535271 1.51053618942575 +137.671234324574 1.52663752860606 +137.695759113878 1.543884206187 +137.720283903182 1.55710749014305 +137.744808692485 1.57285331421275 +137.769333481789 1.59506430556806 +137.793858271092 1.59947949196182 +137.818383060396 1.62998081668096 +137.842907849699 1.63792151954111 +137.867432639003 1.63917906902918 +137.891957428306 1.65489745566272 +137.91648221761 1.67000475723906 +137.941007006913 1.68716724034259 +137.965531796217 1.68719045079455 +137.990056585521 1.69795005599889 +138.014581374824 1.72111752742218 +138.039106164128 1.7276316728872 +138.063630953431 1.73595944493643 +138.088155742735 1.74583698781867 +138.112680532038 1.74064180058802 +138.137205321342 1.74325089297832 +138.161730110645 1.74025058686473 +138.186254899949 1.73562758392578 +138.210779689252 1.73656319489379 +138.235304478556 1.7197631989784 +138.259829267859 1.711176428274 +138.284354057163 1.69195539708933 +138.308878846467 1.69350081481884 +138.33340363577 1.67156345533343 +138.357928425074 1.63803532816322 +138.382453214377 1.6198317556846 +138.406978003681 1.59672980195363 +138.431502792984 1.58114313695668 +138.456027582288 1.55860102552905 +138.480552371591 1.54187166608991 +138.505077160895 1.53592747786868 +138.529601950198 1.51232761928683 +138.554126739502 1.50409723297401 +138.578651528805 1.49372358209506 +138.603176318109 1.48687759039912 +138.627701107413 1.49586552146092 +138.652225896716 1.48697196336832 +138.67675068602 1.47004231710003 +138.701275475323 1.45062438117525 +138.725800264627 1.46204517502664 +138.75032505393 1.46633098429982 +138.774849843234 1.4647773456425 +138.799374632537 1.46809458821918 +138.823899421841 1.47254338344236 +138.848424211144 1.4660596460222 +138.872949000448 1.45869688400305 +138.897473789752 1.46613388361804 +138.921998579055 1.45730113799503 +138.946523368359 1.43975399014968 +138.971048157662 1.43956480637825 +138.995572946966 1.43882767032046 +139.020097736269 1.43483212829156 +139.044622525573 1.41565594540353 +139.069147314876 1.40952656125445 +139.09367210418 1.40820808041771 +139.118196893483 1.39877541928258 +139.142721682787 1.386486695196 +139.16724647209 1.36784097772594 +139.191771261394 1.36172419128136 +139.216296050698 1.35771929490437 +139.240820840001 1.34767523909343 +139.265345629305 1.337062263683 +139.289870418608 1.33628851650408 +139.314395207912 1.3332491983567 +139.338919997215 1.32150668185175 +139.363444786519 1.3285236093738 +139.387969575822 1.31746347776494 +139.412494365126 1.30317330288545 +139.437019154429 1.30252268968739 +139.461543943733 1.31243750346179 +139.486068733037 1.30229732125446 +139.51059352234 1.3225740372174 +139.535118311644 1.31954152701717 +139.559643100947 1.30202390002045 +139.584167890251 1.3058846800102 +139.608692679554 1.31825837274907 +139.633217468858 1.32506371065141 +139.657742258161 1.33585682310848 +139.682267047465 1.32036629531122 +139.706791836768 1.33294485751727 +139.731316626072 1.34835650131552 +139.755841415375 1.34488543089596 +139.780366204679 1.35058009115227 +139.804890993983 1.37987409282868 +139.829415783286 1.39247202980149 +139.85394057259 1.40107460530875 +139.878465361893 1.40436854569092 +139.902990151197 1.4152229056999 +139.9275149405 1.4218101588038 +139.952039729804 1.4247243749451 +139.976564519107 1.43077213584533 +140.001089308411 1.39585523985731 +140.025614097714 1.4053089333558 +140.050138887018 1.40941275317868 +140.074663676322 1.43070108873493 diff --git a/docs/source/examples/example-data/CeO2_635um_zscan.xy b/docs/source/examples/example-data/CeO2_635um_zscan.xy new file mode 100644 index 0000000..ff53fff --- /dev/null +++ b/docs/source/examples/example-data/CeO2_635um_zscan.xy @@ -0,0 +1,152 @@ +'Id: "" Comment: "" Operator: "Lab Manager" Anode: "Mo" Scantype: "Z" TimePerStep: "0.1" +-0.5000 438699.993 +-0.4900 437939.993 +-0.4800 436679.993 +-0.4700 434109.994 +-0.4600 439659.993 +-0.4500 436119.994 +-0.4400 435829.994 +-0.4300 438749.993 +-0.4200 432339.994 +-0.4100 431319.994 +-0.4000 435779.994 +-0.3900 437599.993 +-0.3800 434739.994 +-0.3700 433929.994 +-0.3600 436689.993 +-0.3500 433569.994 +-0.3400 435229.994 +-0.3300 437549.993 +-0.3200 434419.994 +-0.3100 435259.994 +-0.3000 437439.993 +-0.2900 437869.993 +-0.2800 434529.994 +-0.2700 436509.993 +-0.2600 434709.994 +-0.2500 432969.994 +-0.2400 434899.994 +-0.2300 432389.994 +-0.2200 436019.994 +-0.2100 437949.993 +-0.2000 437949.993 +-0.1900 435849.994 +-0.1800 437349.993 +-0.1700 435199.994 +-0.1600 439539.993 +-0.1500 434519.994 +-0.1400 436629.993 +-0.1300 435779.994 +-0.1200 437839.993 +-0.1100 433019.994 +-0.1000 440589.993 +-0.0900 440729.993 +-0.0800 432909.994 +-0.0700 435749.994 +-0.0600 439069.993 +-0.0500 437979.993 +-0.0400 437069.993 +-0.0300 436549.993 +-0.0200 430119.994 +-0.0100 426019.994 +0.0000 418459.994 +0.0100 403369.994 +0.0200 383859.994 +0.0300 365809.995 +0.0400 344199.995 +0.0500 320469.995 +0.0600 294339.996 +0.0700 266309.996 +0.0800 239429.996 +0.0900 209889.997 +0.1000 176649.997 +0.1100 144879.998 +0.1200 115089.998 +0.1300 92299.999 +0.1400 72569.999 +0.1500 58649.999 +0.1600 46629.999 +0.1700 38329.999 +0.1800 33500.000 +0.1900 29950.000 +0.2000 26210.000 +0.2100 24490.000 +0.2200 22100.000 +0.2300 21030.000 +0.2400 20140.000 +0.2500 18260.000 +0.2600 17220.000 +0.2700 17280.000 +0.2800 16080.000 +0.2900 16040.000 +0.3000 15250.000 +0.3100 15030.000 +0.3200 14610.000 +0.3300 13840.000 +0.3400 14300.000 +0.3500 14400.000 +0.3600 14140.000 +0.3700 13810.000 +0.3800 13060.000 +0.3900 13520.000 +0.4000 13930.000 +0.4100 13230.000 +0.4200 14140.000 +0.4300 14110.000 +0.4400 14730.000 +0.4500 13240.000 +0.4600 14850.000 +0.4700 14670.000 +0.4800 16110.000 +0.4900 16920.000 +0.5000 18110.000 +0.5100 18900.000 +0.5200 19600.000 +0.5300 21530.000 +0.5400 22640.000 +0.5500 25950.000 +0.5600 27170.000 +0.5700 31850.000 +0.5800 35309.999 +0.5900 40459.999 +0.6000 48749.999 +0.6100 60139.999 +0.6200 77359.999 +0.6300 98939.999 +0.6400 119429.998 +0.6500 144089.998 +0.6600 173249.997 +0.6700 196839.997 +0.6800 222189.997 +0.6900 251099.996 +0.7000 276849.996 +0.7100 306689.995 +0.7200 324769.995 +0.7300 349759.995 +0.7400 370219.994 +0.7500 389929.994 +0.7600 403689.994 +0.7700 415189.994 +0.7800 419159.994 +0.7900 426049.994 +0.8000 430569.994 +0.8100 433369.994 +0.8200 433519.994 +0.8300 431809.994 +0.8400 432409.994 +0.8500 431049.994 +0.8600 432439.994 +0.8700 429879.994 +0.8800 432939.994 +0.8900 430969.994 +0.9000 429989.994 +0.9100 432439.994 +0.9200 433599.994 +0.9300 431779.994 +0.9400 436329.993 +0.9500 432509.994 +0.9600 429609.994 +0.9700 432349.994 +0.9800 429109.994 +0.9900 430159.994 +1.0000 432219.994 diff --git a/doc/source/examples/example-data/zro2_mo.xy b/docs/source/examples/example-data/zro2_mo.xy similarity index 100% rename from doc/source/examples/example-data/zro2_mo.xy rename to docs/source/examples/example-data/zro2_mo.xy diff --git a/doc/source/examples/examples.rst b/docs/source/examples/examples.rst similarity index 100% rename from doc/source/examples/examples.rst rename to docs/source/examples/examples.rst diff --git a/doc/source/examples/functions-example.rst b/docs/source/examples/functions-example.rst similarity index 96% rename from doc/source/examples/functions-example.rst rename to docs/source/examples/functions-example.rst index 2a909e1..33d64ac 100644 --- a/doc/source/examples/functions-example.rst +++ b/docs/source/examples/functions-example.rst @@ -13,11 +13,11 @@ For example, if you want to load data from ``zro2_mo.xy`` in the ``example-data` .. code-block:: python - from diffpy.utils.parsers.loaddata import loadData + from diffpy.utils.parsers import load_data from diffpy.utils.diffraction_objects import DiffractionObject filepath = "../example-data/zro2_mo.xy" - xarray, yarray = loadData(filepath, unpack=True) + xarray, yarray = load_data(filepath, unpack=True) input_pattern = DiffractionObject( xarray=xarray, yarray=yarray, diff --git a/docs/source/examples/labpdfprocapp-example.rst b/docs/source/examples/labpdfprocapp-example.rst new file mode 100644 index 0000000..c6114f5 --- /dev/null +++ b/docs/source/examples/labpdfprocapp-example.rst @@ -0,0 +1,213 @@ +.. _labpdfprocapp Example: + +:tocdepth: -1 + +labpdfprocapp Example +##################### + +This example provides a quick-start tutorial for using ``diffpy.labpdfproc`` +to apply absorption correction to your 1D diffraction data using the command-line (CLI). +Check ``labpdfproc --help`` for more information. +A graphical user interface (GUI) is also available and is designed to be intuitive and easy to use. + +There are three ways to correct dirraction data within ``diffpy.labpdfproc``, these are, + +1. ``labpdfproc mud``: Provide the diffraction data file(s) and muD value directly. +2. ``labpdfproc zscan``: Provide the diffraction data file(s) and a z-scan file, which will be used to calculate the muD value. +3. ``labpdfproc sample``: Provide the diffraction data file(s) and information about the sample to calculate the theoretical muD value. + +We will go through all three methods in this tutorial. + +.. admonition:: Example Data + + Example data for these examples can be found at: https://github.com/diffpy/diffpy.labpdfproc/tree/main/docs/source/examples/example-data + + +Launching the Graphical User Interface (GUI) +-------------------------------------------- + +To launch the GUI, run one of the following commands in your terminal, + +.. code-block:: bash + + labpdfproc + labpdfproc --gui + +This will open the GUI, which should look something like, + +.. image:: ../img/labpdfproc-gui.jpeg + :align: center + +Below we will go through all the commands using the CLI, but the same principles apply to the GUI. + +.. note:: The first time you run any of the below commands, + you will be prompted to enter your name, email, and ORCID. This will be + appended to metadata in the output file header for reproducibility and tracking purposes. + + +``labpdfproc mud`` Command +--------------------------- + +If you know the muD value for your sample, you can use the ``labpdfproc mud`` +command to apply absorption correction directly. + +To see all the options for this command, type, + +.. code-block:: bash + + labpdfproc mud -h + +To run the correction, specify the path to your diffraction data file(s) and the muD value, + +.. code-block:: bash + + labpdfproc mud + labpdfproc mud zro2_mo.xy 2.5 + +If the flag ``--wavelength`` is not specified, the program will attempt to fetch +the wavelength from a configuration file. +If the wavelength is not found in the configuration file, a ``ValueError`` +will be raised, prompting you to provide the wavelength either through the CLI or the configuration file. + +To provide the wavelength through the CLI, you can use the ``-w`` or ``--wavelength`` flag followed by the wavelength value in angstroms or the X-ray source. +For example, + +.. code-block:: bash + + labpdfproc mud zro2_mo.xy 2.5 -w 0.71303 + labpdfproc mud zro2_mo.xy 2.5 -w Mo + +This will then save the corrected file in the same directory as the input file with the name ``zro2_mo-mud-corrected.chi``. + +To save the correction file, specify the ``-c`` or ``--output-correction`` flag, + +.. code-block:: bash + + labpdfproc mud zro2_mo.xy 2.5 -w 0.71303 -c + +This will then save the correction file in the same directory as the input file with the name ``zro2_mo-cve.chi``. + +``labpdfproc zscan`` Command +---------------------------- + +The ``labpdfproc zscan`` command allows you to calculate the muD value from a z-scan file and apply absorption correction to your diffraction data. +For more information on what a z-scan is, please see the "Examples --> Linear Absorption Coefficient Examples" +section in the ``diffpy.utils`` documentation: https://www.diffpy.org/diffpy.utils/examples/mu_calc_examples.html. + +To see the options for this command, type, + +.. code-block:: bash + + labpdfproc zscan -h + +To run this command, provide the path to your diffraction data file(s) and the z-scan file, + +.. code-block:: bash + + labpdfproc zscan + labpdfproc zscan CeO2_635um_accum_0.xy CeO2_635um_zscan.xy + +Like the ``labpdfproc mud`` command, you can also specify the +wavelength or source type using the ``-w`` flag if it's not found in the configuration file, + +.. code-block:: bash + + labpdfproc zscan CeO2_635um_accum_0.xy CeO2_635um_zscan.xy -w 0.71303 + labpdfproc zscan CeO2_635um_accum_0.xy CeO2_635um_zscan.xy -w Mo + +This will save the corrected file in the same directory as the input file with the name ``CeO2_635um_accum_0.chi``. + +To save the correction file, specify the ``-c`` or ``--output-correction`` flag, + +.. code-block:: bash + + labpdfproc zscan CeO2_635um_accum_0.xy CeO2_635um_zscan.xy -w 0.71303 -c + +This will then save the correction file in the same directory as the input file with the name ``CeO2_635um_accum_0-cve.chi``. + +``labpdfproc sample`` Command +----------------------------- + +The ``labpdfproc sample`` command allows you to calculate the muD value from information +about your sample and apply absorption correction to your diffraction data. + +To see the options for this command, type, + +.. code-block:: bash + + labpdfproc sample -h + +To run this command, provide the path to your diffraction data file(s) along with: + +1) ``sample_composition``: The chemical formula of your sample. +2) ``sample_mass_density``: The mass density of your sample in g/cm^3. If you don't know the mass density, a good approximation is typically ~1/3 of the theoretical packing fraction. +3) ``diameter``: The outer diameter of your capillary. + +.. code-block:: bash + + labpdfproc sample + labpdfproc sample zro2_mo.xy ZrO2 17.45 1.2 + +Once again, you can specify the wavelength or source type using the ``-w`` flag if it's not found in the configuration file, + +.. code-block:: bash + + labpdfproc sample zro2_mo.xy ZrO2 17.45 1.2 -w 0.71303 + labpdfproc sample zro2_mo.xy ZrO2 17.45 1.2 -w Mo + +This will save the corrected file in the same directory as the input file with the name ``zro2_mo.chi``. + +To save the correction file, specify the ``-c`` or ``--output-correction`` flag, + +.. code-block:: bash + + labpdfproc sample zro2_mo.xy ZrO2 17.45 1.2 -w 0.71303 -c + +This will then save the correction file in the same directory as the input file with the name ``zro2_mo-cve.chi``. + +Additional CLI options +---------------------- + +Below is a summary of all the additional flags that can be used with all three commands, + +- ``-h, --help`` + Show this help message and exit. + +- ``-w, --wavelength WAVELENGTH`` + X-ray wavelength in angstroms (numeric) or X-ray source name. + Allowed: ``Ag``, ``AgKa1``, ``AgKa1Ka2``, ``Cu``, ``CuKa1``, ``CuKa1Ka2``, ``Mo``, ``MoKa1``, ``MoKa1Ka2``. + Will be loaded from config files if not specified. + +- ``-x, --xtype XTYPE`` + X-axis type (default: ``tth``). Allowed values: ``angle``, ``tth``, ``twotheta``, ``2theta``, ``d``, ``dspace``, ``q``. + +- ``-m, --method {brute_force, polynomial_interpolation}`` + Method for cylindrical volume element (CVE) calculation (default: ``polynomial_interpolation``). + Allowed methods: ``brute_force``, ``polynomial_interpolation``. + +- ``-o, --output-directory OUTPUT_DIRECTORY`` + Directory to save corrected files (created if needed). Defaults to current directory. + +- ``-f, --force`` + Overwrite existing files. + +- ``-c, --output-correction`` + Also output the absorption correction to a separate file. + +- ``-u, --user-metadata KEY=VALUE [KEY=VALUE ...]`` + Specify key-value pairs to be loaded into metadata. Format: ``key=value``. + - Separate multiple pairs with whitespace. + - No spaces before or after ``=``. + - Avoid using ``=`` in keys. Only the first ``=`` separates key and value. + - If a key or value contains whitespace, enclose it in quotes. + Examples: + ``facility='NSLS II', beamline=28ID-2, 'favorite color'=blue``. + +- ``--username USERNAME`` + Your name (optional, for dataset credit). Will be loaded from config files if not specified. + +- ``--email EMAIL`` + Your email (optional, for dataset credit). Will be loaded from config files if not specified. + +- ``--orcid ORCID`` + Your ORCID ID (optional, for dataset credit). Will be loaded from config files if not specified. diff --git a/doc/source/examples/tools-example.rst b/docs/source/examples/tools-example.rst similarity index 92% rename from doc/source/examples/tools-example.rst rename to docs/source/examples/tools-example.rst index 674d244..7291658 100644 --- a/doc/source/examples/tools-example.rst +++ b/docs/source/examples/tools-example.rst @@ -20,15 +20,13 @@ You can do this in one of the following four ways: # Option 2: From a z-scan file args = Namespace(z_scan_file="zscan.xy") # Option 3: Using sample mass density - args = Namespace(theoretical_from_density="ZrO2,17.45,1.2") - # Option 4: Using packing fraction - args = Namespace(theoretical_from_packing="ZrO2,17.45,0.3") + args = Namespace(sample_composition="ZrO2", sample_mass_density="17.45", diameter="1.2") # Set and view the computed mu*D value args = set_mud(args) print(args.mud) -2. Next, we load the input files for correction using ``set_input_lists(args)``: +1. Next, we load the input files for correction using ``set_input_lists(args)``: .. code-block:: python @@ -59,24 +57,13 @@ If no output directory is specified, it defaults to the current working director # Option 1: Specify wavelength directly args = Namespace(wavelength=0.7) # Option 2: Use a valid anode type - args = Namespace(anode_type="Mo") + args = Namespace(wavelength="Mo") args = set_wavelength(args) Note that you should specify either a wavelength or an anode type, not both, to avoid conflicts. If you provide an anode type, the corresponding wavelength will be retrieved from global parameters. You may use ``labpdfproc --help`` to view a list of valid anode types. If neither is given, it's only acceptable if the input diffraction data is already on a two-theta grid. -To simplify workflows and avoid re-entering it every time, -we recommend saving the wavelength or anode type to a diffpy config file. For example: - -.. code-block:: python - - from pathlib import Path - import json - home_dir = Path.home() - wavelength_data = {"wavelength": 0.3} - with open(home_dir / "diffpyconfig.json", "w") as f: - json.dump(wavelength_data, f) To set the x-axis type (xtype) for your diffraction data: @@ -88,7 +75,7 @@ To set the x-axis type (xtype) for your diffraction data: This sets the xtype to ``tth``. Other valid options including ``q`` and ``d`` spacing. -5. Finally, we load user metadata, user information, and package information into ``args``. +1. Finally, we load user metadata, user information, and package information into ``args``. To load metadata, pass key-value pairs as a list: .. code-block:: python @@ -137,3 +124,19 @@ Using the function ``load_metadata(args, filepath)`` requires both the ``argument.Namespace`` and the current input file path. For more details about working with diffraction objects and how they are written to output files, see https://www.diffpy.org/diffpy.utils/examples/diffraction_objects_example.html. + + +Creating ``diffpyconfig.json`` file +----------------------------------- + +To simplify workflows and avoid re-entering it every time, +we recommend saving the wavelength or anode type to a diffpy config file. For example, + +.. code-block:: python + + from pathlib import Path + import json + home_dir = Path.home() + wavelength_data = {"wavelength": 0.3} + with open(home_dir / "diffpyconfig.json", "w") as f: + json.dump(wavelength_data, f) diff --git a/docs/source/img/labpdfproc-gui.jpeg b/docs/source/img/labpdfproc-gui.jpeg new file mode 100644 index 0000000..9dc8de8 Binary files /dev/null and b/docs/source/img/labpdfproc-gui.jpeg differ diff --git a/doc/source/index.rst b/docs/source/index.rst similarity index 55% rename from doc/source/index.rst rename to docs/source/index.rst index 1de5c3f..1bf6d0f 100644 --- a/doc/source/index.rst +++ b/docs/source/index.rst @@ -4,19 +4,16 @@ .. |title| replace:: diffpy.labpdfproc documentation -diffpy.labpdfproc - Tools for processing x-ray powder diffraction data from laboratory sources. +``diffpy.labpdfproc`` - Tools for processing x-ray powder diffraction data from laboratory sources. -| Software version |release|. +| Software version |release| | Last updated |today|. ======= Authors ======= -diffpy.labpdfproc is developed by Billinge Group -and its community contributors. - -For a detailed list of contributors see +``diffpy.labpdfproc`` is developed by Yucong Chen, Till Schertenleib, Caden Myers, Billinge Group members. This project is maintained by Simon Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors. ============ @@ -26,6 +23,12 @@ Installation See the `README `_ file included with the distribution. +================ +Acknowledgements +================ + +``diffpy.labpdfproc`` is built and maintained with `scikit-package `_. + ================= Table of contents ================= diff --git a/doc/source/license.rst b/docs/source/license.rst similarity index 90% rename from doc/source/license.rst rename to docs/source/license.rst index 9ae52a9..2abd4ff 100644 --- a/doc/source/license.rst +++ b/docs/source/license.rst @@ -9,8 +9,10 @@ OPEN SOURCE LICENSE AGREEMENT ============================= BSD 3-Clause License -Copyright (c) 2024, The Trustees of Columbia University in -the City of New York. +Copyright (c) 2024-2025, The Trustees of Columbia University in the City of New York. +All Rights Reserved. + +Copyright (c) 2026-present, diffpy.labpdfproc developers and contributors. All Rights Reserved. Redistribution and use in source and binary forms, with or without 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/docs/source/snippets/.placeholder b/docs/source/snippets/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/doc/source/utilities/functions-utility.rst b/docs/source/utilities/functions-utility.rst similarity index 100% rename from doc/source/utilities/functions-utility.rst rename to docs/source/utilities/functions-utility.rst diff --git a/doc/source/utilities/labpdfprocapp-utility.rst b/docs/source/utilities/labpdfprocapp-utility.rst similarity index 100% rename from doc/source/utilities/labpdfprocapp-utility.rst rename to docs/source/utilities/labpdfprocapp-utility.rst diff --git a/doc/source/utilities/tools-utility.rst b/docs/source/utilities/tools-utility.rst similarity index 100% rename from doc/source/utilities/tools-utility.rst rename to docs/source/utilities/tools-utility.rst diff --git a/doc/source/utilities/utilities.rst b/docs/source/utilities/utilities.rst similarity index 100% rename from doc/source/utilities/utilities.rst rename to docs/source/utilities/utilities.rst diff --git a/news/applymud.rst b/news/applymud.rst deleted file mode 100644 index e618a21..0000000 --- a/news/applymud.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* new subcommand ``applymud`` to run the original absorption correction process through CLI. - -**Changed:** - -* GitHub workflows for renamed test file. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/check-saved-files.rst b/news/check-saved-files.rst new file mode 100644 index 0000000..514ba98 --- /dev/null +++ b/news/check-saved-files.rst @@ -0,0 +1,25 @@ +**Added:** + +* + +**Changed:** + +* Changed output file behavior to raise an error early if the saved file exists. +* Changed saved file name from ``_corrected.chi`` to ``-mud-corrected.chi``. +* Changed saved file name from ``_cve.chi`` to ``-cve.chi``. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/codecov.rst b/news/codecov.rst deleted file mode 100644 index e3c89a7..0000000 --- a/news/codecov.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Coverage report in each PR - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/codespell.rst b/news/codespell.rst deleted file mode 100644 index 8c5ba6d..0000000 --- a/news/codespell.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Spelling check via Codespell in pre-commit - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/docstring-tests.rst b/news/docstring-tests.rst deleted file mode 100644 index 137f773..0000000 --- a/news/docstring-tests.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Functionality in `load_user_info` to enable user to enter an ORCID. - -**Changed:** - -* All function docstrings and tests to be more informative, incorporating new ORCID function and improving overall clarity. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/fastcalto7.rst b/news/fastcalto7.rst deleted file mode 100644 index b82bd94..0000000 --- a/news/fastcalto7.rst +++ /dev/null @@ -1,24 +0,0 @@ -**Added:** - -* Fast calculation supports values up to muD = 7 - -**Changed:** - -* Default to brute-force computation when muD < 0.5 or > 7. -* Print a warning message instead of error, explicitly stating the input muD value - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/folder-rst-readme.rst b/news/folder-rst-readme.rst deleted file mode 100644 index 24d8f13..0000000 --- a/news/folder-rst-readme.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* doi in Readme for papers. - -**Changed:** - -* hyphens / underscores format according to new scikit-package group standard. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/functions-docs.rst b/news/gooey-fix.rst similarity index 78% rename from news/functions-docs.rst rename to news/gooey-fix.rst index 8142dc4..988fd84 100644 --- a/news/functions-docs.rst +++ b/news/gooey-fix.rst @@ -1,6 +1,6 @@ **Added:** -* Documentation for functions module. +* **Changed:** @@ -12,7 +12,7 @@ **Removed:** -* +* Removed support for Python 3.10 and 3.11. **Fixed:** diff --git a/news/gui.rst b/news/gui.rst deleted file mode 100644 index 11ed94f..0000000 --- a/news/gui.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Gooey support so that the app can be run with GUI - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/main-doc.rst b/news/main-doc.rst deleted file mode 100644 index b4674dd..0000000 --- a/news/main-doc.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Utility and example documentation for the main module. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/muD-options.rst b/news/muD-options.rst deleted file mode 100644 index 1766a48..0000000 --- a/news/muD-options.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Made muD an optional argument and provided different options (manually entry / z-scan file path) for users to specify muD - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/muD-theoretical.rst b/news/muD-theoretical.rst deleted file mode 100644 index 4fde53b..0000000 --- a/news/muD-theoretical.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Functionalities to estimate mu*D theoretically. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/muD.rst b/news/muD.rst deleted file mode 100644 index feae116..0000000 --- a/news/muD.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* no news added - minor edits in mud_calculator.py - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/muD2.rst b/news/muD2.rst deleted file mode 100644 index 617eb2b..0000000 --- a/news/muD2.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* no news added - rename variables in `mud_calculator.py` and edit tests - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/output-wavelength.rst b/news/output-wavelength.rst deleted file mode 100644 index 7522d38..0000000 --- a/news/output-wavelength.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* duplicated wavelength information in output files - -**Security:** - -* diff --git a/news/py313.rst b/news/py313.rst deleted file mode 100644 index 524608e..0000000 --- a/news/py313.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Python 3.13 support - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/recut.rst b/news/recut.rst deleted file mode 100644 index 93e880c..0000000 --- a/news/recut.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* no news: modified .github, .pre-commit-config.yaml and related files to follow new practice for commit and issues. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/recut2.rst b/news/recut2.rst deleted file mode 100644 index 35f4d9d..0000000 --- a/news/recut2.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Recookiecut with updated ``scikit-package`` to enable docs preview in PRs. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/remove-namespace.rst b/news/remove-namespace.rst deleted file mode 100644 index 3ba530e..0000000 --- a/news/remove-namespace.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* Remove the import of extend_path from pkgutil in diffpy/__init__.py since we are not strictly following the Python namespace package convention. - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/tools-doc.rst b/news/tools-doc.rst deleted file mode 100644 index d126b65..0000000 --- a/news/tools-doc.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Utility and example documentation for ``tools`` module. - -**Changed:** - -* Readme: muD now requires the ``--mud`` flag instead of a required argument. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/utils-updates.rst b/news/utils-updates.rst deleted file mode 100644 index fd6d1fc..0000000 --- a/news/utils-updates.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Functions that use DiffractionObject` in `diffpy.utils` to follow the new API. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/wavelength-config.rst b/news/wavelength-config.rst deleted file mode 100644 index 1bf4566..0000000 --- a/news/wavelength-config.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Functionality to read wavelength and anode type directly from a diffpy configuration file. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/wavelength-workflow.rst b/news/wavelength-workflow.rst deleted file mode 100644 index 09891c6..0000000 --- a/news/wavelength-workflow.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Workflow for loading wavelength - raise an error when both wavelength and anode type are specified. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/wavelength.rst b/news/wavelength.rst deleted file mode 100644 index 17fff49..0000000 --- a/news/wavelength.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Increased the number of significant figures for wavelength and separated values for Ka1 and Ka2. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/xtype.rst b/news/xtype.rst deleted file mode 100644 index 20ecef3..0000000 --- a/news/xtype.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Support for independent variables other than two-theta. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/pyproject.toml b/pyproject.toml index 09a5bd9..b7ac149 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,15 +6,18 @@ build-backend = "setuptools.build_meta" name = "diffpy.labpdfproc" dynamic=['version', 'dependencies'] authors = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + {name='Yucong Chen', email='yc4372@columbia.edu'}, + {name='Till Schertenleib', email='ts@chem.ku.dk'}, + {name='Caden Myers', email='cjm2304@columbia.edu'}, + {name='Simon Billinge', email='sbillinge@ucsb.edu'}, ] maintainers = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + {name='Simon Billinge', email='sbillinge@ucsb.edu'}, ] description = "Tools for processing x-ray powder diffraction data from laboratory sources." -keywords = ['powder xrd', 'absorption correction', 'pdf', 'diffpy'] +keywords = ['powder XRD', 'absorption correction', 'PDF', 'diffpy'] readme = "README.rst" -requires-python = ">=3.11, <3.14" +requires-python = ">=3.12, <3.15" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -25,9 +28,9 @@ classifiers = [ 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', 'Operating System :: Unix', - 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', 'Topic :: Scientific/Engineering :: Physics', 'Topic :: Scientific/Engineering :: Chemistry', ] @@ -51,13 +54,21 @@ include = ["*"] # package names should match these glob patterns (["*"] by defa exclude = ["diffpy.labpdfproc.tests*"] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[tool.setuptools.package-data] +"diffpy.labpdfproc" = ["data/*"] + [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} [tool.codespell] exclude-file = ".codespell/ignore_lines.txt" ignore-words = ".codespell/ignore_words.txt" -skip = "*.cif" +skip = "*.cif,*.dat" + +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 [tool.black] line-length = 79 diff --git a/requirements/README.txt b/requirements/README.txt deleted file mode 100644 index 3de372a..0000000 --- a/requirements/README.txt +++ /dev/null @@ -1,11 +0,0 @@ -# YOU MAY DELETE THIS FILE AFTER SETTING UP DEPENDENCIES! -# -# This directory is where you should place your project dependencies. -# "pip.txt" should contain all required packages not available on conda. -# All other files should contain only packages available to download from conda. -# build.txt should contain all packages required to build (not run) the project. -# run.txt should contain all packages (including optional packages) required for a user to run the program. -# test.txt should contain all packages required for the testing suite and to ensure all tests pass. -# docs.txt should contain all packages required for building the package documentation page. -# -# YOU MAY DELETE THIS FILE AFTER SETTING UP DEPENDENCIES! diff --git a/requirements/conda.txt b/requirements/conda.txt index 5aef5a8..e687e1c 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -3,3 +3,4 @@ diffpy.utils pandas scipy wxpython +gooey diff --git a/requirements/docs.txt b/requirements/docs.txt index ab17b1c..1de813f 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,4 +1,5 @@ sphinx sphinx_rtd_theme +sphinx-copybutton doctr -m2r +m2r2 diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt deleted file mode 100644 index c601d11..0000000 --- a/requirements/requirements-dev.txt +++ /dev/null @@ -1,20 +0,0 @@ -# These are required for developing the package (running the tests, building -# the documentation) but not necessarily required for _using_ it. -black -codecov -coverage -flake8 -isort -nbstripout -pre-commit -pre-commit-hooks -pytest -pytest-mock -sphinx -twine -# These are dependencies of various sphinx extensions for documentation. -ipython -matplotlib -numpydoc -sphinx-copybutton -sphinx_rtd_theme diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 78ce07b..263df6a 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,10 +1,14 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024 The Trustees of Columbia University in the City of New York. +# (c) 2024-2025, The Trustees of Columbia University in the City of New York. # All rights reserved. # -# File coded by: Billinge Group members and community contributors. +# (c) 2026-present, diffpy.labpdfproc developers and contributors. +# All rights reserved. +# +# File coded by: Yucong Chen, Till Schertenleib, Caden Myers, +# Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors diff --git a/src/diffpy/labpdfproc/__init__.py b/src/diffpy/labpdfproc/__init__.py index 3316df6..694c534 100644 --- a/src/diffpy/labpdfproc/__init__.py +++ b/src/diffpy/labpdfproc/__init__.py @@ -1,10 +1,14 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024 The Trustees of Columbia University in the City of New York. +# (c) 2024-2025, The Trustees of Columbia University in the City of New York. # All rights reserved. # -# File coded by: Billinge Group members and community contributors. +# (c) 2026-present, diffpy.labpdfproc developers and contributors. +# All rights reserved. +# +# File coded by: Yucong Chen, Till Schertenleib, Caden Myers, +# Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors diff --git a/src/diffpy/labpdfproc/functions.py b/src/diffpy/labpdfproc/functions.py index 46c9ade..8d7a76a 100644 --- a/src/diffpy/labpdfproc/functions.py +++ b/src/diffpy/labpdfproc/functions.py @@ -1,6 +1,6 @@ import math import warnings -from pathlib import Path +from importlib.resources import files import numpy as np import pandas as pd @@ -17,11 +17,11 @@ CVE_METHODS = ["brute_force", "polynomial_interpolation"] # Pre-computed datasets for polynomial interpolation (fast calculation) +data_dir = files("diffpy.labpdfproc") / "data" MUD_LIST = np.array([0.5, 1, 2, 3, 4, 5, 6, 7]) -CWD = Path(__file__).parent.resolve() -MULS = np.loadtxt(CWD / "data" / "inverse_cve.xy") +MULS = np.loadtxt(data_dir / "inverse_cve.xy") COEFFICIENT_LIST = np.array( - pd.read_csv(CWD / "data" / "coefficient_list.csv", header=None) + pd.read_csv(data_dir / "coefficient_list.csv", header=None) ) INTERPOLATION_FUNCTIONS = [ interp1d(MUD_LIST, coeffs, kind="quadratic") for coeffs in COEFFICIENT_LIST @@ -40,8 +40,8 @@ def __init__( self._get_grid_points() def _get_grid_points(self): - """Given a radius and a grid size, return a grid of points to uniformly - sample that circle.""" + """Given a radius and a grid size, return a grid of points to + uniformly sample that circle.""" xs = np.linspace(-self.radius, self.radius, self.npoints) ys = np.linspace(-self.radius, self.radius, self.npoints) self.grid = { @@ -50,8 +50,8 @@ def _get_grid_points(self): self.total_points_in_grid = len(self.grid) def _get_entry_exit_coordinates(self, coordinate, angle): - """Get the coordinates where the beam enters and leaves the circle for - a given angle and grid point. + """Get the coordinates where the beam enters and leaves the + circle for a given angle and grid point. It is calculated in the following way: For the entry coordinate, @@ -108,8 +108,9 @@ def _get_entry_exit_coordinates(self, coordinate, angle): return entry_point, exit_point def _get_path_length(self, grid_point, angle): - """Return the path length of a horizontal line entering the circle at - the same height to the grid point then exiting at angle. + """Return the path length of a horizontal line entering the + circle at the same height to the grid point then exiting at + angle. Parameters ---------- @@ -136,8 +137,8 @@ def _get_path_length(self, grid_point, angle): return total_distance, primary_distance, secondary_distance def set_distances_at_angle(self, angle): - """Given an angle, set the distances from the grid points to the entry - and exit coordinates. + """Given an angle, set the distances from the grid points to the + entry and exit coordinates. Parameters ---------- @@ -170,8 +171,8 @@ def set_muls_at_angle(self, angle): def _cve_brute_force(input_pattern, mud): - """Compute cve for the given mud on a global grid using the brute-force - method. + """Compute cve for the given mud on a global grid using the brute- + force method. Assume mu=mud/2, given that the same mu*D yields the same cve and D/2=1. @@ -202,8 +203,8 @@ def _cve_brute_force(input_pattern, mud): def _cve_polynomial_interpolation(input_pattern, mud): - """Compute cve using polynomial interpolation method, default to brute- - force computation if mu*D is out of the range (0.5 to 7).""" + """Compute cve using polynomial interpolation method, default to + brute- force computation if mu*D is out of the range (0.5 to 7).""" if mud > 7 or mud < 0.5: warnings.warn( f"Input mu*D = {mud} is out of the acceptable range " @@ -245,7 +246,7 @@ def _cve_method(method): def compute_cve( input_pattern, mud, method="polynomial_interpolation", xtype="tth" ): - f"""Compute and interpolate the cve + f"""Compute and interpolate the cylindrical volume effect (cve) for the given input diffraction data and mu*D using the selected method. @@ -286,8 +287,8 @@ def compute_cve( def apply_corr(input_pattern, absorption_correction): - """Apply absorption correction to the given diffraction object with the - correction diffraction object. + """Apply absorption correction to the given diffraction object with + the correction diffraction object. Parameters ---------- diff --git a/src/diffpy/labpdfproc/labpdfprocapp.py b/src/diffpy/labpdfproc/labpdfprocapp.py index d73caab..db7f873 100644 --- a/src/diffpy/labpdfproc/labpdfprocapp.py +++ b/src/diffpy/labpdfproc/labpdfprocapp.py @@ -1,314 +1,322 @@ +import argparse +import os import sys -from argparse import ArgumentParser from gooey import Gooey, GooeyParser from diffpy.labpdfproc.functions import CVE_METHODS, apply_corr, compute_cve from diffpy.labpdfproc.tools import ( - known_sources, + WAVELENGTHS, load_metadata, + load_wavelength_from_config_file, preprocessing_args, + set_wavelength, ) from diffpy.utils.diffraction_objects import XQUANTITIES, DiffractionObject -from diffpy.utils.parsers.loaddata import loadData +from diffpy.utils.parsers import load_data -theoretical_mud_hmsg_suffix = ( - "in that exact order, " - "separated by commas (e.g., ZrO2,17.45,0.5). " - "If you add whitespaces, " - "enclose it in quotes (e.g., 'ZrO2, 17.45, 0.5'). " -) +def _running_in_gui(): + """Determine if the application is running in a GUI environment. -def _define_arguments(): - args = [ - { - "name": ["input"], - "help": ( - "The filename(s) or folder(s) of the datafile(s) to load. " - "Required.\n" - "Supply a space-separated list of files or directories. " - "Avoid spaces in filenames when possible; " - "if present, enclose the name in quotes. " - "Long lists can be supplied, one per line, " - "in a file with name file_list.txt. " - "If one or more directory is provided, all valid " - "data-files in that directory will be processed. " - "Examples of valid inputs are 'file.xy', 'data/file.xy', " - "'file.xy data/file.xy', " - "'.' (load everything in the current directory), " - "'data' (load everything in the folder ./data), " - "'data/file_list.txt' (load the list of files " - "contained in the text-file called file_list.txt " - "that can be found in the folder ./data), " - "'./*.chi', 'data/*.chi' " - "(load all files with extension .chi in the folder ./data)." - ), - "nargs": "+", - "widget": "MultiFileChooser", - }, - { - "name": ["-a", "--anode-type"], - "help": ( - f"The type of the x-ray source. " - f"Allowed values are {*known_sources, }. " - f"Either specify a known x-ray source or specify wavelength." - ), - "default": None, - }, - { - "name": ["-w", "--wavelength"], - "help": ( - "X-ray source wavelength in angstroms. " - "Not needed if the anode-type is specified." - ), - "type": float, - }, - { - "name": ["-o", "--output-directory"], - "help": ( - "The name of the output directory. " - "If not specified then corrected files will be " - "written to the current directory. " - "If the specified directory doesn't exist it will be created." - ), - "default": None, - "widget": "DirChooser", - }, - { - "name": ["-x", "--xtype"], - "help": ( - f"The quantity on the independent variable axis. " - f"Allowed values: {*XQUANTITIES, }. " - f"If not specified then two-theta " - f"is assumed for the independent variable." - ), - "default": "tth", - }, - { - "name": ["-c", "--output-correction"], - "help": ( - "The absorption correction will be output to a file " - "if this flag is set. " - "Default is that it is not output." - ), - "action": "store_true", - }, - { - "name": ["-f", "--force-overwrite"], - "help": "Outputs will not overwrite existing file " - "unless --force is specified.", - "action": "store_true", - }, - { - "name": ["-m", "--method"], - "help": ( - f"The method for computing absorption correction. " - f"Allowed methods: {*CVE_METHODS, }. " - f"Default method is polynomial interpolation " - f"if not specified." - ), - "default": "polynomial_interpolation", - }, - { - "name": ["-u", "--user-metadata"], - "help": ( - "Specify key-value pairs to be loaded into metadata " - "using the format key=value. " - "Separate pairs with whitespace, " - "and ensure no whitespaces before or after the = sign. " - "Avoid using = in keys. If multiple = signs are present, " - "only the first separates the key and value. " - "If a key or value contains whitespace, enclose it in quotes. " - "For example, facility='NSLS II', " - "'facility=NSLS II', beamline=28ID-2, " - "'beamline'='28ID-2', 'favorite color'=blue, " - "are all valid key=value items." - ), - "nargs": "+", - "metavar": "KEY=VALUE", - }, - { - "name": ["-n", "--username"], - "help": ( - "Username will be loaded from config files. " - "Specify here only if you want to " - "override that behavior at runtime." - ), - "default": None, - }, - { - "name": ["-e", "--email"], - "help": ( - "Email will be loaded from config files. " - "Specify here only if you want to " - "override that behavior at runtime." - ), - "default": None, - }, - { - "name": ["--orcid"], - "help": ( - "ORCID will be loaded from config files. " - "Specify here only if you want to " - "override that behavior at runtime." - ), - "default": None, - }, - ] - return args + This function checks if the standard output (sys.stdout) is + connected to a terminal. If not, it assumes the application is + running in a GUI environment, such as when launched by Gooey. This + is used to prevent ANSI escape sequences from rendering in the GUI. + """ + return not sys.stdout.isatty() -def _add_mud_selection_group(p, use_gui=False): - """Current Options: - 1. Manually enter muD (`--mud`). - 2. Estimate from a z-scan file (`-z` or `--z-scan-file`). - 3. Estimate theoretically based on sample mass density - (`-d` or `--theoretical-from-density`). - 4. Estimate theoretically based on packing fraction - (`-p` or `--theoretical-from-packing`). - """ - g = p.add_argument_group("Options for setting mu*D value (Required)") - g = g.add_mutually_exclusive_group(required=True) - g.add_argument( - "--mud", - type=float, - help="Enter the mu*D value manually.", - **({"widget": "DecimalField"} if use_gui else {}), +def _add_common_args(parser, use_gui=False): + parser.add_argument( + "-w", + "--wavelength", + help=( + "X-ray wavelength in angstroms (numeric) or X-ray source name " + f"(allowed: {', '.join(sorted(WAVELENGTHS.keys()))}). " + "Will be loaded from config files if not specified." + ), + default=None, ) - g.add_argument( - "-z", - "--z-scan-file", + parser.add_argument( + "-x", + "--xtype", help=( - "Estimate mu*D experimentally from a z-scan file. " - "Specify the path to the file " - "used to compute the mu*D value." + "X-axis type (default: tth). Allowed values: " + f"{', '.join(XQUANTITIES)}" ), - **({"widget": "FileChooser"} if use_gui else {}), + default="tth", + ) + parser.add_argument( + "-m", + "--method", + help=( + "Method for cylindrical volume element (CVE) calculation " + "(default: polynomial_interpolation). Allowed methods: " + f"{', '.join(CVE_METHODS)}" + ), + default="polynomial_interpolation", + choices=CVE_METHODS, + ) + parser.add_argument( + "-o", + "--output-directory", + help=( + "Directory to save corrected files (created if needed). " + "Defaults to current directory." + ), + default=None, + **({"widget": "DirChooser"} if use_gui else {}), + ) + parser.add_argument( + "-f", "--force", help="Overwrite existing files", action="store_true" + ) + parser.add_argument( + "-c", + "--output-correction", + help="Also output the absorption correction to a separate file", + action="store_true", + ) + parser.add_argument( + "-u", + "--user-metadata", + help=( + "Specify key-value pairs to be loaded into metadata " + "using the format key=value. " + "Separate pairs with whitespace, " + "and ensure no whitespaces before or after the = sign. " + "Avoid using = in keys. If multiple = signs are present, " + "only the first separates the key and value. " + "If a key or value contains whitespace, enclose it in quotes. " + "For example, facility='NSLS II', " + "'facility=NSLS II', beamline=28ID-2, " + "'beamline'='28ID-2', 'favorite color'=blue, " + "are all valid key=value items." + ), + nargs="+", + metavar="KEY=VALUE", + ) + _add_credit_args(parser, use_gui) + return parser + + +def _add_credit_args(parser, use_gui=False): + parser.add_argument( + "--username", + help=( + "Your name (optional, for dataset credit). " + "Will be loaded from config files if not specified." + ), + default=None, + **({"widget": "TextField"} if use_gui else {}), ) - g.add_argument( - "-d", - "--theoretical-from-density", + parser.add_argument( + "--email", help=( - "Estimate mu*D theoretically using sample mass density. " - "Specify the chemical formula, incident x-ray energy (in keV), " - "and sample mass density (in g/cm^3), " - + theoretical_mud_hmsg_suffix + "Your email (optional, for dataset credit). " + "Will be loaded from config files if not specified." ), + default=None, + **({"widget": "TextField"} if use_gui else {}), ) - g.add_argument( - "-p", - "--theoretical-from-packing", + parser.add_argument( + "--orcid", help=( - "Estimate mu*D theoretically using packing fraction. " - "Specify the chemical formula, incident x-ray energy (in keV), " - "and packing fraction (0 to 1), " + theoretical_mud_hmsg_suffix + "Your ORCID ID (optional, for dataset credit). " + "Will be loaded from config files if not specified." ), + default=None, + **({"widget": "TextField"} if use_gui else {}), ) - return p -def _register_applymud_subparser(subp, use_gui=False): - applymudp = subp.add_parser( - "applymud", help="Apply absorption correction." +def _save_corrected(corrected, input_path, args): + outfile = args.output_directory / (f"{input_path.stem}-mud-corrected.chi") + corrected.metadata = corrected.metadata or {} + corrected.dump(str(outfile), xtype=args.xtype) + print(f"Saved corrected data to {outfile}") + + +def _save_correction(correction, input_path, args): + corrfile = args.output_directory / (f"{input_path.stem}-cve.chi") + correction.metadata = correction.metadata or {} + correction.dump(str(corrfile), xtype=args.xtype) + print(f"Saved correction data to {corrfile}") + + +def _load_pattern(path, xtype, wavelength, metadata): + x, y = load_data(path, unpack=True) + return DiffractionObject( + xarray=x, + yarray=y, + xtype=xtype, + wavelength=wavelength, + scat_quantity="x-ray", + name=path.stem, + metadata=metadata, ) - _add_mud_selection_group(applymudp, use_gui=use_gui) - for arg in _define_arguments(): - names = arg["name"] - options = {k: v for k, v in arg.items() if k != "name"} - if not use_gui and "widget" in options: - options.pop("widget") - applymudp.add_argument(*names, **options) + + +def apply_absorption_correction(args): + """Process all input files with absorption correction.""" + for path in args.input_paths: + metadata = load_metadata(args, path) + pattern = _load_pattern(path, args.xtype, args.wavelength, metadata) + correction = compute_cve( + pattern, args.mud, method=args.method, xtype=args.xtype + ) + correction.metadata = metadata.copy() + corrected_data = apply_corr(pattern, correction) + corrected_data.name = ( + f"Absorption corrected input_data: {pattern.name}" + ) + corrected_data.metadata = metadata.copy() + _save_corrected(corrected_data, path, args) + if args.output_correction: + _save_correction(correction, path, args) def create_parser(use_gui=False): - p = GooeyParser() if use_gui else ArgumentParser() - subp = p.add_subparsers(title="subcommand", dest="subcommand") - _register_applymud_subparser(subp, use_gui) - return p + Parser = GooeyParser if use_gui else argparse.ArgumentParser + # Force no colors when gui is running to avoid ANSI escape codes + # in Gooey output + if use_gui or _running_in_gui(): + os.environ["NO_COLOR"] = "1" + os.environ["CLICOLOR"] = "0" -@Gooey( - required_cols=1, - optional_cols=1, - show_sidebar=True, - program_name="labpdfproc GUI", -) -def _get_args_gui(): - p = create_parser(use_gui=True) - args = p.parse_args() - return args + parser = Parser( + prog="labpdfproc", + description=( + "Apply absorption corrections to laboratory X-ray diffraction " + "data prior to PDF analysis. Supports manual mu*d, " + "z-scan, or sample-based corrections." + ), + formatter_class=argparse.RawTextHelpFormatter, + ) + subp = parser.add_subparsers( + dest="command", required=True, title="Correction method" + ) + # MUD parser + mud_parser = subp.add_parser( + "mud", help="Correct diffraction data using known mu*d value" + ) + mud_parser.add_argument( + "input", + nargs="+", + help=( + "Input X-ray diffraction data file(s) or directory. " + "Can specify multiple files, directories, or use wildcards." + ), + **({"widget": "MultiFileChooser"} if use_gui else {}), + ) + mud_parser.add_argument( + "mud", type=float, help="mu*d value", metavar="mud" + ) + _add_common_args(mud_parser, use_gui) -def _get_args_cli(override_cli_inputs=None): - p = create_parser(use_gui=False) - args = p.parse_args(override_cli_inputs) - return args + # ZSCAN parser + zscan_parser = subp.add_parser( + "zscan", help="Correct diffraction data using a z-scan measurement" + ) + zscan_parser.add_argument( + "input", + nargs="+", + help=( + "Input X-ray diffraction data file(s) or directory. " + "Can specify multiple files, directories, or use wildcards." + ), + **({"widget": "MultiFileChooser"} if use_gui else {}), + ) + zscan_parser.add_argument( + "z_scan_file", + help=( + "Z-scan measurement file. " + "See diffpy.labpdfproc documentation for more information." + ), + **({"widget": "FileChooser"} if use_gui else {}), + ) + _add_common_args(zscan_parser, use_gui) + # SAMPLE parser + sample_parser = subp.add_parser( + "sample", + help="Correct diffraction data using sample composition/density", + ) + sample_parser.add_argument( + "input", + nargs="+", + help=( + "Input X-ray diffraction data file(s) or directory. " + "Can specify multiple files, directories, or use wildcards." + ), + **({"widget": "MultiFileChooser"} if use_gui else {}), + ) + sample_parser.add_argument( + "sample_composition", + help="Chemical formula, e.g. Fe2O3", + ) + sample_parser.add_argument( + "sample_mass_density", + type=float, + help=( + "Sample mass density in capillary (g/cm^3). " + "If unsure, a good estimate is ~1/3 of the " + "theoretical packing fraction density." + ), + ) + sample_parser.add_argument( + "diameter", + type=float, + help="Outer diameter of the capillary in mm", + ) + _add_common_args(sample_parser, use_gui) -def get_args(override_cli_inputs=None, use_gui=False): - return _get_args_gui() if use_gui else _get_args_cli(override_cli_inputs) + return parser -def applymud(args): - args = preprocessing_args(args) - for filepath in args.input_paths: - outfilestem = filepath.stem + "_corrected" - corrfilestem = filepath.stem + "_cve" - outfile = args.output_directory / (outfilestem + ".chi") - corrfile = args.output_directory / (corrfilestem + ".chi") - - if outfile.exists() and not args.force_overwrite: - sys.exit( - f"Output file {str(outfile)} already exists. " - f"Please rerun specifying -f if you want to overwrite it." - ) - if ( - corrfile.exists() - and args.output_correction - and not args.force_overwrite - ): - sys.exit( - f"Corrections file {str(corrfile)} " - f"was requested and already exists. " - f"Please rerun specifying -f if you want to overwrite it." +def _handle_old_api_conversion(args): + """Convert `sample` command arguments to previous format so + functions can accept them without modification.""" + if args.command == "sample": + # Convert sample args to theoretical_from_density format + args = load_wavelength_from_config_file(args) + args = set_wavelength(args) + energy_kev = 12.398 / args.wavelength if args.wavelength else None + if energy_kev: + args.theoretical_from_density = ( + f"{args.sample_composition}," + f"{energy_kev}," + f"{args.sample_mass_density}" ) + return args - xarray, yarray = loadData(filepath, unpack=True) - input_pattern = DiffractionObject( - xarray=xarray, - yarray=yarray, - xtype=args.xtype, - wavelength=args.wavelength, - scat_quantity="x-ray", - name=filepath.stem, - metadata=load_metadata(args, filepath), - ) - - absorption_correction = compute_cve( - input_pattern, args.mud, args.method, args.xtype - ) - corrected_data = apply_corr(input_pattern, absorption_correction) - corrected_data.name = ( - f"Absorption corrected input_data: " f"{input_pattern.name}" - ) - corrected_data.dump(f"{outfile}", xtype=args.xtype) - if args.output_correction: - absorption_correction.dump(f"{corrfile}", xtype=args.xtype) +@Gooey( + program_name="labpdfproc", + required_cols=1, + optional_cols=1, + show_sidebar=True, +) +def get_args_gui(): + parser = create_parser(use_gui=True) + return parser.parse_args() -def run_subcommand(args): - if args.subcommand == "applymud": - return applymud(args) - else: - raise ValueError(f"Unknown subcommand: {args.subcommand}") +def get_args_cli(override=None): + parser = create_parser(use_gui=False) + argv = override if override is not None else sys.argv[1:] + argv = [arg for arg in argv if arg != "--ignore-gooey"] + return parser.parse_args(argv) def main(): use_gui = len(sys.argv) == 1 or "--gui" in sys.argv - args = get_args(use_gui=use_gui) - return run_subcommand(args) + args = get_args_gui() if use_gui else get_args_cli() + args = _handle_old_api_conversion(args) + args = preprocessing_args(args) + apply_absorption_correction(args) if __name__ == "__main__": diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index ee5c6e8..305291e 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -39,13 +39,10 @@ # and will be written into separate arguments for clarity. METADATA_KEYS_TO_EXCLUDE = [ "output_correction", - "force_overwrite", "input", "input_paths", - "wavelength", - "theoretical_from_density", - "theoretical_from_packing", - "subcommand", + "force", + "energy", ] @@ -79,7 +76,8 @@ def set_output_directory(args): def _expand_user_input(args): - """Expand the list of inputs by adding files from file lists and wildcards. + """Expand the list of inputs by adding files from file lists and + wildcards. Parameters ---------- @@ -115,9 +113,9 @@ def _expand_user_input(args): def set_input_lists(args): - """Set input directory and files. It takes cli inputs, checks if they are - files or directories and creates a list of files to be processed which is - stored in the args Namespace. + """Set input directory and files. It takes cli inputs, checks if + they are files or directories and creates a list of files to be + processed which is stored in the args Namespace. Parameters ---------- @@ -166,8 +164,52 @@ def set_input_lists(args): return args +def normalize_wavelength(args): + """Normalize args.wavelength to a float. + + If args.wavelength is: + - None: return args unchanged + - float-like: convert to float + - string: look up corresponding value in WAVELENGTHS (case-insensitive) + + Parameters + ---------- + args : argparse.Namespace + The arguments from the parser. + + Returns + ------- + args : argparse.Namespace + The updated arguments with args.wavelength. + + Raises + ------ + ValueError + If a string wavelength is not a known source. + """ + if args.wavelength is None: + return args + try: + args.wavelength = float(args.wavelength) + return args + except (TypeError, ValueError): + pass + key = str(args.wavelength).strip() + matched = next( + (k for k in WAVELENGTHS if k.lower() == key.lower()), + None, + ) + if matched is None: + raise ValueError( + f"Anode type '{args.wavelength}' not recognized. " + f"Please rerun specifying an anode type from {*known_sources, }." + ) + args.wavelength = WAVELENGTHS[matched] + return args + + def load_wavelength_from_config_file(args): - """Load wavelength and anode type from config files. + """Load wavelength from config files. It prioritizes values in the following order: 1. cli inputs, 2. local config file, 3. global config file. @@ -182,104 +224,92 @@ def load_wavelength_from_config_file(args): args : argparse.Namespace The updated arguments with the updated wavelength and anode type. """ - global_config = _load_config(Path().home() / "diffpyconfig.json") - local_config = _load_config(Path().cwd() / "diffpyconfig.json") - local_has_data = local_config and ( - "wavelength" in local_config or "anode_type" in local_config - ) - global_has_data = global_config and ( - "wavelength" in global_config or "anode_type" in global_config - ) - if not local_has_data and not global_has_data: - print( - "No configuration file was found containing information " - "about the wavelength or anode type. \n" - "You can add the wavelength or anode type " - "to a configuration file on the current computer " - "and it will be automatically associated with " - "subsequent diffpy data by default. \n" - "You will only have to do that once. \n" - "For more information, please refer to www.diffpy.org/" - "diffpy.labpdfproc/examples/toolsexample.html" - ) - if args.wavelength or args.anode_type: - return args - config = local_config if local_has_data else global_config - if config: - args.wavelength = args.wavelength or config.get("wavelength") - args.anode_type = args.anode_type or config.get("anode_type") - return args + if args.wavelength is not None: + return normalize_wavelength(args) + + global_config_file = _load_config(Path().home() / "diffpyconfig.json") + local_config_file = _load_config(Path().cwd() / "diffpyconfig.json") + config_file = None + if ( + isinstance(local_config_file, dict) + and "wavelength" in local_config_file + ): + config_file = local_config_file + elif ( + isinstance(global_config_file, dict) + and "wavelength" in global_config_file + ): + config_file = global_config_file + if config_file is not None: + args.wavelength = config_file.get("wavelength") + return normalize_wavelength(args) + else: + raise ValueError( + "\nThe wavelength was not specified and no " + "configuration file 'diffpyconfig.json' containing " + "the wavelength or X-ray source was found in either the " + "local or home directories. Either specify the wavelength " + "or source using the -w/--wavelength option or " + "create a configuration file.\n\n" + "You can add the wavelength or anode type to a " + "configuration file on this computer. Once created, it " + "will be automatically used for subsequent diffpy data " + "by default, and you will only need to do this once.\n\n" + "For detailed instructions on creating the configuration " + "file, please refer to:\n" + "https://www.diffpy.org/diffpy.labpdfproc/examples/" + "toolsexample.html" + ) def set_wavelength(args): - """Set the wavelength based on the given anode_type or wavelength. + """Set the wavelength based on args.wavelength. - First checks from args. If neither is provided, - it attempts to load from local and then global config file. + args.wavelength may be: + - None + - a number (explicit wavelength in Å) + - a string (X-ray source name) + + If a string is provided, it must match a key in WAVELENGTHS. Parameters ---------- args : argparse.Namespace - The arguments from the parser. Raises ------ ValueError - Raised if: - (1) neither wavelength or anode type is provided - and xtype is not the two-theta grid, - (2) both are provided, - (3) anode_type is not one of the known sources, - (4) wavelength is non-positive. + If wavelength is required but missing, + if a string wavelength is not a known source, + or if a numeric wavelength is non-positive. Returns ------- args : argparse.Namespace - The updated arguments with the wavelength. + Updated arguments with args.wavelength as a float. """ - args = load_wavelength_from_config_file(args) - if args.wavelength is None and args.anode_type is None: + args = normalize_wavelength(args) + if args.wavelength is None: if args.xtype not in ANGLEQUANTITIES: raise ValueError( f"Please provide a wavelength or anode type " f"because the independent variable axis is not on two-theta. " f"Allowed anode types are {*known_sources, }." ) - elif args.wavelength is not None and args.anode_type is not None: - raise ValueError( - f"Please provide either a wavelength or an anode type, not both. " - f"Allowed anode types are {*known_sources, }." - ) - elif args.anode_type is not None: - matched_anode_type = next( - ( - key - for key in WAVELENGTHS - if key.lower() == args.anode_type.lower() - ), - None, - ) - if matched_anode_type is None: - raise ValueError( - f"Anode type '{args.anode_type}' not recognized. " - f"Please rerun specifying an anode_type " - f"from {*known_sources, }." - ) - args.anode_type = matched_anode_type - args.wavelength = WAVELENGTHS[args.anode_type] - elif args.wavelength is not None and args.wavelength <= 0: + return args + if args.wavelength <= 0: raise ValueError( f"Wavelength = {args.wavelength} is not valid. " - "Please rerun specifying a known anode_type " + "Please rerun specifying a known anode type " "or a positive wavelength." ) return args def set_xtype(args): - """Set the xtype based on the given input arguments, raise an error if - xtype is not one of {*XQUANTITIES, }. + """Set the xtype based on the given input arguments, raise an error + if xtype is not one of {*XQUANTITIES, }. Parameters ---------- @@ -334,35 +364,40 @@ def _parse_theoretical_input(input_str): def _set_theoretical_mud_from_density(args): - """Theoretical estimation of mu*D from sample composition, energy, and - sample mass density.""" - sample_composition, energy, sample_mass_density = _parse_theoretical_input( - args.theoretical_from_density - ) - args.sample_composition = sample_composition + """Theoretical estimation of mu*D from sample composition, energy, + and sample mass density.""" + args = normalize_wavelength(args) + if args.wavelength is None: + args = load_wavelength_from_config_file(args) + energy = 12.398 / args.wavelength args.energy = energy - args.sample_mass_density = sample_mass_density - args.mud = compute_mu_using_xraydb( - args.sample_composition, - args.energy, - sample_mass_density=args.sample_mass_density, + args.mud = ( + compute_mu_using_xraydb( + args.sample_composition, + args.energy, + sample_mass_density=args.sample_mass_density, + ) + * args.diameter ) return args def _set_theoretical_mud_from_packing(args): - """Theoretical estimation of mu*D from sample composition, energy, and - packing fraction.""" + """Theoretical estimation of mu*D from sample composition, energy, + and packing fraction.""" sample_composition, energy, packing_fraction = _parse_theoretical_input( args.theoretical_from_packing ) args.sample_composition = sample_composition args.energy = energy args.packing_fraction = packing_fraction - args.mud = compute_mu_using_xraydb( - args.sample_composition, - args.energy, - packing_fraction=args.packing_fraction, + args.mud = ( + compute_mu_using_xraydb( + args.sample_composition, + args.energy, + packing_fraction=args.packing_fraction, + ) + * args.diameter ) return args @@ -386,12 +421,12 @@ def set_mud(args): args : argparse.Namespace The updated arguments with mu*D. """ - if args.z_scan_file: + if args.command == "mud": + return args + if args.command == "zscan": return _set_mud_from_zscan(args) - elif args.theoretical_from_density: + if args.command == "sample": return _set_theoretical_mud_from_density(args) - elif args.theoretical_from_packing: - return _set_theoretical_mud_from_packing(args) return args @@ -404,8 +439,8 @@ def _load_key_value_pair(s): def load_user_metadata(args): - """Load user metadata into args, raise ValueError if it is in incorrect - format. + """Load user metadata into args, raise ValueError if it is in + incorrect format. Parameters ---------- @@ -445,8 +480,9 @@ def load_user_metadata(args): def load_user_info(args): """Load user info into args. If none is provided, call - check_and_build_global_config function from diffpy.utils to prompt the user - for inputs. Otherwise, call get_user_info with the provided arguments. + check_and_build_global_config function from diffpy.utils to prompt + the user for inputs. Otherwise, call get_user_info with the provided + arguments. Parameters ---------- @@ -492,10 +528,31 @@ def load_package_info(args): return args +def _check_saved_file_exists(args): + """Check if the output files already exist based on the input paths + and output directory.""" + existing_files = [] + for path in args.input_paths: + outfile = args.output_directory / (f"{path.stem}-mud-corrected.chi") + if outfile.exists() and not args.force: + existing_files.append(outfile) + if args.output_correction: + corrfile = args.output_directory / (f"{path.stem}-cve.chi") + if corrfile.exists() and not args.force: + existing_files.append(corrfile) + if existing_files: + existing_files_str = "\n".join(str(f) for f in existing_files) + raise FileExistsError( + "The following output files already exist:" + f"\n{existing_files_str}\n" + "Use --force to overwrite them." + ) + + def preprocessing_args(args): - """Perform preprocessing on the provided args. The process includes loading - package and user information, setting input, output, wavelength, anode - type, xtype, mu*D, and loading user metadata. + """Perform preprocessing on the provided args. The process includes + loading package and user information, setting input, output, + wavelength, anode type, xtype, mu*D, and loading user metadata. Parameters ---------- @@ -506,7 +563,13 @@ def preprocessing_args(args): ------- args : argparse.Namespace The updated argparse Namespace with arguments preprocessed. + + Raises + ------ + FileExistsError + If the output files already exist and --force is not used. """ + args = load_wavelength_from_config_file(args) args = set_mud(args) args = set_input_lists(args) args = set_output_directory(args) @@ -515,12 +578,14 @@ def preprocessing_args(args): args = load_user_metadata(args) args = load_user_info(args) args = load_package_info(args) + _check_saved_file_exists(args) return args +# Update load_metadata to use 'input_directory' consistently: def load_metadata(args, filepath): - """Load the relevant metadata from args to write into the header of the - output files. + """Load the relevant metadata from args to write into the header of + the output files. Parameters ---------- @@ -538,6 +603,7 @@ def load_metadata(args, filepath): metadata = copy.deepcopy(vars(args)) for key in METADATA_KEYS_TO_EXCLUDE: metadata.pop(key, None) + metadata["mud"] = round(float(metadata["mud"]), 4) metadata["input_directory"] = str(filepath) metadata["output_directory"] = str(metadata["output_directory"]) return metadata diff --git a/src/diffpy/labpdfproc/version.py b/src/diffpy/labpdfproc/version.py index 13d3b31..26fc43b 100644 --- a/src/diffpy/labpdfproc/version.py +++ b/src/diffpy/labpdfproc/version.py @@ -1,10 +1,14 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024 The Trustees of Columbia University in the City of New York. +# (c) 2024-2025, The Trustees of Columbia University in the City of New York. # All rights reserved. # -# File coded by: Billinge Group members and community contributors. +# (c) 2026-present, diffpy.labpdfproc developers and contributors. +# All rights reserved. +# +# File coded by: Yucong Chen, Till Schertenleib, Caden Myers, +# Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.labpdfproc/graphs/contributors @@ -18,8 +22,9 @@ # __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] # obtain version information -from importlib.metadata import version - -__version__ = version("diffpy.labpdfproc") +from importlib.metadata import PackageNotFoundError, version -# End of file +try: + __version__ = version("diffpy.labpdfproc") +except PackageNotFoundError: + __version__ = "unknown" diff --git a/tests/conftest.py b/tests/conftest.py index 63d4646..cda2974 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,7 +13,8 @@ def user_filesystem(tmp_path): home_dir.mkdir(parents=True, exist_ok=True) test_dir = base_dir / "test_dir" test_dir.mkdir(parents=True, exist_ok=True) - + output_dir = base_dir / "output_dir" + output_dir.mkdir(parents=True, exist_ok=True) chi_data = ( "dataformat = twotheta\n mode = " "xray\n # chi_Q chi_I\n 1 2\n 3 4\n 5 6\n 7 8\n" @@ -59,6 +60,10 @@ def user_filesystem(tmp_path): f.write("good_data.xy \n") f.write(f"{str(input_dir.resolve() / 'good_data.txt')}\n") + with open(output_dir / "good_data-mud-corrected.chi", "w") as f: + f.write(chi_data) + with open(output_dir / "good_data-cve.chi", "w") as f: + f.write(chi_data) home_config_data = { "wavelength": 0.3, "owner_name": "home_username", diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index d7a05d2..044e8fa 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -2,17 +2,17 @@ import pytest -from diffpy.utils.parsers.loaddata import loadData +from diffpy.utils.parsers import load_data # Test that our readable and unreadable files are indeed readable and -# unreadable by loadData (which is our definition of readable and unreadable) -def test_loadData_with_input_files(user_filesystem): +# unreadable by load_data (which is our definition of readable and unreadable) +def test_load_data_with_input_files(user_filesystem): os.chdir(user_filesystem) - xarray_chi, yarray_chi = loadData("good_data.chi", unpack=True) - xarray_xy, yarray_xy = loadData("good_data.xy", unpack=True) - xarray_txt, yarray_txt = loadData("good_data.txt", unpack=True) + xarray_chi, yarray_chi = load_data("good_data.chi", unpack=True) + xarray_xy, yarray_xy = load_data("good_data.xy", unpack=True) + xarray_txt, yarray_txt = load_data("good_data.txt", unpack=True) with pytest.raises(ValueError): - xarray_txt, yarray_txt = loadData("unreadable_file.txt", unpack=True) + xarray_txt, yarray_txt = load_data("unreadable_file.txt", unpack=True) with pytest.raises(ValueError): - xarray_pkl, yarray_pkl = loadData("binary.pkl", unpack=True) + xarray_pkl, yarray_pkl = load_data("binary.pkl", unpack=True) diff --git a/tests/test_tools.py b/tests/test_tools.py index e2028e9..9112699 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -5,7 +5,7 @@ import pytest -from diffpy.labpdfproc.labpdfprocapp import get_args +from diffpy.labpdfproc.labpdfprocapp import get_args_cli from diffpy.labpdfproc.tools import ( known_sources, load_metadata, @@ -13,6 +13,7 @@ load_user_info, load_user_metadata, load_wavelength_from_config_file, + normalize_wavelength, preprocessing_args, set_input_lists, set_mud, @@ -115,8 +116,8 @@ def test_set_input_lists(inputs, expected, user_filesystem): base_dir.resolve() / expected_path for expected_path in expected ] - cli_inputs = ["applymud"] + inputs + ["--mud", "2.5"] - actual_args = get_args(cli_inputs) + cli_inputs = ["mud"] + inputs + ["2.5"] + actual_args = get_args_cli(cli_inputs) actual_args = set_input_lists(actual_args) assert sorted(actual_args.input_paths) == sorted(expected_paths) @@ -161,8 +162,8 @@ def test_set_input_lists(inputs, expected, user_filesystem): def test_set_input_files_bad(inputs, expected_error_msg, user_filesystem): base_dir = Path(user_filesystem) os.chdir(base_dir) - cli_inputs = ["applymud"] + inputs + ["--mud", "2.5"] - actual_args = get_args(cli_inputs) + cli_inputs = ["mud"] + inputs + ["2.5"] + actual_args = get_args_cli(cli_inputs) with pytest.raises(FileNotFoundError, match=re.escape(expected_error_msg)): actual_args = set_input_lists(actual_args) @@ -179,8 +180,8 @@ def test_set_input_files_bad(inputs, expected_error_msg, user_filesystem): def test_set_output_directory(inputs, expected, user_filesystem): os.chdir(user_filesystem) expected_output_directory = Path(user_filesystem) / expected[0] - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = set_output_directory(actual_args) assert actual_args.output_directory == expected_output_directory assert Path(actual_args.output_directory).exists() @@ -190,42 +191,69 @@ def test_set_output_directory(inputs, expected, user_filesystem): def test_set_output_directory_bad(user_filesystem): os.chdir(user_filesystem) cli_inputs = [ - "applymud", + "mud", "data.xy", - "--mud", "2.5", "--output-directory", "good_data.chi", ] - actual_args = get_args(cli_inputs) + actual_args = get_args_cli(cli_inputs) with pytest.raises(FileExistsError): actual_args = set_output_directory(actual_args) assert Path(actual_args.output_directory).exists() assert not Path(actual_args.output_directory).is_dir() +@pytest.mark.parametrize( + "inputs, expected", + [ + # UC1: input is numeric wavelength + # expect to return the same value + (["--wavelength", "0.25"], 0.25), + # UC2: input is valid source name (case-sensitive canonical) + # expect to return the corresponding wavelength from dict + (["--wavelength", "Mo"], 0.71073), + # UC3: input is valid source name, mismatched case + # expect to return the corresponding wavelength from dict + (["--wavelength", "agka1Ka2"], 0.56087), + ], +) +def test_normalize_wavelength(inputs, expected): + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + args = get_args_cli(cli_inputs) + args = normalize_wavelength(args) + assert args.wavelength == expected + + +def test_normalize_wavelength_bad(): + cli_inputs = ["mud", "data.xy", "2.5", "--wavelength", "invalid_source"] + args = get_args_cli(cli_inputs) + with pytest.raises( + ValueError, + match=( + "Anode type 'invalid_source' not recognized\\. " + "Please rerun specifying an anode type from " + ), + ): + normalize_wavelength(args) + + @pytest.mark.parametrize( "inputs, expected", [ # Test with only a home config file (no local config), # expect to return values directly from args - # if either wavelength or anode type is specified, + # if wavelength is specified, # otherwise update args with values from the home config file - # (wavelength=0.3, no anode type). + # (wavelength=0.3). # This test only checks loading behavior, # not value validation (which is handled by `set_wavelength`). # C1: no args, expect to update arg values from home config - ([], {"wavelength": 0.3, "anode_type": None}), + ([], {"wavelength": 0.3}), # C2: wavelength provided, expect to return args unchanged - (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + (["--wavelength", "0.25"], {"wavelength": 0.25}), # C3: anode type provided, expect to return args unchanged - (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), - # C4: both wavelength and anode type provided, - # expect to return args unchanged - ( - ["--wavelength", "0.7", "--anode-type", "Mo"], - {"wavelength": 0.7, "anode_type": "Mo"}, - ), + (["--wavelength", "Mo"], {"wavelength": 0.71073}), ], ) def test_load_wavelength_from_config_file_with_home_conf_file( @@ -236,11 +264,10 @@ def test_load_wavelength_from_config_file_with_home_conf_file( mocker.patch("pathlib.Path.home", lambda _: home_dir) os.chdir(cwd) - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = load_wavelength_from_config_file(actual_args) assert actual_args.wavelength == expected["wavelength"] - assert actual_args.anode_type == expected["anode_type"] @pytest.mark.parametrize( @@ -255,17 +282,11 @@ def test_load_wavelength_from_config_file_with_home_conf_file( # This test only checks loading behavior, # not value validation (which is handled by `set_wavelength`). # C1: no args, expect to update arg values from local config - ([], {"wavelength": 0.6, "anode_type": None}), + ([], {"wavelength": 0.6}), # C2: wavelength provided, expect to return args unchanged - (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + (["--wavelength", "0.25"], {"wavelength": 0.25}), # C3: anode type provided, expect to return args unchanged - (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), - # C4: both wavelength and anode type provided, - # expect to return args unchanged - ( - ["--wavelength", "0.7", "--anode-type", "Mo"], - {"wavelength": 0.7, "anode_type": "Mo"}, - ), + (["--wavelength", "Mo"], {"wavelength": 0.71073}), ], ) def test_load_wavelength_from_config_file_with_local_conf_file( @@ -279,17 +300,83 @@ def test_load_wavelength_from_config_file_with_local_conf_file( with open(cwd / "diffpyconfig.json", "w") as f: json.dump(local_config_data, f) - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = load_wavelength_from_config_file(actual_args) assert actual_args.wavelength == expected["wavelength"] - assert actual_args.anode_type == expected["anode_type"] # remove home config file, expect the same results confile = home_dir / "diffpyconfig.json" os.remove(confile) assert actual_args.wavelength == expected["wavelength"] - assert actual_args.anode_type == expected["anode_type"] + + +@pytest.mark.parametrize( + "local_config, home_config", + [ + # C1: no config files exist + # expected: raise ValueError + (None, None), + # C2: local config is empty, no home config + # expected: raise ValueError + ({}, None), + # C3: no local config, home config is empty + # expected: raise ValueError + (None, {}), + # C4: both config files are empty + # expected: raise ValueError + ({}, {}), + ], +) +def test_load_wavelength_from_config_file_without_conf_files_bad( + mocker, + user_filesystem, + local_config, + home_config, +): + # User tries to correct data without specifying wavelength and + # no config files + # with wavelength exist -- expected to raise ValueError + cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + mocker.patch("pathlib.Path.home", return_value=home_dir) + os.chdir(cwd) + + local_config_file = cwd / "diffpyconfig.json" + if local_config_file.exists(): + local_config_file.unlink() + home_config_file = home_dir / "diffpyconfig.json" + if home_config_file.exists(): + home_config_file.unlink() + + if local_config is not None: + with open(local_config_file, "w") as f: + json.dump(local_config, f) + if home_config is not None: + with open(home_config_file, "w") as f: + json.dump(home_config, f) + + cli_inputs = ["mud", "data.xy", "2.5"] + actual_args = get_args_cli(cli_inputs) + + msg = re.escape( + "\nThe wavelength was not specified and no " + "configuration file 'diffpyconfig.json' containing " + "the wavelength or X-ray source was found in either the " + "local or home directories. Either specify the wavelength " + "or source using the -w/--wavelength option or " + "create a configuration file.\n\n" + "You can add the wavelength or anode type to a " + "configuration file on this computer. Once created, it " + "will be automatically used for subsequent diffpy data " + "by default, and you will only need to do this once.\n\n" + "For detailed instructions on creating the configuration " + "file, please refer to:\n" + "https://www.diffpy.org/diffpy.labpdfproc/examples/" + "toolsexample.html" + ) + with pytest.raises(ValueError, match=msg): + load_wavelength_from_config_file(actual_args) @pytest.mark.parametrize( @@ -299,17 +386,10 @@ def test_load_wavelength_from_config_file_with_local_conf_file( # expect to return args without modification. # This test only checks loading behavior, # not value validation (which is handled by `set_wavelength`). - # C1: no args - ([], {"wavelength": None, "anode_type": None}), # C1: wavelength provided - (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + (["--wavelength", "0.25"], {"wavelength": 0.25}), # C2: anode type provided - (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), - # C4: both wavelength and anode type provided - ( - ["--wavelength", "0.7", "--anode-type", "Mo"], - {"wavelength": 0.7, "anode_type": "Mo"}, - ), + (["--wavelength", "Mo"], {"wavelength": 0.71073}), ], ) def test_load_wavelength_from_config_file_without_conf_files( @@ -322,11 +402,10 @@ def test_load_wavelength_from_config_file_without_conf_files( confile = home_dir / "diffpyconfig.json" os.remove(confile) - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = load_wavelength_from_config_file(actual_args) assert actual_args.wavelength == expected["wavelength"] - assert actual_args.anode_type == expected["anode_type"] @pytest.mark.parametrize( @@ -334,58 +413,55 @@ def test_load_wavelength_from_config_file_without_conf_files( [ # C1: only a valid anode type was entered (case independent), # expect to match the corresponding wavelength - # and preserve the correct case anode type - (["--anode-type", "Mo"], {"wavelength": 0.71073, "anode_type": "Mo"}), + (["--wavelength", "Mo"], {"wavelength": 0.71073}), ( - ["--anode-type", "MoKa1"], - {"wavelength": 0.70930, "anode_type": "MoKa1"}, + ["--wavelength", "MoKa1"], + {"wavelength": 0.70930}, ), ( - ["--anode-type", "MoKa1Ka2"], - {"wavelength": 0.71073, "anode_type": "MoKa1Ka2"}, + ["--wavelength", "MoKa1Ka2"], + {"wavelength": 0.71073}, ), - (["--anode-type", "Ag"], {"wavelength": 0.56087, "anode_type": "Ag"}), + (["--wavelength", "Ag"], {"wavelength": 0.56087}), ( - ["--anode-type", "AgKa1"], - {"wavelength": 0.55941, "anode_type": "AgKa1"}, + ["--wavelength", "AgKa1"], + {"wavelength": 0.55941}, ), ( - ["--anode-type", "AgKa1Ka2"], - {"wavelength": 0.56087, "anode_type": "AgKa1Ka2"}, + ["--wavelength", "AgKa1Ka2"], + {"wavelength": 0.56087}, ), - (["--anode-type", "Cu"], {"wavelength": 1.54184, "anode_type": "Cu"}), + (["--wavelength", "Cu"], {"wavelength": 1.54184}), ( - ["--anode-type", "CuKa1"], - {"wavelength": 1.54056, "anode_type": "CuKa1"}, + ["--wavelength", "CuKa1"], + {"wavelength": 1.54056}, ), ( - ["--anode-type", "CuKa1Ka2"], - {"wavelength": 1.54184, "anode_type": "CuKa1Ka2"}, + ["--wavelength", "CuKa1Ka2"], + {"wavelength": 1.54184}, ), ( - ["--anode-type", "moKa1Ka2"], - {"wavelength": 0.71073, "anode_type": "MoKa1Ka2"}, + ["--wavelength", "moKa1Ka2"], + {"wavelength": 0.71073}, ), - (["--anode-type", "ag"], {"wavelength": 0.56087, "anode_type": "Ag"}), + (["--wavelength", "ag"], {"wavelength": 0.56087}), ( - ["--anode-type", "cuka1"], - {"wavelength": 1.54056, "anode_type": "CuKa1"}, + ["--wavelength", "cuka1"], + {"wavelength": 1.54056}, ), # C2: a valid wavelength was entered, - # expect to include the wavelength only and anode type is None - (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + (["--wavelength", "0.25"], {"wavelength": 0.25}), # C3: nothing passed in, but mu*D was provided and xtype is on tth - # expect wavelength and anode type to be None + # expect wavelength to be None # and program proceeds without error - ([], {"wavelength": None, "anode_type": None}), + ([], {"wavelength": None}), ], ) def test_set_wavelength(inputs, expected): - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = set_wavelength(actual_args) assert actual_args.wavelength == expected["wavelength"] - assert actual_args.anode_type == expected["anode_type"] @pytest.mark.parametrize( @@ -398,30 +474,24 @@ def test_set_wavelength(inputs, expected): f"because the independent variable axis is not on two-theta. " f"Allowed anode types are {*known_sources, }.", ), - ( # C2: both wavelength and anode type were specified - # expect error asking not to specify both - ["--wavelength", "0.7", "--anode-type", "Mo"], - f"Please provide either a wavelength or an anode type, not both. " - f"Allowed anode types are {*known_sources, }.", - ), - ( # C3: invalid anode type + ( # C2: invalid anode type # expect error asking to specify a valid anode type - ["--anode-type", "invalid"], + ["--wavelength", "invalid"], f"Anode type 'invalid' not recognized. " - f"Please rerun specifying an anode_type from {*known_sources, }.", + f"Please rerun specifying an anode type from {*known_sources, }.", ), - ( # C4: invalid wavelength + ( # C3: invalid wavelength # expect error asking to specify a valid wavelength or anode type ["--wavelength", "-0.2"], "Wavelength = -0.2 is not valid. " - "Please rerun specifying a known anode_type " + "Please rerun specifying a known anode type " "or a positive wavelength.", ), ], ) def test_set_wavelength_bad(inputs, expected_error_msg): - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) with pytest.raises(ValueError, match=re.escape(expected_error_msg)): actual_args = set_wavelength(actual_args) @@ -436,15 +506,15 @@ def test_set_wavelength_bad(inputs, expected_error_msg): ], ) def test_set_xtype(inputs, expected_xtype): - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = set_xtype(actual_args) assert actual_args.xtype == expected_xtype def test_set_xtype_bad(): - cli_inputs = ["applymud", "data.xy", "--mud", "2.5", "--xtype", "invalid"] - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5", "--xtype", "invalid"] + actual_args = get_args_cli(cli_inputs) with pytest.raises( ValueError, match=re.escape( @@ -454,29 +524,52 @@ def test_set_xtype_bad(): actual_args = set_xtype(actual_args) +def test_set_mud_from_mud(user_filesystem): + cwd = Path(user_filesystem) + os.chdir(cwd) + cli_inputs = ["mud", "data.xy", "2.5"] + actual_args = get_args_cli(cli_inputs) + actual_args = set_mud(actual_args) + expected_mud = 2.5 + assert actual_args.mud == expected_mud + + +def test_set_mud_from_zscan(user_filesystem): + cwd = Path(user_filesystem) + os.chdir(cwd) + cli_inputs = ["zscan", "data.xy", "test_dir/testfile.xy"] + actual_args = get_args_cli(cli_inputs) + actual_args = set_mud(actual_args) + expected_mud = 3.0 + assert actual_args.mud == pytest.approx(expected_mud, rel=1e-4, abs=0.1) + + @pytest.mark.parametrize( - "inputs, expected_mud", + "inputs,expected_mud", + # C1: user specifies a wavelength + # and the wavelength is used to compute mu*D [ - # C1: user enters muD manually, expect to return the same value - (["--mud", "2.5"], 2.5), - # C2: user provides a z-scan file, expect to estimate through the file - (["--z-scan-file", "test_dir/testfile.xy"], 3), - # C3: user specifies sample composition, energy, - # and sample mass density, - # both with and without whitespaces, expect to estimate theoretically - (["--theoretical-from-density", "ZrO2,17.45,1.2"], 1.49), - (["--theoretical-from-density", "ZrO2, 17.45, 1.2"], 1.49), - # C4: user specifies sample composition, energy, and packing fraction - # both with and without whitespaces, expect to estimate theoretically - # (["--theoretical-from-packing", "ZrO2,17.45,0.3"], 1.49), - # (["--theoretical-from-packing", "ZrO2, 17.45, 0.3"], 1.49), + (["--wavelength", ".71"], 4.32), + # C2: user specifies an anode type + # and the corresponding wavelength is used + # to compute mu*D + (["--wavelength", "Mo"], 4.32), + # C3: user does not specify wavelength or anode type + # and the wavelength is retrieved from a config file + ([], 4.32), ], ) -def test_set_mud(user_filesystem, inputs, expected_mud): +def test_set_mud_from_sample(mocker, user_filesystem, inputs, expected_mud): cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + mocker.patch("pathlib.Path.home", lambda _: home_dir) os.chdir(cwd) - cli_inputs = ["applymud", "data.xy"] + inputs - actual_args = get_args(cli_inputs) + local_config_data = {"wavelength": 0.71} + with open(cwd / "diffpyconfig.json", "w") as f: + json.dump(local_config_data, f) + # [command,datafile,sample_composition,sample_mass_density,diameter] + cli_inputs = ["sample", "data.xy", "ZrO2", "1.745", "2"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = set_mud(actual_args) assert actual_args.mud == pytest.approx(expected_mud, rel=1e-4, abs=0.1) @@ -487,72 +580,20 @@ def test_set_mud(user_filesystem, inputs, expected_mud): # C1: user provides an invalid z-scan file, # expect FileNotFoundError and message to specify a valid file path ( - ["--z-scan-file", "invalid file"], + ["invalid file"], [ FileNotFoundError, "Cannot find invalid file. Please specify a valid file path.", ], ), - # C2.1: (sample mass density option) - # user provides fewer than three input values - # expect ValueError with a message indicating the correct format - ( - ["--theoretical-from-density", "ZrO2,0.5"], - [ - ValueError, - "Invalid mu*D input 'ZrO2,0.5'. " - "Expected format is 'sample composition, energy, " - "sample mass density or packing fraction' " - "(e.g., 'ZrO2,17.45,0.5').", - ], - ), - # C2.2: (packing fraction option) - # user provides fewer than three input values - # expect ValueError with a message indicating the correct format - ( - ["--theoretical-from-packing", "ZrO2,0.5"], - [ - ValueError, - "Invalid mu*D input 'ZrO2,0.5'. " - "Expected format is 'sample composition, energy, " - "sample mass density or packing fraction' " - "(e.g., 'ZrO2,17.45,0.5').", - ], - ), - # C3.1: (sample mass density option) - # user provides more than 3 input values - # expect ValueError with a message indicating the correct format - ( - ["--theoretical-from-density", "ZrO2,17.45,1.5,0.5"], - [ - ValueError, - "Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. " - "Expected format is 'sample composition, energy, " - "sample mass density or packing fraction' " - "(e.g., 'ZrO2,17.45,0.5').", - ], - ), - # C3.2: (packing fraction option) - # user provides more than 3 input values - # expect ValueError with a message indicating the correct format - ( - ["--theoretical-from-packing", "ZrO2,17.45,1.5,0.5"], - [ - ValueError, - "Invalid mu*D input 'ZrO2,17.45,1.5,0.5'. " - "Expected format is 'sample composition, energy, " - "sample mass density or packing fraction' " - "(e.g., 'ZrO2,17.45,0.5').", - ], - ), ], ) def test_set_mud_bad(user_filesystem, inputs, expected): expected_error, expected_error_msg = expected cwd = Path(user_filesystem) os.chdir(cwd) - cli_inputs = ["applymud", "data.xy"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["zscan", "data.xy"] + inputs + actual_args = get_args_cli(cli_inputs) with pytest.raises(expected_error, match=re.escape(expected_error_msg)): actual_args = set_mud(actual_args) @@ -578,13 +619,13 @@ def test_set_mud_bad(user_filesystem, inputs, expected): ], ) def test_load_user_metadata(inputs, expected): - expected_args = get_args(["applymud", "data.xy", "--mud", "2.5"]) + expected_args = get_args_cli(["mud", "data.xy", "2.5"]) for expected_pair in expected: setattr(expected_args, expected_pair[0], expected_pair[1]) delattr(expected_args, "user_metadata") - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) actual_args = load_user_metadata(actual_args) assert actual_args == expected_args @@ -619,8 +660,8 @@ def test_load_user_metadata(inputs, expected): ], ) def test_load_user_metadata_bad(inputs, expected_error_msg): - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] + inputs - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + inputs + actual_args = get_args_cli(cli_inputs) with pytest.raises(ValueError, match=re.escape(expected_error_msg)): actual_args = load_user_metadata(actual_args) @@ -682,9 +723,8 @@ def test_load_user_info(monkeypatch, inputs, expected, user_filesystem): os.chdir(cwd) cli_inputs = [ - "applymud", + "mud", "data.xy", - "--mud", "2.5", "--username", inputs["username"], @@ -693,7 +733,7 @@ def test_load_user_info(monkeypatch, inputs, expected, user_filesystem): "--orcid", inputs["orcid"], ] - actual_args = get_args(cli_inputs) + actual_args = get_args_cli(cli_inputs) actual_args = load_user_info(actual_args) assert actual_args.username == expected["username"] assert actual_args.email == expected["email"] @@ -707,8 +747,8 @@ def test_load_package_info(mocker): "3.3.0" if package_name == "diffpy.utils" else "1.2.3" ), ) - cli_inputs = ["applymud", "data.xy", "--mud", "2.5"] - actual_args = get_args(cli_inputs) + cli_inputs = ["mud", "data.xy", "2.5"] + actual_args = get_args_cli(cli_inputs) actual_args = load_package_info(actual_args) assert actual_args.package_info == { "diffpy.labpdfproc": "1.2.3", @@ -716,7 +756,44 @@ def test_load_package_info(mocker): } -def test_load_metadata(mocker, user_filesystem): +@pytest.mark.parametrize( + "inputs,expected", + # C1: user corrects data using `mud` command + # expect to include mud value and method + [ + ( + ["mud", ".", "2.5"], + { + "mud": 2.5, + "command": "mud", + }, + ), + # C2: user corrects data using `zscan` command + # expect to include z-scan file and method + ( + ["zscan", ".", "test_dir/testfile.xy"], + { + "z_scan_file": "test_dir/testfile.xy", + "command": "zscan", + "mud": 3.0, + }, + ), + # C3: user corrects data using `sample` command + # expected to include sample composition, + # mass density, diameter, and method + ( + ["sample", ".", "ZrO2", "1.745", "2"], + { + "sample_composition": "ZrO2", + "sample_mass_density": 1.745, + "diameter": 2.0, + "command": "sample", + "mud": 4.3321, + }, + ), + ], +) +def test_load_metadata(mocker, user_filesystem, inputs, expected): # Test if the function loads args # (which will be loaded into the header file). # Expect to include mu*D, anode type, xtype, cve method, @@ -732,12 +809,8 @@ def test_load_metadata(mocker, user_filesystem): "3.3.0" if package_name == "diffpy.utils" else "1.2.3" ), ) - cli_inputs = [ - "applymud", - ".", - "--mud", - "2.5", - "--anode-type", + cli_inputs = inputs + [ + "--wavelength", "Mo", "--user-metadata", "key=value", @@ -748,14 +821,18 @@ def test_load_metadata(mocker, user_filesystem): "--orcid", "cli_orcid", ] - actual_args = get_args(cli_inputs) + actual_args = get_args_cli(cli_inputs) actual_args = preprocessing_args(actual_args) for filepath in actual_args.input_paths: + if "z_scan_file" in expected: + # adjust path to be relative to cwd + expected["z_scan_file"] = str( + (cwd / expected["z_scan_file"]).resolve() + ) actual_metadata = load_metadata(actual_args, filepath) expected_metadata = { - "mud": 2.5, "input_directory": str(filepath), - "anode_type": "Mo", + "wavelength": 0.71073, "output_directory": str(Path.cwd().resolve()), "xtype": "tth", "method": "polynomial_interpolation", @@ -767,6 +844,41 @@ def test_load_metadata(mocker, user_filesystem): "diffpy.labpdfproc": "1.2.3", "diffpy.utils": "3.3.0", }, - "z_scan_file": None, + **expected, } assert actual_metadata == expected_metadata + + +def test_preprocess_args_bad(user_filesystem, monkeypatch): + # Case: user tries to run absorption correction, but the output + # filenames already for *-mud-corrected.chi and *-cve.chi exists. + # expected: preprocess_args catches this early and raises an Error + cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + # set cwd so program can find diffpyconfig.json + monkeypatch.setattr("pathlib.Path.home", lambda _: home_dir) + input_data_file = str(user_filesystem / "good_data.chi") + existing_corrected_file = str( + user_filesystem / "output_dir" / "good_data-mud-corrected.chi" + ) + existing_corrected_cve_file = str( + user_filesystem / "output_dir" / "good_data-cve.chi" + ) + cli_inputs = [ + "mud", + input_data_file, + "2.5", + "-o", + str(user_filesystem / "output_dir"), + "-c", # -c flag saves the cve file + ] + args = get_args_cli(cli_inputs) + args = set_input_lists(args) + msg = ( + "The following output files already exist:" + f"\n{existing_corrected_file}\n" + f"{existing_corrected_cve_file}\n" + "Use --force to overwrite them." + ) + with pytest.raises(FileExistsError, match=re.escape(msg)): + preprocessing_args(args)