diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..a860452 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = pystog/_version.py diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..a4b4285 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,40 @@ +name: pystog_cd + +env: {} + +on: + push: + tags: + - 'v*' + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: true + python-version: 3.7 + channels: conda-forge + + - name: Build Python package and Upload to PyPi + shell: bash -l {0} + env: + PYPI_TOKEN_PASSWORD: ${{ secrets.PYPI_TOKEN }} + run: | + pip install wheel twine + python setup.py sdist bdist_wheel + twine upload --username "__token__" --password $PYPI_TOKEN_PASSWORD dist/* + + - name: Build conda package and upload to Anaconda + shell: bash -l {0} + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }} + run: | + conda install -y anaconda-client conda-build conda-verify + cd conda.recipe + conda build --output-folder . . + anaconda upload --label main noarch/*.tar.bz2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9a8e691 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: pystog_ci + +env: {} + +on: + push: + branches: + - '*' + tags: + - 'v*' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + python-version: ["3.6", "3.7", "3.8", "3.9"] + + steps: + - uses: actions/checkout@v2 + - uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: true + python-version: ${{ matrix.python-version }} + channels: conda-forge + + - name: Conda install deps + shell: bash -l {0} + run: | + conda install --file requirements.txt --file requirements-dev.txt + conda install pip + pip install tox-gh-actions + + - name: Lint and Test with Tox + shell: bash -l {0} + run: tox diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c88c3de..0000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: python -python: - - '3.6' - - '3.7' - - '3.8' - - '3.9' -install: - - pip install -r requirements.txt - - pip install -r requirements-dev.txt - - python setup.py install -script: - - flake8 . --count -after_success: - - codecov -deploy: - skip_cleanup: true - skip_existing: true - provider: pypi - user: mcdonnellmt - password: - secure: pTnhLJiCPr8wTdMgh5yOLenu/rR+Zx8t0a12wqpACS/Oxx5YE1cIiKMOi7LgNFOgcq3m3DvJ2PEwLUVWOPxHmHSCwqFQKfXYahCXf1QcJV834+WoEiACgY4DYVMXQhossCvy3+rPKKV+k5BcHYOJZQul9AE9Dv/k6P4Nifw673dHG5N+ZgjHRY74CwKufPoKYXa+ZyUGYJDa5AOw/QfT2lxLiYwx/Fi4xqPLlPCxaRMQzRUf/WCI1PH6tGDG/8RaWGTe4k9JntJRL8O/h35+WV5mnCBx/xiTOCcHp6NpgKuX+lmiOYGCH0Z5+9N+CcptZgg9GDrXoRYLxVQk5pitwA/m2XP9GVFvqhmeSEtHHrWHPCSI3hJLqcP+RYc9fGiIojo9pqgVPa4fKfnFrwtGLcEyVMqb6FlWPjvhGJUGcbyE2T+9PZFE8DfHUzgVqSv4JRa4GK12JtI/oKyz/m3wHNA98pQiJMsAqcK3zWkKERVRipJHdLl1CJKVpqf+xra3gvgXF6lmpLGaWhiwtPbNvG3IJsufW/q67VmhA9ER5MZw/yyWdU/eGX6p6FNeUdz4aAifgF8LoX5eS/DtiVX6/VFedq+X6Nl95F7nodbHoI9Mnnq/eIj7VnqP/5bWfhWs0kKaHc4ha5exuoyTvPWuRl1s/EsAqKyGxKCfCibh518= - on: - tags: true diff --git a/MANIFEST.in b/MANIFEST.in index 6291010..4f3a0c3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include versioneer.py include pystog/_version.py +include requirements*.txt diff --git a/README.md b/README.md index 86306d3..196d799 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ Total Scattering Function Manipulator: ----------------------------------------------------------- -| Dev | Other | Tutorials | -|-----|-------|------------| -|[![Build Status](https://travis-ci.org/neutrons/pystog.svg?branch=master)](https://travis-ci.org/neutrons/pystog) | [![PyPI version](https://badge.fury.io/py/pystog.svg)](https://badge.fury.io/py/pystog) | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/neutrons/pystog/master?filepath=tutorials) | -| [![codecov](https://codecov.io/gh/neutrons/pystog/branch/master/graph/badge.svg)](https://codecov.io/gh/neutrons/pystog) | [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) | | -|[![Documentation Status](https://readthedocs.org/projects/pystog/badge/?version=latest)](https://pystog.readthedocs.io/en/latest/?badge=latest) | [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) | | +| Health | Release | Other | +|--------|---------|------------| +| [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fneutrons%2Fpystog%2Fbadge%3Fref%3Dmaster&style=plastic)](https://actions-badge.atrox.dev/neutrons/pystog/goto?ref=master) | [![PyPI version](https://badge.fury.io/py/pystog.svg)](https://badge.fury.io/py/pystog) | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/neutrons/pystog/master?filepath=tutorials) | +| [![codecov](https://codecov.io/gh/neutrons/pystog/branch/master/graph/badge.svg)](https://codecov.io/gh/neutrons/pystog) | [![Anaconda-Server Badge](https://anaconda.org/neutrons/pystog/badges/version.svg)](https://anaconda.org/neutrons/pystog)| [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) | +|[![Documentation Status](https://readthedocs.org/projects/pystog/badge/?version=latest)](https://pystog.readthedocs.io/en/latest/?badge=latest) | [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) | | From total scattering functions, we have reciprocal-space structure factors and real-space pair distribution functions that are related via a Fourier transform. PyStoG is a package that allows for: 1. Converting between the various functions used by different "communities" (ie researchers who study crystalline versus amorphous or glass materials). Conversions are for either real-space or reciprocal-space. diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index f9e8115..a5c618c 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -1,4 +1,4 @@ -{% set data = load_setup_py() %} +{% set data = load_setup_py_data() %} package: name: pystog @@ -25,9 +25,6 @@ requirements: test: imports: - pystog - - pystog.converter.Converter - - pystog.transformer.Transformer - - pystog.fourier_filter.FourierFilter about: home: https://github.com/neutrons/pystog diff --git a/pystog/converter.py b/pystog/converter.py index a24c153..3ca5453 100644 --- a/pystog/converter.py +++ b/pystog/converter.py @@ -86,7 +86,8 @@ def F_to_DCS(self, q, fq, dfq=None, **kwargs): :param dfq: uncertainty vector :type dfq: numpy.array or list - :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, uncertainty vector) + :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, + uncertainty vector) :rtype: (numpy.array, numpy.array) """ fq, dfq = self.F_to_FK(q, fq, dfq, **kwargs) @@ -138,7 +139,8 @@ def S_to_DCS(self, q, sq, dsq=None, **kwargs): :param dsq: uncertainty vector :type dsq: numpy.array or list - :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, uncertainty vector) + :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, + uncertainty vector) :rtype: (numpy.array, numpy.array) """ fq, dfq = self.S_to_FK(q, sq, dsq, **kwargs) @@ -189,7 +191,8 @@ def FK_to_DCS(self, q, fq, dfq=None, **kwargs): :param dfq: uncertainty vector :type dfq: numpy.array or list - :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, uncertainty vector) + :return: (:math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector, + uncertainty vector) :rtype: (numpy.array, numpy.array) """ return fq + kwargs[''], dfq diff --git a/pystog/fourier_filter.py b/pystog/fourier_filter.py index 82f62b3..2820057 100644 --- a/pystog/fourier_filter.py +++ b/pystog/fourier_filter.py @@ -53,7 +53,7 @@ def g_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` @@ -62,27 +62,36 @@ def g_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): and the filtered :math:`r` and :math:`g(r)`. Thus, - [:math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, - :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`g(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`Q[S(Q)-1]_{FF}`, + :math:`Q`, + :math:`Q[S(Q)-1]`, + :math:`r_{FF}`, + :math:`g(r)_{FF}` + ] :rtype: tuple of numpy.array """ # setup qmin, qmax, and get low-r region to back transform qmin = min(q) qmax = max(q) - r_tmp, gr_tmp_initial, dgr_tmp_initial = self.transformer.apply_cropping( + r_tmp, gr_tmp_init, dgr_tmp_init = self.transformer.apply_cropping( r, gr, 0.0, cutoff, dy=dgr) # Shift low-r so it goes to 1 at "high-r" for this section. Reduces the # sinc function issue. - gr_tmp = gr_tmp_initial + 1 + gr_tmp = gr_tmp_init + 1 # Transform the shifted low-r region to F(Q) to get F(Q)_ft - q_ft, fq_ft, dfq_ft = self.transformer.g_to_F(r_tmp, gr_tmp, q, dgr=dgr_tmp_initial, - **kwargs) - q_ft, fq_ft, dfq_ft = self.transformer.apply_cropping(q_ft, fq_ft, qmin, qmax, dy=dfq_ft) + q_ft, fq_ft, dfq_ft = self.transformer.g_to_F( + r_tmp, gr_tmp, q, dgr=dgr_tmp_init, **kwargs) + + q_ft, fq_ft, dfq_ft = self.transformer.apply_cropping( + q_ft, fq_ft, qmin, qmax, dy=dfq_ft) # Subtract F(Q)_ft from original F(Q) = delta_F(Q) - q, fq, dfq = self.transformer.apply_cropping(q, fq, qmin, qmax, dy=dfq) + q, fq, dfq = self.transformer.apply_cropping( + q, fq, qmin, qmax, dy=dfq) fq = (fq - fq_ft) dfq = np.sqrt(dfq**2 + dfq_ft**2) @@ -103,7 +112,7 @@ def g_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): :type q: numpy.array or list :param sq: :math:`S(Q)` vector :type sq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` @@ -135,7 +144,7 @@ def g_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` @@ -151,7 +160,8 @@ def g_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - fq_ft, dfq_ft = self.converter.F_to_FK(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + fq_ft, dfq_ft = self.converter.F_to_FK( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr @@ -168,7 +178,7 @@ def g_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and @@ -187,7 +197,8 @@ def g_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - dcs_ft, ddcs_ft = self.converter.F_to_DCS(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + dcs_ft, ddcs_ft = self.converter.F_to_DCS( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q_ft, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr @@ -204,7 +215,7 @@ def G_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` @@ -213,8 +224,14 @@ def G_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, - [:math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, - :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`Q[S(Q)-1]_{FF}`, + :math:`Q`, + :math:`Q[S(Q)-1]`, + :math:`r_{FF}`, + :math:`G_{PDFFIT}(r)_{FF}` + ] :rtype: tuple of numpy.array """ gr, dgr = self.converter.G_to_g(r, gr, dgr=dgr, **kwargs) @@ -235,7 +252,7 @@ def G_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`S(Q)` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` @@ -244,8 +261,14 @@ def G_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, - [:math:`Q_{FF}`, :math:`S(Q)_{FF}`, - :math:`Q`, :math:`S(Q)`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`S(Q)_{FF}`, + :math:`Q`, + :math:`S(Q)`, + :math:`r_{FF}`, + :math:`G_{PDFFIT}(r)_{FF}` + ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.S_to_F(q, sq, dsq=dsq) @@ -267,7 +290,7 @@ def G_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` @@ -276,14 +299,21 @@ def G_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, - [:math:`Q_{FF}`, :math:`F(Q)_{FF}`, - :math:`Q`, :math:`F(Q)`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`F(Q)_{FF}`, + :math:`Q`, + :math:`F(Q)`, + :math:`r_{FF}`, + :math:`G_{PDFFIT}(r)_{FF}` + ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.G_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - fq_ft, dfq_ft = self.converter.F_to_FK(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + fq_ft, dfq_ft = self.converter.F_to_FK( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr @@ -300,7 +330,7 @@ def G_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and @@ -319,7 +349,8 @@ def G_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.G_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - dcs_ft, ddcs_ft = self.converter.F_to_DCS(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + dcs_ft, ddcs_ft = self.converter.F_to_DCS( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr @@ -336,7 +367,7 @@ def GK_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` @@ -345,8 +376,14 @@ def GK_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, - [:math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, - :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`Q[S(Q)-1]_{FF}`, + :math:`Q`, + :math:`Q[S(Q)-1]`, + :math:`r_{FF}`, + :math:`G_{Keen Version}(r)_{FF}` + ] :rtype: tuple of numpy.array """ @@ -368,7 +405,7 @@ def GK_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`S(Q)` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` @@ -377,8 +414,14 @@ def GK_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, - [:math:`Q_{FF}`, :math:`S(Q)_{FF}`, - :math:`Q`, :math:`S(Q)`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`S(Q)_{FF}`, + :math:`Q`, + :math:`S(Q)`, + :math:`r_{FF}`, + :math:`G_{Keen Version}(r)_{FF}` + ] :rtype: tuple of numpy.array """ @@ -401,7 +444,7 @@ def GK_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` @@ -410,19 +453,27 @@ def GK_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, - [:math:`Q_{FF}`, :math:`F(Q)_{FF}`, - :math:`Q`, :math:`F(Q)`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}]` + [ + :math:`Q_{FF}`, + :math:`F(Q)_{FF}`, + :math:`Q`, + :math:`F(Q)`, + :math:`r_{FF}`, + :math:`G_{Keen Version}(r)_{FF}` + ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.GK_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - fq_ft, dfq_ft = self.converter.F_to_FK(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + fq_ft, dfq_ft = self.converter.F_to_FK( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr - def GK_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): + def GK_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, + **kwargs): """Fourier filters real space :math:`G_{Keen Version}(r)` using the reciprocal space :math:`\\frac{d \\sigma}{d \\Omega}(Q)` @@ -435,7 +486,7 @@ def GK_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list - :param cutoff: The :math:`r_{max}` value to filter from 0. to this cutoff + :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and @@ -454,6 +505,7 @@ def GK_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.GK_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) - dcs_ft, ddcs_ft = self.converter.F_to_DCS(q_ft, fq_ft, dfq=dfq_ft, **kwargs) + dcs_ft, ddcs_ft = self.converter.F_to_DCS( + q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr diff --git a/pystog/stog.py b/pystog/stog.py index 1d999dc..255cf88 100644 --- a/pystog/stog.py +++ b/pystog/stog.py @@ -285,7 +285,8 @@ def rdelta(self): """The :math:`\\Delta r` for the :math:`r`-space vector :getter: Return :math:`\\Delta r` value - :setter: Set the :math:`\\Delta r` value and update :math:`r`-space vector + :setter: Set the :math:`\\Delta r` value + and update :math:`r`-space vector via the **dr** attribute :type: value """ @@ -365,7 +366,8 @@ def bcoh_sqrd(self): where the subscript :math:`i` implies for atom type :math:`i`, :math:`c_{i}` is the concentration of :math:`i`, :math:`b_{coh,i}` is the coherent scattering length of :math:`i`, - and :math:`b^*_{coh,i}` is the complex coherent scattering length of :math:`i` + and :math:`b^*_{coh,i}` + is the complex coherent scattering length of :math:`i` The real part of the :math:`b_{coh,i}` term can be found @@ -461,7 +463,8 @@ def lorch_flag(self): """This sets the option to perform the Lorch dampening correction for the :math:`Q` range. Generally, will help reduce Fourier "ripples", or AKA "Gibbs phenomenon", due to discontinuity at :math:`Q_{max}` - if the reciprocal space function is not at the :math:`Q -> \\infty` limit. + if the reciprocal space function is not at the + :math:`Q -> \\infty` limit. Yet, will also broaden real space function peaks, possibly dubiously. See :class:`pystog.transformer.Transformer` **fourier_transform** and @@ -521,8 +524,8 @@ def merged_opts(self, options): @property def df_individuals(self): """The DataFrame for the input reciprocal space functions - loaded from **files** and with the loading processing from **add_dataset** - class method. + loaded from **files** and with the loading processing + from **add_dataset** class method. :getter: Returns the current individual, input reciprocal space functions DataFrame @@ -763,7 +766,8 @@ def read_all_data(self, **kwargs): Will append all datasets as DataFrames to the **df_inviduals** attribute DataFrame and also convert to :math:`S(Q)` and add to the **df_sq_individuals** - attribute DataFrame in **add_dataset** method via **read_dataset** method. + attribute DataFrame in **add_dataset** method + via **read_dataset** method. """ assert self.files is not None assert len(self.files) != 0 @@ -788,7 +792,8 @@ def read_dataset( and also convert to :math:`S(Q)` and add to the **df_sq_individuals** attribute DataFrame in **add_dataset** method. - :param info: Dict with information for dataset (filename, manipulations, etc.) + :param info: Dict with information for dataset + (filename, manipulations, etc.) :type info: dict :param xcol: The column in the data file that contains the X-axis :type xcol: int @@ -828,13 +833,16 @@ def add_dataset( and also convert to :math:`S(Q)` and add to the **df_sq_individuals** attribute DataFrame. - :param info: Dict with information for dataset (filename, manipulations, etc.) + :param info: Dict with information for dataset + (filename, manipulations, etc.) :type info: dict :param index: Index of the added reciprocal space function dataset :type index: int - :param yscale: Scale factor for the Y data (i.e. :math:`S(Q)`, :math:`F(Q)`, etc.) + :param yscale: Scale factor for the Y data + (i.e. :math:`S(Q)`, :math:`F(Q)`, etc.) :type yscale: float - :param yoffset: Offset factor for the Y data (i.e. :math:`S(Q)`, :math:`F(Q)`, etc.) + :param yoffset: Offset factor for the Y data + (i.e. :math:`S(Q)`, :math:`F(Q)`, etc.) :type yoffset: float :param xoffset: Offset factor for the X data (i.e. :math:`Q`) :type yoffset: float @@ -889,9 +897,11 @@ def add_dataset( info["ReciprocalFunction"] = "S(Q)" if info["ReciprocalFunction"] not in ReciprocalSpaceChoices: - error = "ReciprocalFunction was equal to %s.\n" % info["ReciprocalFunction"] - error += "ReciprocalFunction must be one of the folloing %s" % json.dumps( - ReciprocalSpaceChoices) + error = "ReciprocalFunction was equal to {given}.\n" + error += "ReciprocalFunction must be one of the folloing {options}" + error = error.format( + given=info["ReciprocalFunction"], + options=json.dumps(ReciprocalSpaceChoices)) raise ValueError(error) # Save reciprocal space function to the "invididuals" DataFrame @@ -905,7 +915,8 @@ def add_dataset( if info["ReciprocalFunction"] == "Q[S(Q)-1]": y, dy = self.converter.F_to_S(x, y) elif info["ReciprocalFunction"] == "FK(Q)": - y, dy = self.converter.FK_to_S(x, y, **{'^2': self.bcoh_sqrd}) + y, dy = self.converter.FK_to_S( + x, y, **{'^2': self.bcoh_sqrd}) elif info["ReciprocalFunction"] == "DCS(Q)": y, dy = self.converter.DCS_to_S(x, y, **{'^2': self.bcoh_sqrd, @@ -1072,8 +1083,10 @@ def fourier_filter(self): 3. (optional) Plotted for diagnostics 4. Returned from function - :return: Returns a tuple with :math:`r`, the selected real space function, - :math:`Q`, and :math:`S(Q)` functions + :return: Returns a tuple with :math:`r`, + the selected real space function, + :math:`Q`, + and :math:`S(Q)` functions :rtype: tuple of numpy.array """ kwargs = {'lorch': False, @@ -1085,7 +1098,10 @@ def fourier_filter(self): # Get reciprocal and real space data if self.gr_title not in self.df_gr_master.columns: - print("WARNING: Fourier filtered before initial transform. Peforming now...") + msg = ( + "WARNING: Fourier filtered before initial transform. " + "Peforming now...") + print(msg) self.transform_merged() r = self.df_gr_master[self.gr_title].index.values @@ -1168,10 +1184,16 @@ def apply_lorch(self, q, sq, r): r, gr_lorch, _ = self.transformer.S_to_g( q, sq, r, **{'lorch': True, 'rho': self.density}) elif self.real_space_function == "G(r)": - r, gr_lorch, _ = self.transformer.S_to_G(q, sq, r, **{'lorch': True}) + r, gr_lorch, _ = self.transformer.S_to_G( + q, sq, r, **{'lorch': True}) elif self.real_space_function == "GK(r)": r, gr_lorch, _ = self.transformer.S_to_GK( - q, sq, r, **{'lorch': True, 'rho': self.density, '^2': self.bcoh_sqrd}) + q, sq, r, + **{ + 'lorch': True, + 'rho': self.density, + '^2': self.bcoh_sqrd + }) self.df_gr_master = self.add_to_dataframe( r, gr_lorch, self.df_gr_master, self.gr_lorch_title) @@ -1389,7 +1411,8 @@ def plot_summary_sq(self): def plot_summary_gr(self): """Helper function to multiplot the real space - functions during processing and the :math:`G_{Keen Version}(Q)` function. + functions during processing + and the :math:`G_{Keen Version}(Q)` function. """ if self.GKofR_title not in self.df_gr_master.columns: r = self.df_gr_master[self.gr_title].index.values diff --git a/pystog/transformer.py b/pystog/transformer.py index 23667fa..78412ad 100644 --- a/pystog/transformer.py +++ b/pystog/transformer.py @@ -149,7 +149,8 @@ def fourier_transform(self, :type xmax: float :param dyin: uncertainty vector for yin :type dyin: numpy.array or list - :return: vector pair of transformed domain, range vectors, and uncertainties + :return: vector pair of transformed domain, range vectors, + and uncertainties :rtype: numpy.array, numpy.array, numpy.array """ @@ -496,7 +497,8 @@ def G_to_DCS(self, r, gr, q, dgr=None, **kwargs): :param dgr: :math:`G_{PDFFIT}(r)` uncertainties :type dgr: numpy.array or list - :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and uncertainties + :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, + and uncertainties :rtype: numpy.array, numpy.array, numpy.array """ q, fq, dfq = self.G_to_F(r, gr, q, dgr=dgr, **kwargs) @@ -574,7 +576,8 @@ def GK_to_DCS(self, r, gr, q, dgr=None, **kwargs): :param dgr: :math:`G_{Keen Version}(r)` uncertainties :type dgr: numpy.array or list - :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and uncertainties + :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, + and uncertainties :rtype: numpy.array, numpy.array, numpy.array """ _gr, _dgr = self.converter.GK_to_G(r, gr, dgr=dgr, **kwargs) @@ -651,7 +654,8 @@ def g_to_DCS(self, r, gr, q, dgr=None, **kwargs): :param dgr: :math:`g(r)` uncertainties :type dgr: numpy.array or list - :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and uncertainties + :return: :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, + and uncertainties :rtype: numpy.array, numpy.array, numpy.array """ _gr, _dgr = self.converter.g_to_G(r, gr, dgr=dgr, **kwargs) diff --git a/requirements-dev.txt b/requirements-dev.txt index a594f94..a2d9d2b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,4 @@ mock pytest flake8 +tox diff --git a/setup.cfg b/setup.cfg index e2fb9cd..722a320 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [flake8] -max-line-length = 100 +max-line-length = 80 exclude = .git,.eggs,ENV,./versioneer.py,pystog/_version.py # See the docstring in versioneer.py for instructions. Note that you must diff --git a/setup.py b/setup.py index 2399708..6041009 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ def read_requirements_from_file(filepath): author=",".join(authors), author_email="mcdonnellmt@ornl.gov", url="https://github.com/neutrons/pystog", - description="Transforms reciprocal and real space total scattering functions", + description="Manipulate total scattering functions", long_description_content_type="text/markdown", license="GPL License (version 3)", packages=setuptools.find_packages(exclude=["fortran"]), diff --git a/tests/test_fourier_filter.py b/tests/test_fourier_filter.py index 9b929db..55ff71a 100644 --- a/tests/test_fourier_filter.py +++ b/tests/test_fourier_filter.py @@ -142,7 +142,12 @@ def GK_using_S(self): def GK_using_FK(self): q_ft, fq_ft, q, fq, r, gr, _, _, _ = self.ff.GK_using_FK( - self.r, self.GKofR, self.q, self.fq_keen, self.cutoff, **self.kwargs) + self.r, + self.GKofR, + self.q, + self.fq_keen, + self.cutoff, + **self.kwargs) first, last = self.real_space_first, self.real_space_last assert_allclose(gr[first:last], self.GKofR_ff_target, diff --git a/tests/test_stog.py b/tests/test_stog.py index 4883be9..afb86ff 100644 --- a/tests/test_stog.py +++ b/tests/test_stog.py @@ -85,22 +85,31 @@ def setUp(self): filename = self.material.reciprocal_space_filename self.kwargs_for_files = { 'Files': [ - {'Filename': get_data_path(filename), - 'ReciprocalFunction': 'S(Q)', - 'Qmin': 0.02, - 'Qmax': 15.0, - 'Y': {'Offset': 0.0, - 'Scale': 1.0}, - 'X': {'Offset': 0.0} - }, - {'Filename': get_data_path(self.material.reciprocal_space_filename), - 'ReciprocalFunction': 'S(Q)', - 'Qmin': 1.90, - 'Qmax': 35.2, - 'Y': {'Offset': 0.0, - 'Scale': 1.0}, - 'X': {'Offset': 0.0} - } + { + 'Filename': get_data_path(filename), + 'ReciprocalFunction': 'S(Q)', + 'Qmin': 0.02, + 'Qmax': 15.0, + 'Y': { + 'Offset': 0.0, + 'Scale': 1.0 + }, + 'X': { + 'Offset': 0.0 + } + }, + { + 'Filename': + get_data_path(self.material.reciprocal_space_filename), + 'ReciprocalFunction': 'S(Q)', + 'Qmin': 1.90, + 'Qmax': 35.2, + 'Y': { + 'Offset': 0.0, + 'Scale': 1.0}, + 'X': { + 'Offset': 0.0} + } ] } @@ -324,11 +333,12 @@ def test_stog_real_space_function_setter(self): def test_stog_plotting_kwargs_setter(self): stog = StoG() - new_kwargs = {'figsize': (4, 4), - 'style': 'o', - 'ms': 2, - 'lw': 2, - } + new_kwargs = { + 'figsize': (4, 4), + 'style': 'o', + 'ms': 2, + 'lw': 2, + } stog.plotting_kwargs = new_kwargs self.assertEqual(stog.plotting_kwargs, new_kwargs) @@ -412,90 +422,110 @@ def test_stog_add_dataset(self): # Add the S(Q) data set and check values against targets index = 0 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.sq}), - 'ReciprocalFunction': 'S(Q)'} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.sq}), + 'ReciprocalFunction': 'S(Q)'} stog.add_dataset(info, index=index) self.assertEqual( stog.df_individuals.iloc[self.first].name, self.reciprocal_xtarget) - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) # Add the Q[S(Q)-1] data set and check values for it and S(Q) against # targets index = 1 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.fq}), - 'ReciprocalFunction': 'Q[S(Q)-1]'} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.fq}), + 'ReciprocalFunction': 'Q[S(Q)-1]' + } stog.add_dataset(info, index=index) - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['Q[S(Q)-1]_%d' % index], - self.fq_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['Q[S(Q)-1]_%d' % index], + self.fq_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) # Add the FK(Q) data set and check values for it and S(Q) against # targets index = 2 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.fq_keen}), - 'ReciprocalFunction': 'FK(Q)'} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.fq_keen}), + 'ReciprocalFunction': 'FK(Q)'} stog.add_dataset(info, index=index) - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['FK(Q)_%d' % index], - self.fq_keen_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['FK(Q)_%d' % index], + self.fq_keen_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) # Add the DCS(Q) data set and check values for it and S(Q) against # targets index = 3 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.dcs}), - 'ReciprocalFunction': 'DCS(Q)'} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.dcs}), + 'ReciprocalFunction': 'DCS(Q)'} stog.add_dataset(info, index=index) - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['DCS(Q)_%d' % index], - self.dcs_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['DCS(Q)_%d' % index], + self.dcs_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) def test_stog_add_dataset_yscale(self): # Scale S(Q) and make sure it does not equal original target values stog = StoG() index = 0 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.sq}), - 'ReciprocalFunction': 'S(Q)', - 'Y': {'Scale': 2.0}} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.sq}), + 'ReciprocalFunction': 'S(Q)', + 'Y': {'Scale': 2.0}} stog.add_dataset(info, index=index) - self.assertNotEqual(stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0]) - self.assertNotEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0]) + self.assertNotEqual( + stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0]) + self.assertNotEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0]) def test_stog_add_dataset_yoffset(self): # Offset S(Q) and make sure it does not equal original target values stog = StoG() index = 0 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.sq}), - 'ReciprocalFunction': 'S(Q)', - 'Y': {'Offset': 2.0}} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.sq}), + 'ReciprocalFunction': 'S(Q)', + 'Y': {'Offset': 2.0}} stog.add_dataset(info, index=index) - self.assertNotEqual(stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0]) - self.assertNotEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0]) + self.assertNotEqual( + stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0]) + self.assertNotEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0]) def test_stog_add_dataset_xoffset(self): # Offset Q from 1.96 -> 2.14 stog = StoG() index = 0 - info = {'data': pd.DataFrame({'x': self.q, 'y': self.sq}), - 'ReciprocalFunction': 'S(Q)', - 'X': {'Offset': 0.2}} + info = { + 'data': pd.DataFrame({'x': self.q, 'y': self.sq}), + 'ReciprocalFunction': 'S(Q)', + 'X': {'Offset': 0.2}} stog.add_dataset(info, index=index) self.assertEqual(stog.df_individuals.iloc[self.first].name, 2.14) @@ -558,12 +588,14 @@ def test_stog_read_dataset(self): # Check S(Q) data against targets self.assertEqual( stog.df_individuals.iloc[self.first].name, self.reciprocal_xtarget) - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['S(Q)_%d' % info['index']], - self.sq_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % info['index']], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['S(Q)_%d' % info['index']], + self.sq_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % info['index']], + self.sq_target[0], + places=places) def test_stog_read_all_data_assertion(self): stog = StoG() @@ -581,7 +613,9 @@ def test_stog_read_all_data_for_files_length(self): stog.read_all_data() # Check S(Q) data against targets - self.assertEqual(len(stog.files), len(self.kwargs_for_files['Files'])) + self.assertEqual( + len(stog.files), + len(self.kwargs_for_files['Files'])) def test_stog_read_all_data(self): # Number of decimal places for precision @@ -596,12 +630,14 @@ def test_stog_read_all_data(self): self.assertEqual( stog.df_individuals.iloc[self.first].name, self.reciprocal_xtarget) for index in range(len(stog.files)): - self.assertAlmostEqual(stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) - self.assertAlmostEqual(stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) + self.assertAlmostEqual( + stog.df_sq_individuals.iloc[self.first]['S(Q)_%d' % index], + self.sq_target[0], + places=places) def test_stog_merge_data(self): # Number of decimal places for precision @@ -616,9 +652,10 @@ def test_stog_merge_data(self): # Check S(Q) data against targets self.assertEqual( stog.df_sq_master.iloc[self.first].name, self.reciprocal_xtarget) - self.assertAlmostEqual(stog.df_sq_master.iloc[self.first][stog.sq_title], - self.sq_target[0], - places=places) + self.assertAlmostEqual( + stog.df_sq_master.iloc[self.first][stog.sq_title], + self.sq_target[0], + places=places) def test_stog_merge_data_qsq_opts_scale(self): # Number of decimal places for precision @@ -674,24 +711,28 @@ def test_stog_transform_merged_default(self): stog.transform_merged() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], - self.gofr_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], + self.gofr_target[0], + places=places) # Test if no dr defined stog.dr = None stog.transform_merged() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], - self.gofr_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], + self.gofr_target[0], + places=places) def test_stog_transform_merged_GofR(self): # Number of decimal places for precision @@ -706,12 +747,14 @@ def test_stog_transform_merged_GofR(self): stog.transform_merged() # Check G(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], - self.GofR_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], + self.GofR_target[0], + places=places) def test_stog_transform_merged_GKofR(self): # Number of decimal places for precision @@ -726,12 +769,14 @@ def test_stog_transform_merged_GKofR(self): stog.transform_merged() # Check GK(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], - self.GKofR_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_title], + self.GKofR_target[0], + places=places) def test_stog_transform_merged_for_nan_after_filter(self): # Load S(Q) for Argon from test data @@ -761,12 +806,14 @@ def test_stog_fourier_filter(self): stog.fourier_filter() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], - self.gofr_ff_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], + self.gofr_ff_target[0], + places=places) def test_stog_fourier_filter_before_transform_merged_call(self): # Number of decimal places for precision @@ -781,12 +828,14 @@ def test_stog_fourier_filter_before_transform_merged_call(self): stog.fourier_filter() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], - self.gofr_ff_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], + self.gofr_ff_target[0], + places=places) def test_stog_fourier_filter_GofR(self): # Number of decimal places for precision @@ -803,12 +852,14 @@ def test_stog_fourier_filter_GofR(self): stog.fourier_filter() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], - self.GofR_ff_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], + self.GofR_ff_target[0], + places=places) def test_stog_fourier_filter_GKofR(self): # Number of decimal places for precision @@ -825,12 +876,14 @@ def test_stog_fourier_filter_GKofR(self): stog.fourier_filter() # Check g(r) data against targets - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first].name, - self.real_xtarget, - places=places) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], - self.GKofR_ff_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first].name, + self.real_xtarget, + places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_ft_title], + self.GKofR_ff_target[0], + places=places) @patch("matplotlib.pyplot.show") def test_stog_fourier_filter_with_plot_flag(self, mock_show): @@ -877,9 +930,10 @@ def test_stog_apply_lorch_default(self): q, sq, r, gr = stog.fourier_filter() stog.apply_lorch(q, sq, r) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_lorch_title], - self.gofr_lorch_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_lorch_title], + self.gofr_lorch_target[0], + places=places) def test_stog_apply_lorch_GofR(self): # Number of decimal places for precision @@ -896,9 +950,10 @@ def test_stog_apply_lorch_GofR(self): q, sq, r, gr = stog.fourier_filter() stog.apply_lorch(q, sq, r) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][stog.gr_lorch_title], - self.GofR_lorch_target[0], - places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_lorch_title], + self.GofR_lorch_target[0], + places=places) def test_stog_apply_lorch_GKofR(self): # Number of decimal places for precision @@ -915,8 +970,9 @@ def test_stog_apply_lorch_GKofR(self): q, sq, r, gr = stog.fourier_filter() stog.apply_lorch(q, sq, r) - self.assertAlmostEqual(stog.df_gr_master.iloc[self.real_space_first][ - stog.gr_lorch_title], self.GKofR_lorch_target[0], places=places) + self.assertAlmostEqual( + stog.df_gr_master.iloc[self.real_space_first][stog.gr_lorch_title], + self.GKofR_lorch_target[0], places=places) @patch("matplotlib.pyplot.show") def test_stog_apply_lorch_with_plot_flag(self, mock_show): diff --git a/tox.ini b/tox.ini index bcab86d..3e94b65 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,17 @@ [tox] -envlist = py27,py35,py36,py37,lint,coverage +envlist = py36,py37,py38,py39,lint,coverage -[travis] +[gh-actions] python = - 2.7: py27 - 3.5: py35 - 3.6: py36, lint, pylint, test - 3.7: py37 + 3.6: py36 + 3.7: py36, lint, coverage + 3.8: py38 + 3.9: py39 [testenv] deps = -rrequirements.txt + -rrequirements-dev.txt commands = pytest @@ -19,8 +20,9 @@ deps = flake8 commands = flake8 --ignore=E402 --max-line-length=100 pystog/ flake8 --ignore=E402 --max-line-length=100 tests/ + flake8 --ignore=E402 --max-line-length=100 setup.py [testenv:coverage] -deps = codecov -commands = coverage python setup.py test +deps = pytest-cov +commands = pytest --cov=pystog --cov-report=term-missing tests/