From ccca75fc7b491c9fa57646cde185e2810c8fcdaa Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Wed, 22 Feb 2023 13:29:59 +0100 Subject: [PATCH 001/226] Added support for _H-M_ref space group keyword --- src/diffpy/structure/parsers/p_cif.py | 1 + src/diffpy/structure/tests/testp_cif.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 32c101bf..f0d2bc08 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -472,6 +472,7 @@ def _parse_space_group_symop_operation_xyz(self, block): sg_nameHall = (block.get('_space_group_name_Hall', '') or block.get('_symmetry_space_group_name_Hall', '')) sg_nameHM = (block.get('_space_group_name_H-M_alt', '') or + block.get('_space_group_name_H-M_ref', '') or block.get('_symmetry_space_group_name_H-M', '')) self.cif_sgname = (sg_nameHall or sg_nameHM or None) sgid = (block.get('_space_group_IT_number', '') or diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/testp_cif.py index 9adf088d..b6eb66c7 100644 --- a/src/diffpy/structure/tests/testp_cif.py +++ b/src/diffpy/structure/tests/testp_cif.py @@ -71,6 +71,7 @@ class TestP_cif(unittest.TestCase): graphiteciffile = datafile('graphite.cif') cdsebulkpdffitfile = datafile('CdSe_bulk.stru') teiciffile = datafile('TeI.cif') + refciffile = datafile('Ni_ref.cif') places = 6 @@ -334,6 +335,14 @@ def test_spacegroup_anisotropy(self): self.assertTrue(all(stru.anisotropy)) return + def test_spacegroup_ref(self): + "verify space group reference" + pfile = self.pfile + pfile.parseFile(self.refciffile) + sg = pfile.spacegroup + self.assertEqual('Fm-3m', sg.short_name) + + return def test_adp_type_ani(self): "verify adp type override to anisotropic" From 48d187d19b6681479c0afbdf5b6c2644f52ae9fe Mon Sep 17 00:00:00 2001 From: Piotr Rozyczko Date: Wed, 22 Feb 2023 13:31:53 +0100 Subject: [PATCH 002/226] Added test file --- .../structure/tests/testdata/Ni_ref.cif | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/diffpy/structure/tests/testdata/Ni_ref.cif diff --git a/src/diffpy/structure/tests/testdata/Ni_ref.cif b/src/diffpy/structure/tests/testdata/Ni_ref.cif new file mode 100644 index 00000000..82232f42 --- /dev/null +++ b/src/diffpy/structure/tests/testdata/Ni_ref.cif @@ -0,0 +1,21 @@ +data_2102245 +_cell_length_a 3.562 +_cell_length_b 3.562 +_cell_length_c 3.562 +_cell_angle_alpha 90.00000000 +_cell_angle_beta 90.00000000 +_cell_angle_gamma 90.00000000 +_space_group_name_H-M_ref 'F m -3 m' + + +loop_ +_atom_site_label +_atom_site_type_symbol +_atom_site_fract_x +_atom_site_fract_y +_atom_site_fract_z +_atom_site_occupancy +_atom_site_adp_type +_atom_site_U_iso_or_equiv +Ni Ni 0.00000000 0.00000000 0.00000000 1.00000000 Uiso 0.025 + From 186b7feb6c226edd82eb27d0b2a4e3b09b231c51 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 02:40:20 -0400 Subject: [PATCH 003/226] add untracked files --- .flake8 | 11 + .github/workflows/docs.yml | 43 +++ .github/workflows/main.yml | 54 ++++ .github/workflows/pre-commit.yml | 19 ++ .isort.cfg | 4 + .pre-commit-config.yaml | 43 +++ AUTHORS.rst | 10 + CHANGELOG.rst | 5 + CODE_OF_CONDUCT.rst | 133 ++++++++ LICENSE.rst | 30 ++ doc/Makefile | 194 ++++++++++++ doc/make.bat | 36 +++ doc/source/_static/.placeholder | 0 .../api/diffpy.structure.example_package.rst | 31 ++ doc/source/api/diffpy.structure.rst | 30 ++ doc/source/conf.py | 289 ++++++++++++++++++ doc/source/diffpy.structure.apps.rst | 30 ++ doc/source/diffpy.structure.expansion.rst | 38 +++ doc/source/diffpy.structure.parsers.rst | 94 ++++++ doc/source/index.rst | 44 +++ doc/source/license.rst | 39 +++ doc/source/mod_atom.rst | 7 + doc/source/mod_lattice.rst | 7 + doc/source/mod_spacegroup.rst | 7 + doc/source/package.rst | 130 ++++++++ doc/source/release.rst | 5 + news/TEMPLATE.rst | 23 ++ pyproject.toml | 72 +++++ requirements/README.txt | 11 + requirements/build.txt | 2 + requirements/docs.txt | 4 + requirements/pip.txt | 0 requirements/run.txt | 0 requirements/test.txt | 5 + src/diffpy/structure/tests/conftest.py | 19 ++ 35 files changed, 1469 insertions(+) create mode 100644 .flake8 create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .isort.cfg create mode 100644 .pre-commit-config.yaml create mode 100644 AUTHORS.rst create mode 100644 CHANGELOG.rst create mode 100644 CODE_OF_CONDUCT.rst create mode 100644 LICENSE.rst create mode 100644 doc/Makefile create mode 100644 doc/make.bat create mode 100644 doc/source/_static/.placeholder create mode 100644 doc/source/api/diffpy.structure.example_package.rst create mode 100644 doc/source/api/diffpy.structure.rst create mode 100644 doc/source/conf.py create mode 100644 doc/source/diffpy.structure.apps.rst create mode 100644 doc/source/diffpy.structure.expansion.rst create mode 100644 doc/source/diffpy.structure.parsers.rst create mode 100644 doc/source/index.rst create mode 100644 doc/source/license.rst create mode 100644 doc/source/mod_atom.rst create mode 100644 doc/source/mod_lattice.rst create mode 100644 doc/source/mod_spacegroup.rst create mode 100644 doc/source/package.rst create mode 100644 doc/source/release.rst create mode 100644 news/TEMPLATE.rst create mode 100644 pyproject.toml create mode 100644 requirements/README.txt create mode 100644 requirements/build.txt create mode 100644 requirements/docs.txt create mode 100644 requirements/pip.txt create mode 100644 requirements/run.txt create mode 100644 requirements/test.txt create mode 100644 src/diffpy/structure/tests/conftest.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..2d2cb168 --- /dev/null +++ b/.flake8 @@ -0,0 +1,11 @@ +[flake8] +exclude = + .git, + __pycache__, + build, + dist, + doc/source/conf.py +max-line-length = 115 +# 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 +extend-ignore = E203 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..a4661f5c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,43 @@ +name: Build Documentation + +on: + push: + branches: + - main + release: + +jobs: + test: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: build + auto-update-conda: true + + - name: install requirements + run: >- + conda install -n build -c conda-forge + --file requirements/build.txt + --file requirements/run.txt + --file requirements/docs.txt + --quiet --yes + + - name: install the package + run: python -m pip install . --no-deps + + - name: build documents + run: make -C doc html + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./doc/build/html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..c0551e76 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,54 @@ +name: CI + +on: + push: + branches: + - main + - CI + pull_request: + workflow_dispatch: + +jobs: + miniconda: + name: Miniconda ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: ["ubuntu-latest"] + steps: + - name: check out diffpy.structure + uses: actions/checkout@v3 + with: + repository: diffpy/diffpy.structure + path: . + fetch-depth: 0 # avoid shallow clone with no tags + + - name: initialize miniconda + # this uses a marketplace action that sets up miniconda in a way that makes + # it easier to use. I tried setting it up without this and it was a pain + uses: conda-incubator/setup-miniconda@v2 + with: + activate-environment: test + # environment.yml file is needed by this action. Because I don't want + # maintain this but rather maintain the requirements files it just has + # basic things in it like conda and pip + environment-file: ./environment.yml + python-version: 3 + auto-activate-base: false + + - name: install diffpy.structure requirements + shell: bash -l {0} + run: | + conda config --set always_yes yes --set changeps1 no + conda config --add channels conda-forge + conda activate test + conda install --file requirements/run.txt + conda install --file requirements/test.txt + pip install . + - name: Validate diffpy.structure + shell: bash -l {0} + run: | + conda activate test + coverage run -m pytest -vv -s + coverage report -m + codecov diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000..f2ff7e42 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,19 @@ +name: pre-commit + +on: + pull_request: + push: + workflow_dispatch: + +jobs: + pre-commit: + # pull requests are a duplicate of a branch push if within the same repo. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - uses: pre-commit/action@v3.0.0 + with: + extra_args: --all-files diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..e0926f42 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,4 @@ +[settings] +line_length = 115 +multi_line_output = 3 +include_trailing_comma = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..c4588061 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +default_language_version: + python: python3 +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit hooks + autofix_prs: true + autoupdate_branch: 'pre-commit-autoupdate' + autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' + autoupdate_schedule: monthly + skip: [no-commit-to-branch] + submodules: false +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + exclude: '\.(rst|txt)$' + - repo: https://github.com/psf/black + rev: 24.4.2 + hooks: + - id: black + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black"] + - repo: https://github.com/kynan/nbstripout + rev: 0.7.1 + hooks: + - id: nbstripout + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: no-commit-to-branch + name: Prevent Commit to Main Branch + args: ["--branch", "main"] + stages: [pre-commit] diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 00000000..7f4c6d8e --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,10 @@ +Authors +======= + +Billinge Group and community contibutors. + +Contributors +------------ + +For a list of contributors, visit +https://github.com/diffpy/diffpy.structure/graphs/contributors diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 00000000..26694512 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,5 @@ +============= +Release Notes +============= + +.. current developments diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..ff9c3561 --- /dev/null +++ b/CODE_OF_CONDUCT.rst @@ -0,0 +1,133 @@ +===================================== + Contributor Covenant Code of Conduct +===================================== + +Our Pledge +---------- + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +Our Standards +------------- + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Enforcement Responsibilities +---------------------------- + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +Scope +----- + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +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. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +Enforcement Guidelines +---------------------- + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +1. Correction +**************** + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +2. Warning +************* + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +3. Temporary Ban +****************** + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +4. Permanent Ban +****************** + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +Attribution +----------- + +This Code of Conduct is adapted from the `Contributor Covenant `_. + +Community Impact Guidelines were inspired by `Mozilla's code of conduct enforcement ladder `_. + +For answers to common questions about this code of conduct, see the `FAQ `_. `Translations are available `_ diff --git a/LICENSE.rst b/LICENSE.rst new file mode 100644 index 00000000..95a04ac9 --- /dev/null +++ b/LICENSE.rst @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2024, The Trustees of Columbia University +in the City of New York. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 00000000..fe03b556 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,194 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build +BASENAME = $(subst .,,$(subst $() $(),,diffpy.structure)) + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/$(BASENAME).qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/$(BASENAME).qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/$(BASENAME)" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/$(BASENAME)" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +# Manual publishing to the gh-pages branch + +GITREPOPATH = $(shell cd $(CURDIR) && git rev-parse --git-dir) +GITREMOTE = origin +GITREMOTEURL = $(shell git config --get remote.$(GITREMOTE).url) +GITLASTCOMMIT = $(shell git rev-parse --short HEAD) + +publish: + @test -d build/html || \ + ( echo >&2 "Run 'make html' first!"; false ) + git show-ref --verify --quiet refs/heads/gh-pages || \ + git branch --track gh-pages $(GITREMOTE)/gh-pages + test -d build/gh-pages || \ + git clone -s -b gh-pages $(GITREPOPATH) build/gh-pages + cd build/gh-pages && \ + git pull $(GITREMOTEURL) gh-pages + rsync -acv --delete --exclude=.git --exclude=.rsync-exclude \ + --exclude-from=build/gh-pages/.rsync-exclude \ + --link-dest=$(CURDIR)/build/html build/html/ build/gh-pages/ + cd build/gh-pages && \ + git add --all . && \ + git diff --cached --quiet || \ + git commit -m "Sync with the source at $(GITLASTCOMMIT)." + cd build/gh-pages && \ + git push origin gh-pages diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 00000000..ac53d5bd --- /dev/null +++ b/doc/make.bat @@ -0,0 +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 diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/doc/source/api/diffpy.structure.example_package.rst b/doc/source/api/diffpy.structure.example_package.rst new file mode 100644 index 00000000..3595000a --- /dev/null +++ b/doc/source/api/diffpy.structure.example_package.rst @@ -0,0 +1,31 @@ +.. _example_package documentation: + +|title| +======= + +.. |title| replace:: diffpy.structure.example_package package + +.. automodule:: diffpy.structure.example_package + :members: + :undoc-members: + :show-inheritance: + +|foo| +----- + +.. |foo| replace:: diffpy.structure.example_package.foo module + +.. automodule:: diffpy.structure.example_package.foo + :members: + :undoc-members: + :show-inheritance: + +|bar| +----- + +.. |bar| replace:: diffpy.structure.example_package.bar module + +.. automodule:: diffpy.structure.example_package.foo + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst new file mode 100644 index 00000000..cdcc80ea --- /dev/null +++ b/doc/source/api/diffpy.structure.rst @@ -0,0 +1,30 @@ +:tocdepth: -1 + +|title| +======= + +.. |title| replace:: diffpy.structure package + +.. automodule:: diffpy.structure + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + diffpy.structure.example_package + +Submodules +---------- + +|module| +-------- + +.. |module| replace:: diffpy.structure.example_submodule module + +.. automodule:: diffpy.structure.example_submodule + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 00000000..f7b1c770 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,289 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# diffpy.structure documentation build configuration file, created by +# sphinx-quickstart on Thu Jan 30 15:49:41 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import time +from importlib.metadata import version +from pathlib import Path + +# 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. +# 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" + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.todo", + "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", + "sphinx_rtd_theme", + "m2r", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "diffpy.structure" +copyright = "%Y, The Trustees of Columbia University in the City of New York" + +# The version info for the project you're documenting, acts as replacement for +# |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. +release = fullversion + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +today = time.strftime("%B %d, %Y", time.localtime()) +year = today.split()[-1] +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' +# substitute YEAR in the copyright string +copyright = copyright.replace("%Y", year) + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["build"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# A list of ignored prefixes for module index sorting. +modindex_common_prefix = ["diffpy.structure"] + +# Display all warnings for missing links. +nitpicky = True + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# 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. +# +html_theme_options = { + "navigation_with_keys": "true", +} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +basename = "diffpy.structure".replace(" ", "").replace(".", "") +htmlhelp_basename = basename + "doc" + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ("index", "diffpy.structure.tex", "diffpy.structure Documentation", ab_authors, "manual"), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [("index", "diffpy.structure", "diffpy.structure Documentation", ab_authors, 1)] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + "index", + "diffpy.structure", + "diffpy.structure Documentation", + ab_authors, + "diffpy.structure", + "One line description of project.", + "Miscellaneous", + ), +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +# intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/diffpy.structure.apps.rst b/doc/source/diffpy.structure.apps.rst new file mode 100644 index 00000000..e17b2d77 --- /dev/null +++ b/doc/source/diffpy.structure.apps.rst @@ -0,0 +1,30 @@ +diffpy.structure.apps package +============================= + +Submodules +---------- + +diffpy.structure.apps.anyeye module +----------------------------------- + +.. automodule:: diffpy.structure.apps.anyeye + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.apps.transtru module +------------------------------------- + +.. automodule:: diffpy.structure.apps.transtru + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: diffpy.structure.apps + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/diffpy.structure.expansion.rst b/doc/source/diffpy.structure.expansion.rst new file mode 100644 index 00000000..9e9f8f53 --- /dev/null +++ b/doc/source/diffpy.structure.expansion.rst @@ -0,0 +1,38 @@ +diffpy.structure.expansion package +================================== + +Submodules +---------- + +diffpy.structure.expansion.makeellipsoid module +----------------------------------------------- + +.. automodule:: diffpy.structure.expansion.makeellipsoid + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.expansion.shapeutils module +-------------------------------------------- + +.. automodule:: diffpy.structure.expansion.shapeutils + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.expansion.supercell_mod module +----------------------------------------------- + +.. automodule:: diffpy.structure.expansion.supercell_mod + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: diffpy.structure.expansion + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/diffpy.structure.parsers.rst b/doc/source/diffpy.structure.parsers.rst new file mode 100644 index 00000000..3ddc7d14 --- /dev/null +++ b/doc/source/diffpy.structure.parsers.rst @@ -0,0 +1,94 @@ +diffpy.structure.parsers package +================================ + +Submodules +---------- + +diffpy.structure.parsers.p_auto module +-------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_auto + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_cif module +------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_cif + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_discus module +---------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_discus + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_pdb module +------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_pdb + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_pdffit module +---------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_pdffit + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_rawxyz module +---------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_rawxyz + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_xcfg module +-------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_xcfg + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_xyz module +------------------------------------- + +.. automodule:: diffpy.structure.parsers.p_xyz + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.parser_index_mod module +------------------------------------------------ + +.. automodule:: diffpy.structure.parsers.parser_index_mod + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.structureparser module +----------------------------------------------- + +.. automodule:: diffpy.structure.parsers.structureparser + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: diffpy.structure.parsers + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 00000000..54ec3695 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,44 @@ +####### +|title| +####### + +.. |title| replace:: diffpy.structure documentation + +diffpy.structure - Crystal structure container and parsers for structure formats.. + +| Software version |release|. +| Last updated |today|. + +======= +Authors +======= + +diffpy.structure is developed by Billinge Group +and its community contributors. + +For a detailed list of contributors see +https://github.com/diffpy/diffpy.structure/graphs/contributors. + +============ +Installation +============ + +See the `README `_ +file included with the distribution. + +================= +Table of contents +================= +.. toctree:: + :titlesonly: + + license + release + Package API + +======= +Indices +======= + +* :ref:`genindex` +* :ref:`search` diff --git a/doc/source/license.rst b/doc/source/license.rst new file mode 100644 index 00000000..cfab61c2 --- /dev/null +++ b/doc/source/license.rst @@ -0,0 +1,39 @@ +:tocdepth: -1 + +.. index:: license + +License +####### + +OPEN SOURCE LICENSE AGREEMENT +============================= +BSD 3-Clause License + +Copyright (c) 2024, The Trustees of Columbia University in +the City of New York. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/source/mod_atom.rst b/doc/source/mod_atom.rst new file mode 100644 index 00000000..04c98935 --- /dev/null +++ b/doc/source/mod_atom.rst @@ -0,0 +1,7 @@ +diffpy.structure.atom +===================== + +.. automodule:: diffpy.structure.atom + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/mod_lattice.rst b/doc/source/mod_lattice.rst new file mode 100644 index 00000000..d49f8cf3 --- /dev/null +++ b/doc/source/mod_lattice.rst @@ -0,0 +1,7 @@ +diffpy.structure.lattice +======================== + +.. automodule:: diffpy.structure.lattice + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/mod_spacegroup.rst b/doc/source/mod_spacegroup.rst new file mode 100644 index 00000000..0bef7c3f --- /dev/null +++ b/doc/source/mod_spacegroup.rst @@ -0,0 +1,7 @@ +diffpy.structure.spacegroupmod +============================== + +.. automodule:: diffpy.structure.spacegroupmod + :members: + :undoc-members: + :special-members: __call__, __eq__ diff --git a/doc/source/package.rst b/doc/source/package.rst new file mode 100644 index 00000000..4179f8e3 --- /dev/null +++ b/doc/source/package.rst @@ -0,0 +1,130 @@ +:tocdepth: 2 + +Package API +########### + + +Submodules +========== + +.. toctree:: + :titlesonly: + + mod_atom + mod_lattice + mod_spacegroup + diffpy.structure.parsers + diffpy.structure.apps + diffpy.structure.expansion + + +diffpy.structure +================ + +.. module:: diffpy.structure + +The top-level diffpy.structure module provides the following objects. + + +Functions +--------- + +.. autofunction:: loadStructure + + +Classes +------- + +:py:class:`~atom.Atom` + describes one atom site in the structure - its type, position, + displacement parameters and so forth. + +:py:class:`~lattice.Lattice` + depicts general coordinate system and associated operations. + +:py:class:`~structure.Structure` + collection of :class:`!Atom` objects that form the structure together + with associated :py:class:`!Lattice`. + + +Exceptions +---------- + +.. autoclass:: StructureFormatError + +.. autoclass:: LatticeError + +.. autoclass:: SymmetryError + + +diffpy.structure.spacegroups +============================ + +.. automodule:: diffpy.structure.spacegroups + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.structureerrors +================================ + +.. automodule:: diffpy.structure.structureerrors + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.symmetryutilities +================================== + +.. automodule:: diffpy.structure.symmetryutilities + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.mmlibspacegroups +================================= + +.. automodule:: diffpy.structure.mmlibspacegroups + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.pdffitstructure +================================ + +.. automodule:: diffpy.structure.pdffitstructure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.sgtbxspacegroups +================================= + +.. automodule:: diffpy.structure.sgtbxspacegroups + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.structure +========================== + +.. automodule:: diffpy.structure.structure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.utils +====================== + +.. automodule:: diffpy.structure.utils + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.version +======================== + +.. automodule:: diffpy.structure.version + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/release.rst b/doc/source/release.rst new file mode 100644 index 00000000..27cd0cc9 --- /dev/null +++ b/doc/source/release.rst @@ -0,0 +1,5 @@ +:tocdepth: -1 + +.. index:: release notes + +.. include:: ../../CHANGELOG.rst diff --git a/news/TEMPLATE.rst b/news/TEMPLATE.rst new file mode 100644 index 00000000..790d30b1 --- /dev/null +++ b/news/TEMPLATE.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..73f92e1b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,72 @@ +[build-system] +requires = ["setuptools>=62.0", "setuptools-git-versioning<2"] +build-backend = "setuptools.build_meta" + +[project] +name = "diffpy.structure" +dynamic=['version'] +authors = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +maintainers = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +description = "Crystal structure container and parsers for structure formats." +keywords = ['diffpy', 'crystal structure data storage CIF PDB'] +readme = "README.rst" +requires-python = ">=3.10" +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Topic :: Scientific/Engineering :: Physics', + 'Topic :: Scientific/Engineering :: Chemistry', +] + +[project.urls] +Homepage = "https://github.com/diffpy/diffpy.structure/" +Issues = "https://github.com/diffpy/diffpy.structure/issues/" + +[tool.setuptools-git-versioning] +enabled = true +template = "{tag}" +dev_template = "{tag}" +dirty_template = "{tag}" + +[tool.setuptools.packages.find] +where = ["src"] # list of folders that contain the packages (["."] by default) +include = ["*"] # package names should match these glob patterns (["*"] by default) +exclude = ["diffpy.structure.tests*"] # exclude packages matching these glob patterns (empty by default) +namespaces = false # to disable scanning PEP 420 namespaces (true by default) + +[tool.black] +line-length = 115 +include = '\.pyi?$' +exclude = ''' +/( + \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | \.rst + | \.txt + | _build + | buck-out + | build + | dist + + # The following are specific to Black, you probably don't want those. + | blib2to3 + | tests/data +)/ +''' diff --git a/requirements/README.txt b/requirements/README.txt new file mode 100644 index 00000000..dc34909d --- /dev/null +++ b/requirements/README.txt @@ -0,0 +1,11 @@ +# 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/build.txt b/requirements/build.txt new file mode 100644 index 00000000..f72d870d --- /dev/null +++ b/requirements/build.txt @@ -0,0 +1,2 @@ +python +setuptools diff --git a/requirements/docs.txt b/requirements/docs.txt new file mode 100644 index 00000000..ab17b1c8 --- /dev/null +++ b/requirements/docs.txt @@ -0,0 +1,4 @@ +sphinx +sphinx_rtd_theme +doctr +m2r diff --git a/requirements/pip.txt b/requirements/pip.txt new file mode 100644 index 00000000..e69de29b diff --git a/requirements/run.txt b/requirements/run.txt new file mode 100644 index 00000000..e69de29b diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 00000000..6f9ccf84 --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,5 @@ +flake8 +pytest +codecov +coverage +pytest-env diff --git a/src/diffpy/structure/tests/conftest.py b/src/diffpy/structure/tests/conftest.py new file mode 100644 index 00000000..e3b63139 --- /dev/null +++ b/src/diffpy/structure/tests/conftest.py @@ -0,0 +1,19 @@ +import json +from pathlib import Path + +import pytest + + +@pytest.fixture +def user_filesystem(tmp_path): + base_dir = Path(tmp_path) + home_dir = base_dir / "home_dir" + home_dir.mkdir(parents=True, exist_ok=True) + cwd_dir = base_dir / "cwd_dir" + cwd_dir.mkdir(parents=True, exist_ok=True) + + home_config_data = {"username": "home_username", "email": "home@email.com"} + with open(home_dir / "diffpyconfig.json", "w") as f: + json.dump(home_config_data, f) + + yield tmp_path From 17acda0ee3b1ee2d68129e8b341dff1a66c4ee92 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 02:46:51 -0400 Subject: [PATCH 004/226] remove extra manual/source --- doc/manual/source/conf.py | 223 ------------------ doc/manual/source/diffpy.structure.apps.rst | 30 --- .../source/diffpy.structure.expansion.rst | 38 --- .../source/diffpy.structure.parsers.rst | 94 -------- doc/manual/source/index.rst | 73 ------ doc/manual/source/license.rst | 142 ----------- doc/manual/source/mod_atom.rst | 7 - doc/manual/source/mod_lattice.rst | 7 - doc/manual/source/mod_spacegroup.rst | 7 - doc/manual/source/package.rst | 130 ---------- doc/manual/source/release.rst | 3 - 11 files changed, 754 deletions(-) delete mode 100644 doc/manual/source/conf.py delete mode 100644 doc/manual/source/diffpy.structure.apps.rst delete mode 100644 doc/manual/source/diffpy.structure.expansion.rst delete mode 100644 doc/manual/source/diffpy.structure.parsers.rst delete mode 100644 doc/manual/source/index.rst delete mode 100644 doc/manual/source/license.rst delete mode 100644 doc/manual/source/mod_atom.rst delete mode 100644 doc/manual/source/mod_lattice.rst delete mode 100644 doc/manual/source/mod_spacegroup.rst delete mode 100644 doc/manual/source/package.rst delete mode 100644 doc/manual/source/release.rst diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py deleted file mode 100644 index 33d28b8d..00000000 --- a/doc/manual/source/conf.py +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# diffpy.structure documentation build configuration file, created by -# sphinx-quickstart on Mon Mar 27 11:16:48 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# 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 os.path.abspath to make it absolute, like shown here. - -import os -import sys -import time -import importlib - -sys.path.insert(0, os.path.abspath('../../..')) - -# abbreviations -ab_authors = 'Pavol Juhás, Christopher L. Farrow, Simon J.L. Billinge group' - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -needs_sphinx = '1.5' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.napoleon', - 'sphinx.ext.intersphinx', -# 'sphinx.ext.coverage', -# 'sphinx.ext.doctest', - 'm2r', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = ['.rst', '.md'] - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'diffpy.structure' -copyright = '%Y, Brookhaven National Laboratory' -author = ab_authors - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -from setup import versiondata -fullversion = versiondata.get('DEFAULT', 'version') -# The short X.Y version. -version = ''.join(fullversion.split('.post')[:1]) -# The full version, including alpha/beta/rc tags. -release = fullversion - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -today_seconds = versiondata.getint('DEFAULT', 'timestamp') -today = time.strftime('%B %d, %Y', time.localtime(today_seconds)) -year = today.split()[-1] -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' -# substitute YEAR in the copyright string -copyright = copyright.replace('%Y', year) - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None -default_role = 'any' - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True -add_function_parentheses = False - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True -add_module_names = False - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['diffpy.structure'] - -# Display all warnings for missing links. -nitpicky = True - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_py3doc_enhanced_theme' -tmod = importlib.import_module(html_theme) -html_theme_path = [tmod.get_html_theme_path()] - -# 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. -# -html_theme_options = { - 'collapsiblesidebar' : 'true', - 'navigation_with_keys' : 'true', -} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'diffpystructuredoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'diffpy.structure_manual.tex', 'diffpy.structure Documentation', - ab_authors, 'manual'), -] - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'diffpy.structure', 'diffpy.structure Documentation', - ab_authors.split(', '), 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'diffpy.structure', 'diffpy.structure Documentation', - ab_authors, 'diffpy.structure', 'One line description of project.', - 'Miscellaneous'), -] - - -# -- intersphinx configuration -------------------------------------------- - -intersphinx_mapping = { - 'python' : ('https://docs.python.org/3.10', None), - 'numpy' : ('https://docs.scipy.org/doc/numpy', None), -} - -# -- autodoc configuration ------------------------------------------------ -# See http://www.sphinx-doc.org/en/stable/ext/autodoc.html - -autodoc_member_order = 'bysource' - - -# -- napoleon configuration ----------------------------------------------- -# See https://sphinxcontrib-napoleon.readthedocs.io. - -napoleon_google_docstring = False -napoleon_numpy_docstring = True -napoleon_use_param = False -napoleon_use_rtype = False diff --git a/doc/manual/source/diffpy.structure.apps.rst b/doc/manual/source/diffpy.structure.apps.rst deleted file mode 100644 index e17b2d77..00000000 --- a/doc/manual/source/diffpy.structure.apps.rst +++ /dev/null @@ -1,30 +0,0 @@ -diffpy.structure.apps package -============================= - -Submodules ----------- - -diffpy.structure.apps.anyeye module ------------------------------------ - -.. automodule:: diffpy.structure.apps.anyeye - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.apps.transtru module -------------------------------------- - -.. automodule:: diffpy.structure.apps.transtru - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: diffpy.structure.apps - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/diffpy.structure.expansion.rst b/doc/manual/source/diffpy.structure.expansion.rst deleted file mode 100644 index 9e9f8f53..00000000 --- a/doc/manual/source/diffpy.structure.expansion.rst +++ /dev/null @@ -1,38 +0,0 @@ -diffpy.structure.expansion package -================================== - -Submodules ----------- - -diffpy.structure.expansion.makeellipsoid module ------------------------------------------------ - -.. automodule:: diffpy.structure.expansion.makeellipsoid - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.expansion.shapeutils module --------------------------------------------- - -.. automodule:: diffpy.structure.expansion.shapeutils - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.expansion.supercell_mod module ------------------------------------------------ - -.. automodule:: diffpy.structure.expansion.supercell_mod - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: diffpy.structure.expansion - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/diffpy.structure.parsers.rst b/doc/manual/source/diffpy.structure.parsers.rst deleted file mode 100644 index 3ddc7d14..00000000 --- a/doc/manual/source/diffpy.structure.parsers.rst +++ /dev/null @@ -1,94 +0,0 @@ -diffpy.structure.parsers package -================================ - -Submodules ----------- - -diffpy.structure.parsers.p_auto module --------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_auto - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_cif module -------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_cif - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_discus module ----------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_discus - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_pdb module -------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_pdb - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_pdffit module ----------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_pdffit - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_rawxyz module ----------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_rawxyz - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_xcfg module --------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_xcfg - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.p_xyz module -------------------------------------- - -.. automodule:: diffpy.structure.parsers.p_xyz - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.parser_index_mod module ------------------------------------------------- - -.. automodule:: diffpy.structure.parsers.parser_index_mod - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.parsers.structureparser module ------------------------------------------------ - -.. automodule:: diffpy.structure.parsers.structureparser - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: diffpy.structure.parsers - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/index.rst b/doc/manual/source/index.rst deleted file mode 100644 index 520f8cb5..00000000 --- a/doc/manual/source/index.rst +++ /dev/null @@ -1,73 +0,0 @@ -######################################################################## -diffpy.structure documentation -######################################################################## - -diffpy.structure - simple storage and manipulation of crystal structures - -| Software version |release|. -| Last updated |today|. - -The diffpy.structure package provides objects for storing atomic -coordinates, displacement parameters and other crystal structure data. -diffpy.structure supports import and export of structure data in several -structure formats such as CIF, PDB, xyz. It provides conversion -between fractional and absolute Cartesian coordinates, functions for -symmetry expansion from asymmetric unit and generation of symmetry -constraints for atom positions and displacement parameters. diffpy.structure -includes definitions of all space groups in over 500 symmetry settings. - - -Authors -======================================================================== - -diffpy.structure is developed by members of the Billinge Group at -Columbia University and at Brookhaven National Laboratory including -Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. - -For a detailed list of contributors see -https://github.com/diffpy/diffpy.structure/graphs/contributors. - - -Acknowledgments -======================================================================== - -Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* -originate from the pymmlib project, http://pymmlib.sourceforge.net. -Less common settings of space groups were generating using the -Computational Crystallography Toolbox, -http://cctbx.sourceforge.net. - - -.. index:: citation, reference - -Reference -======================================================================== - -If you use this program for a scientific research that leads -to publication, we ask that you acknowledge use of the program -by citing the following paper in your publication: - - P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, - `Complex modeling: a strategy and software program for combining - multiple information sources to solve ill posed structure and - nanostructure inverse problems - `__, - *Acta Crystallogr. A* **71**, 562-568 (2015). - - -Table of contents -======================================================================== - -.. toctree:: - :titlesonly: - - license - release - package - - -Indices -======================================================================== - -* :ref:`genindex` -* :ref:`search` diff --git a/doc/manual/source/license.rst b/doc/manual/source/license.rst deleted file mode 100644 index 7d78e94f..00000000 --- a/doc/manual/source/license.rst +++ /dev/null @@ -1,142 +0,0 @@ -.. index:: license - -License -####### - -OPEN SOURCE LICENSE AGREEMENT -============================= - -| Copyright (c) 2009-2011, University of Tennessee -| Copyright (c) 1989, 1991 Free Software Foundation, Inc. -| Copyright (c) 2006, The Regents of the University of California through - Lawrence Berkeley National Laboratory -| Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") -| Copyright (c) 2006-2007, Board of Trustees of Michigan State University -| Copyright (c) 2008-2012, The Trustees of Columbia University in - the City of New York -| Copyright (c) 2014-2019, Brookhaven Science Associates, - Brookhaven National Laboratory - - -The "DiffPy-CMI" is distributed subject to the following license conditions: - - -SOFTWARE LICENSE AGREEMENT -========================== - -Software: **DiffPy-CMI** - - -(1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either -source code, or binary form and accompanying documentation). - -Part of the software was derived from the DANSE, ObjCryst++ (with permission), -PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of -which the original Copyrights are contained in each individual file. - -Each licensee is addressed as "you" or "Licensee." - - -(2) The copyright holders shown above and their third-party Licensors hereby -grant licensee a royalty-free nonexclusive license, subject to the limitations -stated herein and U.S. Government license rights. - - -(3) You may modify and make a copy or copies of the software for use within -your organization, if you meet the following conditions: - - (a) Copies in source code must include the copyright notice and this - software license agreement. - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy. - - -(4) You may modify a copy or copies of the Software or any portion of it, thus -forming a work based on the Software, and distribute copies of such work -outside your organization, if you meet all of the following conditions: - - (a) Copies in source code must include the copyright notice and this - Software License Agreement; - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy; - - (c) Modified copies and works based on the Software must carry prominent - notices stating that you changed specified portions of the Software. - - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -.. rubric:: END OF LICENSE diff --git a/doc/manual/source/mod_atom.rst b/doc/manual/source/mod_atom.rst deleted file mode 100644 index 04c98935..00000000 --- a/doc/manual/source/mod_atom.rst +++ /dev/null @@ -1,7 +0,0 @@ -diffpy.structure.atom -===================== - -.. automodule:: diffpy.structure.atom - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/mod_lattice.rst b/doc/manual/source/mod_lattice.rst deleted file mode 100644 index d49f8cf3..00000000 --- a/doc/manual/source/mod_lattice.rst +++ /dev/null @@ -1,7 +0,0 @@ -diffpy.structure.lattice -======================== - -.. automodule:: diffpy.structure.lattice - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/mod_spacegroup.rst b/doc/manual/source/mod_spacegroup.rst deleted file mode 100644 index 0bef7c3f..00000000 --- a/doc/manual/source/mod_spacegroup.rst +++ /dev/null @@ -1,7 +0,0 @@ -diffpy.structure.spacegroupmod -============================== - -.. automodule:: diffpy.structure.spacegroupmod - :members: - :undoc-members: - :special-members: __call__, __eq__ diff --git a/doc/manual/source/package.rst b/doc/manual/source/package.rst deleted file mode 100644 index 4179f8e3..00000000 --- a/doc/manual/source/package.rst +++ /dev/null @@ -1,130 +0,0 @@ -:tocdepth: 2 - -Package API -########### - - -Submodules -========== - -.. toctree:: - :titlesonly: - - mod_atom - mod_lattice - mod_spacegroup - diffpy.structure.parsers - diffpy.structure.apps - diffpy.structure.expansion - - -diffpy.structure -================ - -.. module:: diffpy.structure - -The top-level diffpy.structure module provides the following objects. - - -Functions ---------- - -.. autofunction:: loadStructure - - -Classes -------- - -:py:class:`~atom.Atom` - describes one atom site in the structure - its type, position, - displacement parameters and so forth. - -:py:class:`~lattice.Lattice` - depicts general coordinate system and associated operations. - -:py:class:`~structure.Structure` - collection of :class:`!Atom` objects that form the structure together - with associated :py:class:`!Lattice`. - - -Exceptions ----------- - -.. autoclass:: StructureFormatError - -.. autoclass:: LatticeError - -.. autoclass:: SymmetryError - - -diffpy.structure.spacegroups -============================ - -.. automodule:: diffpy.structure.spacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structureerrors -================================ - -.. automodule:: diffpy.structure.structureerrors - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.symmetryutilities -================================== - -.. automodule:: diffpy.structure.symmetryutilities - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.mmlibspacegroups -================================= - -.. automodule:: diffpy.structure.mmlibspacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.pdffitstructure -================================ - -.. automodule:: diffpy.structure.pdffitstructure - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.sgtbxspacegroups -================================= - -.. automodule:: diffpy.structure.sgtbxspacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structure -========================== - -.. automodule:: diffpy.structure.structure - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.utils -====================== - -.. automodule:: diffpy.structure.utils - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.version -======================== - -.. automodule:: diffpy.structure.version - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/manual/source/release.rst b/doc/manual/source/release.rst deleted file mode 100644 index 7ec4f81d..00000000 --- a/doc/manual/source/release.rst +++ /dev/null @@ -1,3 +0,0 @@ -.. index:: release notes - -.. mdinclude:: ../../../CHANGELOG.md From bde7ff7682f75967c29a240fd2bba11b5038a7dd Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 02:47:49 -0400 Subject: [PATCH 005/226] .codecov.yml, .gitignore, rever.xsh --- .codecov.yml | 36 ++++++++++++++++++++-- .gitignore | 86 +++++++++++++++++++++++++++++++++++++++++----------- rever.xsh | 14 --------- 3 files changed, 103 insertions(+), 33 deletions(-) delete mode 100644 rever.xsh diff --git a/.codecov.yml b/.codecov.yml index 86671410..04dd6510 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,2 +1,34 @@ -fixes: - - ".*/site-packages/::src/" +# codecov can find this file anywhere in the repo, so we don't need to clutter +# the root folder. +#comment: false + +codecov: + notify: + require_ci_to_pass: no + +coverage: + status: + patch: + default: + target: '70' + if_no_uploads: error + if_not_found: success + if_ci_failed: failure + project: + default: false + library: + target: auto + if_no_uploads: error + if_not_found: success + if_ci_failed: error + paths: '!*/tests/.*' + + tests: + target: 97.9% + paths: '*/tests/.*' + if_not_found: success + +flags: + tests: + paths: + - tests/ diff --git a/.gitignore b/.gitignore index a3fed051..a25212ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,95 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -temp -develop-eggs +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ .installed.cfg -lib -lib64 -tags +*.egg +bin/ +temp/ +tags/ errors.err +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt +pip-delete-this-directory.txt MANIFEST # Unit test / coverage reports +htmlcov/ +.tox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*,cover +.hypothesis/ # Translations *.mo +*.pot # Mr Developer .mr.developer.cfg .project .pydevproject -.settings + +# Django stuff: +*.log + +# Sphinx documentation +docs/build/ +docs/source/generated/ + +# pytest +.pytest_cache/ + +# PyBuilder +target/ + +# Editor files +# mac +.DS_Store +*~ + +# vim +*.swp +*.swo + +# pycharm +.idea/ + +# VSCode +.vscode/ + +# Ipython Notebook +.ipynb_checkpoints # version information setup.cfg diff --git a/rever.xsh b/rever.xsh deleted file mode 100644 index dda2765d..00000000 --- a/rever.xsh +++ /dev/null @@ -1,14 +0,0 @@ -$PROJECT = 'diffpy.structure' -$ACTIVITIES = [ - 'tag', # Creates a tag for the new version number - 'push_tag', # Pushes the tag up to the $TAG_REMOTE - 'pypi', # Sends the package to pypi - 'ghrelease' # Creates a Github release entry for the new tag - ] -$PUSH_TAG_REMOTE = 'git@github.com:diffpy/diffpy.structure.git' # Repo to push tags to -$GITHUB_ORG = 'diffpy' # Github org for Github releases and conda-forge -$GITHUB_REPO = 'diffpy.structure' # Github repo for Github releases and conda-forge -$GHRELEASE_PREPEND = """See [CHANGELOG.md](CHANGELOG.md) for detailed release notes. - -The release is also available at [PyPI](https://pypi.org/project/diffpy.structure/) and [Conda](https://anaconda.org/conda-forge/diffpy.structure). -""" # release message From 15e0c079bc4edfcae38aee724127a8c64a221137 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 02:51:19 -0400 Subject: [PATCH 006/226] AUTHORS.rst, /diffpy/__init__.py, /tests/debug.py --- AUTHORS.rst | 5 ++++- AUTHORS.txt | 10 ---------- src/diffpy/__init__.py | 22 ++++++++++------------ src/diffpy/structure/tests/debug.py | 23 ++++++++++++++--------- 4 files changed, 28 insertions(+), 32 deletions(-) delete mode 100644 AUTHORS.txt diff --git a/AUTHORS.rst b/AUTHORS.rst index 7f4c6d8e..9f6a419f 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,7 +1,10 @@ Authors ======= -Billinge Group and community contibutors. +Pavol Juhas, +Christopher L. Farrow, +Xiaohao Yang, +Simon J.L. Billinge Contributors ------------ diff --git a/AUTHORS.txt b/AUTHORS.txt deleted file mode 100644 index 2d8753c6..00000000 --- a/AUTHORS.txt +++ /dev/null @@ -1,10 +0,0 @@ -Authors: - -Pavol Juhas, -Christopher L. Farrow, -Xiaohao Yang, -Simon J.L. Billinge - -Contributors: - -https://github.com/diffpy/diffpy.structure/graphs/contributors diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 0e070285..3e7952ae 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,26 +1,24 @@ #!/usr/bin/env python ############################################################################## # -# diffpy by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 trustees of the Michigan State University. -# All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.structure/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -"""diffpy - tools for structure analysis by diffraction. - -Blank namespace package. -""" +"""Blank namespace package for module diffpy.""" from pkgutil import extend_path -__path__ = extend_path(__path__, __name__) +__path__ = extend_path(__path__, __name__) # End of file + diff --git a/src/diffpy/structure/tests/debug.py b/src/diffpy/structure/tests/debug.py index 221091de..36d78c9e 100644 --- a/src/diffpy/structure/tests/debug.py +++ b/src/diffpy/structure/tests/debug.py @@ -1,15 +1,15 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.structure Complex Modeling Initiative -# (c) 2016 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.structure/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## @@ -22,9 +22,14 @@ """ -if __name__ == '__main__': +if __name__ == "__main__": import sys + from diffpy.structure.tests import testsuite - pattern = sys.argv[1] if len(sys.argv) > 1 else '' + + pattern = sys.argv[1] if len(sys.argv) > 1 else "" suite = testsuite(pattern) suite.debug() + + +# End of file From e9ad4a145ab8d5be6232c98f20e0d46941b01c0e Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 02:58:31 -0400 Subject: [PATCH 007/226] README --- README.rst | 154 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 66 deletions(-) diff --git a/README.rst b/README.rst index 3e0538e7..8c6adad8 100644 --- a/README.rst +++ b/README.rst @@ -1,14 +1,41 @@ -.. image:: https://travis-ci.org/diffpy/diffpy.structure.svg?branch=master - :target: https://travis-ci.org/diffpy/diffpy.structure +|Icon| |title|_ +=============== -.. image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/master/graph/badge.svg - :target: https://codecov.io/gh/diffpy/diffpy.structure +.. |title| replace:: diffpy.structure +.. _title: https://diffpy.github.io/diffpy.structure +.. |Icon| image:: https://avatars.githubusercontent.com/diffpy + :target: https://diffpy.github.io/diffpy.structure + :height: 100px -diffpy.structure -======================================================================== +|PyPi| |Forge| |PythonVersion| |PR| -storage and manipulation of crystal structure data +|CI| |Codecov| |Black| |Tracking| + +.. |Black| image:: https://img.shields.io/badge/code_style-black-black + :target: https://github.com/psf/black + +.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml + +.. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/main/graph/badge.svg + :target: https://codecov.io/gh/diffpy/diffpy.structure + +.. |Forge| image:: https://img.shields.io/conda/vn/conda-forge/diffpy.structure + :target: https://anaconda.org/conda-forge/diffpy.structure + +.. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + +.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.structure + :target: https://pypi.org/project/diffpy.structure/ + +.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.structure + :target: https://pypi.org/project/diffpy.structure/ + +.. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue + :target: https://github.com/diffpy/diffpy.structure/issues + +Crystal structure container and parsers for structure formats. The diffpy.structure package provides objects for storing atomic coordinates, displacement parameters and other crystal structure data. @@ -20,94 +47,89 @@ of symmetry constraints for atom positions and displacement parameters. diffpy.structure includes definitions of all space groups in over 500 symmetry settings. -To learn more about diffpy.structure library see the -user manual at http://diffpy.github.io/diffpy.structure. +For more information about the diffpy.structure library, please consult our `online documentation `_. +Citation +-------- -REQUIREMENTS ------------------------------------------------------------------------- +If you use diffpy.structure in a scientific publication, we would like you to cite this package as -The diffpy.structure package requires Python 3.7 or later or 2.7 and -the following software: + diffpy.structure Package, https://github.com/diffpy/diffpy.structure -* ``setuptools`` - software distribution tools for Python -* ``NumPy`` - numerical mathematics and fast array operations for Python +Installation +------------ -We recommend to use `Anaconda Python `_ -as it allows to install all software dependencies together with -diffpy.structure. For other Python distributions it is necessary to -install the required software separately. As an example on Ubuntu -Linux the required software can be installed with :: +The preferred method is to use `Miniconda Python +`_ +and install from the "conda-forge" channel of Conda packages. - sudo aptitude install python3-setuptools python3-numpy +To add "conda-forge" to the conda channels, run the following in a terminal. :: -diffpy.structure also uses the -`PyCifRW `_ -library, which is automatically deployed during the -installation process. + conda config --add channels conda-forge +We want to install our packages in a suitable conda environment. +The following creates and activates a new environment named ``diffpy.structure_env`` :: -INSTALLATION ------------------------------------------------------------------------- + conda create -n diffpy.structure_env python=3 + conda activate diffpy.structure_env -The preferred method is to use Anaconda Python and install from the -"diffpy" channel of Anaconda packages :: +Then, to fully install ``diffpy.structure`` in our active environment, run :: - conda config --add channels diffpy - conda install diffpy.structure + conda install diffpy.structure -diffpy.structure is also included in the "diffpy-cmi" collection -of packages for structure analysis :: +Another option is to use ``pip`` to download and install the latest release from +`Python Package Index `_. +To install using ``pip`` into your ``diffpy.structure_env`` environment, we will also have to install dependencies :: - conda install diffpy-cmi + pip install -r https://raw.githubusercontent.com/diffpy/diffpy.structure/main/requirements/run.txt -Another installation option is to use ``easy_install`` to download and -install the latest release from -`Python Package Index `_ :: +and then install the package :: - easy_install diffpy.structure + pip install diffpy.structure -If you prefer to install from sources, navigate to the source archive -directory and run :: +If you prefer to install from sources, after installing the dependencies, obtain the source archive from +`GitHub `_. Once installed, ``cd`` into your ``diffpy.structure`` directory +and run the following :: - python setup.py install + pip install . -You may need to use ``sudo`` with system Python so it is allowed to -copy files to system directories. If sudo is not available, check -the usage info from ``python setup.py install --help`` for options to -install to user-writable locations. The installation integrity can be -verified by changing to the HOME directory and running :: +Support and Contribute +---------------------- - python -m diffpy.structure.tests.run +`Diffpy user group `_ is the discussion forum for general questions and discussions about the use of diffpy.structure. Please join the diffpy.structure users community by joining the Google group. The diffpy.structure 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 `_. -DEVELOPMENT ------------------------------------------------------------------------- +Feel free to fork the project and contribute. To install diffpy.structure +in a development mode, with its sources being directly used by Python +rather than copied to a package directory, use the following in the root +directory :: -diffpy.structure is an open-source software developed as a part of the -DiffPy-CMI complex modeling initiative at the Brookhaven National -Laboratory. The diffpy.structure sources are hosted at -https://github.com/diffpy/diffpy.structure. + pip install -e . -Feel free to fork the project and contribute. To install diffpy.structure -in a development mode, where the sources are directly used by Python -rather than copied to a system directory, use :: +To ensure code quality and to prevent accidental commits into the default branch, please set up the use of our pre-commit +hooks. - python setup.py develop --user +1. Install pre-commit in your working environment by running ``conda install pre-commit``. +2. Initialize pre-commit (one time only) ``pre-commit install``. -ACKNOWLEDGEMENT ------------------------------------------------------------------------- +Thereafter your code will be linted by black and isort and checked against flake8 before you can commit. +If it fails by black or isort, just rerun and it should pass (black and isort will modify the files so should +pass after they are modified). If the flake8 test fails please see the error messages and fix them manually before +trying to commit again. -Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* -originate from the pymmlib project, http://pymmlib.sourceforge.net. +Improvements and fixes are always appreciated. +Before contribuing, please read our `Code of Conduct `_. -CONTACTS ------------------------------------------------------------------------- +Acknowledgement +--------------- -For more information on diffpy.structure please visit the project web-page +Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* +originate from the `pymmlib project `_. -http://www.diffpy.org/ +Contact +------- -or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.structure please visit the project `web-page `_ or email Prof. Simon Billinge at sb2896@columbia.edu. From f3090c8a17e825c5dbc0e9855dc4a3b84c4718e1 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 30 Jun 2024 03:05:50 -0400 Subject: [PATCH 008/226] CHANGELOG --- CHANGELOG.md | 106 ------------------------------------------------ CHANGELOG.rst | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 106 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 83ce9191..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,106 +0,0 @@ -# Release notes - -## Version 3.1.0 – 2022-12-04 - -### Added - -- Compatibility with Python 3.10, 3.9, 3.8 - -### Changed - -### Deprecated - -### Removed - -- Remove the support for Python 3.5, 3.6. - -### Fixed - -## Version 3.0.2 - 2022-10-12 - -### Added - -- A string representation of `SpaceGroup` with key information. - -### Changed - -- Bumped minimum `PyCifRW` version to `4.4.3`. - -### Deprecated - -### Removed - -### Fixed - -- Handling of paths on Windows when using the `P_cif` parser. - -## Version 3.0.1 – 2019-06-27 - -### Added - -- Function `FindSpaceGroup` for space group lookup from its list - of symmetry operations. - -### Changed - -- Reuse existing `SpaceGroup` instance when loading a CIF file. -- Improve check of SpaceGroup identifiers in `GetSpaceGroup`. -- When loading CIF file, preset `Atom.anisotropy` according - to symmetry constraints at each site. Adhere to specific - ADP type when specified in the CIF. - -### Removed - -- Unused attribute `SpaceGroup.alt_name`. - -### Fixed - -- Fix inconsistent (`Atom`, `Structure`) pickle. Preserve `Atom` - ownership in a `Structure` after pickling and unpickling. -- Spuriously linked array-view values after `stru.xyz = 0`. -- Preserve scalar value type when setting `stru.occupancy = value`. -- Process unknown CIF occupancy "?" as an occupancy of 1. -- Incorrect `SymOp` list for spacegroup "B11m" (number 1008). - - -## Version 3.0.0 – 2019-03-11 - -Notable differences from version 1.3.5. - -### Added - -- Compatibility with Python 3.7, 3.6, 3.5 in addition to 2.7. -- Aliases for 17 non-standard space group names from cctbx. -- Support for intersphinx links to Python and NumPy documentation. -- Dependency and use of the `six` PY2/PY3 compatibility package. -- Documentation hosting at readthedocs.org. - -### Changed - -- Rename the package and all its module names to lowercase. -- Use UTF-8 encoding when writing structure files. -- Refactor parsing of XCFG format. Avoid use of generated code. -- Refactor all starred imports to explicit so they can be checked. -- Adopt napoleon style for docstrings. -- Update docstrings for `Atom`, `Lattice`, `SymOp`, `SpaceGroup`. -- Switch to platform-independent "noarch" Anaconda package. - -### Deprecated - -- Old camel case module names such as `diffpy.Structure`. -- Variable `__gitsha__` in the `version` module which was renamed - to `__git_commit__`. - -### Removed - -- Unused exception `IsotropyError`. -- Unused class `BRAtomsStructure` and associated parser. - -### Fixed - -- Loading of empty CIF files with no specified sites. -- Parsing of CIFs with `?` value for unknown displacement parameters. -- Symmetry constraint equations for ADPs so they avoid self-reference. -- Use `StructureFormatError` exception for CIF with unknown space group. -- Open files within the `with` context so they get closed when done. -- Invalid escape sequences in string values. diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 26694512..e446d478 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,3 +3,112 @@ Release Notes ============= .. current developments + +Version 3.1.0 - 2022-12-04 +-------------------------- + +**Added** + +- Compatibility with Python 3.10, 3.9, 3.8 + +**Changed** + +**Deprecated** + +**Removed** + +- Remove the support for Python 3.5, 3.6. + +**Fixed** + +Version 3.0.2 - 2022-10-12 +-------------------------- + +**Added** + +- A string representation of `SpaceGroup` with key information. + +**Changed** + +- Bumped minimum `PyCifRW` version to `4.4.3`. + +**Deprecated** + +**Removed** + +**Fixed** + +- Handling of paths on Windows when using the `P_cif` parser. + +Version 3.0.1 - 2019-06-27 +-------------------------- + +**Added** + +- Function `FindSpaceGroup` for space group lookup from its list + of symmetry operations. + +**Changed** + +- Reuse existing `SpaceGroup` instance when loading a CIF file. +- Improve check of SpaceGroup identifiers in `GetSpaceGroup`. +- When loading CIF file, preset `Atom.anisotropy` according + to symmetry constraints at each site. Adhere to specific + ADP type when specified in the CIF. + +**Removed** + +- Unused attribute `SpaceGroup.alt_name`. + +**Fixed** + +- Fix inconsistent (`Atom`, `Structure`) pickle. Preserve `Atom` + ownership in a `Structure` after pickling and unpickling. +- Spuriously linked array-view values after `stru.xyz = 0`. +- Preserve scalar value type when setting `stru.occupancy = value`. +- Process unknown CIF occupancy "?" as an occupancy of 1. +- Incorrect `SymOp` list for spacegroup "B11m" (number 1008). + + +Version 3.0.0 - 2019-03-11 +-------------------------- + +Notable differences from version 1.3.5. + +**Added** + +- Compatibility with Python 3.7, 3.6, 3.5 in addition to 2.7. +- Aliases for 17 non-standard space group names from cctbx. +- Support for intersphinx links to Python and NumPy documentation. +- Dependency and use of the `six` PY2/PY3 compatibility package. +- Documentation hosting at readthedocs.org. + +**Changed** + +- Rename the package and all its module names to lowercase. +- Use UTF-8 encoding when writing structure files. +- Refactor parsing of XCFG format. Avoid use of generated code. +- Refactor all starred imports to explicit so they can be checked. +- Adopt napoleon style for docstrings. +- Update docstrings for `Atom`, `Lattice`, `SymOp`, `SpaceGroup`. +- Switch to platform-independent "noarch" Anaconda package. + +**Deprecated** + +- Old camel case module names such as `diffpy.Structure`. +- Variable `__gitsha__` in the `version` module which was renamed + to `__git_commit__`. + +**Removed** + +- Unused exception `IsotropyError`. +- Unused class `BRAtomsStructure` and associated parser. + +**Fixed** + +- Loading of empty CIF files with no specified sites. +- Parsing of CIFs with `?` value for unknown displacement parameters. +- Symmetry constraint equations for ADPs so they avoid self-reference. +- Use `StructureFormatError` exception for CIF with unknown space group. +- Open files within the `with` context so they get closed when done. +- Invalid escape sequences in string values. From b33c8c345ea08a9514230e82a3fc5cb978d15f06 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:15:06 -0400 Subject: [PATCH 009/226] remove conda-recipe folder --- conda-recipe/bld.bat | 7 ---- conda-recipe/build.sh | 8 ----- conda-recipe/meta.yaml | 76 ---------------------------------------- conda-recipe/run_test.py | 4 --- 4 files changed, 95 deletions(-) delete mode 100644 conda-recipe/bld.bat delete mode 100644 conda-recipe/build.sh delete mode 100644 conda-recipe/meta.yaml delete mode 100644 conda-recipe/run_test.py diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat deleted file mode 100644 index 0a79fa23..00000000 --- a/conda-recipe/bld.bat +++ /dev/null @@ -1,7 +0,0 @@ -"%PYTHON%" setup.py install -if errorlevel 1 exit 1 - -:: Add more build steps here, if they are necessary. - -:: See http://docs.continuum.io/conda/build.html -:: for a list of environment variables that are set during the build process. diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh deleted file mode 100644 index b7920393..00000000 --- a/conda-recipe/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -$PYTHON setup.py install - -# Add more build steps here, if they are necessary. - -# See http://docs.continuum.io/conda/build.html -# for a list of environment variables that are set during the build process. diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml deleted file mode 100644 index 93c0a64f..00000000 --- a/conda-recipe/meta.yaml +++ /dev/null @@ -1,76 +0,0 @@ -{% set setupdata = load_setup_py_data() %} - -package: - name: diffpy.structure - version: {{ setupdata['version'] }} - -source: - # git_url: https://github.com/diffpy/diffpy.structure - git_url: .. - -build: - preserve_egg_dir: True - noarch: python - - # entry_points: - # Put any entry points (scripts to be generated automatically) here. The - # syntax is module:function. For example - # - # - diffpy.structure = diffpy.structure:main - # - # Would create an entry point called diffpy.structure that calls diffpy.structure.main() - - # If this is a new build for the same version, increment the build - # number. If you do not include this key, it defaults to 0. - # number: 0 - -requirements: - build: - - python >=3.5|2.7* - - setuptools - - six - - pycifrw - - run: - - python >=3.5|2.7* - - setuptools - - numpy >=1.3 - - pycifrw - - six - -test: - # Python imports - imports: - - diffpy.structure - - diffpy.structure.parsers - - diffpy.structure.apps - - diffpy.structure.expansion - - diffpy.structure.tests - # legacy imports - - diffpy.Structure - - diffpy.Structure.Parsers - - diffpy.Structure.apps - - diffpy.Structure.expansion - - diffpy.Structure.tests - - diffpy.structure.applications - - # commands: - # You can put test commands to be run here. Use this to test that the - # entry points work. - - - # You can also put a file called run_test.py in the recipe that will be run - # at test time. - - # requires: - # Put any additional test requirements here. For example - # - nose - -about: - home: https://github.com/diffpy/diffpy.structure - summary: Crystal structure container and parsers for structure formats. - license: Modified BSD License - license_file: LICENSE.txt - -# See http://docs.continuum.io/conda/build.html -# for more information about meta.yaml. diff --git a/conda-recipe/run_test.py b/conda-recipe/run_test.py deleted file mode 100644 index 270ddc42..00000000 --- a/conda-recipe/run_test.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python - -import diffpy.structure.tests -assert diffpy.structure.tests.test().wasSuccessful() From ddec387dcd85a36d491071221d7a0b5c67260086 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:16:30 -0400 Subject: [PATCH 010/226] remove gitarchive, readthedocs, travis, setup --- .gitarchive.cfg | 5 -- .readthedocs.yml | 9 ---- .travis.yml | 113 ----------------------------------------- setup.py | 129 ----------------------------------------------- 4 files changed, 256 deletions(-) delete mode 100644 .gitarchive.cfg delete mode 100644 .readthedocs.yml delete mode 100644 .travis.yml delete mode 100755 setup.py diff --git a/.gitarchive.cfg b/.gitarchive.cfg deleted file mode 100644 index 95e1448c..00000000 --- a/.gitarchive.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -commit = $Format:%H$ -date = $Format:%ci$ -timestamp = $Format:%ct$ -refnames = $Format:%D$ diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 13ef5323..00000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,9 +0,0 @@ -requirements_file: doc/manual/requirements.txt - -python: - version: 3 - setup_py_install: true - use_system_site_packages: true - -# For more fields that can be specified here, see: -# http://docs.readthedocs.io/en/latest/yaml-config.html diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 196bc046..00000000 --- a/.travis.yml +++ /dev/null @@ -1,113 +0,0 @@ -dist: xenial -language: generic - -os: - - linux - - osx - -env: - - MYUSEMC=true MYPYTHON_VERSION=2.7 - - MYUSEMC=true MYPYTHON_VERSION=3.7 - - MYUSEMC=true MYPYTHON_VERSION=3.8 - - MYUSEMC=true MYPYTHON_VERSION=3.9 - - MYUSEMC=true MYPYTHON_VERSION=3.10 - - MYUSEMC=false - -git: - depth: 999999 - -branches: - except: - - /^v[0-9]/ - - -before_install: - - MYNAME=diffpy.structure - - MYCOMMIT="$(git rev-parse HEAD)" - - umask 022 - - git fetch origin --tags - - MYPYTHON=python; MYPIP=pip - - NOSYS=true; NOAPT=true; NOBREW=true; NOMC=true - - if ${MYUSEMC}; then - NOMC=false; - elif [[ ${TRAVIS_OS_NAME} == linux ]]; then - NOAPT=false; NOSYS=false; - MYPIPFLAGS="--user"; - elif [[ ${TRAVIS_OS_NAME} == osx ]]; then - NOBREW=false; NOSYS=false; - MYPYTHON=python3; - MYPIP=pip3; - MYPIPFLAGS="--user"; - fi - - MYMCREPO=https://repo.anaconda.com/miniconda - - case ${TRAVIS_OS_NAME} in - linux) - MYMCBUNDLE=Miniconda3-latest-Linux-x86_64.sh ;; - osx) - MYMCBUNDLE=Miniconda3-latest-MacOSX-x86_64.sh ;; - *) - echo "Unsupported operating system." >&2; - exit 2 ;; - esac - - MYRUNDIR=${PWD}/build/rundir - - - mkdir -p ~/pkgs - - mkdir -p ${MYRUNDIR} - - cp .coveragerc ${MYRUNDIR}/ - - - $NOMC || pushd ~/pkgs - - $NOMC || wget --timestamping ${MYMCREPO}/${MYMCBUNDLE} - - $NOMC || test -x ~/mc/bin/conda || bash ${MYMCBUNDLE} -b -f -p ~/mc - - $NOMC || popd - - $NOMC || source ~/mc/bin/activate base - - $NOMC || conda update --yes conda - - $NOMC || conda install --yes conda-build conda-verify jinja2 - - $NOMC || conda create --name=testenv --yes python=${MYPYTHON_VERSION} coverage - - $NOMC || conda config --add channels diffpy - - - $NOAPT || test "${TRAVIS_OS_NAME}" = "linux" || exit $? - - $NOAPT || PATH="$(echo "$PATH" | sed 's,:/opt/pyenv/[^:]*,,g')" - - $NOAPT || test "$(which python)" = "/usr/bin/python" || ( - which python; exit 1) - - $NOAPT || sudo apt-get update -qq - - $NOAPT || sudo apt-get install -y - python-dev python-numpy python-setuptools build-essential - - - $NOBREW || test "${TRAVIS_OS_NAME}" = "osx" || exit $? - - $NOBREW || brew update - - $NOBREW || brew install gcc || brew link --overwrite gcc - - - $NOSYS || devutils/makesdist - - $NOSYS || MYTARBUNDLE="$(ls -t "${PWD}"/dist/*.tar.gz | head -1)" - - -install: - - $NOMC || conda build --python=${MYPYTHON_VERSION} conda-recipe - - $NOMC || conda render --python=${MYPYTHON_VERSION} --output conda-recipe | - sed 's,.*/,,; s/[.]tar[.]bz2$//; s/-/=/g' > /tmp/mypackage.txt - - $NOMC || source activate testenv - - $NOMC || conda install --yes --use-local --file=/tmp/mypackage.txt - - - $NOSYS || $MYPIP install $MYPIPFLAGS coverage - - $NOSYS || $MYPIP install $MYPIPFLAGS "${MYTARBUNDLE}" - - - cd ${MYRUNDIR} - - MYGIT_REV=$($MYPYTHON -c "import ${MYNAME}.version as v; print(v.__git_commit__)") - - if [[ "${MYCOMMIT}" != "${MYGIT_REV}" ]]; then - echo "Version mismatch ${MYCOMMIT} vs ${MYGIT_REV}."; - exit 1; - fi - - -before_script: - - $NOBREW || USER_BASE="$($MYPYTHON -c 'import site; print(site.USER_BASE)')" - - $NOBREW || PATH="${USER_BASE}/bin:${PATH}" - - -script: - - coverage run --source ${MYNAME} -m ${MYNAME}.tests.run - - -after_success: - - $MYPIP install $MYPIPFLAGS codecov - - codecov diff --git a/setup.py b/setup.py deleted file mode 100755 index 5a6fc69e..00000000 --- a/setup.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python - -"""Objects for storage and manipulation of crystal structure data. - -Packages: diffpy.structure -""" - -import os -import re -import sys -from setuptools import setup, find_packages - -# Use this version when git data are not available, like in git zip archive. -# Update when tagging a new release. -FALLBACK_VERSION = '3.1.0' - -# determine if we run with Python 3. -PY3 = (sys.version_info[0] == 3) - -# versioncfgfile holds version data for git commit hash and date. -# It must reside in the same directory as version.py. -MYDIR = os.path.dirname(os.path.abspath(__file__)) -versioncfgfile = os.path.join(MYDIR, 'src/diffpy/structure/version.cfg') -gitarchivecfgfile = os.path.join(MYDIR, '.gitarchive.cfg') - - -def gitinfo(): - from subprocess import Popen, PIPE - kw = dict(stdout=PIPE, cwd=MYDIR, universal_newlines=True) - proc = Popen(['git', 'describe', '--tags', '--match=v[[:digit:]]*'], **kw) - desc = proc.stdout.read() - proc = Popen(['git', 'log', '-1', '--format=%H %ct %ci'], **kw) - glog = proc.stdout.read() - rv = {} - rv['version'] = '.post'.join(desc.strip().split('-')[:2]).lstrip('v') - rv['commit'], rv['timestamp'], rv['date'] = glog.strip().split(None, 2) - return rv - - -def getversioncfg(): - if PY3: - from configparser import RawConfigParser - else: - from ConfigParser import RawConfigParser - vd0 = dict(version=FALLBACK_VERSION, commit='', date='', timestamp=0) - # first fetch data from gitarchivecfgfile, ignore if it is unexpanded - g = vd0.copy() - cp0 = RawConfigParser(vd0) - cp0.read(gitarchivecfgfile) - if len(cp0.get('DEFAULT', 'commit')) > 20: - g = cp0.defaults() - mx = re.search(r'\btag: v(\d[^,]*)', g.pop('refnames')) - if mx: - g['version'] = mx.group(1) - # then try to obtain version data from git. - gitdir = os.path.join(MYDIR, '.git') - if os.path.exists(gitdir) or 'GIT_DIR' in os.environ: - try: - g = gitinfo() - except OSError: - pass - # finally, check and update the active version file - cp = RawConfigParser() - cp.read(versioncfgfile) - d = cp.defaults() - rewrite = not d or (g['commit'] and ( - g['version'] != d.get('version') or g['commit'] != d.get('commit'))) - if rewrite: - cp.set('DEFAULT', 'version', g['version']) - cp.set('DEFAULT', 'commit', g['commit']) - cp.set('DEFAULT', 'date', g['date']) - cp.set('DEFAULT', 'timestamp', g['timestamp']) - with open(versioncfgfile, 'w') as fp: - cp.write(fp) - return cp - -versiondata = getversioncfg() - -with open(os.path.join(MYDIR, 'README.rst')) as fp: - long_description = fp.read() - -# define distribution -setup_args = dict( - name = "diffpy.structure", - version = versiondata.get('DEFAULT', 'version'), - packages = find_packages(os.path.join(MYDIR, 'src')), - py_modules = ['diffpy.Structure'], - package_dir = {'' : 'src'}, - test_suite = 'diffpy.structure.tests', - include_package_data = True, - zip_safe = False, - install_requires = [ - 'six', - 'pycifrw>=4.4.3', - ], - author = 'Simon J.L. Billinge group', - author_email = 'sb2896@columbia.edu', - maintainer = 'Pavol Juhas', - maintainer_email = 'pavol.juhas@gmail.com', - url = 'https://github.com/diffpy/diffpy.structure', - description = "Crystal structure container " - "and parsers for structure formats.", - long_description = long_description, - long_description_content_type = 'text/x-rst', - license = 'BSD-style license', - keywords = "crystal structure data storage CIF PDB", - classifiers = [ - # List of possible values at - # http://pypi.python.org/pypi?:action=list_classifiers - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Operating System :: Unix', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Topic :: Scientific/Engineering :: Physics', - ], -) - -if __name__ == '__main__': - setup(**setup_args) From 963e3781abde5483fb28a37efe666d71ccfb35c7 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:18:07 -0400 Subject: [PATCH 011/226] modify .coveragerc --- .coveragerc | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/.coveragerc b/.coveragerc index a90c45c4..34ea3e4c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,25 +1,13 @@ -# Configuration of the coverage.py tool for reporting test coverage. - -[report] -# RE patterns for lines to be excluded from consideration. -exclude_lines = - ## Have to re-enable the standard pragma - pragma: no cover - ## Don't complain if tests don't hit defensive assertion code: - raise AssertionError - raise NotImplementedError - ^[ ]*assert False - - ## Don't complain if non-runnable code isn't run: - ^[ ]*@unittest.skip\b - ^[ ]{4}unittest.main() - if __name__ == .__main__.: - - [run] +source = + diffpy.structure +[report] omit = - ## Exclude from codecov report: - */tests/debug.py - */apps/*.py - # TODO remove in version 3.1 - */applications/*.py + */python?.?/* + */site-packages/nose/* + # ignore _version.py and versioneer.py + .*version.* + *_version.py + +exclude_lines = + if __name__ == '__main__': From 2fd8cbed050801a5bde445bb37864ec5d2e944f1 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:22:38 -0400 Subject: [PATCH 012/226] modify gitattributes --- .gitattributes | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.gitattributes b/.gitattributes index 13fc0b54..de811ba3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1 @@ -/.gitattributes export-ignore -/.gitignore export-ignore -/.travis.yml export-ignore -/conda-recipe/ export-ignore -/devutils export-ignore -/doc export-ignore -.gitarchive.cfg export-subst -*.bat text eol=crlf +diffpy.structure/_version.py export-subst From 7452562443d405b711a610e1288ef37f9e4ef21f Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:23:10 -0400 Subject: [PATCH 013/226] Merge structure/__init__ --- src/diffpy/structure/__init__.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 2f0661a5..c5197b90 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -1,15 +1,15 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2006 trustees of the Michigan State University. -# All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.structure/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## @@ -35,6 +35,10 @@ from diffpy.structure.pdffitstructure import PDFFitStructure # obtain version information + +"""Crystal structure container and parsers for structure formats.""" + +# package version from diffpy.structure.version import __version__ # top level routines @@ -76,4 +80,8 @@ def loadStructure(filename, fmt='auto', **kw): assert Lattice assert Structure assert PDFFitStructure + +# silence the pyflakes syntax checker assert __version__ or True + +# End of file From a399f18d337ff0cc1b43526eb29c6b967d523aff Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 16:24:08 -0400 Subject: [PATCH 014/226] Use new structure/version and tests/run --- src/diffpy/structure/tests/run.py | 42 ++++++++++++----------- src/diffpy/structure/version.py | 55 ++++++++----------------------- 2 files changed, 36 insertions(+), 61 deletions(-) diff --git a/src/diffpy/structure/tests/run.py b/src/diffpy/structure/tests/run.py index 5bd8b2a8..0270ad83 100644 --- a/src/diffpy/structure/tests/run.py +++ b/src/diffpy/structure/tests/run.py @@ -1,32 +1,34 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 Trustees of the Columbia University -# in the City of New York. All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.structure/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## - """Convenience module for executing all unit tests with - python -m diffpy.structure.tests.run """ +import sys + +import pytest + +if __name__ == "__main__": + # show output results from every test function + args = ["-v"] + # show the message output for skipped and expected failure tests + if len(sys.argv) > 1: + args.extend(sys.argv[1:]) + print("pytest arguments: {}".format(args)) + # call pytest and exit with the return code from pytest + exit_res = pytest.main(args) + sys.exit(exit_res) -if __name__ == '__main__': - import sys - # show warnings by default - if not sys.warnoptions: - import os, warnings - warnings.simplefilter("default") - # also affect subprocesses - os.environ["PYTHONWARNINGS"] = "default" - from diffpy.structure.tests import test - # produce zero exit code for a successful test - sys.exit(not test().wasSuccessful()) +# End of file diff --git a/src/diffpy/structure/version.py b/src/diffpy/structure/version.py index d60b34c6..be7f6a2d 100644 --- a/src/diffpy/structure/version.py +++ b/src/diffpy/structure/version.py @@ -1,53 +1,26 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2008 trustees of the Michigan State University. -# All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.structure/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -""" -Definition of __version__, __date__, __timestamp__, __git_commit__. - -Notes ------ -Variable `__gitsha__` is deprecated as of version 3.0. -Use `__git_commit__` instead. -""" - -__all__ = ['__date__', '__git_commit__', '__timestamp__', '__version__'] - -import os.path - -from pkg_resources import resource_filename - +"""Definition of __version__.""" -# obtain version information from the version.cfg file -cp = dict(version='', date='', commit='', timestamp='0') -fcfg = resource_filename(__name__, 'version.cfg') -if not os.path.isfile(fcfg): # pragma: no cover - from warnings import warn - warn('Package metadata not found, execute "./setup.py egg_info".') - fcfg = os.devnull -with open(fcfg) as fp: - kwords = [[w.strip() for w in line.split(' = ', 1)] - for line in fp if line[:1].isalpha() and ' = ' in line] -assert all(w[0] in cp for w in kwords), "received unrecognized keyword" -cp.update(kwords) +# We do not use the other three variables, but can be added back if needed. +# __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] -__version__ = cp['version'] -__date__ = cp['date'] -__git_commit__ = cp['commit'] -__timestamp__ = int(cp['timestamp']) +# obtain version information +from importlib.metadata import version -# TODO remove deprecated __gitsha__ in version 3.1. -__gitsha__ = __git_commit__ +__version__ = version("diffpy.structure") -del cp, fcfg, fp, kwords +# End of file From 576d49abd028c108d29a56ba96f0537e75306e2c Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 17:33:07 -0400 Subject: [PATCH 015/226] Licenses --- LICENSE.rst | 165 ++++++++++++++++---- LICENSE.txt | 137 ----------------- LICENSE_DANSE.txt => LICENSE_DANSE.rst | 15 +- LICENSE_pymmlib.rst | 203 +++++++++++++++++++++++++ LICENSE_pymmlib.txt | 201 ------------------------ 5 files changed, 353 insertions(+), 368 deletions(-) delete mode 100644 LICENSE.txt rename LICENSE_DANSE.txt => LICENSE_DANSE.rst (85%) create mode 100644 LICENSE_pymmlib.rst delete mode 100644 LICENSE_pymmlib.txt diff --git a/LICENSE.rst b/LICENSE.rst index 95a04ac9..f1fe010e 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -1,30 +1,141 @@ -BSD 3-Clause License +OPEN SOURCE LICENSE AGREEMENT +============================= -Copyright (c) 2024, The Trustees of Columbia University -in the City of New York. +Copyright (c) 1989, 1991 Free Software Foundation, Inc. + +Copyright (c) 2006, The Regents of the University of California through Lawrence Berkeley National Laboratory + +Copyright (c) 2006-2007, Board of Trustees of Michigan State University + +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York + +Copyright (c) 2009-2011, University of Tennessee + +Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") + +Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory + +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The "DiffPy-CMI" is distributed subject to the following license conditions: + +.. code-block:: text + + SOFTWARE LICENSE AGREEMENT + + Software: DiffPy-CMI + + + (1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either + source code, or binary form and accompanying documentation). + + Part of the software was derived from the DANSE, ObjCryst++ (with permission), + PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of + which the original Copyrights are contained in each individual file. + + Each licensee is addressed as "you" or "Licensee." + + + (2) The copyright holders shown above and their third-party Licensors hereby + grant licensee a royalty-free nonexclusive license, subject to the limitations + stated herein and U.S. Government license rights. + + + (3) You may modify and make a copy or copies of the software for use within + your organization, if you meet the following conditions: + + (a) Copies in source code must include the copyright notice and this + software license agreement. + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy. + + + (4) You may modify a copy or copies of the Software or any portion of it, thus + forming a work based on the Software, and distribute copies of such work + outside your organization, if you meet all of the following conditions: + + (a) Copies in source code must include the copyright notice and this + Software License Agreement; + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy; + + (c) Modified copies and works based on the Software must carry prominent + notices stating that you changed specified portions of the Software. + + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + + (5) Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: + The Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer software + to reproduce, prepare derivative works, and perform publicly and display + publicly. + + + (6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND + THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL + LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE + PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION + UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + + (7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING + BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, + WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING + NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS + BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + +END OF LICENSE diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index f6d92af7..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,137 +0,0 @@ -OPEN SOURCE LICENSE AGREEMENT -============================= - -Copyright (c) 2009-2011, University of Tennessee -Copyright (c) 1989, 1991 Free Software Foundation, Inc. -Copyright (c) 2006, The Regents of the University of California through - Lawrence Berkeley National Laboratory -Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") -Copyright (c) 2006-2007, Board of Trustees of Michigan State University -Copyright (c) 2008-2012, The Trustees of Columbia University in the City - of New York - -Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National - Laboratory - - -The "DiffPy-CMI" is distributed subject to the following license conditions: - - -SOFTWARE LICENSE AGREEMENT - - Software: DiffPy-CMI - - -(1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either -source code, or binary form and accompanying documentation). - -Part of the software was derived from the DANSE, ObjCryst++ (with permission), -PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of -which the original Copyrights are contained in each individual file. - -Each licensee is addressed as "you" or "Licensee." - - -(2) The copyright holders shown above and their third-party Licensors hereby -grant licensee a royalty-free nonexclusive license, subject to the limitations -stated herein and U.S. Government license rights. - - -(3) You may modify and make a copy or copies of the software for use within -your organization, if you meet the following conditions: - - (a) Copies in source code must include the copyright notice and this - software license agreement. - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy. - - -(4) You may modify a copy or copies of the Software or any portion of it, thus -forming a work based on the Software, and distribute copies of such work -outside your organization, if you meet all of the following conditions: - - (a) Copies in source code must include the copyright notice and this - Software License Agreement; - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy; - - (c) Modified copies and works based on the Software must carry prominent - notices stating that you changed specified portions of the Software. - - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -END OF LICENSE diff --git a/LICENSE_DANSE.txt b/LICENSE_DANSE.rst similarity index 85% rename from LICENSE_DANSE.txt rename to LICENSE_DANSE.rst index 2a101560..c05648e1 100644 --- a/LICENSE_DANSE.txt +++ b/LICENSE_DANSE.rst @@ -1,26 +1,35 @@ +LICENSE +======= + This program is part of the DiffPy and DANSE open-source projects and is available subject to the conditions and terms laid out below. Copyright 2006-2007, Board of Trustees of Michigan State University, + Copyright 2008-2012, The Trustees of Columbia University in the City of New York. (Copyright holder indicated in each source file). +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +All rights reserved. + For more information please visit the project web-page: + http://www.diffpy.org/ + or email Prof. Simon Billinge at sb2896@columbia.edu Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its +- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/LICENSE_pymmlib.rst b/LICENSE_pymmlib.rst new file mode 100644 index 00000000..e0b82c94 --- /dev/null +++ b/LICENSE_pymmlib.rst @@ -0,0 +1,203 @@ +.. code-block:: text + + The Artistic License 2.0 + + Copyright (c) 2000-2006, The Perl Foundation. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + This license establishes the terms under which a given free software + Package may be copied, modified, distributed, and/or redistributed. + The intent is that the Copyright Holder maintains some artistic + control over the development of that Package while still keeping the + Package available as open source and free software. + + You are always permitted to make arrangements wholly outside of this + license directly with the Copyright Holder of a given Package. If the + terms of this license do not permit the full use that you propose to + make of the Package, you should contact the Copyright Holder and seek + a different licensing arrangement. + + Definitions + + "Copyright Holder" means the individual(s) or organization(s) + named in the copyright notice for the entire Package. + + "Contributor" means any party that has contributed code or other + material to the Package, in accordance with the Copyright Holder's + procedures. + + "You" and "your" means any person who would like to copy, + distribute, or modify the Package. + + "Package" means the collection of files distributed by the + Copyright Holder, and derivatives of that collection and/or of + those files. A given Package may consist of either the Standard + Version, or a Modified Version. + + "Distribute" means providing a copy of the Package or making it + accessible to anyone else, or in the case of a company or + organization, to others outside of your company or organization. + + "Distributor Fee" means any fee that you charge for Distributing + this Package or providing support for this Package to another + party. It does not mean licensing fees. + + "Standard Version" refers to the Package if it has not been + modified, or has been modified only in ways explicitly requested + by the Copyright Holder. + + "Modified Version" means the Package, if it has been changed, and + such changes were not explicitly requested by the Copyright + Holder. + + "Original License" means this Artistic License as Distributed with + the Standard Version of the Package, in its current version or as + it may be modified by The Perl Foundation in the future. + + "Source" form means the source code, documentation source, and + configuration files for the Package. + + "Compiled" form means the compiled bytecode, object code, binary, + or any other form resulting from mechanical transformation or + translation of the Source form. + + + Permission for Use and Modification Without Distribution + + (1) You are permitted to use the Standard Version and create and use + Modified Versions for any purpose without restriction, provided that + you do not Distribute the Modified Version. + + + Permissions for Redistribution of the Standard Version + + (2) You may Distribute verbatim copies of the Source form of the + Standard Version of this Package in any medium without restriction, + either gratis or for a Distributor Fee, provided that you duplicate + all of the original copyright notices and associated disclaimers. At + your discretion, such verbatim copies may or may not include a + Compiled form of the Package. + + (3) You may apply any bug fixes, portability changes, and other + modifications made available from the Copyright Holder. The resulting + Package will still be considered the Standard Version, and as such + will be subject to the Original License. + + + Distribution of Modified Versions of the Package as Source + + (4) You may Distribute your Modified Version as Source (either gratis + or for a Distributor Fee, and with or without a Compiled form of the + Modified Version) provided that you clearly document how it differs + from the Standard Version, including, but not limited to, documenting + any non-standard features, executables, or modules, and provided that + you do at least ONE of the following: + + (a) make the Modified Version available to the Copyright Holder + of the Standard Version, under the Original License, so that the + Copyright Holder may include your modifications in the Standard + Version. + + (b) ensure that installation of your Modified Version does not + prevent the user installing or running the Standard Version. In + addition, the Modified Version must bear a name that is different + from the name of the Standard Version. + + (c) allow anyone who receives a copy of the Modified Version to + make the Source form of the Modified Version available to others + under + + (i) the Original License or + + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. + + + Distribution of Compiled Forms of the Standard Version + or Modified Versions without the Source + + (5) You may Distribute Compiled forms of the Standard Version without + the Source, provided that you include complete instructions on how to + get the Source of the Standard Version. Such instructions must be + valid at the time of your distribution. If these instructions, at any + time while you are carrying out such distribution, become invalid, you + must provide new instructions on demand or cease further distribution. + If you provide valid instructions or cease distribution within thirty + days after you become aware that the instructions are invalid, then + you do not forfeit any of your rights under this license. + + (6) You may Distribute a Modified Version in Compiled form without + the Source, provided that you comply with Section 4 with respect to + the Source of the Modified Version. + + + Aggregating or Linking the Package + + (7) You may aggregate the Package (either the Standard Version or + Modified Version) with other packages and Distribute the resulting + aggregation provided that you do not charge a licensing fee for the + Package. Distributor Fees are permitted, and licensing fees for other + components in the aggregation are permitted. The terms of this license + apply to the use and Distribution of the Standard or Modified Versions + as included in the aggregation. + + (8) You are permitted to link Modified and Standard Versions with + other works, to embed the Package in a larger work of your own, or to + build stand-alone binary or bytecode versions of applications that + include the Package, and Distribute the result without restriction, + provided the result does not expose a direct interface to the Package. + + + Items That are Not Considered Part of a Modified Version + + (9) Works (including, but not limited to, modules and scripts) that + merely extend or make use of the Package, do not, by themselves, cause + the Package to be a Modified Version. In addition, such works are not + considered parts of the Package itself, and are not subject to the + terms of this license. + + + General Provisions + + (10) Any use, modification, and distribution of the Standard or + Modified Versions is governed by this Artistic License. By using, + modifying or distributing the Package, you accept this license. Do not + use, modify, or distribute the Package, if you do not accept this + license. + + (11) If your Modified Version has been derived from a Modified + Version made by someone other than you, you are nevertheless required + to ensure that your Modified Version complies with the requirements of + this license. + + (12) This license does not grant you the right to use any trademark, + service mark, tradename, or logo of the Copyright Holder. + + (13) This license includes the non-exclusive, worldwide, + free-of-charge patent license to make, have made, use, offer to sell, + sell, import and otherwise transfer the Package with respect to any + patent claims licensable by the Copyright Holder that are necessarily + infringed by the Package. If you institute patent litigation + (including a cross-claim or counterclaim) against any party alleging + that the Package constitutes direct or contributory patent + infringement, then this Artistic License to you shall terminate on the + date that such litigation is filed. + + (14) Disclaimer of Warranty: + THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS + IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL + LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSE_pymmlib.txt b/LICENSE_pymmlib.txt deleted file mode 100644 index 7d61f060..00000000 --- a/LICENSE_pymmlib.txt +++ /dev/null @@ -1,201 +0,0 @@ - The Artistic License 2.0 - - Copyright (c) 2000-2006, The Perl Foundation. - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Preamble - -This license establishes the terms under which a given free software -Package may be copied, modified, distributed, and/or redistributed. -The intent is that the Copyright Holder maintains some artistic -control over the development of that Package while still keeping the -Package available as open source and free software. - -You are always permitted to make arrangements wholly outside of this -license directly with the Copyright Holder of a given Package. If the -terms of this license do not permit the full use that you propose to -make of the Package, you should contact the Copyright Holder and seek -a different licensing arrangement. - -Definitions - - "Copyright Holder" means the individual(s) or organization(s) - named in the copyright notice for the entire Package. - - "Contributor" means any party that has contributed code or other - material to the Package, in accordance with the Copyright Holder's - procedures. - - "You" and "your" means any person who would like to copy, - distribute, or modify the Package. - - "Package" means the collection of files distributed by the - Copyright Holder, and derivatives of that collection and/or of - those files. A given Package may consist of either the Standard - Version, or a Modified Version. - - "Distribute" means providing a copy of the Package or making it - accessible to anyone else, or in the case of a company or - organization, to others outside of your company or organization. - - "Distributor Fee" means any fee that you charge for Distributing - this Package or providing support for this Package to another - party. It does not mean licensing fees. - - "Standard Version" refers to the Package if it has not been - modified, or has been modified only in ways explicitly requested - by the Copyright Holder. - - "Modified Version" means the Package, if it has been changed, and - such changes were not explicitly requested by the Copyright - Holder. - - "Original License" means this Artistic License as Distributed with - the Standard Version of the Package, in its current version or as - it may be modified by The Perl Foundation in the future. - - "Source" form means the source code, documentation source, and - configuration files for the Package. - - "Compiled" form means the compiled bytecode, object code, binary, - or any other form resulting from mechanical transformation or - translation of the Source form. - - -Permission for Use and Modification Without Distribution - -(1) You are permitted to use the Standard Version and create and use -Modified Versions for any purpose without restriction, provided that -you do not Distribute the Modified Version. - - -Permissions for Redistribution of the Standard Version - -(2) You may Distribute verbatim copies of the Source form of the -Standard Version of this Package in any medium without restriction, -either gratis or for a Distributor Fee, provided that you duplicate -all of the original copyright notices and associated disclaimers. At -your discretion, such verbatim copies may or may not include a -Compiled form of the Package. - -(3) You may apply any bug fixes, portability changes, and other -modifications made available from the Copyright Holder. The resulting -Package will still be considered the Standard Version, and as such -will be subject to the Original License. - - -Distribution of Modified Versions of the Package as Source - -(4) You may Distribute your Modified Version as Source (either gratis -or for a Distributor Fee, and with or without a Compiled form of the -Modified Version) provided that you clearly document how it differs -from the Standard Version, including, but not limited to, documenting -any non-standard features, executables, or modules, and provided that -you do at least ONE of the following: - - (a) make the Modified Version available to the Copyright Holder - of the Standard Version, under the Original License, so that the - Copyright Holder may include your modifications in the Standard - Version. - - (b) ensure that installation of your Modified Version does not - prevent the user installing or running the Standard Version. In - addition, the Modified Version must bear a name that is different - from the name of the Standard Version. - - (c) allow anyone who receives a copy of the Modified Version to - make the Source form of the Modified Version available to others - under - - (i) the Original License or - - (ii) a license that permits the licensee to freely copy, - modify and redistribute the Modified Version using the same - licensing terms that apply to the copy that the licensee - received, and requires that the Source form of the Modified - Version, and of any works derived from it, be made freely - available in that license fees are prohibited but Distributor - Fees are allowed. - - -Distribution of Compiled Forms of the Standard Version -or Modified Versions without the Source - -(5) You may Distribute Compiled forms of the Standard Version without -the Source, provided that you include complete instructions on how to -get the Source of the Standard Version. Such instructions must be -valid at the time of your distribution. If these instructions, at any -time while you are carrying out such distribution, become invalid, you -must provide new instructions on demand or cease further distribution. -If you provide valid instructions or cease distribution within thirty -days after you become aware that the instructions are invalid, then -you do not forfeit any of your rights under this license. - -(6) You may Distribute a Modified Version in Compiled form without -the Source, provided that you comply with Section 4 with respect to -the Source of the Modified Version. - - -Aggregating or Linking the Package - -(7) You may aggregate the Package (either the Standard Version or -Modified Version) with other packages and Distribute the resulting -aggregation provided that you do not charge a licensing fee for the -Package. Distributor Fees are permitted, and licensing fees for other -components in the aggregation are permitted. The terms of this license -apply to the use and Distribution of the Standard or Modified Versions -as included in the aggregation. - -(8) You are permitted to link Modified and Standard Versions with -other works, to embed the Package in a larger work of your own, or to -build stand-alone binary or bytecode versions of applications that -include the Package, and Distribute the result without restriction, -provided the result does not expose a direct interface to the Package. - - -Items That are Not Considered Part of a Modified Version - -(9) Works (including, but not limited to, modules and scripts) that -merely extend or make use of the Package, do not, by themselves, cause -the Package to be a Modified Version. In addition, such works are not -considered parts of the Package itself, and are not subject to the -terms of this license. - - -General Provisions - -(10) Any use, modification, and distribution of the Standard or -Modified Versions is governed by this Artistic License. By using, -modifying or distributing the Package, you accept this license. Do not -use, modify, or distribute the Package, if you do not accept this -license. - -(11) If your Modified Version has been derived from a Modified -Version made by someone other than you, you are nevertheless required -to ensure that your Modified Version complies with the requirements of -this license. - -(12) This license does not grant you the right to use any trademark, -service mark, tradename, or logo of the Copyright Holder. - -(13) This license includes the non-exclusive, worldwide, -free-of-charge patent license to make, have made, use, offer to sell, -sell, import and otherwise transfer the Package with respect to any -patent claims licensable by the Copyright Holder that are necessarily -infringed by the Package. If you institute patent litigation -(including a cross-claim or counterclaim) against any party alleging -that the Package constitutes direct or contributory patent -infringement, then this Artistic License to you shall terminate on the -date that such litigation is filed. - -(14) Disclaimer of Warranty: -THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS -IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR -NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL -LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 06ead97b9202093c96ea983a13118d849c09f40b Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 17:36:44 -0400 Subject: [PATCH 016/226] MANIFEST --- MANIFEST.in | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index eb0a5627..3bcdfb4f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,15 +1,14 @@ -recursive-include src * -include AUTHORS.txt LICENSE*.txt README.rst -recursive-exclude src *.pyc -global-exclude .gitattributes .gitignore .gitarchive.cfg -global-exclude .DS_Store - -# Avoid user content in setup.cfg to make distribution reproducible. -exclude setup.cfg - -# Exclude git-tracked files spuriously added by setuptools_scm -exclude .coveragerc -exclude .travis* -prune conda-recipe -prune devutils -prune doc +include AUTHORS.rst +include LICENSE +include README.rst +include requirements.txt + +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] + +recursive-include docs *.rst conf.py Makefile make.bat + +include diffpy.structure/version.py + +# If including data files in the package, add them like: +# include path/to/data_file From 0d5e895b8bfd1c24357c9e6e98027f070178f147 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 1 Jul 2024 20:56:06 -0400 Subject: [PATCH 017/226] API --- .../api/diffpy.structure.applications.rst | 29 +++++ doc/source/api/diffpy.structure.apps.rst | 29 +++++ .../api/diffpy.structure.example_package.rst | 31 ----- doc/source/api/diffpy.structure.expansion.rst | 37 ++++++ doc/source/api/diffpy.structure.parsers.rst | 93 +++++++++++++++ doc/source/api/diffpy.structure.rst | 108 ++++++++++++++++-- 6 files changed, 287 insertions(+), 40 deletions(-) create mode 100644 doc/source/api/diffpy.structure.applications.rst create mode 100644 doc/source/api/diffpy.structure.apps.rst delete mode 100644 doc/source/api/diffpy.structure.example_package.rst create mode 100644 doc/source/api/diffpy.structure.expansion.rst create mode 100644 doc/source/api/diffpy.structure.parsers.rst diff --git a/doc/source/api/diffpy.structure.applications.rst b/doc/source/api/diffpy.structure.applications.rst new file mode 100644 index 00000000..57dedf41 --- /dev/null +++ b/doc/source/api/diffpy.structure.applications.rst @@ -0,0 +1,29 @@ +:tocdepth: -1 + +diffpy.structure.applications package +===================================== + +.. automodule:: diffpy.structure.applications + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.structure.applications.transtru module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.applications.transtru + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.applications.anyeye module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.applications.anyeye + :members: + :undoc-members: + :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.apps.rst b/doc/source/api/diffpy.structure.apps.rst new file mode 100644 index 00000000..5ac351dd --- /dev/null +++ b/doc/source/api/diffpy.structure.apps.rst @@ -0,0 +1,29 @@ +:tocdepth: -1 + +diffpy.structure.apps package +============================= + +.. automodule:: diffpy.structure.apps + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.structure.apps.transtru module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.apps.transtru + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.apps.anyeye module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.apps.anyeye + :members: + :undoc-members: + :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.example_package.rst b/doc/source/api/diffpy.structure.example_package.rst deleted file mode 100644 index 3595000a..00000000 --- a/doc/source/api/diffpy.structure.example_package.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. _example_package documentation: - -|title| -======= - -.. |title| replace:: diffpy.structure.example_package package - -.. automodule:: diffpy.structure.example_package - :members: - :undoc-members: - :show-inheritance: - -|foo| ------ - -.. |foo| replace:: diffpy.structure.example_package.foo module - -.. automodule:: diffpy.structure.example_package.foo - :members: - :undoc-members: - :show-inheritance: - -|bar| ------ - -.. |bar| replace:: diffpy.structure.example_package.bar module - -.. automodule:: diffpy.structure.example_package.foo - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/diffpy.structure.expansion.rst b/doc/source/api/diffpy.structure.expansion.rst new file mode 100644 index 00000000..afce983c --- /dev/null +++ b/doc/source/api/diffpy.structure.expansion.rst @@ -0,0 +1,37 @@ +:tocdepth: -1 + +diffpy.structure.expansion package +================================== + +.. automodule:: diffpy.structure.expansion + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.structure.expansion.shapeutils module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.expansion.shapeutils + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.expansion.makeellipsoid module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.expansion.makeellipsoid + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.expansion.supercell_mod module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.expansion.supercell_mod + :members: + :undoc-members: + :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.parsers.rst b/doc/source/api/diffpy.structure.parsers.rst new file mode 100644 index 00000000..54a88f2e --- /dev/null +++ b/doc/source/api/diffpy.structure.parsers.rst @@ -0,0 +1,93 @@ +:tocdepth: -1 + +diffpy.structure.parsers package +================================ + +.. automodule:: diffpy.structure.parsers + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.structure.parsers.p_rawxyz module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_rawxyz + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.structureparser module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.structureparser + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_cif module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_cif + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_auto module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_auto + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_pdffit module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_pdffit + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_xcfg module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_xcfg + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.parser_index_mod module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.parser_index_mod + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_pdb module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_pdb + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_discus module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_discus + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.parsers.p_xyz module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_xyz + :members: + :undoc-members: + :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index cdcc80ea..8d60dd1c 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -1,9 +1,7 @@ :tocdepth: -1 -|title| -======= - -.. |title| replace:: diffpy.structure package +diffpy.structure package +======================== .. automodule:: diffpy.structure :members: @@ -14,17 +12,109 @@ Subpackages ----------- .. toctree:: - diffpy.structure.example_package + :titlesonly: + + diffpy.structure.parsers + diffpy.structure.expansion + diffpy.structure.applications + diffpy.structure.apps Submodules ---------- -|module| --------- +diffpy.structure.spacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.spacegroups + :members: + :undoc-members: + :show-inheritance: -.. |module| replace:: diffpy.structure.example_submodule module +diffpy.structure._legacy_importer module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.structure.example_submodule +.. automodule:: diffpy.structure._legacy_importer :members: :undoc-members: :show-inheritance: + +diffpy.structure.structureerrors module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.structureerrors + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.spacegroupmod module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.spacegroupmod + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.utils module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.utils + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.lattice module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.lattice + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.structure module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.structure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.mmlibspacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.mmlibspacegroups + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.symmetryutilities module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.symmetryutilities + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.atom module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.atom + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.pdffitstructure module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.pdffitstructure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.sgtbxspacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.sgtbxspacegroups + :members: + :undoc-members: + :show-inheritance: + From ef95170146298a5ff2a6bacadb6ef5d491b15ae6 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 2 Jul 2024 11:02:15 -0400 Subject: [PATCH 018/226] CHANGELOG --- CHANGELOG.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e446d478..3d4b5e17 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,23 @@ Release Notes .. current developments +Version 3.2.0 - 2024-7-2 +-------------------------- +**Added:** + +**Changed:** + +**Deprecated:** + +**Removed:** + +**Fixed:** + +- Repo structure modified to the new diffpy standard + +**Security:** + + Version 3.1.0 - 2022-12-04 -------------------------- From 0ca1c9e215d6543269c868d6ee56f13daa5a546b Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 2 Jul 2024 16:01:56 -0400 Subject: [PATCH 019/226] deleted: doc/source/package.rst --- doc/source/package.rst | 130 ----------------------------------------- 1 file changed, 130 deletions(-) delete mode 100644 doc/source/package.rst diff --git a/doc/source/package.rst b/doc/source/package.rst deleted file mode 100644 index 4179f8e3..00000000 --- a/doc/source/package.rst +++ /dev/null @@ -1,130 +0,0 @@ -:tocdepth: 2 - -Package API -########### - - -Submodules -========== - -.. toctree:: - :titlesonly: - - mod_atom - mod_lattice - mod_spacegroup - diffpy.structure.parsers - diffpy.structure.apps - diffpy.structure.expansion - - -diffpy.structure -================ - -.. module:: diffpy.structure - -The top-level diffpy.structure module provides the following objects. - - -Functions ---------- - -.. autofunction:: loadStructure - - -Classes -------- - -:py:class:`~atom.Atom` - describes one atom site in the structure - its type, position, - displacement parameters and so forth. - -:py:class:`~lattice.Lattice` - depicts general coordinate system and associated operations. - -:py:class:`~structure.Structure` - collection of :class:`!Atom` objects that form the structure together - with associated :py:class:`!Lattice`. - - -Exceptions ----------- - -.. autoclass:: StructureFormatError - -.. autoclass:: LatticeError - -.. autoclass:: SymmetryError - - -diffpy.structure.spacegroups -============================ - -.. automodule:: diffpy.structure.spacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structureerrors -================================ - -.. automodule:: diffpy.structure.structureerrors - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.symmetryutilities -================================== - -.. automodule:: diffpy.structure.symmetryutilities - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.mmlibspacegroups -================================= - -.. automodule:: diffpy.structure.mmlibspacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.pdffitstructure -================================ - -.. automodule:: diffpy.structure.pdffitstructure - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.sgtbxspacegroups -================================= - -.. automodule:: diffpy.structure.sgtbxspacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structure -========================== - -.. automodule:: diffpy.structure.structure - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.utils -====================== - -.. automodule:: diffpy.structure.utils - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.version -======================== - -.. automodule:: diffpy.structure.version - :members: - :undoc-members: - :show-inheritance: From 602047fd391a872c230ed2f5bb2545b8446447f8 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 2 Jul 2024 16:21:05 -0400 Subject: [PATCH 020/226] add more information in README and index --- README.rst | 14 ++++++++++++-- doc/source/index.rst | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 8c6adad8..5dd3a227 100644 --- a/README.rst +++ b/README.rst @@ -52,9 +52,16 @@ For more information about the diffpy.structure library, please consult our `onl Citation -------- -If you use diffpy.structure in a scientific publication, we would like you to cite this package as +If you use this program for a scientific research that leads +to publication, we ask that you acknowledge use of the program +by citing the following paper in your publication: - diffpy.structure Package, https://github.com/diffpy/diffpy.structure + P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, + `Complex modeling: a strategy and software program for combining + multiple information sources to solve ill posed structure and + nanostructure inverse problems + `__, + *Acta Crystallogr. A* **71**, 562-568 (2015). Installation ------------ @@ -129,6 +136,9 @@ Acknowledgement Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* originate from the `pymmlib project `_. +Less common settings of space groups were generating using the +`Computational Crystallography Toolbox `_. + Contact ------- diff --git a/doc/source/index.rst b/doc/source/index.rst index 54ec3695..457e4105 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,16 +9,52 @@ diffpy.structure - Crystal structure container and parsers for structure formats | Software version |release|. | Last updated |today|. +The diffpy.structure package provides objects for storing atomic +coordinates, displacement parameters and other crystal structure data. +diffpy.structure supports import and export of structure data in several +structure formats such as CIF, PDB, xyz. It provides conversion +between fractional and absolute Cartesian coordinates, functions for +symmetry expansion from asymmetric unit and generation of symmetry +constraints for atom positions and displacement parameters. diffpy.structure +includes definitions of all space groups in over 500 symmetry settings. + ======= Authors ======= -diffpy.structure is developed by Billinge Group -and its community contributors. +diffpy.structure is developed by members of the Billinge Group at +Columbia University and at Brookhaven National Laboratory including +Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.structure/graphs/contributors. +Acknowledgments +=============== + +Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* +originate from the pymmlib project, http://pymmlib.sourceforge.net. +Less common settings of space groups were generating using the +Computational Crystallography Toolbox, +http://cctbx.sourceforge.net. + + +.. index:: citation, reference + +Reference +========= + +If you use this program for a scientific research that leads +to publication, we ask that you acknowledge use of the program +by citing the following paper in your publication: + + P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, + `Complex modeling: a strategy and software program for combining + multiple information sources to solve ill posed structure and + nanostructure inverse problems + `__, + *Acta Crystallogr. A* **71**, 562-568 (2015). + ============ Installation ============ @@ -29,6 +65,7 @@ file included with the distribution. ================= Table of contents ================= + .. toctree:: :titlesonly: From 31fa5720a1bde8f77609216943e0188ed9938fbd Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 2 Jul 2024 16:27:08 -0400 Subject: [PATCH 021/226] switch back to unittest run for now --- src/diffpy/structure/tests/run.py | 42 +++++++++++++++---------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/diffpy/structure/tests/run.py b/src/diffpy/structure/tests/run.py index 0270ad83..5bd8b2a8 100644 --- a/src/diffpy/structure/tests/run.py +++ b/src/diffpy/structure/tests/run.py @@ -1,34 +1,32 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024 The Trustees of Columbia University in the City of New York. -# All rights reserved. +# diffpy.structure by DANSE Diffraction group +# Simon J. L. Billinge +# (c) 2010 Trustees of the Columbia University +# in the City of New York. All rights reserved. # -# File coded by: Billinge Group members and community contributors. +# File coded by: Pavol Juhas # -# See GitHub contributions for a more detailed list of contributors. -# https://github.com/diffpy/diffpy.structure/graphs/contributors -# -# See LICENSE.rst for license information. +# See AUTHORS.txt for a list of people who contributed. +# See LICENSE_DANSE.txt for license information. # ############################################################################## + """Convenience module for executing all unit tests with + python -m diffpy.structure.tests.run """ -import sys - -import pytest - -if __name__ == "__main__": - # show output results from every test function - args = ["-v"] - # show the message output for skipped and expected failure tests - if len(sys.argv) > 1: - args.extend(sys.argv[1:]) - print("pytest arguments: {}".format(args)) - # call pytest and exit with the return code from pytest - exit_res = pytest.main(args) - sys.exit(exit_res) -# End of file +if __name__ == '__main__': + import sys + # show warnings by default + if not sys.warnoptions: + import os, warnings + warnings.simplefilter("default") + # also affect subprocesses + os.environ["PYTHONWARNINGS"] = "default" + from diffpy.structure.tests import test + # produce zero exit code for a successful test + sys.exit(not test().wasSuccessful()) From 4e3f6844eea2102fa90cd4cc11614fa9aff130ef Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:28:05 +0000 Subject: [PATCH 022/226] [pre-commit.ci] auto fixes from pre-commit hooks --- devutils/makesdist | 38 +- devutils/sgtbx_extra_groups.py | 87 +- .../api/diffpy.structure.applications.rst | 1 - doc/source/api/diffpy.structure.apps.rst | 1 - doc/source/api/diffpy.structure.expansion.rst | 1 - doc/source/api/diffpy.structure.parsers.rst | 1 - doc/source/api/diffpy.structure.rst | 1 - src/diffpy/Structure.py | 2 +- src/diffpy/__init__.py | 1 - src/diffpy/structure/__init__.py | 13 +- src/diffpy/structure/_legacy_importer.py | 21 +- src/diffpy/structure/applications/__init__.py | 9 +- src/diffpy/structure/apps/anyeye.py | 125 +- src/diffpy/structure/apps/transtru.py | 22 +- src/diffpy/structure/atom.py | 177 +- .../structure/expansion/makeellipsoid.py | 15 +- src/diffpy/structure/expansion/shapeutils.py | 3 +- .../structure/expansion/supercell_mod.py | 16 +- src/diffpy/structure/lattice.py | 271 +- src/diffpy/structure/mmlibspacegroups.py | 13997 ++++++++-------- src/diffpy/structure/parsers/__init__.py | 14 +- src/diffpy/structure/parsers/p_auto.py | 38 +- src/diffpy/structure/parsers/p_cif.py | 359 +- src/diffpy/structure/parsers/p_discus.py | 138 +- src/diffpy/structure/parsers/p_pdb.py | 252 +- src/diffpy/structure/parsers/p_pdffit.py | 194 +- src/diffpy/structure/parsers/p_rawxyz.py | 25 +- src/diffpy/structure/parsers/p_xcfg.py | 317 +- src/diffpy/structure/parsers/p_xyz.py | 33 +- .../structure/parsers/parser_index_mod.py | 120 +- .../structure/parsers/structureparser.py | 14 +- src/diffpy/structure/pdffitstructure.py | 38 +- src/diffpy/structure/sgtbxspacegroups.py | 4796 +++--- src/diffpy/structure/spacegroupmod.py | 269 +- src/diffpy/structure/spacegroups.py | 1470 +- src/diffpy/structure/structure.py | 369 +- src/diffpy/structure/structureerrors.py | 13 +- src/diffpy/structure/symmetryutilities.py | 295 +- src/diffpy/structure/tests/__init__.py | 24 +- src/diffpy/structure/tests/run.py | 8 +- src/diffpy/structure/tests/testatom.py | 74 +- .../structure/tests/testdata/CdSe_bulk.stru | 4 +- .../structure/tests/testdata/LiCl-bad.cif | 19 +- .../structure/tests/testdata/Ni-bad.stru | 4 +- .../structure/tests/testdata/Ni-discus.stru | 4 +- src/diffpy/structure/tests/testdata/Ni.stru | 4 +- .../structure/tests/testdata/Ni_ref.cif | 1 - .../structure/tests/testdata/arginine.pdb | 56 +- .../structure/tests/testdata/bucky-bad2.xyz | 2 - src/diffpy/structure/tests/testdata/bucky.xyz | 2 - src/diffpy/structure/tests/testlattice.py | 145 +- .../structure/tests/testloadstructure.py | 45 +- src/diffpy/structure/tests/testoldimports.py | 33 +- src/diffpy/structure/tests/testp_cif.py | 285 +- src/diffpy/structure/tests/testp_discus.py | 114 +- src/diffpy/structure/tests/testp_pdffit.py | 189 +- src/diffpy/structure/tests/testparsers.py | 189 +- src/diffpy/structure/tests/testspacegroups.py | 63 +- src/diffpy/structure/tests/teststructure.py | 372 +- src/diffpy/structure/tests/testsupercell.py | 45 +- .../structure/tests/testsymmetryutilities.py | 333 +- src/diffpy/structure/tests/testutils.py | 2 + src/diffpy/structure/utils.py | 18 +- 63 files changed, 13706 insertions(+), 11885 deletions(-) diff --git a/devutils/makesdist b/devutils/makesdist index 6aaae616..e77257ea 100755 --- a/devutils/makesdist +++ b/devutils/makesdist @@ -1,51 +1,57 @@ #!/usr/bin/env python -'''Create source distribution tar.gz archive, where each file belongs +"""Create source distribution tar.gz archive, where each file belongs to a root user and modification time is set to the git commit time. -''' +""" -import sys +import glob +import gzip import os import subprocess -import glob +import sys import tarfile -import gzip BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, BASEDIR) -from setup import versiondata, FALLBACK_VERSION -timestamp = versiondata.getint('DEFAULT', 'timestamp') +from setup import FALLBACK_VERSION, versiondata -vfb = versiondata.get('DEFAULT', 'version').split('.post')[0] + '.post0' +timestamp = versiondata.getint("DEFAULT", "timestamp") + +vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" emsg = "Invalid FALLBACK_VERSION. Expected %r got %r." assert vfb == FALLBACK_VERSION, emsg % (vfb, FALLBACK_VERSION) + def inform(s): sys.stdout.write(s) sys.stdout.flush() return + inform('Run "setup.py sdist --formats=tar" ') -cmd_sdist = [sys.executable] + 'setup.py sdist --formats=tar'.split() -ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, 'w')) -if ec: sys.exit(ec) +cmd_sdist = [sys.executable] + "setup.py sdist --formats=tar".split() +ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, "w")) +if ec: + sys.exit(ec) inform("[done]\n") -tarname = max(glob.glob(BASEDIR + '/dist/*.tar'), key=os.path.getmtime) +tarname = max(glob.glob(BASEDIR + "/dist/*.tar"), key=os.path.getmtime) tfin = tarfile.open(tarname) -fpout = gzip.GzipFile(tarname + '.gz', 'w', mtime=0) -tfout = tarfile.open(fileobj=fpout, mode='w') +fpout = gzip.GzipFile(tarname + ".gz", "w", mtime=0) +tfout = tarfile.open(fileobj=fpout, mode="w") + def fixtarinfo(tinfo): tinfo.uid = tinfo.gid = 0 - tinfo.uname = tinfo.gname = 'root' + tinfo.uname = tinfo.gname = "root" tinfo.mtime = timestamp tinfo.mode &= ~0o022 return tinfo -inform('Filter %s --> %s.gz ' % (2 * (os.path.basename(tarname),))) + +inform("Filter %s --> %s.gz " % (2 * (os.path.basename(tarname),))) for ti in tfin: tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py index 5c61ded0..4cab28c2 100644 --- a/devutils/sgtbx_extra_groups.py +++ b/devutils/sgtbx_extra_groups.py @@ -1,28 +1,31 @@ #!/usr/bin/env python -'''Quick and extremely dirty script for generating code for SpaceGroup that +"""Quick and extremely dirty script for generating code for SpaceGroup that are defined in cctbx, but not in mmLib. It was used to generate module sgtbxspacegroups. This is a utility script that should not be included with code distribution. Not to be included with code distributions. -''' +""" -import re import math +import re + import numpy -from diffpy.structure.spacegroups import SpaceGroup, SymOp -from diffpy.structure.spacegroups import mmLibSpaceGroupList -from diffpy.structure.spacegroups import IsSpaceGroupIdentifier from cctbx import sgtbx +from diffpy.structure.spacegroups import IsSpaceGroupIdentifier, SpaceGroup, SymOp, mmLibSpaceGroupList + + def tupleToSGArray(tpl): if not _rtarrays: import diffpy.structure.SpaceGroups as sgmod + for n in dir(sgmod): - if not n.startswith('Rot_') and not n.startswith('Tr_'): continue + if not n.startswith("Rot_") and not n.startswith("Tr_"): + continue a = getattr(sgmod, n) t = tuple(a.flatten()) _rtarrays[t] = a @@ -31,12 +34,13 @@ def tupleToSGArray(tpl): if tpl not in _rtarrays: _rtarrays[tpl] = numpy.array(tpl, dtype=float) return _rtarrays[tpl] + + _rtarrays = {} def mmSpaceGroupFromSymbol(symbol): - """Construct SpaceGroup instance from a string symbol using sgtbx data. - """ + """Construct SpaceGroup instance from a string symbol using sgtbx data.""" sginfo = sgtbx.space_group_info(symbol) symop_list = [] symop_list = getSymOpList(sginfo.group()) @@ -44,16 +48,16 @@ def mmSpaceGroupFromSymbol(symbol): uhm = sgtype.lookup_symbol() sgsmbls = sgtbx.space_group_symbols(uhm) kw = {} - kw['number'] = sgtype.number() - kw['num_sym_equiv'] = len(symop_list) - kw['num_primitive_sym_equiv'] = countUniqueRotations(symop_list) - kw['short_name'] = sgsmbls.hermann_mauguin().replace(' ', '') + kw["number"] = sgtype.number() + kw["num_sym_equiv"] = len(symop_list) + kw["num_primitive_sym_equiv"] = countUniqueRotations(symop_list) + kw["short_name"] = sgsmbls.hermann_mauguin().replace(" ", "") pgt = sgsmbls.point_group_type() - pgn = "PG" + re.sub(r'-(\d)', '\\1bar', pgt) - kw['point_group_name'] = pgn - kw['crystal_system'] = sgsmbls.crystal_system().upper() - kw['pdb_name'] = sgsmbls.hermann_mauguin() - kw['symop_list'] = symop_list + pgn = "PG" + re.sub(r"-(\d)", "\\1bar", pgt) + kw["point_group_name"] = pgn + kw["crystal_system"] = sgsmbls.crystal_system().upper() + kw["pdb_name"] = sgsmbls.hermann_mauguin() + kw["symop_list"] = symop_list mmsg = SpaceGroup(**kw) return mmsg @@ -87,7 +91,8 @@ def countUniqueRotations(symop_list): def cmpSpaceGroups(sg0, sg1): - if sg0 is sg1: return True + if sg0 is sg1: + return True s0 = hashMMSpaceGroup(sg0) s1 = hashMMSpaceGroup(sg1) return s0 == s1 @@ -100,6 +105,8 @@ def findEquivalentMMSpaceGroup(grp): _equivmmsg.setdefault(ssgn, sgn) ssg = hashSgtbxGroup(grp) return _equivmmsg.get(ssg) + + _equivmmsg = {} @@ -112,24 +119,27 @@ def findEquivalentSgtbxSpaceGroup(sgmm): _equivsgtbx.setdefault(hgrp, grp) hgmm = hashMMSpaceGroup(sgmm) return _equivsgtbx.get(hgmm) + + _equivsgtbx = {} def hashMMSpaceGroup(sg): lines = [str(sg.number % 1000)] + sorted(map(str, sg.iter_symops())) - s = '\n'.join(lines) + s = "\n".join(lines) return s def hashSgtbxGroup(grp): n = grp.type().number() lines = [str(n)] + sorted(map(str, getSymOpList(grp))) - s = '\n'.join(lines) + s = "\n".join(lines) return s + sgnumbers = [sg.number for sg in mmLibSpaceGroupList] -_SGsrc = '''\ +_SGsrc = """\ sg%(number)i = SpaceGroup( number = %(number)i, num_sym_equiv = %(num_sym_equiv)i, @@ -142,32 +152,37 @@ def hashSgtbxGroup(grp): @SYMOPS@ ] ) -''' +""" + def SGCode(mmsg): src0 = _SGsrc % mmsg.__dict__ - src1 = src0.replace('@SYMOPS@', SymOpsCode(mmsg)) + src1 = src0.replace("@SYMOPS@", SymOpsCode(mmsg)) return src1 def SymOpsCode(mmsg): - lst = ["%8s%s," % ('', SymOpCode(op)) for op in mmsg.iter_symops()] - src = '\n'.join(lst).strip() + lst = ["%8s%s," % ("", SymOpCode(op)) for op in mmsg.iter_symops()] + src = "\n".join(lst).strip() return src def SymOpCode(op): if not _rtnames: import diffpy.structure.SpaceGroups as sgmod + for n in dir(sgmod): - if not n.startswith('Rot_') and not n.startswith('Tr_'): continue + if not n.startswith("Rot_") and not n.startswith("Tr_"): + continue a = getattr(sgmod, n) at = tuple(a.flatten()) - _rtnames[at] = 'sgmod.' + n + _rtnames[at] = "sgmod." + n nR = _rtnames[tuple(op.R.flatten())] nt = _rtnames[tuple(op.t)] - src = 'SymOp(%s, %s)' % (nR, nt) + src = "SymOp(%s, %s)" % (nR, nt) return src + + _rtnames = {} @@ -176,16 +191,20 @@ def main(): for smbls in sgtbx.space_group_symbol_iterator(): uhm = smbls.universal_hermann_mauguin() grp = sgtbx.space_group_info(uhm).group() - if findEquivalentMMSpaceGroup(grp): continue - shn = smbls.hermann_mauguin().replace(' ', '') - if IsSpaceGroupIdentifier(shn): continue + if findEquivalentMMSpaceGroup(grp): + continue + shn = smbls.hermann_mauguin().replace(" ", "") + if IsSpaceGroupIdentifier(shn): + continue sg = mmSpaceGroupFromSymbol(uhm) hsg = hashMMSpaceGroup(sg) - if hsg in duplicates: continue + if hsg in duplicates: + continue adjustMMSpaceGroupNumber(sg) duplicates.add(hsg) print(SGCode(sg)) return -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/doc/source/api/diffpy.structure.applications.rst b/doc/source/api/diffpy.structure.applications.rst index 57dedf41..30316d0b 100644 --- a/doc/source/api/diffpy.structure.applications.rst +++ b/doc/source/api/diffpy.structure.applications.rst @@ -26,4 +26,3 @@ diffpy.structure.applications.anyeye module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.apps.rst b/doc/source/api/diffpy.structure.apps.rst index 5ac351dd..8b91adf5 100644 --- a/doc/source/api/diffpy.structure.apps.rst +++ b/doc/source/api/diffpy.structure.apps.rst @@ -26,4 +26,3 @@ diffpy.structure.apps.anyeye module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.expansion.rst b/doc/source/api/diffpy.structure.expansion.rst index afce983c..34529fcd 100644 --- a/doc/source/api/diffpy.structure.expansion.rst +++ b/doc/source/api/diffpy.structure.expansion.rst @@ -34,4 +34,3 @@ diffpy.structure.expansion.supercell_mod module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.parsers.rst b/doc/source/api/diffpy.structure.parsers.rst index 54a88f2e..74a27bcb 100644 --- a/doc/source/api/diffpy.structure.parsers.rst +++ b/doc/source/api/diffpy.structure.parsers.rst @@ -90,4 +90,3 @@ diffpy.structure.parsers.p_xyz module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index 8d60dd1c..e414b921 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -117,4 +117,3 @@ diffpy.structure.sgtbxspacegroups module :members: :undoc-members: :show-inheritance: - diff --git a/src/diffpy/Structure.py b/src/diffpy/Structure.py index ee3c69ab..7847de42 100644 --- a/src/diffpy/Structure.py +++ b/src/diffpy/Structure.py @@ -29,6 +29,6 @@ import diffpy.structure._legacy_importer # replace this module with the new one -sys.modules['diffpy.Structure'] = diffpy.structure +sys.modules["diffpy.Structure"] = diffpy.structure # End of file diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 3e7952ae..ee55ab5f 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -21,4 +21,3 @@ __path__ = extend_path(__path__, __name__) # End of file - diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index c5197b90..377a1991 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -27,12 +27,11 @@ # Interface definitions ------------------------------------------------------ -from diffpy.structure.structureerrors import (StructureFormatError, - LatticeError, SymmetryError) from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice -from diffpy.structure.structure import Structure from diffpy.structure.pdffitstructure import PDFFitStructure +from diffpy.structure.structure import Structure +from diffpy.structure.structureerrors import LatticeError, StructureFormatError, SymmetryError # obtain version information @@ -43,7 +42,8 @@ # top level routines -def loadStructure(filename, fmt='auto', **kw): + +def loadStructure(filename, fmt="auto", **kw): """ Load new structure object from the specified file. @@ -69,13 +69,14 @@ def loadStructure(filename, fmt='auto', **kw): and 'discus' formats. """ from diffpy.structure.parsers import getParser + p = getParser(fmt, **kw) rv = p.parseFile(filename) return rv + # silence pyflakes checker -assert (StructureFormatError and - LatticeError and SymmetryError) +assert StructureFormatError and LatticeError and SymmetryError assert Atom assert Lattice assert Structure diff --git a/src/diffpy/structure/_legacy_importer.py b/src/diffpy/structure/_legacy_importer.py index 8bb36114..743de895 100644 --- a/src/diffpy/structure/_legacy_importer.py +++ b/src/diffpy/structure/_legacy_importer.py @@ -27,15 +27,18 @@ import sys from warnings import warn + import six if six.PY2: import importlib + class mock_importlib_abc(object): MetaPathFinder = object Loader = object + importlib.abc = mock_importlib_abc - sys.modules.setdefault('importlib.abc', mock_importlib_abc) + sys.modules.setdefault("importlib.abc", mock_importlib_abc) del mock_importlib_abc import importlib.abc @@ -44,9 +47,10 @@ class mock_importlib_abc(object): # ---------------------------------------------------------------------------- + class FindRenamedStructureModule(importlib.abc.MetaPathFinder): - prefix = 'diffpy.Structure.' + prefix = "diffpy.Structure." def find_spec(self, fullname, path=None, target=None): # only handle submodules of diffpy.Structure @@ -59,8 +63,8 @@ def find_spec(self, fullname, path=None, target=None): spec.loader = MapRenamedStructureModule() return spec - if six.PY2: + def find_module(self, fullname, path): # only handle submodules of diffpy.Structure loader = None @@ -68,10 +72,12 @@ def find_module(self, fullname, path): loader = MapRenamedStructureModule() return loader + # end of class FindRenamedStructureModule # ---------------------------------------------------------------------------- + class MapRenamedStructureModule(importlib.abc.Loader): """ Loader for old camel-case module names. @@ -86,26 +92,25 @@ def create_module(self, spec): warn(WMSG.format(spec.name, lcname), DeprecationWarning, stacklevel=2) return mod - def exec_module(self, module): return - if six.PY2: from collections import namedtuple - ModuleSpec = namedtuple('ModuleSpec', 'name') + + ModuleSpec = namedtuple("ModuleSpec", "name") def load_module(self, fullname): spec = self.ModuleSpec(fullname) return self.create_module(spec) + # end of class MapRenamedStructureModule # ---------------------------------------------------------------------------- # show deprecation warning for diffpy.Structure -warn(WMSG.format('diffpy.Structure', 'diffpy.structure'), - DeprecationWarning, stacklevel=2) +warn(WMSG.format("diffpy.Structure", "diffpy.structure"), DeprecationWarning, stacklevel=2) # install meta path finder for diffpy.Structure submodules sys.meta_path.append(FindRenamedStructureModule()) diff --git a/src/diffpy/structure/applications/__init__.py b/src/diffpy/structure/applications/__init__.py index 50e8dae2..bc4f87eb 100644 --- a/src/diffpy/structure/applications/__init__.py +++ b/src/diffpy/structure/applications/__init__.py @@ -23,7 +23,8 @@ from warnings import warn - -warn("Module 'diffpy.structure.applications' is deprecated. " - "Import 'diffpy.structure.apps' instead.", - DeprecationWarning, stacklevel=2) +warn( + "Module 'diffpy.structure.applications' is deprecated. " "Import 'diffpy.structure.apps' instead.", + DeprecationWarning, + stacklevel=2, +) diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index cf101da3..ff98a0c0 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -35,31 +35,34 @@ from __future__ import print_function -import sys import os import re import signal +import sys + from diffpy.structure import StructureFormatError # parameter dictionary -pd = { 'formula' : None, - 'watch' : False, - 'viewer' : 'atomeye', - 'formats' : ['xcfg', 'pdb'], +pd = { + "formula": None, + "watch": False, + "viewer": "atomeye", + "formats": ["xcfg", "pdb"], } -def usage(style = None): +def usage(style=None): """show usage info, for style=="brief" show only first 2 lines""" import os.path + myname = os.path.basename(sys.argv[0]) msg = __doc__.replace("anyeye", myname) - if style == 'brief': - msg = msg.split("\n")[1] + "\n" + \ - "Try `%s --help' for more information." % myname + if style == "brief": + msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname else: from diffpy.structure.parsers import inputFormats - fmts = [ f for f in inputFormats() if f != 'auto' ] + + fmts = [f for f in inputFormats() if f != "auto"] msg = msg.replace("inputFormats", " ".join(fmts)) print(msg) return @@ -67,6 +70,7 @@ def usage(style = None): def version(): from diffpy.structure import __version__ + print("anyeye", __version__) return @@ -77,6 +81,7 @@ def loadStructureFile(filename, format="auto"): Return a tuple of (Structure, fileformat). """ from diffpy.structure import Structure + stru = Structure() p = stru.read(filename, format) fileformat = p.format @@ -85,48 +90,51 @@ def loadStructureFile(filename, format="auto"): def convertStructureFile(pd): # make temporary directory on the first pass - if 'tmpdir' not in pd: + if "tmpdir" not in pd: from tempfile import mkdtemp - pd['tmpdir'] = mkdtemp() - strufile = pd['strufile'] - tmpfile = os.path.join(pd['tmpdir'], os.path.basename(strufile)) - pd['tmpfile'] = tmpfile + + pd["tmpdir"] = mkdtemp() + strufile = pd["strufile"] + tmpfile = os.path.join(pd["tmpdir"], os.path.basename(strufile)) + pd["tmpfile"] = tmpfile # speed up file processing in the watch mode - fmt = pd.get('format', 'auto') + fmt = pd.get("format", "auto") stru = None - if fmt == 'auto': + if fmt == "auto": stru, fmt = loadStructureFile(strufile) - pd['fmt'] = fmt + pd["fmt"] = fmt # if fmt is recognized by the viewer, use as is - if fmt in pd['formats'] and pd['formula'] is None: + if fmt in pd["formats"] and pd["formula"] is None: import shutil - shutil.copyfile(strufile, tmpfile+'.tmp') - os.rename(tmpfile+'.tmp', tmpfile) + + shutil.copyfile(strufile, tmpfile + ".tmp") + os.rename(tmpfile + ".tmp", tmpfile) return # otherwise convert to the first recognized viewer format if stru is None: stru = loadStructureFile(strufile, fmt)[0] - if pd['formula']: - formula = pd['formula'] + if pd["formula"]: + formula = pd["formula"] if len(formula) != len(stru): - emsg = "Formula has %i atoms while structure %i" % ( - len(formula), len(stru) ) + emsg = "Formula has %i atoms while structure %i" % (len(formula), len(stru)) raise RuntimeError(emsg) for a, el in zip(stru, formula): a.element = el elif format == "rawxyz": for a in stru: - if a.element == "": a.element = "C" - stru.write(tmpfile+'.tmp', pd['formats'][0]) - os.rename(tmpfile+'.tmp', tmpfile) + if a.element == "": + a.element = "C" + stru.write(tmpfile + ".tmp", pd["formats"][0]) + os.rename(tmpfile + ".tmp", tmpfile) return def watchStructureFile(pd): from time import sleep - strufile = pd['strufile'] - tmpfile = pd['tmpfile'] - while pd['watch']: + + strufile = pd["strufile"] + tmpfile = pd["tmpfile"] + while pd["watch"]: if os.path.getmtime(tmpfile) < os.path.getmtime(strufile): convertStructureFile(pd) sleep(1) @@ -134,31 +142,31 @@ def watchStructureFile(pd): def cleanUp(pd): - if 'tmpfile' in pd: - os.remove(pd['tmpfile']) - del pd['tmpfile'] - if 'tmpdir' in pd: - os.rmdir(pd['tmpdir']) - del pd['tmpdir'] + if "tmpfile" in pd: + os.remove(pd["tmpfile"]) + del pd["tmpfile"] + if "tmpdir" in pd: + os.rmdir(pd["tmpdir"]) + del pd["tmpdir"] return def parseFormula(formula): """parse chemical formula and return a list of elements""" # remove all blanks - formula = re.sub(r'\s', '', formula) - if not re.match('^[A-Z]', formula): + formula = re.sub(r"\s", "", formula) + if not re.match("^[A-Z]", formula): raise RuntimeError("InvalidFormula '%s'" % formula) - elcnt = re.split('([A-Z][a-z]?)', formula)[1:] + elcnt = re.split("([A-Z][a-z]?)", formula)[1:] ellst = [] try: for i in range(0, len(elcnt), 2): el = elcnt[i] - cnt = elcnt[i+1] + cnt = elcnt[i + 1] cnt = (cnt == "") and 1 or int(cnt) - ellst.extend(cnt*[el]) + ellst.extend(cnt * [el]) except ValueError: - emsg = "Invalid formula, %r is not valid count" % elcnt[i+1] + emsg = "Invalid formula, %r is not valid count" % elcnt[i + 1] raise RuntimeError(emsg) return ellst @@ -173,7 +181,7 @@ def signalHandler(signum, stackframe): signal.signal(signum, signal.SIG_DFL) if signum == signal.SIGCHLD: pid, exit_status = os.wait() - exit_status = (exit_status >> 8) + (exit_status & 0x00ff) + exit_status = (exit_status >> 8) + (exit_status & 0x00FF) die(exit_status, pd) else: die(1, pd) @@ -182,12 +190,13 @@ def signalHandler(signum, stackframe): def main(): import getopt + # default parameters - pd['watch'] = False + pd["watch"] = False try: - opts, args = getopt.getopt(sys.argv[1:], "f:whV", - ["formula=", "watch", "viewer=", "formats=", - "help", "version"]) + opts, args = getopt.getopt( + sys.argv[1:], "f:whV", ["formula=", "watch", "viewer=", "formats=", "help", "version"] + ) except getopt.GetoptError as errmsg: print(errmsg, file=sys.stderr) die(2) @@ -195,16 +204,16 @@ def main(): for o, a in opts: if o in ("-f", "--formula"): try: - pd['formula'] = parseFormula(a) + pd["formula"] = parseFormula(a) except RuntimeError as msg: print(msg, file=sys.stderr) die(2) elif o in ("-w", "--watch"): - pd['watch'] = True + pd["watch"] = True elif o == "--viewer": - pd['viewer'] = a + pd["viewer"] = a elif o == "--formats": - pd['formats'] = [w.strip() for w in a.split(',')] + pd["formats"] = [w.strip() for w in a.split(",")] elif o in ("-h", "--help"): usage() die() @@ -212,12 +221,12 @@ def main(): version() die() if len(args) < 1: - usage('brief') + usage("brief") die() elif len(args) > 1: print("too many structure files", file=sys.stderr) die(2) - pd['strufile'] = args[0] + pd["strufile"] = args[0] # trap the following signals signal.signal(signal.SIGHUP, signalHandler) signal.signal(signal.SIGQUIT, signalHandler) @@ -225,14 +234,14 @@ def main(): signal.signal(signal.SIGTERM, signalHandler) signal.signal(signal.SIGINT, signalHandler) env = os.environ.copy() - if os.path.basename(pd['viewer']).startswith('atomeye'): - env['XLIB_SKIP_ARGB_VISUALS'] = "1" + if os.path.basename(pd["viewer"]).startswith("atomeye"): + env["XLIB_SKIP_ARGB_VISUALS"] = "1" # try to run the thing: try: convertStructureFile(pd) - spawnargs = (pd['viewer'], pd['viewer'], pd['tmpfile'], env) + spawnargs = (pd["viewer"], pd["viewer"], pd["tmpfile"], env) # load strufile in atomeye - if pd['watch']: + if pd["watch"]: signal.signal(signal.SIGCLD, signalHandler) os.spawnlpe(os.P_NOWAIT, *spawnargs) watchStructureFile(pd) diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 05207ed1..902cb237 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -37,16 +37,18 @@ from diffpy.structure import Structure, StructureFormatError -def usage(style = None): + +def usage(style=None): """show usage info, for style=="brief" show only first 2 lines""" import os.path + myname = os.path.basename(sys.argv[0]) msg = __doc__.replace("transtru", myname) - if style == 'brief': - msg = msg.split("\n")[1] + "\n" + \ - "Try `%s --help' for more information." % myname + if style == "brief": + msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname else: from diffpy.structure.parsers import inputFormats, outputFormats + msg = msg.replace("inputFormats", " ".join(inputFormats())) msg = msg.replace("outputFormats", " ".join(outputFormats())) print(msg) @@ -55,16 +57,17 @@ def usage(style = None): def version(): from diffpy.structure import __version__ + print("diffpy.structure", __version__) return def main(): import getopt + # default parameters try: - opts, args = getopt.getopt(sys.argv[1:], "hV", - ["help", "version"]) + opts, args = getopt.getopt(sys.argv[1:], "hV", ["help", "version"]) except getopt.GetoptError as errmsg: print(errmsg, file=sys.stderr) sys.exit(2) @@ -77,12 +80,13 @@ def main(): version() sys.exit() if len(args) < 1: - usage('brief') + usage("brief") sys.exit() # process arguments from diffpy.structure.parsers import inputFormats, outputFormats + try: - infmt, outfmt = args[0].split('..', 1) + infmt, outfmt = args[0].split("..", 1) if infmt not in inputFormats(): print("'%s' is not valid input format" % infmt, file=sys.stderr) sys.exit(2) @@ -100,7 +104,7 @@ def main(): stru.readStr(sys.stdin.read(), infmt) else: stru.read(strufile, infmt) - sys.stdout.write( stru.writeStr(outfmt) ) + sys.stdout.write(stru.writeStr(outfmt)) except IndexError: print("strufile not specified", file=sys.stderr) sys.exit(2) diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index 2742b6a7..3745d56a 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -23,11 +23,12 @@ from diffpy.structure.lattice import cartesian as cartesian_lattice # conversion constants -_BtoU = 1.0/(8 * numpy.pi**2) -_UtoB = 1.0/_BtoU +_BtoU = 1.0 / (8 * numpy.pi**2) +_UtoB = 1.0 / _BtoU # ---------------------------------------------------------------------------- + class Atom(object): """ Storage of structure information relevant for a single atom. @@ -91,14 +92,23 @@ class Atom(object): # Internal storage of the displacement parameters. # instance attributes that have immutable default values - element = '' - label = '' + element = "" + label = "" occupancy = 1.0 _anisotropy = False lattice = None - def __init__(self, atype=None, xyz=None, label=None, occupancy=None, - anisotropy=None, U=None, Uisoequiv=None, lattice=None): + def __init__( + self, + atype=None, + xyz=None, + label=None, + occupancy=None, + anisotropy=None, + U=None, + Uisoequiv=None, + lattice=None, + ): """ Create atom of the specified type at the given lattice coordinates. @@ -110,7 +120,7 @@ def __init__(self, atype=None, xyz=None, label=None, occupancy=None, raise ValueError(emsg) # declare data members self.xyz = numpy.zeros(3, dtype=float) - self._U = numpy.zeros((3,3), dtype=float) + self._U = numpy.zeros((3, 3), dtype=float) # assign them as needed if isinstance(atype, Atom): atype.__copy__(target=self) @@ -137,7 +147,6 @@ def __init__(self, atype=None, xyz=None, label=None, occupancy=None, self.anisotropy = bool(anisotropy) return - def msdLat(self, vl): """ Calculate mean square displacement along the lattice vector. @@ -152,19 +161,17 @@ def msdLat(self, vl): float The mean square displacement along *vl*. """ - if not self.anisotropy: return self.Uisoequiv + if not self.anisotropy: + return self.Uisoequiv # here we need to calculate msd lat = self.lattice or cartesian_lattice - vln = numpy.array(vl, dtype=float)/lat.norm(vl) + vln = numpy.array(vl, dtype=float) / lat.norm(vl) G = lat.metrics - rhs = numpy.array([ G[0]*lat.ar, - G[1]*lat.br, - G[2]*lat.cr ], dtype=float) + rhs = numpy.array([G[0] * lat.ar, G[1] * lat.br, G[2] * lat.cr], dtype=float) rhs = numpy.dot(rhs, vln) msd = numpy.dot(rhs, numpy.dot(self.U, rhs)) return msd - def msdCart(self, vc): """ Calculate mean square displacement along the Cartesian vector. @@ -179,7 +186,8 @@ def msdCart(self, vc): float The mean square displacement along *vc*. """ - if not self.anisotropy: return self.Uisoequiv + if not self.anisotropy: + return self.Uisoequiv # here we need to calculate msd lat = self.lattice or cartesian_lattice vcn = numpy.array(vc, dtype=float) @@ -189,17 +197,14 @@ def msdCart(self, vc): msd = numpy.dot(vcn, numpy.dot(Uc, vcn)) return msd - def __repr__(self): """ String representation of this Atom. """ xyz = self.xyz - s = "%-4s %8.6f %8.6f %8.6f %6.4f" % \ - (self.element, xyz[0], xyz[1], xyz[2], self.occupancy) + s = "%-4s %8.6f %8.6f %8.6f %6.4f" % (self.element, xyz[0], xyz[1], xyz[2], self.occupancy) return s - def __copy__(self, target=None): """ Create a copy of this instance. @@ -228,15 +233,21 @@ def __copy__(self, target=None): # property handlers ------------------------------------------------------ - x = property(lambda self: self.xyz[0], - lambda self, val: self.xyz.__setitem__(0, val), - doc='float : fractional coordinate *x*, same as ``xyz[0]``.') - y = property(lambda self: self.xyz[1], - lambda self, val: self.xyz.__setitem__(1, val), - doc='float : fractional coordinate *y*, same as ``xyz[1]``.') - z = property(lambda self: self.xyz[2], - lambda self, val: self.xyz.__setitem__(2, val), - doc='float : fractional coordinate *z*, same as ``xyz[2]``.') + x = property( + lambda self: self.xyz[0], + lambda self, val: self.xyz.__setitem__(0, val), + doc="float : fractional coordinate *x*, same as ``xyz[0]``.", + ) + y = property( + lambda self: self.xyz[1], + lambda self, val: self.xyz.__setitem__(1, val), + doc="float : fractional coordinate *y*, same as ``xyz[1]``.", + ) + z = property( + lambda self: self.xyz[2], + lambda self, val: self.xyz.__setitem__(2, val), + doc="float : fractional coordinate *z*, same as ``xyz[2]``.", + ) # xyz_cartn @@ -350,15 +361,15 @@ def _set_Uij(self, i, j, value): tensor *U*. """ - U11 = property(lambda self : self._get_Uij(0, 0), - lambda self, value : self._set_Uij(0, 0, value), - doc=_doc_uii.format(0)) - U22 = property(lambda self : self._get_Uij(1, 1), - lambda self, value : self._set_Uij(1, 1, value), - doc=_doc_uii.format(1)) - U33 = property(lambda self : self._get_Uij(2, 2), - lambda self, value : self._set_Uij(2, 2, value), - doc=_doc_uii.format(2)) + U11 = property( + lambda self: self._get_Uij(0, 0), lambda self, value: self._set_Uij(0, 0, value), doc=_doc_uii.format(0) + ) + U22 = property( + lambda self: self._get_Uij(1, 1), lambda self, value: self._set_Uij(1, 1, value), doc=_doc_uii.format(1) + ) + U33 = property( + lambda self: self._get_Uij(2, 2), lambda self, value: self._set_Uij(2, 2, value), doc=_doc_uii.format(2) + ) _doc_uij = """ float : The ``U[{0}, {1}]`` element of the displacement tensor `U`. @@ -367,15 +378,15 @@ def _set_Uij(self, i, j, value): has no effect when `anisotropy` is ``False``. """ - U12 = property(lambda self : self._get_Uij(0, 1), - lambda self, value : self._set_Uij(0, 1, value), - doc=_doc_uij.format(0, 1)) - U13 = property(lambda self : self._get_Uij(0, 2), - lambda self, value : self._set_Uij(0, 2, value), - doc=_doc_uij.format(0, 2)) - U23 = property(lambda self : self._get_Uij(1, 2), - lambda self, value : self._set_Uij(1, 2, value), - doc=_doc_uij.format(1, 2)) + U12 = property( + lambda self: self._get_Uij(0, 1), lambda self, value: self._set_Uij(0, 1, value), doc=_doc_uij.format(0, 1) + ) + U13 = property( + lambda self: self._get_Uij(0, 2), lambda self, value: self._set_Uij(0, 2, value), doc=_doc_uij.format(0, 2) + ) + U23 = property( + lambda self: self._get_Uij(1, 2), lambda self, value: self._set_Uij(1, 2, value), doc=_doc_uij.format(1, 2) + ) # clean local variables del _doc_uii, _doc_uij @@ -395,13 +406,18 @@ def Uisoequiv(self): if self.lattice is None: return numpy.trace(self._U) / 3.0 lat = self.lattice - rv = 1.0 / 3.0 * ( - self._U[0,0]*lat.ar*lat.ar*lat.a*lat.a + - self._U[1,1]*lat.br*lat.br*lat.b*lat.b + - self._U[2,2]*lat.cr*lat.cr*lat.c*lat.c + - 2*self._U[0,1]*lat.ar*lat.br*lat.a*lat.b*lat.cg + - 2*self._U[0,2]*lat.ar*lat.cr*lat.a*lat.c*lat.cb + - 2*self._U[1,2]*lat.br*lat.cr*lat.b*lat.c*lat.ca) + rv = ( + 1.0 + / 3.0 + * ( + self._U[0, 0] * lat.ar * lat.ar * lat.a * lat.a + + self._U[1, 1] * lat.br * lat.br * lat.b * lat.b + + self._U[2, 2] * lat.cr * lat.cr * lat.c * lat.c + + 2 * self._U[0, 1] * lat.ar * lat.br * lat.a * lat.b * lat.cg + + 2 * self._U[0, 2] * lat.ar * lat.cr * lat.a * lat.c * lat.cb + + 2 * self._U[1, 2] * lat.br * lat.cr * lat.b * lat.c * lat.ca + ) + ) return rv @Uisoequiv.setter @@ -436,24 +452,36 @@ def Uisoequiv(self, value): when `anisotropy` is ``False``. """ - B11 = property(lambda self : _UtoB * self._get_Uij(0, 0), - lambda self, value : self._set_Uij(0, 0, _BtoU * value), - doc=_doc_bii.format(1)) - B22 = property(lambda self : _UtoB * self._get_Uij(1, 1), - lambda self, value : self._set_Uij(1, 1, _BtoU * value), - doc=_doc_bii.format(2)) - B33 = property(lambda self : _UtoB * self._get_Uij(2, 2), - lambda self, value : self._set_Uij(2, 2, _BtoU * value), - doc=_doc_bii.format(3)) - B12 = property(lambda self : _UtoB * self._get_Uij(0, 1), - lambda self, value : self._set_Uij(0, 1, _BtoU * value), - doc=_doc_bij.format(1, 2)) - B13 = property(lambda self : _UtoB * self._get_Uij(0, 2), - lambda self, value : self._set_Uij(0, 2, _BtoU * value), - doc=_doc_bij.format(1, 3)) - B23 = property(lambda self : _UtoB * self._get_Uij(1, 2), - lambda self, value : self._set_Uij(1, 2, _BtoU * value), - doc=_doc_bij.format(2, 3)) + B11 = property( + lambda self: _UtoB * self._get_Uij(0, 0), + lambda self, value: self._set_Uij(0, 0, _BtoU * value), + doc=_doc_bii.format(1), + ) + B22 = property( + lambda self: _UtoB * self._get_Uij(1, 1), + lambda self, value: self._set_Uij(1, 1, _BtoU * value), + doc=_doc_bii.format(2), + ) + B33 = property( + lambda self: _UtoB * self._get_Uij(2, 2), + lambda self, value: self._set_Uij(2, 2, _BtoU * value), + doc=_doc_bii.format(3), + ) + B12 = property( + lambda self: _UtoB * self._get_Uij(0, 1), + lambda self, value: self._set_Uij(0, 1, _BtoU * value), + doc=_doc_bij.format(1, 2), + ) + B13 = property( + lambda self: _UtoB * self._get_Uij(0, 2), + lambda self, value: self._set_Uij(0, 2, _BtoU * value), + doc=_doc_bij.format(1, 3), + ) + B23 = property( + lambda self: _UtoB * self._get_Uij(1, 2), + lambda self, value: self._set_Uij(1, 2, _BtoU * value), + doc=_doc_bij.format(2, 3), + ) # clean local variables del _doc_bii, _doc_bij @@ -476,10 +504,12 @@ def Bisoequiv(self, value): self.Uisoequiv = _BtoU * value return + # End of class Atom # Local Helpers -------------------------------------------------------------- + class _AtomCartesianCoordinates(numpy.ndarray): """ Specialized numpy.ndarray for accessing Cartesian coordinates. @@ -499,13 +529,11 @@ def __new__(self, atom): """ return numpy.empty(3, dtype=float).view(self) - def __init__(self, atom): self._atom = atom self.asarray[:] = atom.lattice.cartesian(atom.xyz) return - @property def asarray(self): """ @@ -513,7 +541,6 @@ def asarray(self): """ return self.view(numpy.ndarray) - def __setitem__(self, idx, value): """ Set some element or slice of this Cartesian coordinates. @@ -525,7 +552,6 @@ def __setitem__(self, idx, value): self._atom.xyz[:] = self._atom.lattice.fractional(self) return - def __array_wrap__(self, out_arr, context=None): """ Ensure math operations on this type yield standard numpy array. @@ -542,4 +568,5 @@ def __setslice__(self, lo, hi, sequence): # ------------------------------------------------------------------------ + # End of _AtomCartesianCoordinates diff --git a/src/diffpy/structure/expansion/makeellipsoid.py b/src/diffpy/structure/expansion/makeellipsoid.py index 9b22b69b..bfd3a8e3 100644 --- a/src/diffpy/structure/expansion/makeellipsoid.py +++ b/src/diffpy/structure/expansion/makeellipsoid.py @@ -16,7 +16,9 @@ """Make a spheroid nanoparticle from a template structure.""" from math import ceil + from numpy import array + from diffpy.structure import Structure from diffpy.structure.expansion.shapeutils import findCenter @@ -46,8 +48,10 @@ def makeEllipsoid(S, a, b=None, c=None): Returns a new structure instance """ - if b is None: b = a - if c is None: c = a + if b is None: + b = a + if c is None: + c = a sabc = array([a, b, c]) # Create a supercell large enough for the ellipsoid @@ -56,6 +60,7 @@ def makeEllipsoid(S, a, b=None, c=None): mno = max(ceil(2 * xi) for xi in frac) * array([1, 1, 1]) # Make the supercell from diffpy.structure.expansion import supercell + newS = supercell(S, mno) lat = newS.lattice @@ -72,8 +77,8 @@ def makeEllipsoid(S, a, b=None, c=None): # Calculate (x/a)**2 + (y/b)**2 + (z/c)**2 xyz = lat.cartesian(newS[j].xyz) - darray = ((xyz-cxyz)/sabc)**2 - d = sum(darray)**0.5 + darray = ((xyz - cxyz) / sabc) ** 2 + d = sum(darray) ** 0.5 # Discard atom if (x/a)**2 + (y/b)**2 + (z/c)**2 > 1 if d > 1: @@ -84,10 +89,12 @@ def makeEllipsoid(S, a, b=None, c=None): return newS + # ---------------------------------------------------------------------------- if __name__ == "__main__": import os.path + datadir = "../../tests/testdata" S = Structure() S.read(os.path.join(datadir, "CdSe_bulk.stru"), "pdffit") diff --git a/src/diffpy/structure/expansion/shapeutils.py b/src/diffpy/structure/expansion/shapeutils.py index 6638ee77..d05daecf 100644 --- a/src/diffpy/structure/expansion/shapeutils.py +++ b/src/diffpy/structure/expansion/shapeutils.py @@ -15,6 +15,7 @@ """Utilities for making shapes.""" + def findCenter(S): """Find the approximate center atom of a structure. @@ -24,7 +25,7 @@ def findCenter(S): """ best = -1 bestd = len(S) - center = [0.5, 0.5, 0.5] # the cannonical center + center = [0.5, 0.5, 0.5] # the cannonical center for i in range(len(S)): d = S.lattice.dist(S[i].xyz, center) diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index aa71a8fe..d0dc5f0a 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -17,7 +17,8 @@ """ import numpy -from diffpy.structure import Structure, Atom + +from diffpy.structure import Atom, Structure def supercell(S, mno): @@ -55,10 +56,7 @@ def supercell(S, mno): return newS # back to business - ijklist = [(i,j,k) - for i in range(mno[0]) - for j in range(mno[1]) - for k in range(mno[2])] + ijklist = [(i, j, k) for i in range(mno[0]) for j in range(mno[1]) for k in range(mno[2])] # numpy.floor returns float array mnofloats = numpy.array(mno, dtype=float) @@ -67,16 +65,14 @@ def supercell(S, mno): for a in S: for ijk in ijklist: adup = Atom(a) - adup.xyz = (a.xyz + ijk)/mnofloats + adup.xyz = (a.xyz + ijk) / mnofloats newAtoms.append(adup) # newS can own references in newAtoms, no need to make copies newS.__setitem__(slice(None), newAtoms, copy=False) # take care of lattice parameters - newS.lattice.setLatPar( - a=mno[0]*S.lattice.a, - b=mno[1]*S.lattice.b, - c=mno[2]*S.lattice.c ) + newS.lattice.setLatPar(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) return newS + # End of supercell diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index e18e9fc0..4924850b 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -21,24 +21,25 @@ """ import math + import numpy import numpy.linalg as numalg + from diffpy.structure import LatticeError # Helper Functions ----------------------------------------------------------- # exact values of cosd -_EXACT_COSD = { - 0.0 : +1.0, 60.0 : +0.5, 90.0 : 0.0, 120.0 : -0.5, - 180.0 : -1.0, 240.0 : -0.5, 270.0 : 0.0, 300.0 : +0.5 -} +_EXACT_COSD = {0.0: +1.0, 60.0: +0.5, 90.0: 0.0, 120.0: -0.5, 180.0: -1.0, 240.0: -0.5, 270.0: 0.0, 300.0: +0.5} + def cosd(x): """Return the cosine of x (measured in degrees). Avoid round-off errors for exact cosine values. """ rv = _EXACT_COSD.get(x % 360.0) - if rv is None: rv = math.cos(math.radians(x)) + if rv is None: + rv = math.cos(math.radians(x)) return rv @@ -48,8 +49,10 @@ def sind(x): """ return cosd(90.0 - x) + # ---------------------------------------------------------------------------- + class Lattice(object): """ General coordinate system and associated operations. @@ -132,110 +135,101 @@ class Lattice(object): # properties ------------------------------------------------------------- - a = property(lambda self: self._a, - lambda self, value: self.setLatPar(a=value), - doc='The unit cell length *a*.') + a = property( + lambda self: self._a, lambda self, value: self.setLatPar(a=value), doc="The unit cell length *a*." + ) - b = property(lambda self: self._b, - lambda self, value: self.setLatPar(b=value), - doc='The unit cell length *b*.') + b = property( + lambda self: self._b, lambda self, value: self.setLatPar(b=value), doc="The unit cell length *b*." + ) - c = property(lambda self: self._c, - lambda self, value: self.setLatPar(c=value), - doc='The unit cell length *c*.') + c = property( + lambda self: self._c, lambda self, value: self.setLatPar(c=value), doc="The unit cell length *c*." + ) - alpha = property(lambda self: self._alpha, - lambda self, value: self.setLatPar(alpha=value), - doc='The cell angle *alpha* in degrees.') + alpha = property( + lambda self: self._alpha, + lambda self, value: self.setLatPar(alpha=value), + doc="The cell angle *alpha* in degrees.", + ) - beta = property(lambda self: self._beta, - lambda self, value: self.setLatPar(beta=value), - doc='The cell angle *beta* in degrees.') + beta = property( + lambda self: self._beta, + lambda self, value: self.setLatPar(beta=value), + doc="The cell angle *beta* in degrees.", + ) - gamma = property(lambda self: self._gamma, - lambda self, value: self.setLatPar(gamma=value), - doc='The cell angle *gamma* in degrees.') + gamma = property( + lambda self: self._gamma, + lambda self, value: self.setLatPar(gamma=value), + doc="The cell angle *gamma* in degrees.", + ) # read-only derived properties @property def unitvolume(self): - '''The unit cell volume when a = b = c = 1. - ''' + """The unit cell volume when a = b = c = 1.""" # Recalculate lattice cosines to ensure this is right # even if ca, cb, cg data were not yet updated. ca = cosd(self.alpha) cb = cosd(self.beta) cg = cosd(self.gamma) - rv = math.sqrt( 1.0 + 2.0*ca*cb*cg - ca*ca - cb*cb - cg*cg) + rv = math.sqrt(1.0 + 2.0 * ca * cb * cg - ca * ca - cb * cb - cg * cg) return rv - volume = property(lambda self: self.a * self.b * self.c * self.unitvolume, - doc='The unit cell volume.') + volume = property(lambda self: self.a * self.b * self.c * self.unitvolume, doc="The unit cell volume.") - ar = property(lambda self: self._ar, - doc='The cell length *a* of the reciprocal lattice.') + ar = property(lambda self: self._ar, doc="The cell length *a* of the reciprocal lattice.") - br = property(lambda self: self._br, - doc='The cell length *b* of the reciprocal lattice.') + br = property(lambda self: self._br, doc="The cell length *b* of the reciprocal lattice.") - cr = property(lambda self: self._cr, - doc='The cell length *c* of the reciprocal lattice.') + cr = property(lambda self: self._cr, doc="The cell length *c* of the reciprocal lattice.") - alphar = property(lambda self: self._alphar, - doc='The reciprocal cell angle *alpha* in degrees.') + alphar = property(lambda self: self._alphar, doc="The reciprocal cell angle *alpha* in degrees.") - betar = property(lambda self: self._betar, - doc='The reciprocal cell angle *beta* in degrees') + betar = property(lambda self: self._betar, doc="The reciprocal cell angle *beta* in degrees") - gammar = property(lambda self: self._gammar, - doc='The reciprocal cell angle *gamma* in degrees') + gammar = property(lambda self: self._gammar, doc="The reciprocal cell angle *gamma* in degrees") - ca = property(lambda self: self._ca, - doc='The cosine of the cell angle *alpha*.') + ca = property(lambda self: self._ca, doc="The cosine of the cell angle *alpha*.") - cb = property(lambda self: self._cb, - doc='The cosine of the cell angle *beta*.') + cb = property(lambda self: self._cb, doc="The cosine of the cell angle *beta*.") - cg = property(lambda self: self._cg, - doc='The cosine of the cell angle *gamma*.') + cg = property(lambda self: self._cg, doc="The cosine of the cell angle *gamma*.") - sa = property(lambda self: self._sa, - doc='The sine of the cell angle *alpha*.') + sa = property(lambda self: self._sa, doc="The sine of the cell angle *alpha*.") - sb = property(lambda self: self._sb, - doc='The sine of the cell angle *beta*.') + sb = property(lambda self: self._sb, doc="The sine of the cell angle *beta*.") - sg = property(lambda self: self._sg, - doc='The sine of the cell angle *gamma*.') + sg = property(lambda self: self._sg, doc="The sine of the cell angle *gamma*.") - car = property(lambda self: self._car, - doc='The cosine of the reciprocal angle *alpha*.') + car = property(lambda self: self._car, doc="The cosine of the reciprocal angle *alpha*.") - cbr = property(lambda self: self._cbr, - doc='The cosine of the reciprocal angle *beta*.') + cbr = property(lambda self: self._cbr, doc="The cosine of the reciprocal angle *beta*.") - cgr = property(lambda self: self._cgr, - doc='The cosine of the reciprocal angle *gamma*.') + cgr = property(lambda self: self._cgr, doc="The cosine of the reciprocal angle *gamma*.") - sar = property(lambda self: self._sar, - doc='The sine of the reciprocal angle *alpha*.') + sar = property(lambda self: self._sar, doc="The sine of the reciprocal angle *alpha*.") - sbr = property(lambda self: self._sbr, - doc='flot: Sine of the reciprocal angle *beta*.') + sbr = property(lambda self: self._sbr, doc="flot: Sine of the reciprocal angle *beta*.") - sgr = property(lambda self: self._sgr, - doc='The sine of the reciprocal angle *gamma*.') + sgr = property(lambda self: self._sgr, doc="The sine of the reciprocal angle *gamma*.") # done with properties --------------------------------------------------- - def __init__(self, a=None, b=None, c=None, - alpha=None, beta=None, gamma=None, - baserot=None, base=None): + def __init__(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, baserot=None, base=None): # build a set of provided argument names for later use. - apairs = (('a', a), ('b', b), ('c', c), - ('alpha', alpha), ('beta', beta), ('gamma', gamma), - ('baserot', baserot), ('base', base)) + apairs = ( + ("a", a), + ("b", b), + ("c", c), + ("alpha", alpha), + ("beta", beta), + ("gamma", gamma), + ("baserot", baserot), + ("base", base), + ) argset = set(n for n, v in apairs if v is not None) # initialize data members, they values will be set by setLatPar() self._a = self._b = self._c = None @@ -265,15 +259,13 @@ def __init__(self, a=None, b=None, c=None, self.__dict__.update(a.__dict__) # otherwise do default Lattice(a, b, c, alpha, beta, gamma) else: - abcabg = ('a', 'b', 'c', 'alpha', 'beta', 'gamma') + abcabg = ("a", "b", "c", "alpha", "beta", "gamma") if not argset.issuperset(abcabg): raise ValueError("Provide all 6 cell parameters.") self.setLatPar(a, b, c, alpha, beta, gamma, baserot=baserot) return - - def setLatPar(self, a=None, b=None, c=None, - alpha=None, beta=None, gamma=None, baserot=None): + def setLatPar(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, baserot=None): """Set one or more lattice parameters. This updates all attributes that depend on the lattice parameters. @@ -301,13 +293,20 @@ def setLatPar(self, a=None, b=None, c=None, Parameters that are not specified will keep their initial values. """ - if a is not None: self._a = float(a) - if b is not None: self._b = float(b) - if c is not None: self._c = float(c) - if alpha is not None: self._alpha = float(alpha) - if beta is not None: self._beta = float(beta) - if gamma is not None: self._gamma = float(gamma) - if baserot is not None: self.baserot = numpy.array(baserot) + if a is not None: + self._a = float(a) + if b is not None: + self._b = float(b) + if c is not None: + self._c = float(c) + if alpha is not None: + self._alpha = float(alpha) + if beta is not None: + self._beta = float(beta) + if gamma is not None: + self._gamma = float(gamma) + if baserot is not None: + self.baserot = numpy.array(baserot) self._ca = ca = cosd(self.alpha) self._cb = cb = cosd(self.beta) self._cg = cg = cosd(self.gamma) @@ -317,30 +316,32 @@ def setLatPar(self, a=None, b=None, c=None, # cache the unit volume value Vunit = self.unitvolume # reciprocal lattice - self._ar = ar = sa/(self.a*Vunit) - self._br = br = sb/(self.b*Vunit) - self._cr = cr = sg/(self.c*Vunit) - self._car = car = (cb*cg - ca)/(sb*sg) - self._cbr = cbr = (ca*cg - cb)/(sa*sg) - self._cgr = cgr = (ca*cb - cg)/(sa*sb) - self._sar = math.sqrt(1.0 - car*car) - self._sbr = math.sqrt(1.0 - cbr*cbr) - self._sgr = sgr = math.sqrt(1.0 - cgr*cgr) + self._ar = ar = sa / (self.a * Vunit) + self._br = br = sb / (self.b * Vunit) + self._cr = cr = sg / (self.c * Vunit) + self._car = car = (cb * cg - ca) / (sb * sg) + self._cbr = cbr = (ca * cg - cb) / (sa * sg) + self._cgr = cgr = (ca * cb - cg) / (sa * sb) + self._sar = math.sqrt(1.0 - car * car) + self._sbr = math.sqrt(1.0 - cbr * cbr) + self._sgr = sgr = math.sqrt(1.0 - cgr * cgr) self._alphar = math.degrees(math.acos(car)) self._betar = math.degrees(math.acos(cbr)) self._gammar = math.degrees(math.acos(cgr)) # metrics tensor - self.metrics = numpy.array( [ - [ self.a*self.a, self.a*self.b*cg, self.a*self.c*cb ], - [ self.b*self.a*cg, self.b*self.b, self.b*self.c*ca ], - [ self.c*self.a*cb, self.c*self.b*ca, self.c*self.c ] ], - dtype=float ) + self.metrics = numpy.array( + [ + [self.a * self.a, self.a * self.b * cg, self.a * self.c * cb], + [self.b * self.a * cg, self.b * self.b, self.b * self.c * ca], + [self.c * self.a * cb, self.c * self.b * ca, self.c * self.c], + ], + dtype=float, + ) # standard Cartesian coordinates of lattice vectors - self.stdbase = numpy.array( [ - [ 1.0/ar, -cgr/sgr/ar, cb*self.a ], - [ 0.0, self.b*sa, self.b*ca ], - [ 0.0, 0.0, self.c ] ], - dtype=float ) + self.stdbase = numpy.array( + [[1.0 / ar, -cgr / sgr / ar, cb * self.a], [0.0, self.b * sa, self.b * ca], [0.0, 0.0, self.c]], + dtype=float, + ) # Cartesian coordinates of lattice vectors self.base = numpy.dot(self.stdbase, self.baserot) self.recbase = numalg.inv(self.base) @@ -350,7 +351,6 @@ def setLatPar(self, a=None, b=None, c=None, self.isotropicunit = _isotropicunit(self.recnormbase) return - def setLatBase(self, base): """Set new base vectors for this lattice. @@ -372,12 +372,12 @@ def setLatBase(self, base): elif detbase < 0.0: emsg = "base is not right-handed" raise LatticeError(emsg) - self._a = a = math.sqrt(numpy.dot(self.base[0,:], self.base[0,:])) - self._b = b = math.sqrt(numpy.dot(self.base[1,:], self.base[1,:])) - self._c = c = math.sqrt(numpy.dot(self.base[2,:], self.base[2,:])) - self._ca = ca = numpy.dot(self.base[1,:], self.base[2,:]) / (b*c) - self._cb = cb = numpy.dot(self.base[0,:], self.base[2,:]) / (a*c) - self._cg = cg = numpy.dot(self.base[0,:], self.base[1,:]) / (a*b) + self._a = a = math.sqrt(numpy.dot(self.base[0, :], self.base[0, :])) + self._b = b = math.sqrt(numpy.dot(self.base[1, :], self.base[1, :])) + self._c = c = math.sqrt(numpy.dot(self.base[2, :], self.base[2, :])) + self._ca = ca = numpy.dot(self.base[1, :], self.base[2, :]) / (b * c) + self._cb = cb = numpy.dot(self.base[0, :], self.base[2, :]) / (a * c) + self._cg = cg = numpy.dot(self.base[0, :], self.base[1, :]) / (a * b) self._sa = sa = math.sqrt(1.0 - ca**2) self._sb = sb = math.sqrt(1.0 - cb**2) self._sg = sg = math.sqrt(1.0 - cg**2) @@ -387,12 +387,12 @@ def setLatBase(self, base): # cache the unit volume value Vunit = self.unitvolume # reciprocal lattice - self._ar = ar = sa/(self.a*Vunit) - self._br = br = sb/(self.b*Vunit) - self._cr = cr = sg/(self.c*Vunit) - self._car = car = (cb*cg - ca)/(sb*sg) - self._cbr = cbr = (ca*cg - cb)/(sa*sg) - self._cgr = cgr = (ca*cb - cg)/(sa*sb) + self._ar = ar = sa / (self.a * Vunit) + self._br = br = sb / (self.b * Vunit) + self._cr = cr = sg / (self.c * Vunit) + self._car = car = (cb * cg - ca) / (sb * sg) + self._cbr = cbr = (ca * cg - cb) / (sa * sg) + self._cgr = cgr = (ca * cb - cg) / (sa * sb) self._sar = math.sqrt(1.0 - car**2) self._sbr = math.sqrt(1.0 - cbr**2) self._sgr = sgr = math.sqrt(1.0 - cgr**2) @@ -400,11 +400,9 @@ def setLatBase(self, base): self._betar = math.degrees(math.acos(cbr)) self._gammar = math.degrees(math.acos(cgr)) # standard orientation of lattice vectors - self.stdbase = numpy.array([ - [ 1.0/ar, -cgr/sgr/ar, cb*a ], - [ 0.0, b*sa, b*ca ], - [ 0.0, 0.0, c ]], - dtype=float) + self.stdbase = numpy.array( + [[1.0 / ar, -cgr / sgr / ar, cb * a], [0.0, b * sa, b * ca], [0.0, 0.0, c]], dtype=float + ) # calculate unit cell rotation matrix, base = stdbase @ baserot self.baserot = numpy.dot(numalg.inv(self.stdbase), self.base) self.recbase = numalg.inv(self.base) @@ -413,14 +411,12 @@ def setLatBase(self, base): self.recnormbase = self.recbase / [ar, br, cr] self.isotropicunit = _isotropicunit(self.recnormbase) # update metrics tensor - self.metrics = numpy.array([ - [ a*a, a*b*cg, a*c*cb ], - [ b*a*cg, b*b, b*c*ca ], - [ c*a*cb, c*b*ca, c*c ]], - dtype=float) + self.metrics = numpy.array( + [[a * a, a * b * cg, a * c * cb], [b * a * cg, b * b, b * c * ca], [c * a * cb, c * b * ca, c * c]], + dtype=float, + ) return - def abcABG(self): """ Returns @@ -430,7 +426,6 @@ def abcABG(self): rv = (self.a, self.b, self.c, self.alpha, self.beta, self.gamma) return rv - def reciprocal(self): """ Returns @@ -441,7 +436,6 @@ def reciprocal(self): rv = Lattice(base=numpy.transpose(self.recbase)) return rv - def cartesian(self, u): """Transform lattice vector to Cartesian coordinates. @@ -459,7 +453,6 @@ def cartesian(self, u): rc = numpy.dot(u, self.base) return rc - def fractional(self, rc): """Transform Cartesian vector to fractional lattice coordinates. @@ -477,7 +470,6 @@ def fractional(self, rc): u = numpy.dot(rc, self.recbase) return u - def dot(self, u, v): """Calculate dot product of 2 lattice vectors. @@ -497,7 +489,6 @@ def dot(self, u, v): dp = (u * numpy.dot(v, self.metrics)).sum(axis=-1) return dp - def norm(self, xyz): """Calculate norm of a lattice vector. @@ -512,8 +503,7 @@ def norm(self, xyz): The magnitude of the lattice vector *xyz*. """ # this is a few percent faster than sqrt(dot(u, u)). - return numpy.sqrt((self.cartesian(xyz)**2).sum(axis=-1)) - + return numpy.sqrt((self.cartesian(xyz) ** 2).sum(axis=-1)) def rnorm(self, hkl): """Calculate norm of a reciprocal vector. @@ -531,7 +521,6 @@ def rnorm(self, hkl): hklcartn = numpy.dot(hkl, self.recbase.T) return numpy.sqrt((hklcartn**2).sum(axis=-1)) - def dist(self, u, v): """Calculate distance between 2 points in lattice coordinates. @@ -554,7 +543,6 @@ def dist(self, u, v): duv = numpy.asarray(u) - v return self.norm(duv) - def angle(self, u, v): """Calculate angle between 2 lattice vectors in degrees. @@ -570,7 +558,7 @@ def angle(self, u, v): float The angle between lattice vectors *u* and *v* in degrees. """ - ca = self.dot(u, v)/( self.norm(u)*self.norm(v) ) + ca = self.dot(u, v) / (self.norm(u) * self.norm(v)) # avoid round-off errors that would make abs(ca) greater than 1 if numpy.isscalar(ca): ca = max(min(ca, 1), -1) @@ -581,7 +569,6 @@ def angle(self, u, v): rv = numpy.degrees(numpy.arccos(ca)) return rv - def isanisotropic(self, umx): """True if displacement parameter matrix is anisotropic. @@ -605,27 +592,26 @@ def isanisotropic(self, umx): rv = udmax > self._epsilon return rv - def __repr__(self): - """String representation of this lattice. - """ + """String representation of this lattice.""" I3 = numpy.identity(3, dtype=float) - rotbaseI3diff = max(numpy.reshape(numpy.fabs(self.baserot-I3), 9)) - cartlatpar = numpy.array([1.0, 1.0, 1.0 , 90.0, 90.0, 90.0]) + rotbaseI3diff = max(numpy.reshape(numpy.fabs(self.baserot - I3), 9)) + cartlatpar = numpy.array([1.0, 1.0, 1.0, 90.0, 90.0, 90.0]) latpardiff = cartlatpar - self.abcABG() if rotbaseI3diff > self._epsilon: s = "Lattice(base=%r)" % self.base elif numpy.fabs(latpardiff).max() < self._epsilon: s = "Lattice()" else: - s = "Lattice(a=%g, b=%g, c=%g, alpha=%g, beta=%g, gamma=%g)" % \ - self.abcABG() + s = "Lattice(a=%g, b=%g, c=%g, alpha=%g, beta=%g, gamma=%g)" % self.abcABG() return s + # End of class Lattice # Local Helpers -------------------------------------------------------------- + def _isotropicunit(recnormbase): """Calculate tensor of unit isotropic displacement parameters. @@ -647,6 +633,7 @@ def _isotropicunit(recnormbase): isounit[2, 2] = 1 return isounit + # Module Constants ----------------------------------------------------------- cartesian = Lattice() diff --git a/src/diffpy/structure/mmlibspacegroups.py b/src/diffpy/structure/mmlibspacegroups.py index ef2c97bd..33f284d3 100644 --- a/src/diffpy/structure/mmlibspacegroups.py +++ b/src/diffpy/structure/mmlibspacegroups.py @@ -6,7324 +6,7882 @@ """Space groups defined as a part of the pymmlib. """ -from diffpy.structure.spacegroupmod import SpaceGroup, SymOp from diffpy.structure.spacegroupmod import ( - Rot_X_Y_Z, Rot_mX_mY_mZ, Rot_mX_Y_mZ, Rot_X_mY_Z, - Rot_mX_mY_Z, Rot_X_mY_mZ, Rot_mX_Y_Z, Rot_X_Y_mZ, - Rot_mY_X_Z, Rot_Y_mX_Z, Rot_Y_mX_mZ, Rot_mY_X_mZ, - Rot_Y_X_mZ, Rot_mY_mX_mZ, Rot_mY_mX_Z, Rot_Y_X_Z, - Rot_mY_XmY_Z, Rot_mXY_mX_Z, Rot_Z_X_Y, Rot_Y_Z_X, - Rot_Y_mXY_mZ, Rot_XmY_X_mZ, Rot_mZ_mX_mY, Rot_mY_mZ_mX, - Rot_mXY_Y_mZ, Rot_X_XmY_mZ, Rot_XmY_mY_mZ, Rot_mX_mXY_mZ, - Rot_mX_mZ_mY, Rot_mZ_mY_mX, Rot_mXY_Y_Z, Rot_X_XmY_Z, - Rot_XmY_mY_Z, Rot_mX_mXY_Z, Rot_X_Z_Y, Rot_Z_Y_X, - Rot_Y_mXY_Z, Rot_XmY_X_Z, Rot_mY_XmY_mZ, Rot_mXY_mX_mZ, - Rot_Z_mX_mY, Rot_mZ_mX_Y, Rot_mZ_X_mY, Rot_mY_Z_mX, - Rot_Y_mZ_mX, Rot_mY_mZ_X, Rot_mZ_X_Y, Rot_Z_X_mY, - Rot_Z_mX_Y, Rot_Y_mZ_X, Rot_mY_Z_X, Rot_Y_Z_mX, - Rot_X_Z_mY, Rot_mX_Z_Y, Rot_X_mZ_Y, Rot_Z_Y_mX, - Rot_Z_mY_X, Rot_mZ_Y_X, Rot_mX_Z_mY, Rot_mX_mZ_Y, - Rot_X_mZ_mY, Rot_Z_mY_mX, Rot_mZ_Y_mX, Rot_mZ_mY_X, - Tr_0_0_0, Tr_0_12_0, Tr_12_12_0, Tr_0_0_12, - Tr_12_12_12, Tr_0_12_12, Tr_12_0_12, Tr_12_0_0, - Tr_14_14_14, Tr_14_34_34, Tr_34_14_34, Tr_34_34_14, - Tr_0_0_14, Tr_0_0_34, Tr_0_12_14, Tr_12_0_34, - Tr_12_12_14, Tr_12_12_34, Tr_0_12_34, Tr_12_0_14, - Tr_0_0_13, Tr_0_0_23, Tr_23_13_13, Tr_13_23_23, - Tr_23_13_56, Tr_13_23_16, Tr_0_0_56, Tr_0_0_16, - Tr_34_14_14, Tr_34_34_34, Tr_14_14_34, Tr_14_34_14, + Rot_mX_mXY_mZ, + Rot_mX_mXY_Z, + Rot_mX_mY_mZ, + Rot_mX_mY_Z, + Rot_mX_mZ_mY, + Rot_mX_mZ_Y, + Rot_mX_Y_mZ, + Rot_mX_Y_Z, + Rot_mX_Z_mY, + Rot_mX_Z_Y, + Rot_mXY_mX_mZ, + Rot_mXY_mX_Z, + Rot_mXY_Y_mZ, + Rot_mXY_Y_Z, + Rot_mY_mX_mZ, + Rot_mY_mX_Z, + Rot_mY_mZ_mX, + Rot_mY_mZ_X, + Rot_mY_X_mZ, + Rot_mY_X_Z, + Rot_mY_XmY_mZ, + Rot_mY_XmY_Z, + Rot_mY_Z_mX, + Rot_mY_Z_X, + Rot_mZ_mX_mY, + Rot_mZ_mX_Y, + Rot_mZ_mY_mX, + Rot_mZ_mY_X, + Rot_mZ_X_mY, + Rot_mZ_X_Y, + Rot_mZ_Y_mX, + Rot_mZ_Y_X, + Rot_X_mY_mZ, + Rot_X_mY_Z, + Rot_X_mZ_mY, + Rot_X_mZ_Y, + Rot_X_XmY_mZ, + Rot_X_XmY_Z, + Rot_X_Y_mZ, + Rot_X_Y_Z, + Rot_X_Z_mY, + Rot_X_Z_Y, + Rot_XmY_mY_mZ, + Rot_XmY_mY_Z, + Rot_XmY_X_mZ, + Rot_XmY_X_Z, + Rot_Y_mX_mZ, + Rot_Y_mX_Z, + Rot_Y_mXY_mZ, + Rot_Y_mXY_Z, + Rot_Y_mZ_mX, + Rot_Y_mZ_X, + Rot_Y_X_mZ, + Rot_Y_X_Z, + Rot_Y_Z_mX, + Rot_Y_Z_X, + Rot_Z_mX_mY, + Rot_Z_mX_Y, + Rot_Z_mY_mX, + Rot_Z_mY_X, + Rot_Z_X_mY, + Rot_Z_X_Y, + Rot_Z_Y_mX, + Rot_Z_Y_X, + SpaceGroup, + SymOp, + Tr_0_0_0, + Tr_0_0_12, + Tr_0_0_13, + Tr_0_0_14, + Tr_0_0_16, + Tr_0_0_23, + Tr_0_0_34, + Tr_0_0_56, + Tr_0_12_0, + Tr_0_12_12, + Tr_0_12_14, + Tr_0_12_34, + Tr_12_0_0, + Tr_12_0_12, + Tr_12_0_14, + Tr_12_0_34, + Tr_12_12_0, + Tr_12_12_12, + Tr_12_12_14, + Tr_12_12_34, + Tr_13_23_16, + Tr_13_23_23, + Tr_14_14_14, + Tr_14_14_34, + Tr_14_34_14, + Tr_14_34_34, + Tr_23_13_13, + Tr_23_13_56, + Tr_34_14_14, + Tr_34_14_34, + Tr_34_34_14, + Tr_34_34_34, ) ## spacegroup definitions sg1 = SpaceGroup( - number = 1, - num_sym_equiv = 1, - num_primitive_sym_equiv = 1, - short_name = "P1", - point_group_name = "PG1", - crystal_system = "TRICLINIC", - pdb_name = "P 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0)]) + number=1, + num_sym_equiv=1, + num_primitive_sym_equiv=1, + short_name="P1", + point_group_name="PG1", + crystal_system="TRICLINIC", + pdb_name="P 1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0)], +) sg2 = SpaceGroup( - number = 2, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P-1", - point_group_name = "PG1bar", - crystal_system = "TRICLINIC", - pdb_name = "P -1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0)]) + number=2, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P-1", + point_group_name="PG1bar", + crystal_system="TRICLINIC", + pdb_name="P -1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0)], +) sg3 = SpaceGroup( - number = 3, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P2", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 2 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0)]) + number=3, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P2", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="P 1 2 1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0)], +) sg4 = SpaceGroup( - number = 4, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P21", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 21 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0)]) + number=4, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P21", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="P 1 21 1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0)], +) sg5 = SpaceGroup( - number = 5, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "C2", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 2 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0)]) + number=5, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="C2", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="C 1 2 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + ], +) sg6 = SpaceGroup( - number = 6, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "Pm", - point_group_name = "PGm", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0)]) + number=6, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pm", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 m 1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0)], +) sg7 = SpaceGroup( - number = 7, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "Pc", - point_group_name = "PGm", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12)]) + number=7, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pc", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 c 1", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12)], +) sg8 = SpaceGroup( - number = 8, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "Cm", - point_group_name = "PGm", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0)]) + number=8, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="Cm", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C 1 m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + ], +) sg9 = SpaceGroup( - number = 9, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "Cc", - point_group_name = "PGm", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12)]) + number=9, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="Cc", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C 1 c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + ], +) sg10 = SpaceGroup( - number = 10, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P2/m", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 2/m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0)]) + number=10, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/m", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 2/m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + ], +) sg11 = SpaceGroup( - number = 11, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P21/m", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 21/m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_12_0)]) + number=11, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/m", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 21/m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + ], +) sg12 = SpaceGroup( - number = 12, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C2/m", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 2/m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0)]) + number=12, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C2/m", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 1 2/m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + ], +) sg13 = SpaceGroup( - number = 13, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P2/c", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 2/c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12)]) + number=13, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/c", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 2/c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + ], +) sg14 = SpaceGroup( - number = 14, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P21/c", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 21/c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12)]) + number=14, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/c", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 21/c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + ], +) sg15 = SpaceGroup( - number = 15, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C2/c", - point_group_name = "PG2/m", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 2/c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12)]) + number=15, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C2/c", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 1 2/c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + ], +) sg16 = SpaceGroup( - number = 16, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P222", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0)]) + number=16, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + ], +) sg17 = SpaceGroup( - number = 17, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P2221", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2 2 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0)]) + number=17, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2221", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 2 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + ], +) sg18 = SpaceGroup( - number = 18, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P21212", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0)]) + number=18, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21212", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + ], +) sg19 = SpaceGroup( - number = 19, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P212121", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21 21 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0)]) + number=19, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P212121", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 21 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + ], +) sg20 = SpaceGroup( - number = 20, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C2221", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2 2 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0)]) + number=20, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C2221", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 2 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + ], +) sg21 = SpaceGroup( - number = 21, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C222", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0)]) + number=21, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + ], +) sg22 = SpaceGroup( - number = 22, - num_sym_equiv = 16, - num_primitive_sym_equiv = 4, - short_name = "F222", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F 2 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0)]) + number=22, + num_sym_equiv=16, + num_primitive_sym_equiv=4, + short_name="F222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + ], +) sg23 = SpaceGroup( - number = 23, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I222", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 2 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12)]) + number=23, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + ], +) sg24 = SpaceGroup( - number = 24, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I212121", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 21 21 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12)]) + number=24, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I212121", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="I 21 21 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + ], +) sg25 = SpaceGroup( - number = 25, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pmm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P m m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=25, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pmm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg26 = SpaceGroup( - number = 26, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pmc21", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P m c 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=26, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pmc21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m c 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg27 = SpaceGroup( - number = 27, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pcc2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P c c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=27, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pcc2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg28 = SpaceGroup( - number = 28, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pma2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P m a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_0)]) + number=28, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pma2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_0), + ], +) sg29 = SpaceGroup( - number = 29, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pca21", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P c a 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_12)]) + number=29, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pca21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c a 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + ], +) sg30 = SpaceGroup( - number = 30, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pnc2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P n c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12)]) + number=30, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pnc2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + ], +) sg31 = SpaceGroup( - number = 31, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pmn21", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P m n 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=31, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pmn21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m n 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg32 = SpaceGroup( - number = 32, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pba2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P b a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=32, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pba2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg33 = SpaceGroup( - number = 33, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pna21", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P n a 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=33, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pna21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n a 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg34 = SpaceGroup( - number = 34, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "Pnn2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P n n 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=34, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pnn2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n n 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg35 = SpaceGroup( - number = 35, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Cmm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C m m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=35, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Cmm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C m m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg36 = SpaceGroup( - number = 36, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Cmc21", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C m c 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=36, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Cmc21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C m c 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg37 = SpaceGroup( - number = 37, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Ccc2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C c c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=37, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Ccc2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C c c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg38 = SpaceGroup( - number = 38, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Amm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "A m m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12)]) + number=38, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Amm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A m m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + ], +) sg39 = SpaceGroup( - number = 39, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Abm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "A b m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_Z, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=39, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Abm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A b m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_Z, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg40 = SpaceGroup( - number = 40, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Ama2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "A m a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=40, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Ama2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A m a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg41 = SpaceGroup( - number = 41, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Aba2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "A b a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12)]) + number=41, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Aba2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A b a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + ], +) sg42 = SpaceGroup( - number = 42, - num_sym_equiv = 16, - num_primitive_sym_equiv = 4, - short_name = "Fmm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F m m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=42, + num_sym_equiv=16, + num_primitive_sym_equiv=4, + short_name="Fmm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F m m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg43 = SpaceGroup( - number = 43, - num_sym_equiv = 16, - num_primitive_sym_equiv = 4, - short_name = "Fdd2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F d d 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_14_14_14), - SymOp(Rot_mX_Y_Z, Tr_14_14_14), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_14_34_34), - SymOp(Rot_mX_Y_Z, Tr_14_34_34), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_34_14_34), - SymOp(Rot_mX_Y_Z, Tr_34_14_34), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_34_34_14), - SymOp(Rot_mX_Y_Z, Tr_34_34_14)]) + number=43, + num_sym_equiv=16, + num_primitive_sym_equiv=4, + short_name="Fdd2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F d d 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_14_14_14), + SymOp(Rot_mX_Y_Z, Tr_14_14_14), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_14_34_34), + SymOp(Rot_mX_Y_Z, Tr_14_34_34), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_34_14_34), + SymOp(Rot_mX_Y_Z, Tr_34_14_34), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_34_34_14), + SymOp(Rot_mX_Y_Z, Tr_34_34_14), + ], +) sg44 = SpaceGroup( - number = 44, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Imm2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I m m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=44, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Imm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I m m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg45 = SpaceGroup( - number = 45, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Iba2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I b a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=45, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Iba2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I b a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg46 = SpaceGroup( - number = 46, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "Ima2", - point_group_name = "PGmm2", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I m a 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12)]) + number=46, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="Ima2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I m a 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + ], +) sg47 = SpaceGroup( - number = 47, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pmmm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=47, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg48 = SpaceGroup( - number = 48, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pnnn", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/n 2/n 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=48, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnnn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/n 2/n 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg49 = SpaceGroup( - number = 49, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pccm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/c 2/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=49, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pccm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/c 2/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg50 = SpaceGroup( - number = 50, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pban", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/b 2/a 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=50, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pban", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/b 2/a 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg51 = SpaceGroup( - number = 51, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pmma", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/m 2/m 2/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_0)]) + number=51, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/m 2/m 2/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_0), + ], +) sg52 = SpaceGroup( - number = 52, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pnna", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/n 21/n 2/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12)]) + number=52, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnna", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/n 21/n 2/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + ], +) sg53 = SpaceGroup( - number = 53, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pmna", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/m 2/n 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=53, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmna", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/m 2/n 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg54 = SpaceGroup( - number = 54, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pcca", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/c 2/c 2/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12)]) + number=54, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/c 2/c 2/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + ], +) sg55 = SpaceGroup( - number = 55, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pbam", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/b 21/a 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=55, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/b 21/a 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg56 = SpaceGroup( - number = 56, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pccn", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/c 21/c 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12)]) + number=56, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pccn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/c 21/c 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + ], +) sg57 = SpaceGroup( - number = 57, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pbcm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2/b 21/c 21/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_0)]) + number=57, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2/b 21/c 21/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_0), + ], +) sg58 = SpaceGroup( - number = 58, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pnnm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/n 21/n 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=58, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnnm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/n 21/n 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg59 = SpaceGroup( - number = 59, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pmmn", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/m 21/m 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0)]) + number=59, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmmn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/m 21/m 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + ], +) sg60 = SpaceGroup( - number = 60, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pbcn", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/b 2/c 21/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=60, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbcn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/b 2/c 21/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg61 = SpaceGroup( - number = 61, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pbca", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/b 21/c 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=61, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/b 21/c 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg62 = SpaceGroup( - number = 62, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pnma", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/n 21/m 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=62, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/n 21/m 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg63 = SpaceGroup( - number = 63, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Cmcm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/m 2/c 21/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=63, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Cmcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/m 2/c 21/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg64 = SpaceGroup( - number = 64, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Cmca", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/m 2/c 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=64, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Cmca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/m 2/c 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg65 = SpaceGroup( - number = 65, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Cmmm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=65, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Cmmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg66 = SpaceGroup( - number = 66, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Cccm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/c 2/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=66, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Cccm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/c 2/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg67 = SpaceGroup( - number = 67, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Cmma", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/m 2/m 2/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=67, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Cmma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/m 2/m 2/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg68 = SpaceGroup( - number = 68, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Ccca", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2/c 2/c 2/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12)]) + number=68, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Ccca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2/c 2/c 2/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + ], +) sg69 = SpaceGroup( - number = 69, - num_sym_equiv = 32, - num_primitive_sym_equiv = 8, - short_name = "Fmmm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F 2/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0)]) + number=69, + num_sym_equiv=32, + num_primitive_sym_equiv=8, + short_name="Fmmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + ], +) sg70 = SpaceGroup( - number = 70, - num_sym_equiv = 32, - num_primitive_sym_equiv = 8, - short_name = "Fddd", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F 2/d 2/d 2/d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_14_14_14), - SymOp(Rot_X_Y_mZ, Tr_14_14_14), - SymOp(Rot_X_mY_Z, Tr_14_14_14), - SymOp(Rot_mX_Y_Z, Tr_14_14_14), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_14_34_34), - SymOp(Rot_X_Y_mZ, Tr_14_34_34), - SymOp(Rot_X_mY_Z, Tr_14_34_34), - SymOp(Rot_mX_Y_Z, Tr_14_34_34), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_34_14_34), - SymOp(Rot_X_Y_mZ, Tr_34_14_34), - SymOp(Rot_X_mY_Z, Tr_34_14_34), - SymOp(Rot_mX_Y_Z, Tr_34_14_34), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_34_34_14), - SymOp(Rot_X_Y_mZ, Tr_34_34_14), - SymOp(Rot_X_mY_Z, Tr_34_34_14), - SymOp(Rot_mX_Y_Z, Tr_34_34_14)]) + number=70, + num_sym_equiv=32, + num_primitive_sym_equiv=8, + short_name="Fddd", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2/d 2/d 2/d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_14_14_14), + SymOp(Rot_X_Y_mZ, Tr_14_14_14), + SymOp(Rot_X_mY_Z, Tr_14_14_14), + SymOp(Rot_mX_Y_Z, Tr_14_14_14), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_14_34_34), + SymOp(Rot_X_Y_mZ, Tr_14_34_34), + SymOp(Rot_X_mY_Z, Tr_14_34_34), + SymOp(Rot_mX_Y_Z, Tr_14_34_34), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_34_14_34), + SymOp(Rot_X_Y_mZ, Tr_34_14_34), + SymOp(Rot_X_mY_Z, Tr_34_14_34), + SymOp(Rot_mX_Y_Z, Tr_34_14_34), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_34_34_14), + SymOp(Rot_X_Y_mZ, Tr_34_34_14), + SymOp(Rot_X_mY_Z, Tr_34_34_14), + SymOp(Rot_mX_Y_Z, Tr_34_34_14), + ], +) sg71 = SpaceGroup( - number = 71, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Immm", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 2/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=71, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Immm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg72 = SpaceGroup( - number = 72, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Ibam", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 2/b 2/a 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=72, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Ibam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2/b 2/a 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg73 = SpaceGroup( - number = 73, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Ibca", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 21/b 21/c 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_12)]) + number=73, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Ibca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I 21/b 21/c 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + ], +) sg74 = SpaceGroup( - number = 74, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "Imma", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 21/m 21/m 21/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12)]) + number=74, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="Imma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I 21/m 21/m 21/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + ], +) sg75 = SpaceGroup( - number = 75, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P4", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "P 4", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0)]) + number=75, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P4", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="P 4", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + ], +) sg76 = SpaceGroup( - number = 76, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P41", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "P 41", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_0_0_14), - SymOp(Rot_Y_mX_Z, Tr_0_0_34)]) + number=76, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P41", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="P 41", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_0_0_14), + SymOp(Rot_Y_mX_Z, Tr_0_0_34), + ], +) sg77 = SpaceGroup( - number = 77, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P42", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "P 42", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12)]) + number=77, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P42", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="P 42", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + ], +) sg78 = SpaceGroup( - number = 78, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P43", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "P 43", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_0_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_0_14)]) + number=78, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P43", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="P 43", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_0_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_0_14), + ], +) sg79 = SpaceGroup( - number = 79, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I4", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "I 4", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12)]) + number=79, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I4", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="I 4", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + ], +) sg80 = SpaceGroup( - number = 80, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I41", - point_group_name = "PG4", - crystal_system = "TETRAGONAL", - pdb_name = "I 41", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14)]) + number=80, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I41", + point_group_name="PG4", + crystal_system="TETRAGONAL", + pdb_name="I 41", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + ], +) sg81 = SpaceGroup( - number = 81, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P-4", - point_group_name = "PG4bar", - crystal_system = "TETRAGONAL", - pdb_name = "P -4", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0)]) + number=81, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P-4", + point_group_name="PG4bar", + crystal_system="TETRAGONAL", + pdb_name="P -4", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + ], +) sg82 = SpaceGroup( - number = 82, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I-4", - point_group_name = "PG4bar", - crystal_system = "TETRAGONAL", - pdb_name = "I -4", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12)]) + number=82, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I-4", + point_group_name="PG4bar", + crystal_system="TETRAGONAL", + pdb_name="I -4", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + ], +) sg83 = SpaceGroup( - number = 83, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4/m", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0)]) + number=83, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4/m", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="P 4/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + ], +) sg84 = SpaceGroup( - number = 84, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42/m", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12)]) + number=84, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42/m", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="P 42/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + ], +) sg85 = SpaceGroup( - number = 85, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4/n", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0)]) + number=85, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4/n", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="P 4/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + ], +) sg86 = SpaceGroup( - number = 86, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42/n", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0)]) + number=86, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42/n", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="P 42/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + ], +) sg87 = SpaceGroup( - number = 87, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I4/m", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "I 4/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12)]) + number=87, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I4/m", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="I 4/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + ], +) sg88 = SpaceGroup( - number = 88, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I41/a", - point_group_name = "PG4/m", - crystal_system = "TETRAGONAL", - pdb_name = "I 41/a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_mX_mY_mZ, Tr_0_12_14), - SymOp(Rot_X_Y_mZ, Tr_12_0_34), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_mX_mY_mZ, Tr_12_0_34), - SymOp(Rot_X_Y_mZ, Tr_0_12_14), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_0)]) + number=88, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I41/a", + point_group_name="PG4/m", + crystal_system="TETRAGONAL", + pdb_name="I 41/a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_mX_mY_mZ, Tr_0_12_14), + SymOp(Rot_X_Y_mZ, Tr_12_0_34), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_mX_mY_mZ, Tr_12_0_34), + SymOp(Rot_X_Y_mZ, Tr_0_12_14), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + ], +) sg89 = SpaceGroup( - number = 89, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P422", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0)]) + number=89, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P422", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 4 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + ], +) sg90 = SpaceGroup( - number = 90, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4212", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0)]) + number=90, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4212", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 4 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + ], +) sg91 = SpaceGroup( - number = 91, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4122", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 41 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_0_0_14), - SymOp(Rot_Y_mX_Z, Tr_0_0_34), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_34), - SymOp(Rot_mY_mX_mZ, Tr_0_0_14)]) + number=91, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4122", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 41 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_0_0_14), + SymOp(Rot_Y_mX_Z, Tr_0_0_34), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_34), + SymOp(Rot_mY_mX_mZ, Tr_0_0_14), + ], +) sg92 = SpaceGroup( - number = 92, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P41212", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 41 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_12_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_12_34), - SymOp(Rot_mX_Y_mZ, Tr_12_12_14), - SymOp(Rot_X_mY_mZ, Tr_12_12_34), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12)]) + number=92, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P41212", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 41 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_12_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_12_34), + SymOp(Rot_mX_Y_mZ, Tr_12_12_14), + SymOp(Rot_X_mY_mZ, Tr_12_12_34), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + ], +) sg93 = SpaceGroup( - number = 93, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4222", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12)]) + number=93, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4222", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 42 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + ], +) sg94 = SpaceGroup( - number = 94, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42212", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0)]) + number=94, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42212", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 42 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + ], +) sg95 = SpaceGroup( - number = 95, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4322", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 43 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_0_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_0_14), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_14), - SymOp(Rot_mY_mX_mZ, Tr_0_0_34)]) + number=95, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4322", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 43 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_0_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_0_14), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_14), + SymOp(Rot_mY_mX_mZ, Tr_0_0_34), + ], +) sg96 = SpaceGroup( - number = 96, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P43212", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 43 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_12_12_34), - SymOp(Rot_Y_mX_Z, Tr_12_12_14), - SymOp(Rot_mX_Y_mZ, Tr_12_12_34), - SymOp(Rot_X_mY_mZ, Tr_12_12_14), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12)]) + number=96, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P43212", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 43 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_12_12_34), + SymOp(Rot_Y_mX_Z, Tr_12_12_14), + SymOp(Rot_mX_Y_mZ, Tr_12_12_34), + SymOp(Rot_X_mY_mZ, Tr_12_12_14), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + ], +) sg97 = SpaceGroup( - number = 97, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I422", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "I 4 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12)]) + number=97, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I422", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="I 4 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + ], +) sg98 = SpaceGroup( - number = 98, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I4122", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "I 41 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_mX_Y_mZ, Tr_12_0_34), - SymOp(Rot_X_mY_mZ, Tr_0_12_14), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_mX_Y_mZ, Tr_0_12_14), - SymOp(Rot_X_mY_mZ, Tr_12_0_34), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12)]) + number=98, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I4122", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="I 41 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_mX_Y_mZ, Tr_12_0_34), + SymOp(Rot_X_mY_mZ, Tr_0_12_14), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_mX_Y_mZ, Tr_0_12_14), + SymOp(Rot_X_mY_mZ, Tr_12_0_34), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + ], +) sg99 = SpaceGroup( - number = 99, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4mm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 m m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=99, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4mm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 4 m m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg100 = SpaceGroup( - number = 100, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4bm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 b m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=100, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4bm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 4 b m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg101 = SpaceGroup( - number = 101, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42cm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 c m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=101, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42cm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 42 c m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg102 = SpaceGroup( - number = 102, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42nm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 n m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=102, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42nm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 42 n m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg103 = SpaceGroup( - number = 103, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4cc", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 c c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=103, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4cc", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 4 c c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg104 = SpaceGroup( - number = 104, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P4nc", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4 n c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=104, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P4nc", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 4 n c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg105 = SpaceGroup( - number = 105, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42mc", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 m c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=105, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42mc", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 42 m c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg106 = SpaceGroup( - number = 106, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42bc", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 b c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=106, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42bc", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="P 42 b c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg107 = SpaceGroup( - number = 107, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I4mm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "I 4 m m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=107, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I4mm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="I 4 m m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg108 = SpaceGroup( - number = 108, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I4cm", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "I 4 c m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=108, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I4cm", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="I 4 c m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg109 = SpaceGroup( - number = 109, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I41md", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "I 41 m d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_12_14), - SymOp(Rot_Y_X_Z, Tr_12_0_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_0_34), - SymOp(Rot_Y_X_Z, Tr_0_12_14)]) + number=109, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I41md", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="I 41 m d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_12_14), + SymOp(Rot_Y_X_Z, Tr_12_0_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_0_34), + SymOp(Rot_Y_X_Z, Tr_0_12_14), + ], +) sg110 = SpaceGroup( - number = 110, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I41cd", - point_group_name = "PG4mm", - crystal_system = "TETRAGONAL", - pdb_name = "I 41 c d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_0_12_34), - SymOp(Rot_Y_X_Z, Tr_12_0_14), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_0_14), - SymOp(Rot_Y_X_Z, Tr_0_12_34)]) + number=110, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I41cd", + point_group_name="PG4mm", + crystal_system="TETRAGONAL", + pdb_name="I 41 c d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_0_12_34), + SymOp(Rot_Y_X_Z, Tr_12_0_14), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_0_14), + SymOp(Rot_Y_X_Z, Tr_0_12_34), + ], +) sg111 = SpaceGroup( - number = 111, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-42m", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 2 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=111, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-42m", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="P -4 2 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg112 = SpaceGroup( - number = 112, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-42c", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 2 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=112, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-42c", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="P -4 2 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg113 = SpaceGroup( - number = 113, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-421m", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 21 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=113, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-421m", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="P -4 21 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg114 = SpaceGroup( - number = 114, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-421c", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 21 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=114, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-421c", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="P -4 21 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg115 = SpaceGroup( - number = 115, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-4m2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0)]) + number=115, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-4m2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="P -4 m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + ], +) sg116 = SpaceGroup( - number = 116, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-4c2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12)]) + number=116, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-4c2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="P -4 c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + ], +) sg117 = SpaceGroup( - number = 117, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-4b2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 b 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0)]) + number=117, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-4b2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="P -4 b 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + ], +) sg118 = SpaceGroup( - number = 118, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P-4n2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "P -4 n 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12)]) + number=118, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P-4n2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="P -4 n 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + ], +) sg119 = SpaceGroup( - number = 119, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I-4m2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "I -4 m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12)]) + number=119, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I-4m2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="I -4 m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + ], +) sg120 = SpaceGroup( - number = 120, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I-4c2", - point_group_name = "PG4barm2", - crystal_system = "TETRAGONAL", - pdb_name = "I -4 c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0)]) + number=120, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I-4c2", + point_group_name="PG4barm2", + crystal_system="TETRAGONAL", + pdb_name="I -4 c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + ], +) sg121 = SpaceGroup( - number = 121, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I-42m", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "I -4 2 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=121, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I-42m", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="I -4 2 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg122 = SpaceGroup( - number = 122, - num_sym_equiv = 16, - num_primitive_sym_equiv = 8, - short_name = "I-42d", - point_group_name = "PG4bar2m", - crystal_system = "TETRAGONAL", - pdb_name = "I -4 2 d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_34), - SymOp(Rot_X_mY_mZ, Tr_12_0_34), - SymOp(Rot_mY_mX_Z, Tr_12_0_34), - SymOp(Rot_Y_X_Z, Tr_12_0_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_14), - SymOp(Rot_X_mY_mZ, Tr_0_12_14), - SymOp(Rot_mY_mX_Z, Tr_0_12_14), - SymOp(Rot_Y_X_Z, Tr_0_12_14)]) + number=122, + num_sym_equiv=16, + num_primitive_sym_equiv=8, + short_name="I-42d", + point_group_name="PG4bar2m", + crystal_system="TETRAGONAL", + pdb_name="I -4 2 d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_34), + SymOp(Rot_X_mY_mZ, Tr_12_0_34), + SymOp(Rot_mY_mX_Z, Tr_12_0_34), + SymOp(Rot_Y_X_Z, Tr_12_0_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_14), + SymOp(Rot_X_mY_mZ, Tr_0_12_14), + SymOp(Rot_mY_mX_Z, Tr_0_12_14), + SymOp(Rot_Y_X_Z, Tr_0_12_14), + ], +) sg123 = SpaceGroup( - number = 123, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/mmm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=123, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/mmm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg124 = SpaceGroup( - number = 124, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/mcc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/m 2/c 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=124, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/mcc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/m 2/c 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg125 = SpaceGroup( - number = 125, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/nbm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/n 2/b 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_12_12_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=125, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/nbm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/n 2/b 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_12_12_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg126 = SpaceGroup( - number = 126, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/nnc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/n 2/n 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=126, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/nnc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/n 2/n 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg127 = SpaceGroup( - number = 127, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/mbm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/m 21/b 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=127, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/mbm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/m 21/b 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg128 = SpaceGroup( - number = 128, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/mnc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/m 21/n 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=128, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/mnc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/m 21/n 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg129 = SpaceGroup( - number = 129, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/nmm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/n 21/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=129, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/nmm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/n 21/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg130 = SpaceGroup( - number = 130, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P4/ncc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 4/n 2/c 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=130, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P4/ncc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 4/n 2/c 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg131 = SpaceGroup( - number = 131, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/mmc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/m 2/m 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=131, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/mmc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/m 2/m 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg132 = SpaceGroup( - number = 132, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/mcm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/m 2/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=132, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/mcm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/m 2/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg133 = SpaceGroup( - number = 133, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/nbc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/n 2/b 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12)]) + number=133, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/nbc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/n 2/b 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + ], +) sg134 = SpaceGroup( - number = 134, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/nnm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/n 2/n 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=134, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/nnm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/n 2/n 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg135 = SpaceGroup( - number = 135, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/mbc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/m 21/b 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=135, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/mbc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/m 21/b 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg136 = SpaceGroup( - number = 136, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/mnm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/m 21/n 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0)]) + number=136, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/mnm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/m 21/n 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + ], +) sg137 = SpaceGroup( - number = 137, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/nmc", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/n 21/m 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=137, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/nmc", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/n 21/m 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg138 = SpaceGroup( - number = 138, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = "P42/ncm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "P 42/n 21/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=138, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="P42/ncm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="P 42/n 21/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg139 = SpaceGroup( - number = 139, - num_sym_equiv = 32, - num_primitive_sym_equiv = 16, - short_name = "I4/mmm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "I 4/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12)]) + number=139, + num_sym_equiv=32, + num_primitive_sym_equiv=16, + short_name="I4/mmm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="I 4/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + ], +) sg140 = SpaceGroup( - number = 140, - num_sym_equiv = 32, - num_primitive_sym_equiv = 16, - short_name = "I4/mcm", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "I 4/m 2/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0)]) + number=140, + num_sym_equiv=32, + num_primitive_sym_equiv=16, + short_name="I4/mcm", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="I 4/m 2/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + ], +) sg141 = SpaceGroup( - number = 141, - num_sym_equiv = 32, - num_primitive_sym_equiv = 16, - short_name = "I41/amd", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "I 41/a 2/m 2/d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_mX_Y_mZ, Tr_12_0_34), - SymOp(Rot_X_mY_mZ, Tr_0_12_14), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_12_14), - SymOp(Rot_X_Y_mZ, Tr_12_0_34), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_0_34), - SymOp(Rot_Y_X_Z, Tr_0_12_14), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_mX_Y_mZ, Tr_0_12_14), - SymOp(Rot_X_mY_mZ, Tr_12_0_34), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_34), - SymOp(Rot_X_Y_mZ, Tr_0_12_14), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_12_14), - SymOp(Rot_Y_X_Z, Tr_12_0_34)]) + number=141, + num_sym_equiv=32, + num_primitive_sym_equiv=16, + short_name="I41/amd", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="I 41/a 2/m 2/d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_mX_Y_mZ, Tr_12_0_34), + SymOp(Rot_X_mY_mZ, Tr_0_12_14), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_12_14), + SymOp(Rot_X_Y_mZ, Tr_12_0_34), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_0_34), + SymOp(Rot_Y_X_Z, Tr_0_12_14), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_mX_Y_mZ, Tr_0_12_14), + SymOp(Rot_X_mY_mZ, Tr_12_0_34), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_34), + SymOp(Rot_X_Y_mZ, Tr_0_12_14), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_12_14), + SymOp(Rot_Y_X_Z, Tr_12_0_34), + ], +) sg142 = SpaceGroup( - number = 142, - num_sym_equiv = 32, - num_primitive_sym_equiv = 16, - short_name = "I41/acd", - point_group_name = "PG4/mmm", - crystal_system = "TETRAGONAL", - pdb_name = "I 41/a 2/c 2/d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_14), - SymOp(Rot_Y_mX_Z, Tr_12_0_34), - SymOp(Rot_mX_Y_mZ, Tr_12_0_14), - SymOp(Rot_X_mY_mZ, Tr_0_12_34), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_12_14), - SymOp(Rot_X_Y_mZ, Tr_12_0_34), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_0_14), - SymOp(Rot_Y_X_Z, Tr_0_12_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_34), - SymOp(Rot_Y_mX_Z, Tr_0_12_14), - SymOp(Rot_mX_Y_mZ, Tr_0_12_34), - SymOp(Rot_X_mY_mZ, Tr_12_0_14), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_0_34), - SymOp(Rot_X_Y_mZ, Tr_0_12_14), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_0_12_34), - SymOp(Rot_Y_X_Z, Tr_12_0_14)]) + number=142, + num_sym_equiv=32, + num_primitive_sym_equiv=16, + short_name="I41/acd", + point_group_name="PG4/mmm", + crystal_system="TETRAGONAL", + pdb_name="I 41/a 2/c 2/d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_14), + SymOp(Rot_Y_mX_Z, Tr_12_0_34), + SymOp(Rot_mX_Y_mZ, Tr_12_0_14), + SymOp(Rot_X_mY_mZ, Tr_0_12_34), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_12_14), + SymOp(Rot_X_Y_mZ, Tr_12_0_34), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_0_14), + SymOp(Rot_Y_X_Z, Tr_0_12_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_34), + SymOp(Rot_Y_mX_Z, Tr_0_12_14), + SymOp(Rot_mX_Y_mZ, Tr_0_12_34), + SymOp(Rot_X_mY_mZ, Tr_12_0_14), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_0_34), + SymOp(Rot_X_Y_mZ, Tr_0_12_14), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_0_12_34), + SymOp(Rot_Y_X_Z, Tr_12_0_14), + ], +) sg143 = SpaceGroup( - number = 143, - num_sym_equiv = 3, - num_primitive_sym_equiv = 3, - short_name = "P3", - point_group_name = "PG3", - crystal_system = "TRIGONAL", - pdb_name = "P 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0)]) + number=143, + num_sym_equiv=3, + num_primitive_sym_equiv=3, + short_name="P3", + point_group_name="PG3", + crystal_system="TRIGONAL", + pdb_name="P 3", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_0), SymOp(Rot_mXY_mX_Z, Tr_0_0_0)], +) sg144 = SpaceGroup( - number = 144, - num_sym_equiv = 3, - num_primitive_sym_equiv = 3, - short_name = "P31", - point_group_name = "PG3", - crystal_system = "TRIGONAL", - pdb_name = "P 31", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23)]) + number=144, + num_sym_equiv=3, + num_primitive_sym_equiv=3, + short_name="P31", + point_group_name="PG3", + crystal_system="TRIGONAL", + pdb_name="P 31", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_13), SymOp(Rot_mXY_mX_Z, Tr_0_0_23)], +) sg145 = SpaceGroup( - number = 145, - num_sym_equiv = 3, - num_primitive_sym_equiv = 3, - short_name = "P32", - point_group_name = "PG3", - crystal_system = "TRIGONAL", - pdb_name = "P 32", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13)]) + number=145, + num_sym_equiv=3, + num_primitive_sym_equiv=3, + short_name="P32", + point_group_name="PG3", + crystal_system="TRIGONAL", + pdb_name="P 32", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_23), SymOp(Rot_mXY_mX_Z, Tr_0_0_13)], +) sg146 = SpaceGroup( - number = 146, - num_sym_equiv = 9, - num_primitive_sym_equiv = 3, - short_name = "H3", - point_group_name = "PG3", - crystal_system = "TRIGONAL", - pdb_name = "H 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23)]) + number=146, + num_sym_equiv=9, + num_primitive_sym_equiv=3, + short_name="H3", + point_group_name="PG3", + crystal_system="TRIGONAL", + pdb_name="H 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + ], +) sg1146 = SpaceGroup( - number = 1146, - num_sym_equiv = 3, - num_primitive_sym_equiv = 3, - short_name = "R3", - point_group_name = "PG3", - crystal_system = "TRIGONAL", - pdb_name = "R 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0)]) + number=1146, + num_sym_equiv=3, + num_primitive_sym_equiv=3, + short_name="R3", + point_group_name="PG3", + crystal_system="TRIGONAL", + pdb_name="R 3", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_Z_X_Y, Tr_0_0_0), SymOp(Rot_Y_Z_X, Tr_0_0_0)], +) sg147 = SpaceGroup( - number = 147, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P-3", - point_group_name = "PG3bar", - crystal_system = "TRIGONAL", - pdb_name = "P -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0)]) + number=147, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P-3", + point_group_name="PG3bar", + crystal_system="TRIGONAL", + pdb_name="P -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + ], +) sg148 = SpaceGroup( - number = 148, - num_sym_equiv = 18, - num_primitive_sym_equiv = 6, - short_name = "H-3", - point_group_name = "PG3bar", - crystal_system = "TRIGONAL", - pdb_name = "H -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_mX_mY_mZ, Tr_23_13_13), - SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), - SymOp(Rot_XmY_X_mZ, Tr_23_13_13), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_mX_mY_mZ, Tr_13_23_23), - SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), - SymOp(Rot_XmY_X_mZ, Tr_13_23_23)]) + number=148, + num_sym_equiv=18, + num_primitive_sym_equiv=6, + short_name="H-3", + point_group_name="PG3bar", + crystal_system="TRIGONAL", + pdb_name="H -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_mX_mY_mZ, Tr_23_13_13), + SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), + SymOp(Rot_XmY_X_mZ, Tr_23_13_13), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_mX_mY_mZ, Tr_13_23_23), + SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), + SymOp(Rot_XmY_X_mZ, Tr_13_23_23), + ], +) sg1148 = SpaceGroup( - number = 1148, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "R-3", - point_group_name = "PG3bar", - crystal_system = "TRIGONAL", - pdb_name = "R -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0)]) + number=1148, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="R-3", + point_group_name="PG3bar", + crystal_system="TRIGONAL", + pdb_name="R -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + ], +) sg149 = SpaceGroup( - number = 149, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P312", - point_group_name = "PG312", - crystal_system = "TRIGONAL", - pdb_name = "P 3 1 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + number=149, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P312", + point_group_name="PG312", + crystal_system="TRIGONAL", + pdb_name="P 3 1 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg150 = SpaceGroup( - number = 150, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P321", - point_group_name = "PG321", - crystal_system = "TRIGONAL", - pdb_name = "P 3 2 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=150, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P321", + point_group_name="PG321", + crystal_system="TRIGONAL", + pdb_name="P 3 2 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mXY_mZ, Tr_0_0_0)]) + SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), + ], +) sg151 = SpaceGroup( - number = 151, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3112", - point_group_name = "PG312", - crystal_system = "TRIGONAL", - pdb_name = "P 31 1 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_mY_mX_mZ, Tr_0_0_23), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_13), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + number=151, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3112", + point_group_name="PG312", + crystal_system="TRIGONAL", + pdb_name="P 31 1 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_mY_mX_mZ, Tr_0_0_23), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_13), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg152 = SpaceGroup( - number = 152, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3121", - point_group_name = "PG321", - crystal_system = "TRIGONAL", - pdb_name = "P 31 2 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=152, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3121", + point_group_name="PG321", + crystal_system="TRIGONAL", + pdb_name="P 31 2 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_23), - SymOp(Rot_mX_mXY_mZ, Tr_0_0_13)]) + SymOp(Rot_mX_mXY_mZ, Tr_0_0_13), + ], +) sg153 = SpaceGroup( - number = 153, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3212", - point_group_name = "PG312", - crystal_system = "TRIGONAL", - pdb_name = "P 32 1 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_mY_mX_mZ, Tr_0_0_13), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_23), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + number=153, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3212", + point_group_name="PG312", + crystal_system="TRIGONAL", + pdb_name="P 32 1 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_mY_mX_mZ, Tr_0_0_13), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_23), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg154 = SpaceGroup( - number = 154, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3221", - point_group_name = "PG321", - crystal_system = "TRIGONAL", - pdb_name = "P 32 2 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=154, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3221", + point_group_name="PG321", + crystal_system="TRIGONAL", + pdb_name="P 32 2 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_13), - SymOp(Rot_mX_mXY_mZ, Tr_0_0_23)]) + SymOp(Rot_mX_mXY_mZ, Tr_0_0_23), + ], +) sg155 = SpaceGroup( - number = 155, - num_sym_equiv = 18, - num_primitive_sym_equiv = 6, - short_name = "H32", - point_group_name = "PG321", - crystal_system = "TRIGONAL", - pdb_name = "H 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=155, + num_sym_equiv=18, + num_primitive_sym_equiv=6, + short_name="H32", + point_group_name="PG321", + crystal_system="TRIGONAL", + pdb_name="H 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_Y_X_mZ, Tr_23_13_13), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_Y_X_mZ, Tr_23_13_13), SymOp(Rot_XmY_mY_mZ, Tr_23_13_13), SymOp(Rot_mX_mXY_mZ, Tr_23_13_13), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_Y_X_mZ, Tr_13_23_23), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_Y_X_mZ, Tr_13_23_23), SymOp(Rot_XmY_mY_mZ, Tr_13_23_23), - SymOp(Rot_mX_mXY_mZ, Tr_13_23_23)]) + SymOp(Rot_mX_mXY_mZ, Tr_13_23_23), + ], +) sg1155 = SpaceGroup( - number = 1155, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "R32", - point_group_name = "PG32", - crystal_system = "TRIGONAL", - pdb_name = "R 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0)]) + number=1155, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="R32", + point_group_name="PG32", + crystal_system="TRIGONAL", + pdb_name="R 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + ], +) sg156 = SpaceGroup( - number = 156, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3m1", - point_group_name = "PG3m1", - crystal_system = "TRIGONAL", - pdb_name = "P 3 m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0)]) + number=156, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3m1", + point_group_name="PG3m1", + crystal_system="TRIGONAL", + pdb_name="P 3 m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + ], +) sg157 = SpaceGroup( - number = 157, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P31m", - point_group_name = "PG31m", - crystal_system = "TRIGONAL", - pdb_name = "P 3 1 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + number=157, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P31m", + point_group_name="PG31m", + crystal_system="TRIGONAL", + pdb_name="P 3 1 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg158 = SpaceGroup( - number = 158, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P3c1", - point_group_name = "PG3m1", - crystal_system = "TRIGONAL", - pdb_name = "P 3 c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12)]) + number=158, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P3c1", + point_group_name="PG3m1", + crystal_system="TRIGONAL", + pdb_name="P 3 c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + ], +) sg159 = SpaceGroup( - number = 159, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P31c", - point_group_name = "PG31m", - crystal_system = "TRIGONAL", - pdb_name = "P 3 1 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + number=159, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P31c", + point_group_name="PG31m", + crystal_system="TRIGONAL", + pdb_name="P 3 1 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg160 = SpaceGroup( - number = 160, - num_sym_equiv = 18, - num_primitive_sym_equiv = 6, - short_name = "H3m", - point_group_name = "PG3m", - crystal_system = "TRIGONAL", - pdb_name = "H 3 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_mY_mX_Z, Tr_23_13_13), - SymOp(Rot_mXY_Y_Z, Tr_23_13_13), - SymOp(Rot_X_XmY_Z, Tr_23_13_13), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_mY_mX_Z, Tr_13_23_23), - SymOp(Rot_mXY_Y_Z, Tr_13_23_23), - SymOp(Rot_X_XmY_Z, Tr_13_23_23)]) + number=160, + num_sym_equiv=18, + num_primitive_sym_equiv=6, + short_name="H3m", + point_group_name="PG3m", + crystal_system="TRIGONAL", + pdb_name="H 3 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_mY_mX_Z, Tr_23_13_13), + SymOp(Rot_mXY_Y_Z, Tr_23_13_13), + SymOp(Rot_X_XmY_Z, Tr_23_13_13), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_mY_mX_Z, Tr_13_23_23), + SymOp(Rot_mXY_Y_Z, Tr_13_23_23), + SymOp(Rot_X_XmY_Z, Tr_13_23_23), + ], +) sg1160 = SpaceGroup( - number = 1160, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "R3m", - point_group_name = "PG3m", - crystal_system = "TRIGONAL", - pdb_name = "R 3 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0)]) + number=1160, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="R3m", + point_group_name="PG3m", + crystal_system="TRIGONAL", + pdb_name="R 3 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + ], +) sg161 = SpaceGroup( - number = 161, - num_sym_equiv = 18, - num_primitive_sym_equiv = 6, - short_name = "H3c", - point_group_name = "PG3m", - crystal_system = "TRIGONAL", - pdb_name = "H 3 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_mY_mX_Z, Tr_23_13_56), - SymOp(Rot_mXY_Y_Z, Tr_23_13_56), - SymOp(Rot_X_XmY_Z, Tr_23_13_56), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_mY_mX_Z, Tr_13_23_16), - SymOp(Rot_mXY_Y_Z, Tr_13_23_16), - SymOp(Rot_X_XmY_Z, Tr_13_23_16)]) + number=161, + num_sym_equiv=18, + num_primitive_sym_equiv=6, + short_name="H3c", + point_group_name="PG3m", + crystal_system="TRIGONAL", + pdb_name="H 3 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_mY_mX_Z, Tr_23_13_56), + SymOp(Rot_mXY_Y_Z, Tr_23_13_56), + SymOp(Rot_X_XmY_Z, Tr_23_13_56), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_mY_mX_Z, Tr_13_23_16), + SymOp(Rot_mXY_Y_Z, Tr_13_23_16), + SymOp(Rot_X_XmY_Z, Tr_13_23_16), + ], +) sg1161 = SpaceGroup( - number = 1161, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "R3c", - point_group_name = "PG3m", - crystal_system = "TRIGONAL", - pdb_name = "R 3 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12)]) + number=1161, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="R3c", + point_group_name="PG3m", + crystal_system="TRIGONAL", + pdb_name="R 3 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + ], +) sg162 = SpaceGroup( - number = 162, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-31m", - point_group_name = "PG3bar1m", - crystal_system = "TRIGONAL", - pdb_name = "P -3 1 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + number=162, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-31m", + point_group_name="PG3bar1m", + crystal_system="TRIGONAL", + pdb_name="P -3 1 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg163 = SpaceGroup( - number = 163, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-31c", - point_group_name = "PG3bar1m", - crystal_system = "TRIGONAL", - pdb_name = "P -3 1 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + number=163, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-31c", + point_group_name="PG3bar1m", + crystal_system="TRIGONAL", + pdb_name="P -3 1 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg164 = SpaceGroup( - number = 164, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-3m1", - point_group_name = "PG3barm1", - crystal_system = "TRIGONAL", - pdb_name = "P -3 2/m 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=164, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-3m1", + point_group_name="PG3barm1", + crystal_system="TRIGONAL", + pdb_name="P -3 2/m 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0)]) + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + ], +) sg165 = SpaceGroup( - number = 165, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-3c1", - point_group_name = "PG3barm1", - crystal_system = "TRIGONAL", - pdb_name = "P -3 2/c 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), + number=165, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-3c1", + point_group_name="PG3barm1", + crystal_system="TRIGONAL", + pdb_name="P -3 2/c 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), SymOp(Rot_XmY_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mXY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12)]) + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + ], +) sg166 = SpaceGroup( - number = 166, - num_sym_equiv = 36, - num_primitive_sym_equiv = 12, - short_name = "H-3m", - point_group_name = "PG3barm", - crystal_system = "TRIGONAL", - pdb_name = "H -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=166, + num_sym_equiv=36, + num_primitive_sym_equiv=12, + short_name="H-3m", + point_group_name="PG3barm", + crystal_system="TRIGONAL", + pdb_name="H -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_Y_X_mZ, Tr_23_13_13), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_Y_X_mZ, Tr_23_13_13), SymOp(Rot_XmY_mY_mZ, Tr_23_13_13), SymOp(Rot_mX_mXY_mZ, Tr_23_13_13), - SymOp(Rot_mX_mY_mZ, Tr_23_13_13), - SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), - SymOp(Rot_XmY_X_mZ, Tr_23_13_13), - SymOp(Rot_mY_mX_Z, Tr_23_13_13), - SymOp(Rot_mXY_Y_Z, Tr_23_13_13), - SymOp(Rot_X_XmY_Z, Tr_23_13_13), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_Y_X_mZ, Tr_13_23_23), + SymOp(Rot_mX_mY_mZ, Tr_23_13_13), + SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), + SymOp(Rot_XmY_X_mZ, Tr_23_13_13), + SymOp(Rot_mY_mX_Z, Tr_23_13_13), + SymOp(Rot_mXY_Y_Z, Tr_23_13_13), + SymOp(Rot_X_XmY_Z, Tr_23_13_13), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_Y_X_mZ, Tr_13_23_23), SymOp(Rot_XmY_mY_mZ, Tr_13_23_23), SymOp(Rot_mX_mXY_mZ, Tr_13_23_23), - SymOp(Rot_mX_mY_mZ, Tr_13_23_23), - SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), - SymOp(Rot_XmY_X_mZ, Tr_13_23_23), - SymOp(Rot_mY_mX_Z, Tr_13_23_23), - SymOp(Rot_mXY_Y_Z, Tr_13_23_23), - SymOp(Rot_X_XmY_Z, Tr_13_23_23)]) + SymOp(Rot_mX_mY_mZ, Tr_13_23_23), + SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), + SymOp(Rot_XmY_X_mZ, Tr_13_23_23), + SymOp(Rot_mY_mX_Z, Tr_13_23_23), + SymOp(Rot_mXY_Y_Z, Tr_13_23_23), + SymOp(Rot_X_XmY_Z, Tr_13_23_23), + ], +) sg1166 = SpaceGroup( - number = 1166, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "R-3m", - point_group_name = "PG3barm", - crystal_system = "TRIGONAL", - pdb_name = "R -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0)]) + number=1166, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="R-3m", + point_group_name="PG3barm", + crystal_system="TRIGONAL", + pdb_name="R -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + ], +) sg167 = SpaceGroup( - number = 167, - num_sym_equiv = 36, - num_primitive_sym_equiv = 12, - short_name = "H-3c", - point_group_name = "PG3barm", - crystal_system = "TRIGONAL", - pdb_name = "H -3 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), + number=167, + num_sym_equiv=36, + num_primitive_sym_equiv=12, + short_name="H-3c", + point_group_name="PG3barm", + crystal_system="TRIGONAL", + pdb_name="H -3 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), SymOp(Rot_XmY_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mXY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_23_13_13), - SymOp(Rot_mY_XmY_Z, Tr_23_13_13), - SymOp(Rot_mXY_mX_Z, Tr_23_13_13), - SymOp(Rot_Y_X_mZ, Tr_23_13_56), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_23_13_13), + SymOp(Rot_mY_XmY_Z, Tr_23_13_13), + SymOp(Rot_mXY_mX_Z, Tr_23_13_13), + SymOp(Rot_Y_X_mZ, Tr_23_13_56), SymOp(Rot_XmY_mY_mZ, Tr_23_13_56), SymOp(Rot_mX_mXY_mZ, Tr_23_13_56), - SymOp(Rot_mX_mY_mZ, Tr_23_13_13), - SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), - SymOp(Rot_XmY_X_mZ, Tr_23_13_13), - SymOp(Rot_mY_mX_Z, Tr_23_13_56), - SymOp(Rot_mXY_Y_Z, Tr_23_13_56), - SymOp(Rot_X_XmY_Z, Tr_23_13_56), - SymOp(Rot_X_Y_Z, Tr_13_23_23), - SymOp(Rot_mY_XmY_Z, Tr_13_23_23), - SymOp(Rot_mXY_mX_Z, Tr_13_23_23), - SymOp(Rot_Y_X_mZ, Tr_13_23_16), + SymOp(Rot_mX_mY_mZ, Tr_23_13_13), + SymOp(Rot_Y_mXY_mZ, Tr_23_13_13), + SymOp(Rot_XmY_X_mZ, Tr_23_13_13), + SymOp(Rot_mY_mX_Z, Tr_23_13_56), + SymOp(Rot_mXY_Y_Z, Tr_23_13_56), + SymOp(Rot_X_XmY_Z, Tr_23_13_56), + SymOp(Rot_X_Y_Z, Tr_13_23_23), + SymOp(Rot_mY_XmY_Z, Tr_13_23_23), + SymOp(Rot_mXY_mX_Z, Tr_13_23_23), + SymOp(Rot_Y_X_mZ, Tr_13_23_16), SymOp(Rot_XmY_mY_mZ, Tr_13_23_16), SymOp(Rot_mX_mXY_mZ, Tr_13_23_16), - SymOp(Rot_mX_mY_mZ, Tr_13_23_23), - SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), - SymOp(Rot_XmY_X_mZ, Tr_13_23_23), - SymOp(Rot_mY_mX_Z, Tr_13_23_16), - SymOp(Rot_mXY_Y_Z, Tr_13_23_16), - SymOp(Rot_X_XmY_Z, Tr_13_23_16)]) + SymOp(Rot_mX_mY_mZ, Tr_13_23_23), + SymOp(Rot_Y_mXY_mZ, Tr_13_23_23), + SymOp(Rot_XmY_X_mZ, Tr_13_23_23), + SymOp(Rot_mY_mX_Z, Tr_13_23_16), + SymOp(Rot_mXY_Y_Z, Tr_13_23_16), + SymOp(Rot_X_XmY_Z, Tr_13_23_16), + ], +) sg1167 = SpaceGroup( - number = 1167, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "R-3c", - point_group_name = "PG3barm", - crystal_system = "TRIGONAL", - pdb_name = "R -3 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12)]) + number=1167, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="R-3c", + point_group_name="PG3barm", + crystal_system="TRIGONAL", + pdb_name="R -3 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + ], +) sg168 = SpaceGroup( - number = 168, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P6", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 6", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0)]) + number=168, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P6", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 6", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + ], +) sg169 = SpaceGroup( - number = 169, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P61", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 61", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_56), - SymOp(Rot_XmY_X_Z, Tr_0_0_16)]) + number=169, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P61", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 61", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_56), + SymOp(Rot_XmY_X_Z, Tr_0_0_16), + ], +) sg170 = SpaceGroup( - number = 170, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P65", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 65", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_16), - SymOp(Rot_XmY_X_Z, Tr_0_0_56)]) + number=170, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P65", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 65", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_16), + SymOp(Rot_XmY_X_Z, Tr_0_0_56), + ], +) sg171 = SpaceGroup( - number = 171, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P62", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 62", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_23), - SymOp(Rot_XmY_X_Z, Tr_0_0_13)]) + number=171, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P62", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 62", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_23), + SymOp(Rot_XmY_X_Z, Tr_0_0_13), + ], +) sg172 = SpaceGroup( - number = 172, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P64", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 64", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_13), - SymOp(Rot_XmY_X_Z, Tr_0_0_23)]) + number=172, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P64", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 64", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_13), + SymOp(Rot_XmY_X_Z, Tr_0_0_23), + ], +) sg173 = SpaceGroup( - number = 173, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P63", - point_group_name = "PG6", - crystal_system = "HEXAGONAL", - pdb_name = "P 63", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12)]) + number=173, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P63", + point_group_name="PG6", + crystal_system="HEXAGONAL", + pdb_name="P 63", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + ], +) sg174 = SpaceGroup( - number = 174, - num_sym_equiv = 6, - num_primitive_sym_equiv = 6, - short_name = "P-6", - point_group_name = "PG6bar", - crystal_system = "HEXAGONAL", - pdb_name = "P -6", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + number=174, + num_sym_equiv=6, + num_primitive_sym_equiv=6, + short_name="P-6", + point_group_name="PG6bar", + crystal_system="HEXAGONAL", + pdb_name="P -6", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mXY_mX_mZ, Tr_0_0_0)]) + SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), + ], +) sg175 = SpaceGroup( - number = 175, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6/m", - point_group_name = "PG6/m", - crystal_system = "HEXAGONAL", - pdb_name = "P 6/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + number=175, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6/m", + point_group_name="PG6/m", + crystal_system="HEXAGONAL", + pdb_name="P 6/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mXY_mX_mZ, Tr_0_0_0)]) + SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), + ], +) sg176 = SpaceGroup( - number = 176, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P63/m", - point_group_name = "PG6/m", - crystal_system = "HEXAGONAL", - pdb_name = "P 63/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), + number=176, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P63/m", + point_group_name="PG6/m", + crystal_system="HEXAGONAL", + pdb_name="P 63/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), SymOp(Rot_mY_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mXY_mX_mZ, Tr_0_0_12)]) + SymOp(Rot_mXY_mX_mZ, Tr_0_0_12), + ], +) sg177 = SpaceGroup( - number = 177, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P622", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 6 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=177, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P622", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 6 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg178 = SpaceGroup( - number = 178, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6122", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 61 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_56), - SymOp(Rot_XmY_X_Z, Tr_0_0_16), - SymOp(Rot_Y_X_mZ, Tr_0_0_13), + number=178, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6122", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 61 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_56), + SymOp(Rot_XmY_X_Z, Tr_0_0_16), + SymOp(Rot_Y_X_mZ, Tr_0_0_13), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_23), - SymOp(Rot_mY_mX_mZ, Tr_0_0_56), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_16)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_56), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_16), + ], +) sg179 = SpaceGroup( - number = 179, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6522", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 65 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_16), - SymOp(Rot_XmY_X_Z, Tr_0_0_56), - SymOp(Rot_Y_X_mZ, Tr_0_0_23), + number=179, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6522", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 65 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_16), + SymOp(Rot_XmY_X_Z, Tr_0_0_56), + SymOp(Rot_Y_X_mZ, Tr_0_0_23), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_13), - SymOp(Rot_mY_mX_mZ, Tr_0_0_16), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_56)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_16), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_56), + ], +) sg180 = SpaceGroup( - number = 180, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6222", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 62 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_23), - SymOp(Rot_mXY_mX_Z, Tr_0_0_13), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_23), - SymOp(Rot_XmY_X_Z, Tr_0_0_13), - SymOp(Rot_Y_X_mZ, Tr_0_0_23), + number=180, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6222", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 62 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_23), + SymOp(Rot_XmY_X_Z, Tr_0_0_13), + SymOp(Rot_Y_X_mZ, Tr_0_0_23), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_13), - SymOp(Rot_mY_mX_mZ, Tr_0_0_23), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_13)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_23), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_13), + ], +) sg181 = SpaceGroup( - number = 181, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6422", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 64 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_13), - SymOp(Rot_mXY_mX_Z, Tr_0_0_23), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_13), - SymOp(Rot_XmY_X_Z, Tr_0_0_23), - SymOp(Rot_Y_X_mZ, Tr_0_0_13), + number=181, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6422", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 64 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_13), + SymOp(Rot_XmY_X_Z, Tr_0_0_23), + SymOp(Rot_Y_X_mZ, Tr_0_0_13), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_23), - SymOp(Rot_mY_mX_mZ, Tr_0_0_13), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_23)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_13), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_23), + ], +) sg182 = SpaceGroup( - number = 182, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6322", - point_group_name = "PG622", - crystal_system = "HEXAGONAL", - pdb_name = "P 63 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=182, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6322", + point_group_name="PG622", + crystal_system="HEXAGONAL", + pdb_name="P 63 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_12)]) + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_12), + ], +) sg183 = SpaceGroup( - number = 183, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6mm", - point_group_name = "PG6mm", - crystal_system = "HEXAGONAL", - pdb_name = "P 6 m m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + number=183, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6mm", + point_group_name="PG6mm", + crystal_system="HEXAGONAL", + pdb_name="P 6 m m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg184 = SpaceGroup( - number = 184, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P6cc", - point_group_name = "PG6mm", - crystal_system = "HEXAGONAL", - pdb_name = "P 6 c c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + number=184, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P6cc", + point_group_name="PG6mm", + crystal_system="HEXAGONAL", + pdb_name="P 6 c c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg185 = SpaceGroup( - number = 185, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P63cm", - point_group_name = "PG6mm", - crystal_system = "HEXAGONAL", - pdb_name = "P 63 c m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + number=185, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P63cm", + point_group_name="PG6mm", + crystal_system="HEXAGONAL", + pdb_name="P 63 c m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg186 = SpaceGroup( - number = 186, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P63mc", - point_group_name = "PG6mm", - crystal_system = "HEXAGONAL", - pdb_name = "P 63 m c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + number=186, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P63mc", + point_group_name="PG6mm", + crystal_system="HEXAGONAL", + pdb_name="P 63 m c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg187 = SpaceGroup( - number = 187, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-6m2", - point_group_name = "PG6barm2", - crystal_system = "HEXAGONAL", - pdb_name = "P -6 m 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + number=187, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-6m2", + point_group_name="PG6barm2", + crystal_system="HEXAGONAL", + pdb_name="P -6 m 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg188 = SpaceGroup( - number = 188, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-6c2", - point_group_name = "PG6barm2", - crystal_system = "HEXAGONAL", - pdb_name = "P -6 c 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), + number=188, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-6c2", + point_group_name="PG6barm2", + crystal_system="HEXAGONAL", + pdb_name="P -6 c 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), SymOp(Rot_mY_XmY_mZ, Tr_0_0_12), SymOp(Rot_mXY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + ], +) sg189 = SpaceGroup( - number = 189, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-62m", - point_group_name = "PG6bar2m", - crystal_system = "HEXAGONAL", - pdb_name = "P -6 2 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + number=189, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-62m", + point_group_name="PG6bar2m", + crystal_system="HEXAGONAL", + pdb_name="P -6 2 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg190 = SpaceGroup( - number = 190, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P-62c", - point_group_name = "PG6bar2m", - crystal_system = "HEXAGONAL", - pdb_name = "P -6 2 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), + number=190, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P-62c", + point_group_name="PG6bar2m", + crystal_system="HEXAGONAL", + pdb_name="P -6 2 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), SymOp(Rot_mY_XmY_mZ, Tr_0_0_12), SymOp(Rot_mXY_mX_mZ, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg191 = SpaceGroup( - number = 191, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P6/mmm", - point_group_name = "PG6/mmm", - crystal_system = "HEXAGONAL", - pdb_name = "P 6/m 2/m 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=191, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P6/mmm", + point_group_name="PG6/mmm", + crystal_system="HEXAGONAL", + pdb_name="P 6/m 2/m 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg192 = SpaceGroup( - number = 192, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P6/mcc", - point_group_name = "PG6/mmm", - crystal_system = "HEXAGONAL", - pdb_name = "P 6/m 2/c 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_Y_mXY_Z, Tr_0_0_0), - SymOp(Rot_XmY_X_Z, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), + number=192, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P6/mcc", + point_group_name="PG6/mmm", + crystal_system="HEXAGONAL", + pdb_name="P 6/m 2/c 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_Y_mXY_Z, Tr_0_0_0), + SymOp(Rot_XmY_X_Z, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), SymOp(Rot_XmY_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mXY_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_mXY_mX_mZ, Tr_0_0_0), SymOp(Rot_mY_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg193 = SpaceGroup( - number = 193, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P63/mcm", - point_group_name = "PG6/mmm", - crystal_system = "HEXAGONAL", - pdb_name = "P 63/m 2/c 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), + number=193, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P63/mcm", + point_group_name="PG6/mmm", + crystal_system="HEXAGONAL", + pdb_name="P 63/m 2/c 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), SymOp(Rot_XmY_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mXY_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_XmY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_XmY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), SymOp(Rot_mXY_mX_mZ, Tr_0_0_12), SymOp(Rot_mY_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_mXY_Y_Z, Tr_0_0_12), - SymOp(Rot_X_XmY_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_XmY_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mXY_Z, Tr_0_0_0)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_mXY_Y_Z, Tr_0_0_12), + SymOp(Rot_X_XmY_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_XmY_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mXY_Z, Tr_0_0_0), + ], +) sg194 = SpaceGroup( - number = 194, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P63/mmc", - point_group_name = "PG6/mmm", - crystal_system = "HEXAGONAL", - pdb_name = "P 63/m 2/m 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mY_XmY_Z, Tr_0_0_0), - SymOp(Rot_mXY_mX_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_Y_mXY_Z, Tr_0_0_12), - SymOp(Rot_XmY_X_Z, Tr_0_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), + number=194, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P63/mmc", + point_group_name="PG6/mmm", + crystal_system="HEXAGONAL", + pdb_name="P 63/m 2/m 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_Y_mXY_Z, Tr_0_0_12), + SymOp(Rot_XmY_X_Z, Tr_0_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), SymOp(Rot_XmY_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mXY_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), - SymOp(Rot_XmY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_mXY_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_XmY_mZ, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_Y_mXY_mZ, Tr_0_0_0), + SymOp(Rot_XmY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), SymOp(Rot_mXY_mX_mZ, Tr_0_0_12), SymOp(Rot_mY_XmY_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_mXY_Y_Z, Tr_0_0_0), - SymOp(Rot_X_XmY_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_XmY_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mXY_Z, Tr_0_0_12)]) + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_mXY_Y_Z, Tr_0_0_0), + SymOp(Rot_X_XmY_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_XmY_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mXY_Z, Tr_0_0_12), + ], +) sg195 = SpaceGroup( - number = 195, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P23", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "P 2 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0)]) + number=195, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P23", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="P 2 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + ], +) sg196 = SpaceGroup( - number = 196, - num_sym_equiv = 48, - num_primitive_sym_equiv = 12, - short_name = "F23", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "F 2 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0)]) + number=196, + num_sym_equiv=48, + num_primitive_sym_equiv=12, + short_name="F23", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="F 2 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + ], +) sg197 = SpaceGroup( - number = 197, - num_sym_equiv = 24, - num_primitive_sym_equiv = 12, - short_name = "I23", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "I 2 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_12_12)]) + number=197, + num_sym_equiv=24, + num_primitive_sym_equiv=12, + short_name="I23", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="I 2 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_12_12), + ], +) sg198 = SpaceGroup( - number = 198, - num_sym_equiv = 12, - num_primitive_sym_equiv = 12, - short_name = "P213", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "P 21 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12)]) + number=198, + num_sym_equiv=12, + num_primitive_sym_equiv=12, + short_name="P213", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="P 21 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + ], +) sg199 = SpaceGroup( - number = 199, - num_sym_equiv = 24, - num_primitive_sym_equiv = 12, - short_name = "I213", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "I 21 3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_0)]) + number=199, + num_sym_equiv=24, + num_primitive_sym_equiv=12, + short_name="I213", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="I 21 3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_0), + ], +) sg200 = SpaceGroup( - number = 200, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "Pm-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "P 2/m -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0)]) + number=200, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="Pm-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="P 2/m -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + ], +) sg201 = SpaceGroup( - number = 201, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "Pn-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "P 2/n -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_12_12_12), - SymOp(Rot_Z_X_mY, Tr_12_12_12), - SymOp(Rot_Z_mX_Y, Tr_12_12_12), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_12), - SymOp(Rot_Y_Z_mX, Tr_12_12_12)]) + number=201, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="Pn-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="P 2/n -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_12_12_12), + SymOp(Rot_Z_X_mY, Tr_12_12_12), + SymOp(Rot_Z_mX_Y, Tr_12_12_12), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_12), + SymOp(Rot_Y_Z_mX, Tr_12_12_12), + ], +) sg202 = SpaceGroup( - number = 202, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "Fm-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "F 2/m -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12), - SymOp(Rot_mZ_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_X_Y, Tr_0_12_12), - SymOp(Rot_Z_X_mY, Tr_0_12_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_0_12_12), - SymOp(Rot_Y_Z_mX, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_mZ_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_X_Y, Tr_12_0_12), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_12_0_12), - SymOp(Rot_mY_mZ_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_X, Tr_12_0_12), - SymOp(Rot_mY_Z_X, Tr_12_0_12), - SymOp(Rot_Y_Z_mX, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_12_0), - SymOp(Rot_Z_mX_Y, Tr_12_12_0), - SymOp(Rot_mY_mZ_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_X, Tr_12_12_0), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_12_0)]) + number=202, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="Fm-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="F 2/m -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + SymOp(Rot_mZ_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_X_Y, Tr_0_12_12), + SymOp(Rot_Z_X_mY, Tr_0_12_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_0_12_12), + SymOp(Rot_Y_Z_mX, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_mZ_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_X_Y, Tr_12_0_12), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_12_0_12), + SymOp(Rot_mY_mZ_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_X, Tr_12_0_12), + SymOp(Rot_mY_Z_X, Tr_12_0_12), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_12_0), + SymOp(Rot_Z_mX_Y, Tr_12_12_0), + SymOp(Rot_mY_mZ_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_X, Tr_12_12_0), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_12_0), + ], +) sg203 = SpaceGroup( - number = 203, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "Fd-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "F 2/d -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_14_14_14), - SymOp(Rot_X_Y_mZ, Tr_14_14_14), - SymOp(Rot_X_mY_Z, Tr_14_14_14), - SymOp(Rot_mX_Y_Z, Tr_14_14_14), - SymOp(Rot_mZ_mX_mY, Tr_14_14_14), - SymOp(Rot_mZ_X_Y, Tr_14_14_14), - SymOp(Rot_Z_X_mY, Tr_14_14_14), - SymOp(Rot_Z_mX_Y, Tr_14_14_14), - SymOp(Rot_mY_mZ_mX, Tr_14_14_14), - SymOp(Rot_Y_mZ_X, Tr_14_14_14), - SymOp(Rot_mY_Z_X, Tr_14_14_14), - SymOp(Rot_Y_Z_mX, Tr_14_14_14), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_14_34_34), - SymOp(Rot_X_Y_mZ, Tr_14_34_34), - SymOp(Rot_X_mY_Z, Tr_14_34_34), - SymOp(Rot_mX_Y_Z, Tr_14_34_34), - SymOp(Rot_mZ_mX_mY, Tr_14_34_34), - SymOp(Rot_mZ_X_Y, Tr_14_34_34), - SymOp(Rot_Z_X_mY, Tr_14_34_34), - SymOp(Rot_Z_mX_Y, Tr_14_34_34), - SymOp(Rot_mY_mZ_mX, Tr_14_34_34), - SymOp(Rot_Y_mZ_X, Tr_14_34_34), - SymOp(Rot_mY_Z_X, Tr_14_34_34), - SymOp(Rot_Y_Z_mX, Tr_14_34_34), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_34_14_34), - SymOp(Rot_X_Y_mZ, Tr_34_14_34), - SymOp(Rot_X_mY_Z, Tr_34_14_34), - SymOp(Rot_mX_Y_Z, Tr_34_14_34), - SymOp(Rot_mZ_mX_mY, Tr_34_14_34), - SymOp(Rot_mZ_X_Y, Tr_34_14_34), - SymOp(Rot_Z_X_mY, Tr_34_14_34), - SymOp(Rot_Z_mX_Y, Tr_34_14_34), - SymOp(Rot_mY_mZ_mX, Tr_34_14_34), - SymOp(Rot_Y_mZ_X, Tr_34_14_34), - SymOp(Rot_mY_Z_X, Tr_34_14_34), - SymOp(Rot_Y_Z_mX, Tr_34_14_34), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_34_34_14), - SymOp(Rot_X_Y_mZ, Tr_34_34_14), - SymOp(Rot_X_mY_Z, Tr_34_34_14), - SymOp(Rot_mX_Y_Z, Tr_34_34_14), - SymOp(Rot_mZ_mX_mY, Tr_34_34_14), - SymOp(Rot_mZ_X_Y, Tr_34_34_14), - SymOp(Rot_Z_X_mY, Tr_34_34_14), - SymOp(Rot_Z_mX_Y, Tr_34_34_14), - SymOp(Rot_mY_mZ_mX, Tr_34_34_14), - SymOp(Rot_Y_mZ_X, Tr_34_34_14), - SymOp(Rot_mY_Z_X, Tr_34_34_14), - SymOp(Rot_Y_Z_mX, Tr_34_34_14)]) + number=203, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="Fd-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="F 2/d -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_14_14_14), + SymOp(Rot_X_Y_mZ, Tr_14_14_14), + SymOp(Rot_X_mY_Z, Tr_14_14_14), + SymOp(Rot_mX_Y_Z, Tr_14_14_14), + SymOp(Rot_mZ_mX_mY, Tr_14_14_14), + SymOp(Rot_mZ_X_Y, Tr_14_14_14), + SymOp(Rot_Z_X_mY, Tr_14_14_14), + SymOp(Rot_Z_mX_Y, Tr_14_14_14), + SymOp(Rot_mY_mZ_mX, Tr_14_14_14), + SymOp(Rot_Y_mZ_X, Tr_14_14_14), + SymOp(Rot_mY_Z_X, Tr_14_14_14), + SymOp(Rot_Y_Z_mX, Tr_14_14_14), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_14_34_34), + SymOp(Rot_X_Y_mZ, Tr_14_34_34), + SymOp(Rot_X_mY_Z, Tr_14_34_34), + SymOp(Rot_mX_Y_Z, Tr_14_34_34), + SymOp(Rot_mZ_mX_mY, Tr_14_34_34), + SymOp(Rot_mZ_X_Y, Tr_14_34_34), + SymOp(Rot_Z_X_mY, Tr_14_34_34), + SymOp(Rot_Z_mX_Y, Tr_14_34_34), + SymOp(Rot_mY_mZ_mX, Tr_14_34_34), + SymOp(Rot_Y_mZ_X, Tr_14_34_34), + SymOp(Rot_mY_Z_X, Tr_14_34_34), + SymOp(Rot_Y_Z_mX, Tr_14_34_34), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_34_14_34), + SymOp(Rot_X_Y_mZ, Tr_34_14_34), + SymOp(Rot_X_mY_Z, Tr_34_14_34), + SymOp(Rot_mX_Y_Z, Tr_34_14_34), + SymOp(Rot_mZ_mX_mY, Tr_34_14_34), + SymOp(Rot_mZ_X_Y, Tr_34_14_34), + SymOp(Rot_Z_X_mY, Tr_34_14_34), + SymOp(Rot_Z_mX_Y, Tr_34_14_34), + SymOp(Rot_mY_mZ_mX, Tr_34_14_34), + SymOp(Rot_Y_mZ_X, Tr_34_14_34), + SymOp(Rot_mY_Z_X, Tr_34_14_34), + SymOp(Rot_Y_Z_mX, Tr_34_14_34), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_34_34_14), + SymOp(Rot_X_Y_mZ, Tr_34_34_14), + SymOp(Rot_X_mY_Z, Tr_34_34_14), + SymOp(Rot_mX_Y_Z, Tr_34_34_14), + SymOp(Rot_mZ_mX_mY, Tr_34_34_14), + SymOp(Rot_mZ_X_Y, Tr_34_34_14), + SymOp(Rot_Z_X_mY, Tr_34_34_14), + SymOp(Rot_Z_mX_Y, Tr_34_34_14), + SymOp(Rot_mY_mZ_mX, Tr_34_34_14), + SymOp(Rot_Y_mZ_X, Tr_34_34_14), + SymOp(Rot_mY_Z_X, Tr_34_34_14), + SymOp(Rot_Y_Z_mX, Tr_34_34_14), + ], +) sg204 = SpaceGroup( - number = 204, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "Im-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "I 2/m -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_12_12_12), - SymOp(Rot_Z_X_mY, Tr_12_12_12), - SymOp(Rot_Z_mX_Y, Tr_12_12_12), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_12), - SymOp(Rot_Y_Z_mX, Tr_12_12_12)]) + number=204, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="Im-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="I 2/m -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_12_12_12), + SymOp(Rot_Z_X_mY, Tr_12_12_12), + SymOp(Rot_Z_mX_Y, Tr_12_12_12), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_12), + SymOp(Rot_Y_Z_mX, Tr_12_12_12), + ], +) sg205 = SpaceGroup( - number = 205, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "Pa-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "P 21/a -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_0_12)]) + number=205, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="Pa-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="P 21/a -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + ], +) sg206 = SpaceGroup( - number = 206, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "Ia-3", - point_group_name = "PGm3bar", - crystal_system = "CUBIC", - pdb_name = "I 21/a -3", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_0_0_12), - SymOp(Rot_Z_X_mY, Tr_0_12_0), - SymOp(Rot_Z_mX_Y, Tr_12_0_0), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_12), - SymOp(Rot_Y_Z_mX, Tr_0_12_0)]) + number=206, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="Ia-3", + point_group_name="PGm3bar", + crystal_system="CUBIC", + pdb_name="I 21/a -3", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_0_0_12), + SymOp(Rot_Z_X_mY, Tr_0_12_0), + SymOp(Rot_Z_mX_Y, Tr_12_0_0), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_12), + SymOp(Rot_Y_Z_mX, Tr_0_12_0), + ], +) sg207 = SpaceGroup( - number = 207, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P432", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "P 4 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0)]) + number=207, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P432", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="P 4 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + ], +) sg208 = SpaceGroup( - number = 208, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P4232", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "P 42 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12)]) + number=208, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P4232", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="P 42 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + ], +) sg209 = SpaceGroup( - number = 209, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "F432", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "F 4 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_12_12), - SymOp(Rot_mY_mX_mZ, Tr_0_12_12), - SymOp(Rot_Y_mX_Z, Tr_0_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_12), - SymOp(Rot_X_Z_mY, Tr_0_12_12), - SymOp(Rot_mX_Z_Y, Tr_0_12_12), - SymOp(Rot_mX_mZ_mY, Tr_0_12_12), - SymOp(Rot_X_mZ_Y, Tr_0_12_12), - SymOp(Rot_Z_Y_mX, Tr_0_12_12), - SymOp(Rot_Z_mY_X, Tr_0_12_12), - SymOp(Rot_mZ_Y_X, Tr_0_12_12), - SymOp(Rot_mZ_mY_mX, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_12_0_12), - SymOp(Rot_mY_mX_mZ, Tr_12_0_12), - SymOp(Rot_Y_mX_Z, Tr_12_0_12), - SymOp(Rot_mY_X_Z, Tr_12_0_12), - SymOp(Rot_X_Z_mY, Tr_12_0_12), - SymOp(Rot_mX_Z_Y, Tr_12_0_12), - SymOp(Rot_mX_mZ_mY, Tr_12_0_12), - SymOp(Rot_X_mZ_Y, Tr_12_0_12), - SymOp(Rot_Z_Y_mX, Tr_12_0_12), - SymOp(Rot_Z_mY_X, Tr_12_0_12), - SymOp(Rot_mZ_Y_X, Tr_12_0_12), - SymOp(Rot_mZ_mY_mX, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_X_Z_mY, Tr_12_12_0), - SymOp(Rot_mX_Z_Y, Tr_12_12_0), - SymOp(Rot_mX_mZ_mY, Tr_12_12_0), - SymOp(Rot_X_mZ_Y, Tr_12_12_0), - SymOp(Rot_Z_Y_mX, Tr_12_12_0), - SymOp(Rot_Z_mY_X, Tr_12_12_0), - SymOp(Rot_mZ_Y_X, Tr_12_12_0), - SymOp(Rot_mZ_mY_mX, Tr_12_12_0)]) + number=209, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="F432", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="F 4 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_12_12), + SymOp(Rot_mY_mX_mZ, Tr_0_12_12), + SymOp(Rot_Y_mX_Z, Tr_0_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_12), + SymOp(Rot_X_Z_mY, Tr_0_12_12), + SymOp(Rot_mX_Z_Y, Tr_0_12_12), + SymOp(Rot_mX_mZ_mY, Tr_0_12_12), + SymOp(Rot_X_mZ_Y, Tr_0_12_12), + SymOp(Rot_Z_Y_mX, Tr_0_12_12), + SymOp(Rot_Z_mY_X, Tr_0_12_12), + SymOp(Rot_mZ_Y_X, Tr_0_12_12), + SymOp(Rot_mZ_mY_mX, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_12_0_12), + SymOp(Rot_mY_mX_mZ, Tr_12_0_12), + SymOp(Rot_Y_mX_Z, Tr_12_0_12), + SymOp(Rot_mY_X_Z, Tr_12_0_12), + SymOp(Rot_X_Z_mY, Tr_12_0_12), + SymOp(Rot_mX_Z_Y, Tr_12_0_12), + SymOp(Rot_mX_mZ_mY, Tr_12_0_12), + SymOp(Rot_X_mZ_Y, Tr_12_0_12), + SymOp(Rot_Z_Y_mX, Tr_12_0_12), + SymOp(Rot_Z_mY_X, Tr_12_0_12), + SymOp(Rot_mZ_Y_X, Tr_12_0_12), + SymOp(Rot_mZ_mY_mX, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_X_Z_mY, Tr_12_12_0), + SymOp(Rot_mX_Z_Y, Tr_12_12_0), + SymOp(Rot_mX_mZ_mY, Tr_12_12_0), + SymOp(Rot_X_mZ_Y, Tr_12_12_0), + SymOp(Rot_Z_Y_mX, Tr_12_12_0), + SymOp(Rot_Z_mY_X, Tr_12_12_0), + SymOp(Rot_mZ_Y_X, Tr_12_12_0), + SymOp(Rot_mZ_mY_mX, Tr_12_12_0), + ], +) sg210 = SpaceGroup( - number = 210, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "F4132", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "F 41 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_14_34_34), - SymOp(Rot_mY_X_Z, Tr_34_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_34), - SymOp(Rot_mX_Z_Y, Tr_34_34_14), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_14_34_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_34), - SymOp(Rot_Z_mY_X, Tr_14_34_34), - SymOp(Rot_mZ_Y_X, Tr_34_34_14), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_34_34_14), - SymOp(Rot_mY_mX_mZ, Tr_14_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_34_34_14), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_14), - SymOp(Rot_Z_Y_mX, Tr_34_34_14), - SymOp(Rot_Z_mY_X, Tr_14_14_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_34_34), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_14_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_14_34), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_14_34_34), - SymOp(Rot_X_Z_mY, Tr_14_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_34), - SymOp(Rot_mX_mZ_mY, Tr_34_14_34), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_14_14), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_14_34_34), - SymOp(Rot_mZ_mY_mX, Tr_34_14_34), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_34_34_14), - SymOp(Rot_Y_mX_Z, Tr_34_14_34), - SymOp(Rot_mY_X_Z, Tr_14_14_14), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_14_14_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_14), - SymOp(Rot_X_mZ_Y, Tr_34_14_34), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_14_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_14)]) + number=210, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="F4132", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="F 41 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_14_34_34), + SymOp(Rot_mY_X_Z, Tr_34_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_34), + SymOp(Rot_mX_Z_Y, Tr_34_34_14), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_14_34_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_34), + SymOp(Rot_Z_mY_X, Tr_14_34_34), + SymOp(Rot_mZ_Y_X, Tr_34_34_14), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_34_34_14), + SymOp(Rot_mY_mX_mZ, Tr_14_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_34_34_14), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_14), + SymOp(Rot_Z_Y_mX, Tr_34_34_14), + SymOp(Rot_Z_mY_X, Tr_14_14_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_34_34), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_14_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_14_34), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_14_34_34), + SymOp(Rot_X_Z_mY, Tr_14_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_34), + SymOp(Rot_mX_mZ_mY, Tr_34_14_34), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_14_14), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_14_34_34), + SymOp(Rot_mZ_mY_mX, Tr_34_14_34), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_34_34_14), + SymOp(Rot_Y_mX_Z, Tr_34_14_34), + SymOp(Rot_mY_X_Z, Tr_14_14_14), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_14_14_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_14), + SymOp(Rot_X_mZ_Y, Tr_34_14_34), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_14_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_14), + ], +) sg211 = SpaceGroup( - number = 211, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "I432", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "I 4 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12)]) + number=211, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="I432", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="I 4 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + ], +) sg212 = SpaceGroup( - number = 212, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P4332", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "P 43 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14)]) + number=212, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P4332", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="P 43 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + ], +) sg213 = SpaceGroup( - number = 213, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P4132", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "P 41 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_34), - SymOp(Rot_mY_X_Z, Tr_14_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_14), - SymOp(Rot_Z_mY_X, Tr_14_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_34_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_34)]) + number=213, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P4132", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="P 41 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_34), + SymOp(Rot_mY_X_Z, Tr_14_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_14), + SymOp(Rot_Z_mY_X, Tr_14_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_34_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_34), + ], +) sg214 = SpaceGroup( - number = 214, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "I4132", - point_group_name = "PG432", - crystal_system = "CUBIC", - pdb_name = "I 41 3 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_34), - SymOp(Rot_mY_X_Z, Tr_14_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_14), - SymOp(Rot_Z_mY_X, Tr_14_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_34_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_0), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14)]) + number=214, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="I4132", + point_group_name="PG432", + crystal_system="CUBIC", + pdb_name="I 41 3 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_34), + SymOp(Rot_mY_X_Z, Tr_14_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_14), + SymOp(Rot_Z_mY_X, Tr_14_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_34_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_0), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + ], +) sg215 = SpaceGroup( - number = 215, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P-43m", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "P -4 3 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0)]) + number=215, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P-43m", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="P -4 3 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + ], +) sg216 = SpaceGroup( - number = 216, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "F-43m", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "F -4 3 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_Z, Tr_0_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_12_12), - SymOp(Rot_X_Z_Y, Tr_0_12_12), - SymOp(Rot_mX_Z_mY, Tr_0_12_12), - SymOp(Rot_mX_mZ_Y, Tr_0_12_12), - SymOp(Rot_X_mZ_mY, Tr_0_12_12), - SymOp(Rot_Z_Y_X, Tr_0_12_12), - SymOp(Rot_Z_mY_mX, Tr_0_12_12), - SymOp(Rot_mZ_Y_mX, Tr_0_12_12), - SymOp(Rot_mZ_mY_X, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_Z, Tr_12_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_0_12), - SymOp(Rot_Y_mX_mZ, Tr_12_0_12), - SymOp(Rot_mY_X_mZ, Tr_12_0_12), - SymOp(Rot_X_Z_Y, Tr_12_0_12), - SymOp(Rot_mX_Z_mY, Tr_12_0_12), - SymOp(Rot_mX_mZ_Y, Tr_12_0_12), - SymOp(Rot_X_mZ_mY, Tr_12_0_12), - SymOp(Rot_Z_Y_X, Tr_12_0_12), - SymOp(Rot_Z_mY_mX, Tr_12_0_12), - SymOp(Rot_mZ_Y_mX, Tr_12_0_12), - SymOp(Rot_mZ_mY_X, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_12_12_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_0), - SymOp(Rot_X_Z_Y, Tr_12_12_0), - SymOp(Rot_mX_Z_mY, Tr_12_12_0), - SymOp(Rot_mX_mZ_Y, Tr_12_12_0), - SymOp(Rot_X_mZ_mY, Tr_12_12_0), - SymOp(Rot_Z_Y_X, Tr_12_12_0), - SymOp(Rot_Z_mY_mX, Tr_12_12_0), - SymOp(Rot_mZ_Y_mX, Tr_12_12_0), - SymOp(Rot_mZ_mY_X, Tr_12_12_0)]) + number=216, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="F-43m", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="F -4 3 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_Z, Tr_0_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_12_12), + SymOp(Rot_X_Z_Y, Tr_0_12_12), + SymOp(Rot_mX_Z_mY, Tr_0_12_12), + SymOp(Rot_mX_mZ_Y, Tr_0_12_12), + SymOp(Rot_X_mZ_mY, Tr_0_12_12), + SymOp(Rot_Z_Y_X, Tr_0_12_12), + SymOp(Rot_Z_mY_mX, Tr_0_12_12), + SymOp(Rot_mZ_Y_mX, Tr_0_12_12), + SymOp(Rot_mZ_mY_X, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_Z, Tr_12_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_0_12), + SymOp(Rot_Y_mX_mZ, Tr_12_0_12), + SymOp(Rot_mY_X_mZ, Tr_12_0_12), + SymOp(Rot_X_Z_Y, Tr_12_0_12), + SymOp(Rot_mX_Z_mY, Tr_12_0_12), + SymOp(Rot_mX_mZ_Y, Tr_12_0_12), + SymOp(Rot_X_mZ_mY, Tr_12_0_12), + SymOp(Rot_Z_Y_X, Tr_12_0_12), + SymOp(Rot_Z_mY_mX, Tr_12_0_12), + SymOp(Rot_mZ_Y_mX, Tr_12_0_12), + SymOp(Rot_mZ_mY_X, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_12_12_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_0), + SymOp(Rot_X_Z_Y, Tr_12_12_0), + SymOp(Rot_mX_Z_mY, Tr_12_12_0), + SymOp(Rot_mX_mZ_Y, Tr_12_12_0), + SymOp(Rot_X_mZ_mY, Tr_12_12_0), + SymOp(Rot_Z_Y_X, Tr_12_12_0), + SymOp(Rot_Z_mY_mX, Tr_12_12_0), + SymOp(Rot_mZ_Y_mX, Tr_12_12_0), + SymOp(Rot_mZ_mY_X, Tr_12_12_0), + ], +) sg217 = SpaceGroup( - number = 217, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "I-43m", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "I -4 3 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12)]) + number=217, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="I-43m", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="I -4 3 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + ], +) sg218 = SpaceGroup( - number = 218, - num_sym_equiv = 24, - num_primitive_sym_equiv = 24, - short_name = "P-43n", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "P -4 3 n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12)]) + number=218, + num_sym_equiv=24, + num_primitive_sym_equiv=24, + short_name="P-43n", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="P -4 3 n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + ], +) sg219 = SpaceGroup( - number = 219, - num_sym_equiv = 96, - num_primitive_sym_equiv = 24, - short_name = "F-43c", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "F -4 3 c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_Z, Tr_12_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_0_0), - SymOp(Rot_Y_mX_mZ, Tr_12_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_0_0), - SymOp(Rot_X_Z_Y, Tr_12_0_0), - SymOp(Rot_mX_Z_mY, Tr_12_0_0), - SymOp(Rot_mX_mZ_Y, Tr_12_0_0), - SymOp(Rot_X_mZ_mY, Tr_12_0_0), - SymOp(Rot_Z_Y_X, Tr_12_0_0), - SymOp(Rot_Z_mY_mX, Tr_12_0_0), - SymOp(Rot_mZ_Y_mX, Tr_12_0_0), - SymOp(Rot_mZ_mY_X, Tr_12_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_Z, Tr_0_12_0), - SymOp(Rot_mY_mX_Z, Tr_0_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_12_0), - SymOp(Rot_mY_X_mZ, Tr_0_12_0), - SymOp(Rot_X_Z_Y, Tr_0_12_0), - SymOp(Rot_mX_Z_mY, Tr_0_12_0), - SymOp(Rot_mX_mZ_Y, Tr_0_12_0), - SymOp(Rot_X_mZ_mY, Tr_0_12_0), - SymOp(Rot_Z_Y_X, Tr_0_12_0), - SymOp(Rot_Z_mY_mX, Tr_0_12_0), - SymOp(Rot_mZ_Y_mX, Tr_0_12_0), - SymOp(Rot_mZ_mY_X, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_X_Z_Y, Tr_0_0_12), - SymOp(Rot_mX_Z_mY, Tr_0_0_12), - SymOp(Rot_mX_mZ_Y, Tr_0_0_12), - SymOp(Rot_X_mZ_mY, Tr_0_0_12), - SymOp(Rot_Z_Y_X, Tr_0_0_12), - SymOp(Rot_Z_mY_mX, Tr_0_0_12), - SymOp(Rot_mZ_Y_mX, Tr_0_0_12), - SymOp(Rot_mZ_mY_X, Tr_0_0_12)]) + number=219, + num_sym_equiv=96, + num_primitive_sym_equiv=24, + short_name="F-43c", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="F -4 3 c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_Z, Tr_12_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_0_0), + SymOp(Rot_Y_mX_mZ, Tr_12_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_0_0), + SymOp(Rot_X_Z_Y, Tr_12_0_0), + SymOp(Rot_mX_Z_mY, Tr_12_0_0), + SymOp(Rot_mX_mZ_Y, Tr_12_0_0), + SymOp(Rot_X_mZ_mY, Tr_12_0_0), + SymOp(Rot_Z_Y_X, Tr_12_0_0), + SymOp(Rot_Z_mY_mX, Tr_12_0_0), + SymOp(Rot_mZ_Y_mX, Tr_12_0_0), + SymOp(Rot_mZ_mY_X, Tr_12_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_Z, Tr_0_12_0), + SymOp(Rot_mY_mX_Z, Tr_0_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_12_0), + SymOp(Rot_mY_X_mZ, Tr_0_12_0), + SymOp(Rot_X_Z_Y, Tr_0_12_0), + SymOp(Rot_mX_Z_mY, Tr_0_12_0), + SymOp(Rot_mX_mZ_Y, Tr_0_12_0), + SymOp(Rot_X_mZ_mY, Tr_0_12_0), + SymOp(Rot_Z_Y_X, Tr_0_12_0), + SymOp(Rot_Z_mY_mX, Tr_0_12_0), + SymOp(Rot_mZ_Y_mX, Tr_0_12_0), + SymOp(Rot_mZ_mY_X, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_X_Z_Y, Tr_0_0_12), + SymOp(Rot_mX_Z_mY, Tr_0_0_12), + SymOp(Rot_mX_mZ_Y, Tr_0_0_12), + SymOp(Rot_X_mZ_mY, Tr_0_0_12), + SymOp(Rot_Z_Y_X, Tr_0_0_12), + SymOp(Rot_Z_mY_mX, Tr_0_0_12), + SymOp(Rot_mZ_Y_mX, Tr_0_0_12), + SymOp(Rot_mZ_mY_X, Tr_0_0_12), + ], +) sg220 = SpaceGroup( - number = 220, - num_sym_equiv = 48, - num_primitive_sym_equiv = 24, - short_name = "I-43d", - point_group_name = "PG4bar3m", - crystal_system = "CUBIC", - pdb_name = "I -4 3 d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_Z, Tr_14_14_14), - SymOp(Rot_mY_mX_Z, Tr_14_34_34), - SymOp(Rot_Y_mX_mZ, Tr_34_14_34), - SymOp(Rot_mY_X_mZ, Tr_34_34_14), - SymOp(Rot_X_Z_Y, Tr_14_14_14), - SymOp(Rot_mX_Z_mY, Tr_34_34_14), - SymOp(Rot_mX_mZ_Y, Tr_14_34_34), - SymOp(Rot_X_mZ_mY, Tr_34_14_34), - SymOp(Rot_Z_Y_X, Tr_14_14_14), - SymOp(Rot_Z_mY_mX, Tr_34_14_34), - SymOp(Rot_mZ_Y_mX, Tr_34_34_14), - SymOp(Rot_mZ_mY_X, Tr_14_34_34), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_0), - SymOp(Rot_Y_X_Z, Tr_34_34_34), - SymOp(Rot_mY_mX_Z, Tr_34_14_14), - SymOp(Rot_Y_mX_mZ, Tr_14_34_14), - SymOp(Rot_mY_X_mZ, Tr_14_14_34), - SymOp(Rot_X_Z_Y, Tr_34_34_34), - SymOp(Rot_mX_Z_mY, Tr_14_14_34), - SymOp(Rot_mX_mZ_Y, Tr_34_14_14), - SymOp(Rot_X_mZ_mY, Tr_14_34_14), - SymOp(Rot_Z_Y_X, Tr_34_34_34), - SymOp(Rot_Z_mY_mX, Tr_14_34_14), - SymOp(Rot_mZ_Y_mX, Tr_14_14_34), - SymOp(Rot_mZ_mY_X, Tr_34_14_14)]) + number=220, + num_sym_equiv=48, + num_primitive_sym_equiv=24, + short_name="I-43d", + point_group_name="PG4bar3m", + crystal_system="CUBIC", + pdb_name="I -4 3 d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_Z, Tr_14_14_14), + SymOp(Rot_mY_mX_Z, Tr_14_34_34), + SymOp(Rot_Y_mX_mZ, Tr_34_14_34), + SymOp(Rot_mY_X_mZ, Tr_34_34_14), + SymOp(Rot_X_Z_Y, Tr_14_14_14), + SymOp(Rot_mX_Z_mY, Tr_34_34_14), + SymOp(Rot_mX_mZ_Y, Tr_14_34_34), + SymOp(Rot_X_mZ_mY, Tr_34_14_34), + SymOp(Rot_Z_Y_X, Tr_14_14_14), + SymOp(Rot_Z_mY_mX, Tr_34_14_34), + SymOp(Rot_mZ_Y_mX, Tr_34_34_14), + SymOp(Rot_mZ_mY_X, Tr_14_34_34), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_0), + SymOp(Rot_Y_X_Z, Tr_34_34_34), + SymOp(Rot_mY_mX_Z, Tr_34_14_14), + SymOp(Rot_Y_mX_mZ, Tr_14_34_14), + SymOp(Rot_mY_X_mZ, Tr_14_14_34), + SymOp(Rot_X_Z_Y, Tr_34_34_34), + SymOp(Rot_mX_Z_mY, Tr_14_14_34), + SymOp(Rot_mX_mZ_Y, Tr_34_14_14), + SymOp(Rot_X_mZ_mY, Tr_14_34_14), + SymOp(Rot_Z_Y_X, Tr_34_34_34), + SymOp(Rot_Z_mY_mX, Tr_14_34_14), + SymOp(Rot_mZ_Y_mX, Tr_14_14_34), + SymOp(Rot_mZ_mY_X, Tr_34_14_14), + ], +) sg221 = SpaceGroup( - number = 221, - num_sym_equiv = 48, - num_primitive_sym_equiv = 48, - short_name = "Pm-3m", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "P 4/m -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0)]) + number=221, + num_sym_equiv=48, + num_primitive_sym_equiv=48, + short_name="Pm-3m", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="P 4/m -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + ], +) sg222 = SpaceGroup( - number = 222, - num_sym_equiv = 48, - num_primitive_sym_equiv = 48, - short_name = "Pn-3n", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "P 4/n -3 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_12_12_12), - SymOp(Rot_Z_X_mY, Tr_12_12_12), - SymOp(Rot_Z_mX_Y, Tr_12_12_12), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_12), - SymOp(Rot_Y_Z_mX, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12)]) + number=222, + num_sym_equiv=48, + num_primitive_sym_equiv=48, + short_name="Pn-3n", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="P 4/n -3 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_12_12_12), + SymOp(Rot_Z_X_mY, Tr_12_12_12), + SymOp(Rot_Z_mX_Y, Tr_12_12_12), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_12), + SymOp(Rot_Y_Z_mX, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + ], +) sg223 = SpaceGroup( - number = 223, - num_sym_equiv = 48, - num_primitive_sym_equiv = 48, - short_name = "Pm-3n", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "P 42/m -3 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12)]) + number=223, + num_sym_equiv=48, + num_primitive_sym_equiv=48, + short_name="Pm-3n", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="P 42/m -3 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + ], +) sg224 = SpaceGroup( - number = 224, - num_sym_equiv = 48, - num_primitive_sym_equiv = 48, - short_name = "Pn-3m", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "P 42/n -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_12_12_12), - SymOp(Rot_Z_X_mY, Tr_12_12_12), - SymOp(Rot_Z_mX_Y, Tr_12_12_12), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_12), - SymOp(Rot_Y_Z_mX, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0)]) + number=224, + num_sym_equiv=48, + num_primitive_sym_equiv=48, + short_name="Pn-3m", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="P 42/n -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_12_12_12), + SymOp(Rot_Z_X_mY, Tr_12_12_12), + SymOp(Rot_Z_mX_Y, Tr_12_12_12), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_12), + SymOp(Rot_Y_Z_mX, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + ], +) sg225 = SpaceGroup( - number = 225, - num_sym_equiv = 192, - num_primitive_sym_equiv = 48, - short_name = "Fm-3m", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "F 4/m -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_0_12_12), - SymOp(Rot_mY_mX_mZ, Tr_0_12_12), - SymOp(Rot_Y_mX_Z, Tr_0_12_12), - SymOp(Rot_mY_X_Z, Tr_0_12_12), - SymOp(Rot_X_Z_mY, Tr_0_12_12), - SymOp(Rot_mX_Z_Y, Tr_0_12_12), - SymOp(Rot_mX_mZ_mY, Tr_0_12_12), - SymOp(Rot_X_mZ_Y, Tr_0_12_12), - SymOp(Rot_Z_Y_mX, Tr_0_12_12), - SymOp(Rot_Z_mY_X, Tr_0_12_12), - SymOp(Rot_mZ_Y_X, Tr_0_12_12), - SymOp(Rot_mZ_mY_mX, Tr_0_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12), - SymOp(Rot_mZ_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_X_Y, Tr_0_12_12), - SymOp(Rot_Z_X_mY, Tr_0_12_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_0_12_12), - SymOp(Rot_Y_Z_mX, Tr_0_12_12), - SymOp(Rot_mY_mX_Z, Tr_0_12_12), - SymOp(Rot_Y_X_Z, Tr_0_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_12_12), - SymOp(Rot_mX_mZ_Y, Tr_0_12_12), - SymOp(Rot_X_mZ_mY, Tr_0_12_12), - SymOp(Rot_X_Z_Y, Tr_0_12_12), - SymOp(Rot_mX_Z_mY, Tr_0_12_12), - SymOp(Rot_mZ_mY_X, Tr_0_12_12), - SymOp(Rot_mZ_Y_mX, Tr_0_12_12), - SymOp(Rot_Z_mY_mX, Tr_0_12_12), - SymOp(Rot_Z_Y_X, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_12_0_12), - SymOp(Rot_mY_mX_mZ, Tr_12_0_12), - SymOp(Rot_Y_mX_Z, Tr_12_0_12), - SymOp(Rot_mY_X_Z, Tr_12_0_12), - SymOp(Rot_X_Z_mY, Tr_12_0_12), - SymOp(Rot_mX_Z_Y, Tr_12_0_12), - SymOp(Rot_mX_mZ_mY, Tr_12_0_12), - SymOp(Rot_X_mZ_Y, Tr_12_0_12), - SymOp(Rot_Z_Y_mX, Tr_12_0_12), - SymOp(Rot_Z_mY_X, Tr_12_0_12), - SymOp(Rot_mZ_Y_X, Tr_12_0_12), - SymOp(Rot_mZ_mY_mX, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_mZ_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_X_Y, Tr_12_0_12), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_12_0_12), - SymOp(Rot_mY_mZ_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_X, Tr_12_0_12), - SymOp(Rot_mY_Z_X, Tr_12_0_12), - SymOp(Rot_Y_Z_mX, Tr_12_0_12), - SymOp(Rot_mY_mX_Z, Tr_12_0_12), - SymOp(Rot_Y_X_Z, Tr_12_0_12), - SymOp(Rot_mY_X_mZ, Tr_12_0_12), - SymOp(Rot_Y_mX_mZ, Tr_12_0_12), - SymOp(Rot_mX_mZ_Y, Tr_12_0_12), - SymOp(Rot_X_mZ_mY, Tr_12_0_12), - SymOp(Rot_X_Z_Y, Tr_12_0_12), - SymOp(Rot_mX_Z_mY, Tr_12_0_12), - SymOp(Rot_mZ_mY_X, Tr_12_0_12), - SymOp(Rot_mZ_Y_mX, Tr_12_0_12), - SymOp(Rot_Z_mY_mX, Tr_12_0_12), - SymOp(Rot_Z_Y_X, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_0), - SymOp(Rot_mY_mX_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_Z, Tr_12_12_0), - SymOp(Rot_mY_X_Z, Tr_12_12_0), - SymOp(Rot_X_Z_mY, Tr_12_12_0), - SymOp(Rot_mX_Z_Y, Tr_12_12_0), - SymOp(Rot_mX_mZ_mY, Tr_12_12_0), - SymOp(Rot_X_mZ_Y, Tr_12_12_0), - SymOp(Rot_Z_Y_mX, Tr_12_12_0), - SymOp(Rot_Z_mY_X, Tr_12_12_0), - SymOp(Rot_mZ_Y_X, Tr_12_12_0), - SymOp(Rot_mZ_mY_mX, Tr_12_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_12_0), - SymOp(Rot_Z_mX_Y, Tr_12_12_0), - SymOp(Rot_mY_mZ_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_X, Tr_12_12_0), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mZ_Y, Tr_12_12_0), - SymOp(Rot_X_mZ_mY, Tr_12_12_0), - SymOp(Rot_X_Z_Y, Tr_12_12_0), - SymOp(Rot_mX_Z_mY, Tr_12_12_0), - SymOp(Rot_mZ_mY_X, Tr_12_12_0), - SymOp(Rot_mZ_Y_mX, Tr_12_12_0), - SymOp(Rot_Z_mY_mX, Tr_12_12_0), - SymOp(Rot_Z_Y_X, Tr_12_12_0)]) + number=225, + num_sym_equiv=192, + num_primitive_sym_equiv=48, + short_name="Fm-3m", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="F 4/m -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_0_12_12), + SymOp(Rot_mY_mX_mZ, Tr_0_12_12), + SymOp(Rot_Y_mX_Z, Tr_0_12_12), + SymOp(Rot_mY_X_Z, Tr_0_12_12), + SymOp(Rot_X_Z_mY, Tr_0_12_12), + SymOp(Rot_mX_Z_Y, Tr_0_12_12), + SymOp(Rot_mX_mZ_mY, Tr_0_12_12), + SymOp(Rot_X_mZ_Y, Tr_0_12_12), + SymOp(Rot_Z_Y_mX, Tr_0_12_12), + SymOp(Rot_Z_mY_X, Tr_0_12_12), + SymOp(Rot_mZ_Y_X, Tr_0_12_12), + SymOp(Rot_mZ_mY_mX, Tr_0_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + SymOp(Rot_mZ_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_X_Y, Tr_0_12_12), + SymOp(Rot_Z_X_mY, Tr_0_12_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_0_12_12), + SymOp(Rot_Y_Z_mX, Tr_0_12_12), + SymOp(Rot_mY_mX_Z, Tr_0_12_12), + SymOp(Rot_Y_X_Z, Tr_0_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_12_12), + SymOp(Rot_mX_mZ_Y, Tr_0_12_12), + SymOp(Rot_X_mZ_mY, Tr_0_12_12), + SymOp(Rot_X_Z_Y, Tr_0_12_12), + SymOp(Rot_mX_Z_mY, Tr_0_12_12), + SymOp(Rot_mZ_mY_X, Tr_0_12_12), + SymOp(Rot_mZ_Y_mX, Tr_0_12_12), + SymOp(Rot_Z_mY_mX, Tr_0_12_12), + SymOp(Rot_Z_Y_X, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_12_0_12), + SymOp(Rot_mY_mX_mZ, Tr_12_0_12), + SymOp(Rot_Y_mX_Z, Tr_12_0_12), + SymOp(Rot_mY_X_Z, Tr_12_0_12), + SymOp(Rot_X_Z_mY, Tr_12_0_12), + SymOp(Rot_mX_Z_Y, Tr_12_0_12), + SymOp(Rot_mX_mZ_mY, Tr_12_0_12), + SymOp(Rot_X_mZ_Y, Tr_12_0_12), + SymOp(Rot_Z_Y_mX, Tr_12_0_12), + SymOp(Rot_Z_mY_X, Tr_12_0_12), + SymOp(Rot_mZ_Y_X, Tr_12_0_12), + SymOp(Rot_mZ_mY_mX, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_mZ_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_X_Y, Tr_12_0_12), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_12_0_12), + SymOp(Rot_mY_mZ_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_X, Tr_12_0_12), + SymOp(Rot_mY_Z_X, Tr_12_0_12), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + SymOp(Rot_mY_mX_Z, Tr_12_0_12), + SymOp(Rot_Y_X_Z, Tr_12_0_12), + SymOp(Rot_mY_X_mZ, Tr_12_0_12), + SymOp(Rot_Y_mX_mZ, Tr_12_0_12), + SymOp(Rot_mX_mZ_Y, Tr_12_0_12), + SymOp(Rot_X_mZ_mY, Tr_12_0_12), + SymOp(Rot_X_Z_Y, Tr_12_0_12), + SymOp(Rot_mX_Z_mY, Tr_12_0_12), + SymOp(Rot_mZ_mY_X, Tr_12_0_12), + SymOp(Rot_mZ_Y_mX, Tr_12_0_12), + SymOp(Rot_Z_mY_mX, Tr_12_0_12), + SymOp(Rot_Z_Y_X, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_0), + SymOp(Rot_mY_mX_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_Z, Tr_12_12_0), + SymOp(Rot_mY_X_Z, Tr_12_12_0), + SymOp(Rot_X_Z_mY, Tr_12_12_0), + SymOp(Rot_mX_Z_Y, Tr_12_12_0), + SymOp(Rot_mX_mZ_mY, Tr_12_12_0), + SymOp(Rot_X_mZ_Y, Tr_12_12_0), + SymOp(Rot_Z_Y_mX, Tr_12_12_0), + SymOp(Rot_Z_mY_X, Tr_12_12_0), + SymOp(Rot_mZ_Y_X, Tr_12_12_0), + SymOp(Rot_mZ_mY_mX, Tr_12_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_12_0), + SymOp(Rot_Z_mX_Y, Tr_12_12_0), + SymOp(Rot_mY_mZ_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_X, Tr_12_12_0), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mZ_Y, Tr_12_12_0), + SymOp(Rot_X_mZ_mY, Tr_12_12_0), + SymOp(Rot_X_Z_Y, Tr_12_12_0), + SymOp(Rot_mX_Z_mY, Tr_12_12_0), + SymOp(Rot_mZ_mY_X, Tr_12_12_0), + SymOp(Rot_mZ_Y_mX, Tr_12_12_0), + SymOp(Rot_Z_mY_mX, Tr_12_12_0), + SymOp(Rot_Z_Y_X, Tr_12_12_0), + ], +) sg226 = SpaceGroup( - number = 226, - num_sym_equiv = 192, - num_primitive_sym_equiv = 48, - short_name = "Fm-3c", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "F 4/m -3 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_0_0), - SymOp(Rot_mY_mX_mZ, Tr_12_0_0), - SymOp(Rot_Y_mX_Z, Tr_12_0_0), - SymOp(Rot_mY_X_Z, Tr_12_0_0), - SymOp(Rot_X_Z_mY, Tr_12_0_0), - SymOp(Rot_mX_Z_Y, Tr_12_0_0), - SymOp(Rot_mX_mZ_mY, Tr_12_0_0), - SymOp(Rot_X_mZ_Y, Tr_12_0_0), - SymOp(Rot_Z_Y_mX, Tr_12_0_0), - SymOp(Rot_Z_mY_X, Tr_12_0_0), - SymOp(Rot_mZ_Y_X, Tr_12_0_0), - SymOp(Rot_mZ_mY_mX, Tr_12_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_0_12_12), - SymOp(Rot_mZ_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_X_Y, Tr_0_12_12), - SymOp(Rot_Z_X_mY, Tr_0_12_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_0_12_12), - SymOp(Rot_Y_Z_mX, Tr_0_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_0_0), - SymOp(Rot_Y_X_Z, Tr_12_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_0_0), - SymOp(Rot_Y_mX_mZ, Tr_12_0_0), - SymOp(Rot_mX_mZ_Y, Tr_12_0_0), - SymOp(Rot_X_mZ_mY, Tr_12_0_0), - SymOp(Rot_X_Z_Y, Tr_12_0_0), - SymOp(Rot_mX_Z_mY, Tr_12_0_0), - SymOp(Rot_mZ_mY_X, Tr_12_0_0), - SymOp(Rot_mZ_Y_mX, Tr_12_0_0), - SymOp(Rot_Z_mY_mX, Tr_12_0_0), - SymOp(Rot_Z_Y_X, Tr_12_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_0_12_0), - SymOp(Rot_mY_mX_mZ, Tr_0_12_0), - SymOp(Rot_Y_mX_Z, Tr_0_12_0), - SymOp(Rot_mY_X_Z, Tr_0_12_0), - SymOp(Rot_X_Z_mY, Tr_0_12_0), - SymOp(Rot_mX_Z_Y, Tr_0_12_0), - SymOp(Rot_mX_mZ_mY, Tr_0_12_0), - SymOp(Rot_X_mZ_Y, Tr_0_12_0), - SymOp(Rot_Z_Y_mX, Tr_0_12_0), - SymOp(Rot_Z_mY_X, Tr_0_12_0), - SymOp(Rot_mZ_Y_X, Tr_0_12_0), - SymOp(Rot_mZ_mY_mX, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_Z, Tr_12_0_12), - SymOp(Rot_mZ_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_X_Y, Tr_12_0_12), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_12_0_12), - SymOp(Rot_mY_mZ_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_X, Tr_12_0_12), - SymOp(Rot_mY_Z_X, Tr_12_0_12), - SymOp(Rot_Y_Z_mX, Tr_12_0_12), - SymOp(Rot_mY_mX_Z, Tr_0_12_0), - SymOp(Rot_Y_X_Z, Tr_0_12_0), - SymOp(Rot_mY_X_mZ, Tr_0_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_12_0), - SymOp(Rot_mX_mZ_Y, Tr_0_12_0), - SymOp(Rot_X_mZ_mY, Tr_0_12_0), - SymOp(Rot_X_Z_Y, Tr_0_12_0), - SymOp(Rot_mX_Z_mY, Tr_0_12_0), - SymOp(Rot_mZ_mY_X, Tr_0_12_0), - SymOp(Rot_mZ_Y_mX, Tr_0_12_0), - SymOp(Rot_Z_mY_mX, Tr_0_12_0), - SymOp(Rot_Z_Y_X, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_0_0_12), - SymOp(Rot_Y_mX_Z, Tr_0_0_12), - SymOp(Rot_mY_X_Z, Tr_0_0_12), - SymOp(Rot_X_Z_mY, Tr_0_0_12), - SymOp(Rot_mX_Z_Y, Tr_0_0_12), - SymOp(Rot_mX_mZ_mY, Tr_0_0_12), - SymOp(Rot_X_mZ_Y, Tr_0_0_12), - SymOp(Rot_Z_Y_mX, Tr_0_0_12), - SymOp(Rot_Z_mY_X, Tr_0_0_12), - SymOp(Rot_mZ_Y_X, Tr_0_0_12), - SymOp(Rot_mZ_mY_mX, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_12_0), - SymOp(Rot_Z_mX_Y, Tr_12_12_0), - SymOp(Rot_mY_mZ_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_X, Tr_12_12_0), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_12_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mZ_Y, Tr_0_0_12), - SymOp(Rot_X_mZ_mY, Tr_0_0_12), - SymOp(Rot_X_Z_Y, Tr_0_0_12), - SymOp(Rot_mX_Z_mY, Tr_0_0_12), - SymOp(Rot_mZ_mY_X, Tr_0_0_12), - SymOp(Rot_mZ_Y_mX, Tr_0_0_12), - SymOp(Rot_Z_mY_mX, Tr_0_0_12), - SymOp(Rot_Z_Y_X, Tr_0_0_12)]) + number=226, + num_sym_equiv=192, + num_primitive_sym_equiv=48, + short_name="Fm-3c", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="F 4/m -3 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_0_0), + SymOp(Rot_mY_mX_mZ, Tr_12_0_0), + SymOp(Rot_Y_mX_Z, Tr_12_0_0), + SymOp(Rot_mY_X_Z, Tr_12_0_0), + SymOp(Rot_X_Z_mY, Tr_12_0_0), + SymOp(Rot_mX_Z_Y, Tr_12_0_0), + SymOp(Rot_mX_mZ_mY, Tr_12_0_0), + SymOp(Rot_X_mZ_Y, Tr_12_0_0), + SymOp(Rot_Z_Y_mX, Tr_12_0_0), + SymOp(Rot_Z_mY_X, Tr_12_0_0), + SymOp(Rot_mZ_Y_X, Tr_12_0_0), + SymOp(Rot_mZ_mY_mX, Tr_12_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_0_12_12), + SymOp(Rot_mZ_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_X_Y, Tr_0_12_12), + SymOp(Rot_Z_X_mY, Tr_0_12_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_0_12_12), + SymOp(Rot_Y_Z_mX, Tr_0_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_0_0), + SymOp(Rot_Y_X_Z, Tr_12_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_0_0), + SymOp(Rot_Y_mX_mZ, Tr_12_0_0), + SymOp(Rot_mX_mZ_Y, Tr_12_0_0), + SymOp(Rot_X_mZ_mY, Tr_12_0_0), + SymOp(Rot_X_Z_Y, Tr_12_0_0), + SymOp(Rot_mX_Z_mY, Tr_12_0_0), + SymOp(Rot_mZ_mY_X, Tr_12_0_0), + SymOp(Rot_mZ_Y_mX, Tr_12_0_0), + SymOp(Rot_Z_mY_mX, Tr_12_0_0), + SymOp(Rot_Z_Y_X, Tr_12_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_0_12_0), + SymOp(Rot_mY_mX_mZ, Tr_0_12_0), + SymOp(Rot_Y_mX_Z, Tr_0_12_0), + SymOp(Rot_mY_X_Z, Tr_0_12_0), + SymOp(Rot_X_Z_mY, Tr_0_12_0), + SymOp(Rot_mX_Z_Y, Tr_0_12_0), + SymOp(Rot_mX_mZ_mY, Tr_0_12_0), + SymOp(Rot_X_mZ_Y, Tr_0_12_0), + SymOp(Rot_Z_Y_mX, Tr_0_12_0), + SymOp(Rot_Z_mY_X, Tr_0_12_0), + SymOp(Rot_mZ_Y_X, Tr_0_12_0), + SymOp(Rot_mZ_mY_mX, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_Z, Tr_12_0_12), + SymOp(Rot_mZ_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_X_Y, Tr_12_0_12), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_12_0_12), + SymOp(Rot_mY_mZ_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_X, Tr_12_0_12), + SymOp(Rot_mY_Z_X, Tr_12_0_12), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + SymOp(Rot_mY_mX_Z, Tr_0_12_0), + SymOp(Rot_Y_X_Z, Tr_0_12_0), + SymOp(Rot_mY_X_mZ, Tr_0_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_12_0), + SymOp(Rot_mX_mZ_Y, Tr_0_12_0), + SymOp(Rot_X_mZ_mY, Tr_0_12_0), + SymOp(Rot_X_Z_Y, Tr_0_12_0), + SymOp(Rot_mX_Z_mY, Tr_0_12_0), + SymOp(Rot_mZ_mY_X, Tr_0_12_0), + SymOp(Rot_mZ_Y_mX, Tr_0_12_0), + SymOp(Rot_Z_mY_mX, Tr_0_12_0), + SymOp(Rot_Z_Y_X, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_0_0_12), + SymOp(Rot_Y_mX_Z, Tr_0_0_12), + SymOp(Rot_mY_X_Z, Tr_0_0_12), + SymOp(Rot_X_Z_mY, Tr_0_0_12), + SymOp(Rot_mX_Z_Y, Tr_0_0_12), + SymOp(Rot_mX_mZ_mY, Tr_0_0_12), + SymOp(Rot_X_mZ_Y, Tr_0_0_12), + SymOp(Rot_Z_Y_mX, Tr_0_0_12), + SymOp(Rot_Z_mY_X, Tr_0_0_12), + SymOp(Rot_mZ_Y_X, Tr_0_0_12), + SymOp(Rot_mZ_mY_mX, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_12_0), + SymOp(Rot_Z_mX_Y, Tr_12_12_0), + SymOp(Rot_mY_mZ_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_X, Tr_12_12_0), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_12_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mZ_Y, Tr_0_0_12), + SymOp(Rot_X_mZ_mY, Tr_0_0_12), + SymOp(Rot_X_Z_Y, Tr_0_0_12), + SymOp(Rot_mX_Z_mY, Tr_0_0_12), + SymOp(Rot_mZ_mY_X, Tr_0_0_12), + SymOp(Rot_mZ_Y_mX, Tr_0_0_12), + SymOp(Rot_Z_mY_mX, Tr_0_0_12), + SymOp(Rot_Z_Y_X, Tr_0_0_12), + ], +) sg227 = SpaceGroup( - number = 227, - num_sym_equiv = 192, - num_primitive_sym_equiv = 48, - short_name = "Fd-3m", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "F 41/d -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_14_34_34), - SymOp(Rot_mY_X_Z, Tr_34_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_34), - SymOp(Rot_mX_Z_Y, Tr_34_34_14), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_14_34_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_34), - SymOp(Rot_Z_mY_X, Tr_14_34_34), - SymOp(Rot_mZ_Y_X, Tr_34_34_14), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14), - SymOp(Rot_mX_mY_mZ, Tr_14_14_14), - SymOp(Rot_X_Y_mZ, Tr_14_34_34), - SymOp(Rot_X_mY_Z, Tr_34_34_14), - SymOp(Rot_mX_Y_Z, Tr_34_14_34), - SymOp(Rot_mZ_mX_mY, Tr_14_14_14), - SymOp(Rot_mZ_X_Y, Tr_34_14_34), - SymOp(Rot_Z_X_mY, Tr_14_34_34), - SymOp(Rot_Z_mX_Y, Tr_34_34_14), - SymOp(Rot_mY_mZ_mX, Tr_14_14_14), - SymOp(Rot_Y_mZ_X, Tr_34_34_14), - SymOp(Rot_mY_Z_X, Tr_34_14_34), - SymOp(Rot_Y_Z_mX, Tr_14_34_34), - SymOp(Rot_mY_mX_Z, Tr_12_0_12), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_0), - SymOp(Rot_mX_mZ_Y, Tr_12_0_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_0_12), - SymOp(Rot_mZ_Y_mX, Tr_0_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_34_34_14), - SymOp(Rot_mY_mX_mZ, Tr_14_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_34_34_14), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_14), - SymOp(Rot_Z_Y_mX, Tr_34_34_14), - SymOp(Rot_Z_mY_X, Tr_14_14_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_34_34), - SymOp(Rot_mX_mY_mZ, Tr_14_34_34), - SymOp(Rot_X_Y_mZ, Tr_14_14_14), - SymOp(Rot_X_mY_Z, Tr_34_14_34), - SymOp(Rot_mX_Y_Z, Tr_34_34_14), - SymOp(Rot_mZ_mX_mY, Tr_14_34_34), - SymOp(Rot_mZ_X_Y, Tr_34_34_14), - SymOp(Rot_Z_X_mY, Tr_14_14_14), - SymOp(Rot_Z_mX_Y, Tr_34_14_34), - SymOp(Rot_mY_mZ_mX, Tr_14_34_34), - SymOp(Rot_Y_mZ_X, Tr_34_14_34), - SymOp(Rot_mY_Z_X, Tr_34_34_14), - SymOp(Rot_Y_Z_mX, Tr_14_14_14), - SymOp(Rot_mY_mX_Z, Tr_12_12_0), - SymOp(Rot_Y_X_Z, Tr_0_12_12), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_12_0_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_0), - SymOp(Rot_X_mZ_mY, Tr_12_0_12), - SymOp(Rot_X_Z_Y, Tr_0_12_12), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_12_12_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_12_0_12), - SymOp(Rot_Z_Y_X, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_14_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_14_34), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_14_34_34), - SymOp(Rot_X_Z_mY, Tr_14_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_34), - SymOp(Rot_mX_mZ_mY, Tr_34_14_34), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_14_14), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_14_34_34), - SymOp(Rot_mZ_mY_mX, Tr_34_14_34), - SymOp(Rot_mX_mY_mZ, Tr_34_14_34), - SymOp(Rot_X_Y_mZ, Tr_34_34_14), - SymOp(Rot_X_mY_Z, Tr_14_34_34), - SymOp(Rot_mX_Y_Z, Tr_14_14_14), - SymOp(Rot_mZ_mX_mY, Tr_34_14_34), - SymOp(Rot_mZ_X_Y, Tr_14_14_14), - SymOp(Rot_Z_X_mY, Tr_34_34_14), - SymOp(Rot_Z_mX_Y, Tr_14_34_34), - SymOp(Rot_mY_mZ_mX, Tr_34_14_34), - SymOp(Rot_Y_mZ_X, Tr_14_34_34), - SymOp(Rot_mY_Z_X, Tr_14_14_14), - SymOp(Rot_Y_Z_mX, Tr_34_34_14), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_12_0_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_0), - SymOp(Rot_Y_mX_mZ, Tr_0_12_12), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_12_12), - SymOp(Rot_X_Z_Y, Tr_12_0_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_12_12_0), - SymOp(Rot_Z_mY_mX, Tr_0_12_12), - SymOp(Rot_Z_Y_X, Tr_12_0_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_34_34_14), - SymOp(Rot_Y_mX_Z, Tr_34_14_34), - SymOp(Rot_mY_X_Z, Tr_14_14_14), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_14_14_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_14), - SymOp(Rot_X_mZ_Y, Tr_34_14_34), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_14_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_14), - SymOp(Rot_mX_mY_mZ, Tr_34_34_14), - SymOp(Rot_X_Y_mZ, Tr_34_14_34), - SymOp(Rot_X_mY_Z, Tr_14_14_14), - SymOp(Rot_mX_Y_Z, Tr_14_34_34), - SymOp(Rot_mZ_mX_mY, Tr_34_34_14), - SymOp(Rot_mZ_X_Y, Tr_14_34_34), - SymOp(Rot_Z_X_mY, Tr_34_14_34), - SymOp(Rot_Z_mX_Y, Tr_14_14_14), - SymOp(Rot_mY_mZ_mX, Tr_34_34_14), - SymOp(Rot_Y_mZ_X, Tr_14_14_14), - SymOp(Rot_mY_Z_X, Tr_14_34_34), - SymOp(Rot_Y_Z_mX, Tr_34_14_34), - SymOp(Rot_mY_mX_Z, Tr_0_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_0), - SymOp(Rot_mY_X_mZ, Tr_12_0_12), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_12_12), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_12_12_0), - SymOp(Rot_mX_Z_mY, Tr_12_0_12), - SymOp(Rot_mZ_mY_X, Tr_0_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_0_12), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_12_12_0)]) + number=227, + num_sym_equiv=192, + num_primitive_sym_equiv=48, + short_name="Fd-3m", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="F 41/d -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_14_34_34), + SymOp(Rot_mY_X_Z, Tr_34_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_34), + SymOp(Rot_mX_Z_Y, Tr_34_34_14), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_14_34_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_34), + SymOp(Rot_Z_mY_X, Tr_14_34_34), + SymOp(Rot_mZ_Y_X, Tr_34_34_14), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + SymOp(Rot_mX_mY_mZ, Tr_14_14_14), + SymOp(Rot_X_Y_mZ, Tr_14_34_34), + SymOp(Rot_X_mY_Z, Tr_34_34_14), + SymOp(Rot_mX_Y_Z, Tr_34_14_34), + SymOp(Rot_mZ_mX_mY, Tr_14_14_14), + SymOp(Rot_mZ_X_Y, Tr_34_14_34), + SymOp(Rot_Z_X_mY, Tr_14_34_34), + SymOp(Rot_Z_mX_Y, Tr_34_34_14), + SymOp(Rot_mY_mZ_mX, Tr_14_14_14), + SymOp(Rot_Y_mZ_X, Tr_34_34_14), + SymOp(Rot_mY_Z_X, Tr_34_14_34), + SymOp(Rot_Y_Z_mX, Tr_14_34_34), + SymOp(Rot_mY_mX_Z, Tr_12_0_12), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_0), + SymOp(Rot_mX_mZ_Y, Tr_12_0_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_0_12), + SymOp(Rot_mZ_Y_mX, Tr_0_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_34_34_14), + SymOp(Rot_mY_mX_mZ, Tr_14_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_34_34_14), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_14), + SymOp(Rot_Z_Y_mX, Tr_34_34_14), + SymOp(Rot_Z_mY_X, Tr_14_14_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_34_34), + SymOp(Rot_mX_mY_mZ, Tr_14_34_34), + SymOp(Rot_X_Y_mZ, Tr_14_14_14), + SymOp(Rot_X_mY_Z, Tr_34_14_34), + SymOp(Rot_mX_Y_Z, Tr_34_34_14), + SymOp(Rot_mZ_mX_mY, Tr_14_34_34), + SymOp(Rot_mZ_X_Y, Tr_34_34_14), + SymOp(Rot_Z_X_mY, Tr_14_14_14), + SymOp(Rot_Z_mX_Y, Tr_34_14_34), + SymOp(Rot_mY_mZ_mX, Tr_14_34_34), + SymOp(Rot_Y_mZ_X, Tr_34_14_34), + SymOp(Rot_mY_Z_X, Tr_34_34_14), + SymOp(Rot_Y_Z_mX, Tr_14_14_14), + SymOp(Rot_mY_mX_Z, Tr_12_12_0), + SymOp(Rot_Y_X_Z, Tr_0_12_12), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_12_0_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_0), + SymOp(Rot_X_mZ_mY, Tr_12_0_12), + SymOp(Rot_X_Z_Y, Tr_0_12_12), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_12_12_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_12_0_12), + SymOp(Rot_Z_Y_X, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_14_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_14_34), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_14_34_34), + SymOp(Rot_X_Z_mY, Tr_14_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_34), + SymOp(Rot_mX_mZ_mY, Tr_34_14_34), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_14_14), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_14_34_34), + SymOp(Rot_mZ_mY_mX, Tr_34_14_34), + SymOp(Rot_mX_mY_mZ, Tr_34_14_34), + SymOp(Rot_X_Y_mZ, Tr_34_34_14), + SymOp(Rot_X_mY_Z, Tr_14_34_34), + SymOp(Rot_mX_Y_Z, Tr_14_14_14), + SymOp(Rot_mZ_mX_mY, Tr_34_14_34), + SymOp(Rot_mZ_X_Y, Tr_14_14_14), + SymOp(Rot_Z_X_mY, Tr_34_34_14), + SymOp(Rot_Z_mX_Y, Tr_14_34_34), + SymOp(Rot_mY_mZ_mX, Tr_34_14_34), + SymOp(Rot_Y_mZ_X, Tr_14_34_34), + SymOp(Rot_mY_Z_X, Tr_14_14_14), + SymOp(Rot_Y_Z_mX, Tr_34_34_14), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_12_0_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_0), + SymOp(Rot_Y_mX_mZ, Tr_0_12_12), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_12_12), + SymOp(Rot_X_Z_Y, Tr_12_0_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_12_12_0), + SymOp(Rot_Z_mY_mX, Tr_0_12_12), + SymOp(Rot_Z_Y_X, Tr_12_0_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_34_34_14), + SymOp(Rot_Y_mX_Z, Tr_34_14_34), + SymOp(Rot_mY_X_Z, Tr_14_14_14), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_14_14_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_14), + SymOp(Rot_X_mZ_Y, Tr_34_14_34), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_14_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_14), + SymOp(Rot_mX_mY_mZ, Tr_34_34_14), + SymOp(Rot_X_Y_mZ, Tr_34_14_34), + SymOp(Rot_X_mY_Z, Tr_14_14_14), + SymOp(Rot_mX_Y_Z, Tr_14_34_34), + SymOp(Rot_mZ_mX_mY, Tr_34_34_14), + SymOp(Rot_mZ_X_Y, Tr_14_34_34), + SymOp(Rot_Z_X_mY, Tr_34_14_34), + SymOp(Rot_Z_mX_Y, Tr_14_14_14), + SymOp(Rot_mY_mZ_mX, Tr_34_34_14), + SymOp(Rot_Y_mZ_X, Tr_14_14_14), + SymOp(Rot_mY_Z_X, Tr_14_34_34), + SymOp(Rot_Y_Z_mX, Tr_34_14_34), + SymOp(Rot_mY_mX_Z, Tr_0_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_0), + SymOp(Rot_mY_X_mZ, Tr_12_0_12), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_12_12), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_12_12_0), + SymOp(Rot_mX_Z_mY, Tr_12_0_12), + SymOp(Rot_mZ_mY_X, Tr_0_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_0_12), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_12_12_0), + ], +) sg228 = SpaceGroup( - number = 228, - num_sym_equiv = 192, - num_primitive_sym_equiv = 48, - short_name = "Fd-3c", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "F 41/d -3 2/c", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_14_34_34), - SymOp(Rot_mY_X_Z, Tr_34_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_34), - SymOp(Rot_mX_Z_Y, Tr_34_34_14), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_14_34_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_34), - SymOp(Rot_Z_mY_X, Tr_14_34_34), - SymOp(Rot_mZ_Y_X, Tr_34_34_14), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14), - SymOp(Rot_mX_mY_mZ, Tr_34_34_34), - SymOp(Rot_X_Y_mZ, Tr_34_14_14), - SymOp(Rot_X_mY_Z, Tr_14_14_34), - SymOp(Rot_mX_Y_Z, Tr_14_34_14), - SymOp(Rot_mZ_mX_mY, Tr_34_34_34), - SymOp(Rot_mZ_X_Y, Tr_14_34_14), - SymOp(Rot_Z_X_mY, Tr_34_14_14), - SymOp(Rot_Z_mX_Y, Tr_14_14_34), - SymOp(Rot_mY_mZ_mX, Tr_34_34_34), - SymOp(Rot_Y_mZ_X, Tr_14_14_34), - SymOp(Rot_mY_Z_X, Tr_14_34_14), - SymOp(Rot_Y_Z_mX, Tr_34_14_14), - SymOp(Rot_mY_mX_Z, Tr_0_12_0), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_12), - SymOp(Rot_mX_mZ_Y, Tr_0_12_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_12_0), - SymOp(Rot_mZ_Y_mX, Tr_12_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_34_34_14), - SymOp(Rot_mY_mX_mZ, Tr_14_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_34_34_14), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_14), - SymOp(Rot_Z_Y_mX, Tr_34_34_14), - SymOp(Rot_Z_mY_X, Tr_14_14_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_34_34), - SymOp(Rot_mX_mY_mZ, Tr_34_14_14), - SymOp(Rot_X_Y_mZ, Tr_34_34_34), - SymOp(Rot_X_mY_Z, Tr_14_34_14), - SymOp(Rot_mX_Y_Z, Tr_14_14_34), - SymOp(Rot_mZ_mX_mY, Tr_34_14_14), - SymOp(Rot_mZ_X_Y, Tr_14_14_34), - SymOp(Rot_Z_X_mY, Tr_34_34_34), - SymOp(Rot_Z_mX_Y, Tr_14_34_14), - SymOp(Rot_mY_mZ_mX, Tr_34_14_14), - SymOp(Rot_Y_mZ_X, Tr_14_34_14), - SymOp(Rot_mY_Z_X, Tr_14_14_34), - SymOp(Rot_Y_Z_mX, Tr_34_34_34), - SymOp(Rot_mY_mX_Z, Tr_0_0_12), - SymOp(Rot_Y_X_Z, Tr_12_0_0), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_0_12_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_12), - SymOp(Rot_X_mZ_mY, Tr_0_12_0), - SymOp(Rot_X_Z_Y, Tr_12_0_0), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_0_0_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_0_12_0), - SymOp(Rot_Z_Y_X, Tr_12_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_12_0_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_12_0_12), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_X_mZ, Tr_14_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_14_34), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_14_34_34), - SymOp(Rot_X_Z_mY, Tr_14_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_34), - SymOp(Rot_mX_mZ_mY, Tr_34_14_34), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_14_14), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_14_34_34), - SymOp(Rot_mZ_mY_mX, Tr_34_14_34), - SymOp(Rot_mX_mY_mZ, Tr_14_34_14), - SymOp(Rot_X_Y_mZ, Tr_14_14_34), - SymOp(Rot_X_mY_Z, Tr_34_14_14), - SymOp(Rot_mX_Y_Z, Tr_34_34_34), - SymOp(Rot_mZ_mX_mY, Tr_14_34_14), - SymOp(Rot_mZ_X_Y, Tr_34_34_34), - SymOp(Rot_Z_X_mY, Tr_14_14_34), - SymOp(Rot_Z_mX_Y, Tr_34_14_14), - SymOp(Rot_mY_mZ_mX, Tr_14_34_14), - SymOp(Rot_Y_mZ_X, Tr_34_14_14), - SymOp(Rot_mY_Z_X, Tr_34_34_34), - SymOp(Rot_Y_Z_mX, Tr_14_14_34), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_0_12_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_12), - SymOp(Rot_Y_mX_mZ, Tr_12_0_0), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_0_0), - SymOp(Rot_X_Z_Y, Tr_0_12_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_0_0_12), - SymOp(Rot_Z_mY_mX, Tr_12_0_0), - SymOp(Rot_Z_Y_X, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_34_34_14), - SymOp(Rot_Y_mX_Z, Tr_34_14_34), - SymOp(Rot_mY_X_Z, Tr_14_14_14), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_14_14_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_14), - SymOp(Rot_X_mZ_Y, Tr_34_14_34), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_14_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_14), - SymOp(Rot_mX_mY_mZ, Tr_14_14_34), - SymOp(Rot_X_Y_mZ, Tr_14_34_14), - SymOp(Rot_X_mY_Z, Tr_34_34_34), - SymOp(Rot_mX_Y_Z, Tr_34_14_14), - SymOp(Rot_mZ_mX_mY, Tr_14_14_34), - SymOp(Rot_mZ_X_Y, Tr_34_14_14), - SymOp(Rot_Z_X_mY, Tr_14_34_14), - SymOp(Rot_Z_mX_Y, Tr_34_34_34), - SymOp(Rot_mY_mZ_mX, Tr_14_14_34), - SymOp(Rot_Y_mZ_X, Tr_34_34_34), - SymOp(Rot_mY_Z_X, Tr_34_14_14), - SymOp(Rot_Y_Z_mX, Tr_14_34_14), - SymOp(Rot_mY_mX_Z, Tr_12_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_12), - SymOp(Rot_mY_X_mZ, Tr_0_12_0), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_0_0), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_0_0_12), - SymOp(Rot_mX_Z_mY, Tr_0_12_0), - SymOp(Rot_mZ_mY_X, Tr_12_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_12_0), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_0_0_12)]) + number=228, + num_sym_equiv=192, + num_primitive_sym_equiv=48, + short_name="Fd-3c", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="F 41/d -3 2/c", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_14_34_34), + SymOp(Rot_mY_X_Z, Tr_34_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_34), + SymOp(Rot_mX_Z_Y, Tr_34_34_14), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_14_34_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_34), + SymOp(Rot_Z_mY_X, Tr_14_34_34), + SymOp(Rot_mZ_Y_X, Tr_34_34_14), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + SymOp(Rot_mX_mY_mZ, Tr_34_34_34), + SymOp(Rot_X_Y_mZ, Tr_34_14_14), + SymOp(Rot_X_mY_Z, Tr_14_14_34), + SymOp(Rot_mX_Y_Z, Tr_14_34_14), + SymOp(Rot_mZ_mX_mY, Tr_34_34_34), + SymOp(Rot_mZ_X_Y, Tr_14_34_14), + SymOp(Rot_Z_X_mY, Tr_34_14_14), + SymOp(Rot_Z_mX_Y, Tr_14_14_34), + SymOp(Rot_mY_mZ_mX, Tr_34_34_34), + SymOp(Rot_Y_mZ_X, Tr_14_14_34), + SymOp(Rot_mY_Z_X, Tr_14_34_14), + SymOp(Rot_Y_Z_mX, Tr_34_14_14), + SymOp(Rot_mY_mX_Z, Tr_0_12_0), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_12), + SymOp(Rot_mX_mZ_Y, Tr_0_12_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_12_0), + SymOp(Rot_mZ_Y_mX, Tr_12_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_34_34_14), + SymOp(Rot_mY_mX_mZ, Tr_14_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_34_34_14), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_14), + SymOp(Rot_Z_Y_mX, Tr_34_34_14), + SymOp(Rot_Z_mY_X, Tr_14_14_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_34_34), + SymOp(Rot_mX_mY_mZ, Tr_34_14_14), + SymOp(Rot_X_Y_mZ, Tr_34_34_34), + SymOp(Rot_X_mY_Z, Tr_14_34_14), + SymOp(Rot_mX_Y_Z, Tr_14_14_34), + SymOp(Rot_mZ_mX_mY, Tr_34_14_14), + SymOp(Rot_mZ_X_Y, Tr_14_14_34), + SymOp(Rot_Z_X_mY, Tr_34_34_34), + SymOp(Rot_Z_mX_Y, Tr_14_34_14), + SymOp(Rot_mY_mZ_mX, Tr_34_14_14), + SymOp(Rot_Y_mZ_X, Tr_14_34_14), + SymOp(Rot_mY_Z_X, Tr_14_14_34), + SymOp(Rot_Y_Z_mX, Tr_34_34_34), + SymOp(Rot_mY_mX_Z, Tr_0_0_12), + SymOp(Rot_Y_X_Z, Tr_12_0_0), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_0_12_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_12), + SymOp(Rot_X_mZ_mY, Tr_0_12_0), + SymOp(Rot_X_Z_Y, Tr_12_0_0), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_0_0_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_0_12_0), + SymOp(Rot_Z_Y_X, Tr_12_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_12_0_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_12_0_12), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_X_mZ, Tr_14_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_14_34), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_14_34_34), + SymOp(Rot_X_Z_mY, Tr_14_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_34), + SymOp(Rot_mX_mZ_mY, Tr_34_14_34), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_14_14), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_14_34_34), + SymOp(Rot_mZ_mY_mX, Tr_34_14_34), + SymOp(Rot_mX_mY_mZ, Tr_14_34_14), + SymOp(Rot_X_Y_mZ, Tr_14_14_34), + SymOp(Rot_X_mY_Z, Tr_34_14_14), + SymOp(Rot_mX_Y_Z, Tr_34_34_34), + SymOp(Rot_mZ_mX_mY, Tr_14_34_14), + SymOp(Rot_mZ_X_Y, Tr_34_34_34), + SymOp(Rot_Z_X_mY, Tr_14_14_34), + SymOp(Rot_Z_mX_Y, Tr_34_14_14), + SymOp(Rot_mY_mZ_mX, Tr_14_34_14), + SymOp(Rot_Y_mZ_X, Tr_34_14_14), + SymOp(Rot_mY_Z_X, Tr_34_34_34), + SymOp(Rot_Y_Z_mX, Tr_14_14_34), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_0_12_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_12), + SymOp(Rot_Y_mX_mZ, Tr_12_0_0), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_0_0), + SymOp(Rot_X_Z_Y, Tr_0_12_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_0_0_12), + SymOp(Rot_Z_mY_mX, Tr_12_0_0), + SymOp(Rot_Z_Y_X, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_34_34_14), + SymOp(Rot_Y_mX_Z, Tr_34_14_34), + SymOp(Rot_mY_X_Z, Tr_14_14_14), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_14_14_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_14), + SymOp(Rot_X_mZ_Y, Tr_34_14_34), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_14_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_14), + SymOp(Rot_mX_mY_mZ, Tr_14_14_34), + SymOp(Rot_X_Y_mZ, Tr_14_34_14), + SymOp(Rot_X_mY_Z, Tr_34_34_34), + SymOp(Rot_mX_Y_Z, Tr_34_14_14), + SymOp(Rot_mZ_mX_mY, Tr_14_14_34), + SymOp(Rot_mZ_X_Y, Tr_34_14_14), + SymOp(Rot_Z_X_mY, Tr_14_34_14), + SymOp(Rot_Z_mX_Y, Tr_34_34_34), + SymOp(Rot_mY_mZ_mX, Tr_14_14_34), + SymOp(Rot_Y_mZ_X, Tr_34_34_34), + SymOp(Rot_mY_Z_X, Tr_34_14_14), + SymOp(Rot_Y_Z_mX, Tr_14_34_14), + SymOp(Rot_mY_mX_Z, Tr_12_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_12), + SymOp(Rot_mY_X_mZ, Tr_0_12_0), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_0_0), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_0_0_12), + SymOp(Rot_mX_Z_mY, Tr_0_12_0), + SymOp(Rot_mZ_mY_X, Tr_12_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_12_0), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_0_0_12), + ], +) sg229 = SpaceGroup( - number = 229, - num_sym_equiv = 96, - num_primitive_sym_equiv = 48, - short_name = "Im-3m", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "I 4/m -3 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_0_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_0_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_0_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_0), - SymOp(Rot_mY_mX_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_Z, Tr_0_0_0), - SymOp(Rot_mY_X_Z, Tr_0_0_0), - SymOp(Rot_X_Z_mY, Tr_0_0_0), - SymOp(Rot_mX_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_mZ_Y, Tr_0_0_0), - SymOp(Rot_Z_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_X, Tr_0_0_0), - SymOp(Rot_mZ_mY_mX, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_0_0_0), - SymOp(Rot_Z_X_mY, Tr_0_0_0), - SymOp(Rot_Z_mX_Y, Tr_0_0_0), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_0), - SymOp(Rot_Y_Z_mX, Tr_0_0_0), - SymOp(Rot_mY_mX_Z, Tr_0_0_0), - SymOp(Rot_Y_X_Z, Tr_0_0_0), - SymOp(Rot_mY_X_mZ, Tr_0_0_0), - SymOp(Rot_Y_mX_mZ, Tr_0_0_0), - SymOp(Rot_mX_mZ_Y, Tr_0_0_0), - SymOp(Rot_X_mZ_mY, Tr_0_0_0), - SymOp(Rot_X_Z_Y, Tr_0_0_0), - SymOp(Rot_mX_Z_mY, Tr_0_0_0), - SymOp(Rot_mZ_mY_X, Tr_0_0_0), - SymOp(Rot_mZ_Y_mX, Tr_0_0_0), - SymOp(Rot_Z_mY_mX, Tr_0_0_0), - SymOp(Rot_Z_Y_X, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_12_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_12_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_12_12_12), - SymOp(Rot_Y_X_mZ, Tr_12_12_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_12_12), - SymOp(Rot_mY_X_Z, Tr_12_12_12), - SymOp(Rot_X_Z_mY, Tr_12_12_12), - SymOp(Rot_mX_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_mZ_Y, Tr_12_12_12), - SymOp(Rot_Z_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_X, Tr_12_12_12), - SymOp(Rot_mZ_mY_mX, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_12_12_12), - SymOp(Rot_Z_X_mY, Tr_12_12_12), - SymOp(Rot_Z_mX_Y, Tr_12_12_12), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_12), - SymOp(Rot_Y_Z_mX, Tr_12_12_12), - SymOp(Rot_mY_mX_Z, Tr_12_12_12), - SymOp(Rot_Y_X_Z, Tr_12_12_12), - SymOp(Rot_mY_X_mZ, Tr_12_12_12), - SymOp(Rot_Y_mX_mZ, Tr_12_12_12), - SymOp(Rot_mX_mZ_Y, Tr_12_12_12), - SymOp(Rot_X_mZ_mY, Tr_12_12_12), - SymOp(Rot_X_Z_Y, Tr_12_12_12), - SymOp(Rot_mX_Z_mY, Tr_12_12_12), - SymOp(Rot_mZ_mY_X, Tr_12_12_12), - SymOp(Rot_mZ_Y_mX, Tr_12_12_12), - SymOp(Rot_Z_mY_mX, Tr_12_12_12), - SymOp(Rot_Z_Y_X, Tr_12_12_12)]) + number=229, + num_sym_equiv=96, + num_primitive_sym_equiv=48, + short_name="Im-3m", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="I 4/m -3 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_0_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_0_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_0), + SymOp(Rot_mY_mX_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_Z, Tr_0_0_0), + SymOp(Rot_mY_X_Z, Tr_0_0_0), + SymOp(Rot_X_Z_mY, Tr_0_0_0), + SymOp(Rot_mX_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_mZ_Y, Tr_0_0_0), + SymOp(Rot_Z_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_X, Tr_0_0_0), + SymOp(Rot_mZ_mY_mX, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_0_0_0), + SymOp(Rot_Z_X_mY, Tr_0_0_0), + SymOp(Rot_Z_mX_Y, Tr_0_0_0), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_0), + SymOp(Rot_Y_Z_mX, Tr_0_0_0), + SymOp(Rot_mY_mX_Z, Tr_0_0_0), + SymOp(Rot_Y_X_Z, Tr_0_0_0), + SymOp(Rot_mY_X_mZ, Tr_0_0_0), + SymOp(Rot_Y_mX_mZ, Tr_0_0_0), + SymOp(Rot_mX_mZ_Y, Tr_0_0_0), + SymOp(Rot_X_mZ_mY, Tr_0_0_0), + SymOp(Rot_X_Z_Y, Tr_0_0_0), + SymOp(Rot_mX_Z_mY, Tr_0_0_0), + SymOp(Rot_mZ_mY_X, Tr_0_0_0), + SymOp(Rot_mZ_Y_mX, Tr_0_0_0), + SymOp(Rot_Z_mY_mX, Tr_0_0_0), + SymOp(Rot_Z_Y_X, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_12_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_12_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_12_12_12), + SymOp(Rot_Y_X_mZ, Tr_12_12_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_12_12), + SymOp(Rot_mY_X_Z, Tr_12_12_12), + SymOp(Rot_X_Z_mY, Tr_12_12_12), + SymOp(Rot_mX_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_mZ_Y, Tr_12_12_12), + SymOp(Rot_Z_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_X, Tr_12_12_12), + SymOp(Rot_mZ_mY_mX, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_12_12_12), + SymOp(Rot_Z_X_mY, Tr_12_12_12), + SymOp(Rot_Z_mX_Y, Tr_12_12_12), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_12), + SymOp(Rot_Y_Z_mX, Tr_12_12_12), + SymOp(Rot_mY_mX_Z, Tr_12_12_12), + SymOp(Rot_Y_X_Z, Tr_12_12_12), + SymOp(Rot_mY_X_mZ, Tr_12_12_12), + SymOp(Rot_Y_mX_mZ, Tr_12_12_12), + SymOp(Rot_mX_mZ_Y, Tr_12_12_12), + SymOp(Rot_X_mZ_mY, Tr_12_12_12), + SymOp(Rot_X_Z_Y, Tr_12_12_12), + SymOp(Rot_mX_Z_mY, Tr_12_12_12), + SymOp(Rot_mZ_mY_X, Tr_12_12_12), + SymOp(Rot_mZ_Y_mX, Tr_12_12_12), + SymOp(Rot_Z_mY_mX, Tr_12_12_12), + SymOp(Rot_Z_Y_X, Tr_12_12_12), + ], +) sg230 = SpaceGroup( - number = 230, - num_sym_equiv = 96, - num_primitive_sym_equiv = 48, - short_name = "Ia-3d", - point_group_name = "PGm3barm", - crystal_system = "CUBIC", - pdb_name = "I 41/a -3 2/d", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_Z_mX_mY, Tr_12_12_0), - SymOp(Rot_mZ_mX_Y, Tr_12_0_12), - SymOp(Rot_mZ_X_mY, Tr_0_12_12), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_12), - SymOp(Rot_Y_mZ_mX, Tr_12_12_0), - SymOp(Rot_mY_mZ_X, Tr_12_0_12), - SymOp(Rot_Y_X_mZ, Tr_34_14_14), - SymOp(Rot_mY_mX_mZ, Tr_34_34_34), - SymOp(Rot_Y_mX_Z, Tr_14_14_34), - SymOp(Rot_mY_X_Z, Tr_14_34_14), - SymOp(Rot_X_Z_mY, Tr_34_14_14), - SymOp(Rot_mX_Z_Y, Tr_14_34_14), - SymOp(Rot_mX_mZ_mY, Tr_34_34_34), - SymOp(Rot_X_mZ_Y, Tr_14_14_34), - SymOp(Rot_Z_Y_mX, Tr_34_14_14), - SymOp(Rot_Z_mY_X, Tr_14_14_34), - SymOp(Rot_mZ_Y_X, Tr_14_34_14), - SymOp(Rot_mZ_mY_mX, Tr_34_34_34), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_Z, Tr_0_12_12), - SymOp(Rot_mX_Y_Z, Tr_12_12_0), - SymOp(Rot_mZ_mX_mY, Tr_0_0_0), - SymOp(Rot_mZ_X_Y, Tr_12_12_0), - SymOp(Rot_Z_X_mY, Tr_12_0_12), - SymOp(Rot_Z_mX_Y, Tr_0_12_12), - SymOp(Rot_mY_mZ_mX, Tr_0_0_0), - SymOp(Rot_Y_mZ_X, Tr_0_12_12), - SymOp(Rot_mY_Z_X, Tr_12_12_0), - SymOp(Rot_Y_Z_mX, Tr_12_0_12), - SymOp(Rot_mY_mX_Z, Tr_14_34_34), - SymOp(Rot_Y_X_Z, Tr_14_14_14), - SymOp(Rot_mY_X_mZ, Tr_34_34_14), - SymOp(Rot_Y_mX_mZ, Tr_34_14_34), - SymOp(Rot_mX_mZ_Y, Tr_14_34_34), - SymOp(Rot_X_mZ_mY, Tr_34_14_34), - SymOp(Rot_X_Z_Y, Tr_14_14_14), - SymOp(Rot_mX_Z_mY, Tr_34_34_14), - SymOp(Rot_mZ_mY_X, Tr_14_34_34), - SymOp(Rot_mZ_Y_mX, Tr_34_34_14), - SymOp(Rot_Z_mY_mX, Tr_34_14_34), - SymOp(Rot_Z_Y_X, Tr_14_14_14), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_Z_mX_mY, Tr_0_0_12), - SymOp(Rot_mZ_mX_Y, Tr_0_12_0), - SymOp(Rot_mZ_X_mY, Tr_12_0_0), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_0), - SymOp(Rot_Y_mZ_mX, Tr_0_0_12), - SymOp(Rot_mY_mZ_X, Tr_0_12_0), - SymOp(Rot_Y_X_mZ, Tr_14_34_34), - SymOp(Rot_mY_mX_mZ, Tr_14_14_14), - SymOp(Rot_Y_mX_Z, Tr_34_34_14), - SymOp(Rot_mY_X_Z, Tr_34_14_34), - SymOp(Rot_X_Z_mY, Tr_14_34_34), - SymOp(Rot_mX_Z_Y, Tr_34_14_34), - SymOp(Rot_mX_mZ_mY, Tr_14_14_14), - SymOp(Rot_X_mZ_Y, Tr_34_34_14), - SymOp(Rot_Z_Y_mX, Tr_14_34_34), - SymOp(Rot_Z_mY_X, Tr_34_34_14), - SymOp(Rot_mZ_Y_X, Tr_34_14_34), - SymOp(Rot_mZ_mY_mX, Tr_14_14_14), - SymOp(Rot_mX_mY_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_Z, Tr_12_0_0), - SymOp(Rot_mX_Y_Z, Tr_0_0_12), - SymOp(Rot_mZ_mX_mY, Tr_12_12_12), - SymOp(Rot_mZ_X_Y, Tr_0_0_12), - SymOp(Rot_Z_X_mY, Tr_0_12_0), - SymOp(Rot_Z_mX_Y, Tr_12_0_0), - SymOp(Rot_mY_mZ_mX, Tr_12_12_12), - SymOp(Rot_Y_mZ_X, Tr_12_0_0), - SymOp(Rot_mY_Z_X, Tr_0_0_12), - SymOp(Rot_Y_Z_mX, Tr_0_12_0), - SymOp(Rot_mY_mX_Z, Tr_34_14_14), - SymOp(Rot_Y_X_Z, Tr_34_34_34), - SymOp(Rot_mY_X_mZ, Tr_14_14_34), - SymOp(Rot_Y_mX_mZ, Tr_14_34_14), - SymOp(Rot_mX_mZ_Y, Tr_34_14_14), - SymOp(Rot_X_mZ_mY, Tr_14_34_14), - SymOp(Rot_X_Z_Y, Tr_34_34_34), - SymOp(Rot_mX_Z_mY, Tr_14_14_34), - SymOp(Rot_mZ_mY_X, Tr_34_14_14), - SymOp(Rot_mZ_Y_mX, Tr_14_14_34), - SymOp(Rot_Z_mY_mX, Tr_14_34_14), - SymOp(Rot_Z_Y_X, Tr_34_34_34)]) + number=230, + num_sym_equiv=96, + num_primitive_sym_equiv=48, + short_name="Ia-3d", + point_group_name="PGm3barm", + crystal_system="CUBIC", + pdb_name="I 41/a -3 2/d", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Z_mX_mY, Tr_12_12_0), + SymOp(Rot_mZ_mX_Y, Tr_12_0_12), + SymOp(Rot_mZ_X_mY, Tr_0_12_12), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_12), + SymOp(Rot_Y_mZ_mX, Tr_12_12_0), + SymOp(Rot_mY_mZ_X, Tr_12_0_12), + SymOp(Rot_Y_X_mZ, Tr_34_14_14), + SymOp(Rot_mY_mX_mZ, Tr_34_34_34), + SymOp(Rot_Y_mX_Z, Tr_14_14_34), + SymOp(Rot_mY_X_Z, Tr_14_34_14), + SymOp(Rot_X_Z_mY, Tr_34_14_14), + SymOp(Rot_mX_Z_Y, Tr_14_34_14), + SymOp(Rot_mX_mZ_mY, Tr_34_34_34), + SymOp(Rot_X_mZ_Y, Tr_14_14_34), + SymOp(Rot_Z_Y_mX, Tr_34_14_14), + SymOp(Rot_Z_mY_X, Tr_14_14_34), + SymOp(Rot_mZ_Y_X, Tr_14_34_14), + SymOp(Rot_mZ_mY_mX, Tr_34_34_34), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_Z, Tr_0_12_12), + SymOp(Rot_mX_Y_Z, Tr_12_12_0), + SymOp(Rot_mZ_mX_mY, Tr_0_0_0), + SymOp(Rot_mZ_X_Y, Tr_12_12_0), + SymOp(Rot_Z_X_mY, Tr_12_0_12), + SymOp(Rot_Z_mX_Y, Tr_0_12_12), + SymOp(Rot_mY_mZ_mX, Tr_0_0_0), + SymOp(Rot_Y_mZ_X, Tr_0_12_12), + SymOp(Rot_mY_Z_X, Tr_12_12_0), + SymOp(Rot_Y_Z_mX, Tr_12_0_12), + SymOp(Rot_mY_mX_Z, Tr_14_34_34), + SymOp(Rot_Y_X_Z, Tr_14_14_14), + SymOp(Rot_mY_X_mZ, Tr_34_34_14), + SymOp(Rot_Y_mX_mZ, Tr_34_14_34), + SymOp(Rot_mX_mZ_Y, Tr_14_34_34), + SymOp(Rot_X_mZ_mY, Tr_34_14_34), + SymOp(Rot_X_Z_Y, Tr_14_14_14), + SymOp(Rot_mX_Z_mY, Tr_34_34_14), + SymOp(Rot_mZ_mY_X, Tr_14_34_34), + SymOp(Rot_mZ_Y_mX, Tr_34_34_14), + SymOp(Rot_Z_mY_mX, Tr_34_14_34), + SymOp(Rot_Z_Y_X, Tr_14_14_14), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_Z_mX_mY, Tr_0_0_12), + SymOp(Rot_mZ_mX_Y, Tr_0_12_0), + SymOp(Rot_mZ_X_mY, Tr_12_0_0), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_0), + SymOp(Rot_Y_mZ_mX, Tr_0_0_12), + SymOp(Rot_mY_mZ_X, Tr_0_12_0), + SymOp(Rot_Y_X_mZ, Tr_14_34_34), + SymOp(Rot_mY_mX_mZ, Tr_14_14_14), + SymOp(Rot_Y_mX_Z, Tr_34_34_14), + SymOp(Rot_mY_X_Z, Tr_34_14_34), + SymOp(Rot_X_Z_mY, Tr_14_34_34), + SymOp(Rot_mX_Z_Y, Tr_34_14_34), + SymOp(Rot_mX_mZ_mY, Tr_14_14_14), + SymOp(Rot_X_mZ_Y, Tr_34_34_14), + SymOp(Rot_Z_Y_mX, Tr_14_34_34), + SymOp(Rot_Z_mY_X, Tr_34_34_14), + SymOp(Rot_mZ_Y_X, Tr_34_14_34), + SymOp(Rot_mZ_mY_mX, Tr_14_14_14), + SymOp(Rot_mX_mY_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_Z, Tr_12_0_0), + SymOp(Rot_mX_Y_Z, Tr_0_0_12), + SymOp(Rot_mZ_mX_mY, Tr_12_12_12), + SymOp(Rot_mZ_X_Y, Tr_0_0_12), + SymOp(Rot_Z_X_mY, Tr_0_12_0), + SymOp(Rot_Z_mX_Y, Tr_12_0_0), + SymOp(Rot_mY_mZ_mX, Tr_12_12_12), + SymOp(Rot_Y_mZ_X, Tr_12_0_0), + SymOp(Rot_mY_Z_X, Tr_0_0_12), + SymOp(Rot_Y_Z_mX, Tr_0_12_0), + SymOp(Rot_mY_mX_Z, Tr_34_14_14), + SymOp(Rot_Y_X_Z, Tr_34_34_34), + SymOp(Rot_mY_X_mZ, Tr_14_14_34), + SymOp(Rot_Y_mX_mZ, Tr_14_34_14), + SymOp(Rot_mX_mZ_Y, Tr_34_14_14), + SymOp(Rot_X_mZ_mY, Tr_14_34_14), + SymOp(Rot_X_Z_Y, Tr_34_34_34), + SymOp(Rot_mX_Z_mY, Tr_14_14_34), + SymOp(Rot_mZ_mY_X, Tr_34_14_14), + SymOp(Rot_mZ_Y_mX, Tr_14_14_34), + SymOp(Rot_Z_mY_mX, Tr_14_34_14), + SymOp(Rot_Z_Y_X, Tr_34_34_34), + ], +) sg1003 = SpaceGroup( - number = 1003, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P2", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0)]) + number=1003, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P2", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 2", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0)], +) sg1004 = SpaceGroup( - number = 1004, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P1121", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12)]) + number=1004, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P1121", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 21", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_12)], +) sg3004 = SpaceGroup( - number = 3004, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "I21", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "I 1 21 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12)]) + number=3004, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="I21", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="I 1 21 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + ], +) sg1005 = SpaceGroup( - number = 1005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "B2", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "B 1 1 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12)]) + number=1005, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="B2", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + ], +) sg2005 = SpaceGroup( - number = 2005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "A2", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "A 2 1 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12)]) + number=2005, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="A2", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="A 2 1 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + ], +) sg3005 = SpaceGroup( - number = 3005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "C21", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "C 1 21 1", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0)]) + number=3005, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="C21", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="C 1 21 1", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + ], +) sg1006 = SpaceGroup( - number = 1006, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P11m", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0)]) + number=1006, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P11m", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 m", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0)], +) sg1007 = SpaceGroup( - number = 1007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = "P11b", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 b", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0)]) + number=1007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P11b", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 b", + symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0)], +) sg1008 = SpaceGroup( - number = 1008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "B11m", - point_group_name = "PG2", - crystal_system = "MONOCLINIC", - pdb_name = "B 1 1 m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12)]) + number=1008, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="B11m", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + ], +) sg1009 = SpaceGroup( - number = 1009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 2, - short_name = "B11b", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "B 1 1 b", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12)]) + number=1009, + num_sym_equiv=4, + num_primitive_sym_equiv=2, + short_name="B11b", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 b", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + ], +) sg1010 = SpaceGroup( - number = 1010, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P112/m", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0)]) + number=1010, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P112/m", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + ], +) sg1011 = SpaceGroup( - number = 1011, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P1121/m", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 21/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_12)]) + number=1011, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P1121/m", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 21/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_12), + ], +) sg1012 = SpaceGroup( - number = 1012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "B112/m", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "B 1 1 2/m", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12)]) + number=1012, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="B112/m", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 2/m", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + ], +) sg1013 = SpaceGroup( - number = 1013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P112/b", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 2/b", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0)]) + number=1013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P112/b", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 2/b", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + ], +) sg1014 = SpaceGroup( - number = 1014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P1121/b", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "P 1 1 21/b", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_Y_mZ, Tr_0_12_12)]) + number=1014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P1121/b", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 21/b", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_Y_mZ, Tr_0_12_12), + ], +) sg1015 = SpaceGroup( - number = 1015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "B112/b", - point_group_name = "PG2C", - crystal_system = "MONOCLINIC", - pdb_name = "B 1 1 2/b", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_mZ, Tr_12_0_12), - SymOp(Rot_X_Y_mZ, Tr_12_12_12)]) + number=1015, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="B112/b", + point_group_name="PG2C", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 2/b", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_mZ, Tr_12_0_12), + SymOp(Rot_X_Y_mZ, Tr_12_12_12), + ], +) sg1017 = SpaceGroup( - number = 1017, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P2122", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21 2 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_0)]) + number=1017, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2122", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 2 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_0), + ], +) sg2017 = SpaceGroup( - number = 2017, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P2212", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2 21 2", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0)]) + number=2017, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2212", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 21 2", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + ], +) sg1018 = SpaceGroup( - number = 1018, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P21212a", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21 21 2 (a)", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0)]) + number=1018, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21212a", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 21 2 (a)", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + ], +) sg2018 = SpaceGroup( - number = 2018, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P21221", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21 2 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12)]) + number=2018, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21221", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 2 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + ], +) sg3018 = SpaceGroup( - number = 3018, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = "P22121", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 2 21 21", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12)]) + number=3018, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P22121", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 21 21", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + ], +) sg1020 = SpaceGroup( - number = 1020, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C2221a", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2 2 21a)", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12)]) + number=1020, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C2221a", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 2 21a)", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + ], +) sg1021 = SpaceGroup( - number = 1021, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "C222a", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "C 2 2 2a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0)]) + number=1021, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="C222a", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 2 2a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + ], +) sg1022 = SpaceGroup( - number = 1022, - num_sym_equiv = 16, - num_primitive_sym_equiv = 4, - short_name = "F222a", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "F 2 2 2a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_0_12_12), - SymOp(Rot_mX_mY_Z, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_12_12_12), - SymOp(Rot_mX_Y_mZ, Tr_0_0_12), - SymOp(Rot_X_Y_Z, Tr_12_0_12), - SymOp(Rot_mX_mY_Z, Tr_0_12_12), - SymOp(Rot_X_mY_mZ, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - SymOp(Rot_X_Y_Z, Tr_12_12_0), - SymOp(Rot_mX_mY_Z, Tr_0_0_0), - SymOp(Rot_X_mY_mZ, Tr_0_12_0), - SymOp(Rot_mX_Y_mZ, Tr_12_0_0)]) + number=1022, + num_sym_equiv=16, + num_primitive_sym_equiv=4, + short_name="F222a", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2 2 2a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_0_12_12), + SymOp(Rot_mX_mY_Z, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_12_12_12), + SymOp(Rot_mX_Y_mZ, Tr_0_0_12), + SymOp(Rot_X_Y_Z, Tr_12_0_12), + SymOp(Rot_mX_mY_Z, Tr_0_12_12), + SymOp(Rot_X_mY_mZ, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_12_12), + SymOp(Rot_X_Y_Z, Tr_12_12_0), + SymOp(Rot_mX_mY_Z, Tr_0_0_0), + SymOp(Rot_X_mY_mZ, Tr_0_12_0), + SymOp(Rot_mX_Y_mZ, Tr_12_0_0), + ], +) sg1023 = SpaceGroup( - number = 1023, - num_sym_equiv = 8, - num_primitive_sym_equiv = 4, - short_name = "I222a", - point_group_name = "PG222", - crystal_system = "ORTHORHOMBIC", - pdb_name = "I 2 2 2a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12)]) + number=1023, + num_sym_equiv=8, + num_primitive_sym_equiv=4, + short_name="I222a", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 2 2a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + ], +) sg1059 = SpaceGroup( - number = 1059, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "Pmmn2", - point_group_name = "PGmmm", - crystal_system = "ORTHORHOMBIC", - pdb_name = "P 21/m 21/m 2/n", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_mY_mZ, Tr_0_0_0), - SymOp(Rot_X_Y_mZ, Tr_12_12_0), - SymOp(Rot_X_mY_Z, Tr_0_12_0), - SymOp(Rot_mX_Y_Z, Tr_12_0_0)]) + number=1059, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmmn2", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21/m 21/m 2/n", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_mY_mZ, Tr_0_0_0), + SymOp(Rot_X_Y_mZ, Tr_12_12_0), + SymOp(Rot_X_mY_Z, Tr_0_12_0), + SymOp(Rot_mX_Y_Z, Tr_12_0_0), + ], +) sg1094 = SpaceGroup( - number = 1094, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = "P42212a", - point_group_name = "PG422", - crystal_system = "TETRAGONAL", - pdb_name = "P 42 21 2a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_mY_X_Z, Tr_0_12_12), - SymOp(Rot_Y_mX_Z, Tr_12_0_12), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_Y_X_mZ, Tr_0_0_12), - SymOp(Rot_mY_mX_mZ, Tr_12_12_12)]) + number=1094, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="P42212a", + point_group_name="PG422", + crystal_system="TETRAGONAL", + pdb_name="P 42 21 2a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_mY_X_Z, Tr_0_12_12), + SymOp(Rot_Y_mX_Z, Tr_12_0_12), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_Y_X_mZ, Tr_0_0_12), + SymOp(Rot_mY_mX_mZ, Tr_12_12_12), + ], +) sg1197 = SpaceGroup( - number = 1197, - num_sym_equiv = 24, - num_primitive_sym_equiv = 12, - short_name = "I23a", - point_group_name = "PG23", - crystal_system = "CUBIC", - pdb_name = "I 2 3a", - symop_list = [ - SymOp(Rot_X_Y_Z, Tr_0_0_0), - SymOp(Rot_mX_mY_Z, Tr_12_12_0), - SymOp(Rot_X_mY_mZ, Tr_12_0_0), - SymOp(Rot_mX_Y_mZ, Tr_0_12_0), - SymOp(Rot_Y_Z_X, Tr_0_0_0), - SymOp(Rot_mY_mZ_X, Tr_12_12_0), - SymOp(Rot_Y_mZ_mX, Tr_12_0_0), - SymOp(Rot_mY_Z_mX, Tr_0_12_0), - SymOp(Rot_Z_X_Y, Tr_0_0_0), - SymOp(Rot_mZ_mX_Y, Tr_12_12_0), - SymOp(Rot_Z_mX_mY, Tr_12_0_0), - SymOp(Rot_mZ_X_mY, Tr_0_12_0), - SymOp(Rot_X_Y_Z, Tr_12_12_12), - SymOp(Rot_mX_mY_Z, Tr_0_0_12), - SymOp(Rot_X_mY_mZ, Tr_0_12_12), - SymOp(Rot_mX_Y_mZ, Tr_12_0_12), - SymOp(Rot_Y_Z_X, Tr_12_12_12), - SymOp(Rot_mY_mZ_X, Tr_0_0_12), - SymOp(Rot_Y_mZ_mX, Tr_0_12_12), - SymOp(Rot_mY_Z_mX, Tr_12_0_12), - SymOp(Rot_Z_X_Y, Tr_12_12_12), - SymOp(Rot_mZ_mX_Y, Tr_0_0_12), - SymOp(Rot_Z_mX_mY, Tr_0_12_12), - SymOp(Rot_mZ_X_mY, Tr_12_0_12)]) + number=1197, + num_sym_equiv=24, + num_primitive_sym_equiv=12, + short_name="I23a", + point_group_name="PG23", + crystal_system="CUBIC", + pdb_name="I 2 3a", + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mX_mY_Z, Tr_12_12_0), + SymOp(Rot_X_mY_mZ, Tr_12_0_0), + SymOp(Rot_mX_Y_mZ, Tr_0_12_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + SymOp(Rot_mY_mZ_X, Tr_12_12_0), + SymOp(Rot_Y_mZ_mX, Tr_12_0_0), + SymOp(Rot_mY_Z_mX, Tr_0_12_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_mZ_mX_Y, Tr_12_12_0), + SymOp(Rot_Z_mX_mY, Tr_12_0_0), + SymOp(Rot_mZ_X_mY, Tr_0_12_0), + SymOp(Rot_X_Y_Z, Tr_12_12_12), + SymOp(Rot_mX_mY_Z, Tr_0_0_12), + SymOp(Rot_X_mY_mZ, Tr_0_12_12), + SymOp(Rot_mX_Y_mZ, Tr_12_0_12), + SymOp(Rot_Y_Z_X, Tr_12_12_12), + SymOp(Rot_mY_mZ_X, Tr_0_0_12), + SymOp(Rot_Y_mZ_mX, Tr_0_12_12), + SymOp(Rot_mY_Z_mX, Tr_12_0_12), + SymOp(Rot_Z_X_Y, Tr_12_12_12), + SymOp(Rot_mZ_mX_Y, Tr_0_0_12), + SymOp(Rot_Z_mX_mY, Tr_0_12_12), + SymOp(Rot_mZ_X_mY, Tr_12_0_12), + ], +) ## list of the space groups @@ -7592,4 +8150,5 @@ sg1023, sg1059, sg1094, - sg1197] + sg1197, +] diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 00b0479b..142a31ca 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -32,8 +32,8 @@ """ from diffpy.structure import StructureFormatError -from diffpy.structure.parsers.structureparser import StructureParser from diffpy.structure.parsers.parser_index_mod import parser_index +from diffpy.structure.parsers.structureparser import StructureParser # silence pyflakes checker assert StructureParser @@ -49,24 +49,22 @@ def getParser(format, **kw): if format not in parser_index: emsg = "no parser for '%s' format" % format raise StructureFormatError(emsg) - pmod = parser_index[format]['module'] + pmod = parser_index[format]["module"] ns = {} - import_cmd = 'from diffpy.structure.parsers import %s as pm' % pmod + import_cmd = "from diffpy.structure.parsers import %s as pm" % pmod exec(import_cmd, ns) - return ns['pm'].getParser(**kw) + return ns["pm"].getParser(**kw) def inputFormats(): """Return list of implemented input structure formats""" - input_formats = [ fmt for fmt, prop in parser_index.items() - if prop['has_input'] ] + input_formats = [fmt for fmt, prop in parser_index.items() if prop["has_input"]] input_formats.sort() return input_formats def outputFormats(): """return list of implemented output structure formats""" - output_formats = [ fmt for fmt, prop in parser_index.items() - if prop['has_output'] ] + output_formats = [fmt for fmt, prop in parser_index.items() if prop["has_output"]] output_formats.sort() return output_formats diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 523cbf66..2142666b 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -21,8 +21,8 @@ import os from diffpy.structure import StructureFormatError -from diffpy.structure.parsers import StructureParser -from diffpy.structure.parsers import parser_index +from diffpy.structure.parsers import StructureParser, parser_index + class P_auto(StructureParser): """Parser with automatic detection of structure format. @@ -42,22 +42,25 @@ def _getOrderedFormats(self): This only works when self.filename has a known extension. """ from diffpy.structure.parsers import inputFormats - ofmts = [fmt for fmt in inputFormats() if fmt != 'auto'] - if not self.filename: return ofmts + + ofmts = [fmt for fmt in inputFormats() if fmt != "auto"] + if not self.filename: + return ofmts # filename is defined here filebase = os.path.basename(self.filename) from fnmatch import fnmatch + # loop over copy of ofmts for fmt in list(ofmts): - pattern = parser_index[fmt]['file_pattern'] - if pattern in ('*.*', '*'): continue - anymatch = [1 for p in pattern.split('|') if fnmatch(filebase, p)] + pattern = parser_index[fmt]["file_pattern"] + if pattern in ("*.*", "*"): + continue + anymatch = [1 for p in pattern.split("|") if fnmatch(filebase, p)] if anymatch: ofmts.remove(fmt) ofmts.insert(0, fmt) return ofmts - def parseLines(self, lines): """Detect format and create Structure instance from a list of lines. Set format attribute to the detected file format. @@ -66,29 +69,26 @@ def parseLines(self, lines): """ return self._wrapParseMethod("parseLines", lines) - def parse(self, s): """Detect format and create Structure instance from a string. Set format attribute to the detected file format. Return Structure object or raise StructureFormatError exception. """ - return self._wrapParseMethod('parse', s) - + return self._wrapParseMethod("parse", s) def parseFile(self, filename): - '''Detect format and create Structure instance from an existing file. + """Detect format and create Structure instance from an existing file. Set format attribute to the detected file format. filename -- path to structure file Return Structure object. Raise StructureFormatError or IOError. - ''' + """ self.filename = filename return self._wrapParseMethod("parseFile", filename) - def _wrapParseMethod(self, method, *args, **kwargs): """A helper evaluator method. Try the specified parse method with each registered structure parser and return the first successful @@ -99,6 +99,7 @@ def _wrapParseMethod(self, method, *args, **kwargs): Return Structure instance, or raise StructureFormatError. """ from diffpy.structure.parsers import getParser + ofmts = self._getOrderedFormats() stru = None # try all parsers in sequence @@ -115,16 +116,19 @@ def _wrapParseMethod(self, method, *args, **kwargs): except NotImplementedError: pass if stru is None: - emsg = "\n".join([ - "Unknown or invalid structure format.", - "Errors per each tested structure format:"] + parsers_emsgs) + emsg = "\n".join( + ["Unknown or invalid structure format.", "Errors per each tested structure format:"] + + parsers_emsgs + ) raise StructureFormatError(emsg) self.__dict__.update(p.__dict__) return stru + # End of class P_auto # Routines ------------------------------------------------------------------- + def getParser(**kw): return P_auto(**kw) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index f0d2bc08..fe87865c 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -18,18 +18,19 @@ http://www.iucr.org/iucr-top/cif/home.html """ -import sys import re +import sys from contextlib import contextmanager + import numpy import six -from diffpy.structure import Structure, Lattice, Atom -from diffpy.structure import StructureFormatError +from diffpy.structure import Atom, Lattice, Structure, StructureFormatError from diffpy.structure.parsers import StructureParser # ---------------------------------------------------------------------------- + class P_cif(StructureParser): """Simple parser for CIF structure format. Reads Structure from the first block containing _atom_site_label key. @@ -64,42 +65,46 @@ class P_cif(StructureParser): # dictionary set of class methods for translating CIF values # to Atom attributes - _atom_setters = dict.fromkeys(( - '_tr_ignore', - '_tr_atom_site_label', - '_tr_atom_site_type_symbol', - '_tr_atom_site_fract_x', - '_tr_atom_site_fract_y', - '_tr_atom_site_fract_z', - '_tr_atom_site_cartn_x', - '_tr_atom_site_cartn_y', - '_tr_atom_site_cartn_z', - '_tr_atom_site_U_iso_or_equiv', - '_tr_atom_site_B_iso_or_equiv', - '_tr_atom_site_adp_type', '_tr_atom_site_thermal_displace_type', - '_tr_atom_site_occupancy', - '_tr_atom_site_aniso_U_11', - '_tr_atom_site_aniso_U_22', - '_tr_atom_site_aniso_U_33', - '_tr_atom_site_aniso_U_12', - '_tr_atom_site_aniso_U_13', - '_tr_atom_site_aniso_U_23', - '_tr_atom_site_aniso_B_11', - '_tr_atom_site_aniso_B_22', - '_tr_atom_site_aniso_B_33', - '_tr_atom_site_aniso_B_12', - '_tr_atom_site_aniso_B_13', - '_tr_atom_site_aniso_B_23', - )) + _atom_setters = dict.fromkeys( + ( + "_tr_ignore", + "_tr_atom_site_label", + "_tr_atom_site_type_symbol", + "_tr_atom_site_fract_x", + "_tr_atom_site_fract_y", + "_tr_atom_site_fract_z", + "_tr_atom_site_cartn_x", + "_tr_atom_site_cartn_y", + "_tr_atom_site_cartn_z", + "_tr_atom_site_U_iso_or_equiv", + "_tr_atom_site_B_iso_or_equiv", + "_tr_atom_site_adp_type", + "_tr_atom_site_thermal_displace_type", + "_tr_atom_site_occupancy", + "_tr_atom_site_aniso_U_11", + "_tr_atom_site_aniso_U_22", + "_tr_atom_site_aniso_U_33", + "_tr_atom_site_aniso_U_12", + "_tr_atom_site_aniso_U_13", + "_tr_atom_site_aniso_U_23", + "_tr_atom_site_aniso_B_11", + "_tr_atom_site_aniso_B_22", + "_tr_atom_site_aniso_B_33", + "_tr_atom_site_aniso_B_12", + "_tr_atom_site_aniso_B_13", + "_tr_atom_site_aniso_B_23", + ) + ) # make _atom_setters case insensitive for k in list(_atom_setters.keys()): _atom_setters[k] = _atom_setters[k.lower()] = k del k - BtoU = 1.0/(8 * numpy.pi**2) + BtoU = 1.0 / (8 * numpy.pi**2) def _tr_ignore(a, value): return + _tr_ignore = staticmethod(_tr_ignore) def _tr_atom_site_label(a, value): @@ -107,107 +112,130 @@ def _tr_atom_site_label(a, value): # set element when not specified by _atom_site_type_symbol if not a.element: P_cif._tr_atom_site_type_symbol(a, value) + _tr_atom_site_label = staticmethod(_tr_atom_site_label) # 3 regexp groups for nucleon number, atom symbol, and oxidation state - _psymb = re.compile(r'(\d+-)?([a-zA-Z]+)(\d[+-])?') + _psymb = re.compile(r"(\d+-)?([a-zA-Z]+)(\d[+-])?") def _tr_atom_site_type_symbol(a, value): rx = P_cif._psymb.match(value) smbl = rx and rx.group(0) or value smbl = str(smbl) a.element = smbl[:1].upper() + smbl[1:].lower() + _tr_atom_site_type_symbol = staticmethod(_tr_atom_site_type_symbol) def _tr_atom_site_fract_x(a, value): a.xyz[0] = leading_float(value) + _tr_atom_site_fract_x = staticmethod(_tr_atom_site_fract_x) def _tr_atom_site_fract_y(a, value): a.xyz[1] = leading_float(value) + _tr_atom_site_fract_y = staticmethod(_tr_atom_site_fract_y) def _tr_atom_site_fract_z(a, value): a.xyz[2] = leading_float(value) + _tr_atom_site_fract_z = staticmethod(_tr_atom_site_fract_z) def _tr_atom_site_cartn_x(a, value): a.xyz_cartn[0] = leading_float(value) + _tr_atom_site_cartn_x = staticmethod(_tr_atom_site_cartn_x) def _tr_atom_site_cartn_y(a, value): a.xyz_cartn[1] = leading_float(value) + _tr_atom_site_cartn_y = staticmethod(_tr_atom_site_cartn_y) def _tr_atom_site_cartn_z(a, value): a.xyz_cartn[2] = leading_float(value) + _tr_atom_site_cartn_z = staticmethod(_tr_atom_site_cartn_z) def _tr_atom_site_U_iso_or_equiv(a, value): a.Uisoequiv = leading_float(value) + _tr_atom_site_U_iso_or_equiv = staticmethod(_tr_atom_site_U_iso_or_equiv) def _tr_atom_site_B_iso_or_equiv(a, value): a.Uisoequiv = P_cif.BtoU * leading_float(value) + _tr_atom_site_B_iso_or_equiv = staticmethod(_tr_atom_site_B_iso_or_equiv) def _tr_atom_site_adp_type(a, value): a.anisotropy = value not in ("Uiso", "Biso") + _tr_atom_site_adp_type = staticmethod(_tr_atom_site_adp_type) _tr_atom_site_thermal_displace_type = _tr_atom_site_adp_type def _tr_atom_site_occupancy(a, value): a.occupancy = leading_float(value, 1.0) + _tr_atom_site_occupancy = staticmethod(_tr_atom_site_occupancy) def _tr_atom_site_aniso_U_11(a, value): a.U11 = leading_float(value) + _tr_atom_site_aniso_U_11 = staticmethod(_tr_atom_site_aniso_U_11) def _tr_atom_site_aniso_U_22(a, value): a.U22 = leading_float(value) + _tr_atom_site_aniso_U_22 = staticmethod(_tr_atom_site_aniso_U_22) def _tr_atom_site_aniso_U_33(a, value): a.U33 = leading_float(value) + _tr_atom_site_aniso_U_33 = staticmethod(_tr_atom_site_aniso_U_33) def _tr_atom_site_aniso_U_12(a, value): a.U12 = leading_float(value) + _tr_atom_site_aniso_U_12 = staticmethod(_tr_atom_site_aniso_U_12) def _tr_atom_site_aniso_U_13(a, value): a.U13 = leading_float(value) + _tr_atom_site_aniso_U_13 = staticmethod(_tr_atom_site_aniso_U_13) def _tr_atom_site_aniso_U_23(a, value): a.U23 = leading_float(value) + _tr_atom_site_aniso_U_23 = staticmethod(_tr_atom_site_aniso_U_23) def _tr_atom_site_aniso_B_11(a, value): a.U11 = P_cif.BtoU * leading_float(value) + _tr_atom_site_aniso_B_11 = staticmethod(_tr_atom_site_aniso_B_11) def _tr_atom_site_aniso_B_22(a, value): a.U22 = P_cif.BtoU * leading_float(value) + _tr_atom_site_aniso_B_22 = staticmethod(_tr_atom_site_aniso_B_22) def _tr_atom_site_aniso_B_33(a, value): a.U33 = P_cif.BtoU * leading_float(value) + _tr_atom_site_aniso_B_33 = staticmethod(_tr_atom_site_aniso_B_33) def _tr_atom_site_aniso_B_12(a, value): a.U12 = P_cif.BtoU * leading_float(value) + _tr_atom_site_aniso_B_12 = staticmethod(_tr_atom_site_aniso_B_12) def _tr_atom_site_aniso_B_13(a, value): a.U13 = P_cif.BtoU * leading_float(value) + _tr_atom_site_aniso_B_13 = staticmethod(_tr_atom_site_aniso_B_13) def _tr_atom_site_aniso_B_23(a, value): a.U23 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_23 = staticmethod(_tr_atom_site_aniso_B_23) + _tr_atom_site_aniso_B_23 = staticmethod(_tr_atom_site_aniso_B_23) def _get_atom_setters(cifloop): """Find translators of CifLoop items to data in Atom instance. @@ -220,10 +248,11 @@ def _get_atom_setters(cifloop): rv = [] for p in cifloop.keys(): lcname = "_tr" + p.lower() - fncname = P_cif._atom_setters.get(lcname, '_tr_ignore') + fncname = P_cif._atom_setters.get(lcname, "_tr_ignore") f = getattr(P_cif, fncname) rv.append(f) return rv + _get_atom_setters = staticmethod(_get_atom_setters) # normal methods --------------------------------------------------------- @@ -247,19 +276,17 @@ def __init__(self, eps=None): self.cif_sgname = None pass - def parse(self, s): """Create Structure instance from a string in CIF format. Return Structure instance or raise StructureFormatError. """ self.ciffile = None - self.filename = '' + self.filename = "" fp = six.StringIO(s) rv = self._parseCifDataSource(fp) return rv - def parseLines(self, lines): """Parse list of lines in CIF format. @@ -267,10 +294,9 @@ def parseLines(self, lines): Return Structure instance or raise StructureFormatError. """ - s = "\n".join(lines) + '\n' + s = "\n".join(lines) + "\n" return self.parse(s) - def parseFile(self, filename): """Create Structure from an existing CIF file. @@ -285,7 +311,6 @@ def parseFile(self, filename): # all good here return rv - def _parseCifDataSource(self, datasource): """\ Open and process CIF data from the specified `datasource`. @@ -308,12 +333,13 @@ def _parseCifDataSource(self, datasource): When the data do not constitute a valid CIF format. """ from CifFile import CifFile, StarError + self.stru = None try: with _suppressCifParserOutput(): # Use `grammar` option to digest values with curly-brackets. # Ref: https://bitbucket.org/jamesrhester/pycifrw/issues/19 - self.ciffile = CifFile(datasource, grammar='auto') + self.ciffile = CifFile(datasource, grammar="auto") for blockname in self.ciffile.keys(): self._parseCifBlock(blockname) # stop after reading the first structure @@ -326,7 +352,6 @@ def _parseCifDataSource(self, datasource): six.reraise(StructureFormatError, e, exc_traceback) return self.stru - def _parseCifBlock(self, blockname): """Translate CIF file block, skip blocks without _atom_site_label. Updates data members stru, eau. @@ -336,7 +361,8 @@ def _parseCifBlock(self, blockname): No return value. """ block = self.ciffile[blockname] - if '_atom_site_label' not in block: return + if "_atom_site_label" not in block: + return # here block contains structure, initialize output data self.stru = Structure() self.labelindex.clear() @@ -348,7 +374,6 @@ def _parseCifBlock(self, blockname): self._parse_space_group_symop_operation_xyz(block) return - def _parse_lattice(self, block): """Obtain lattice parameters from a CifBlock. This method updates self.stru.lattice. @@ -357,16 +382,17 @@ def _parse_lattice(self, block): No return value. """ - if '_cell_length_a' not in block: return + if "_cell_length_a" not in block: + return # obtain lattice parameters try: latpars = ( - leading_float(block['_cell_length_a']), - leading_float(block['_cell_length_b']), - leading_float(block['_cell_length_c']), - leading_float(block['_cell_angle_alpha']), - leading_float(block['_cell_angle_beta']), - leading_float(block['_cell_angle_gamma']), + leading_float(block["_cell_length_a"]), + leading_float(block["_cell_length_b"]), + leading_float(block["_cell_length_c"]), + leading_float(block["_cell_angle_alpha"]), + leading_float(block["_cell_angle_beta"]), + leading_float(block["_cell_angle_gamma"]), ) except KeyError as err: exc_type, exc_value, exc_traceback = sys.exc_info() @@ -376,7 +402,6 @@ def _parse_lattice(self, block): self.stru.lattice = Lattice(*latpars) return - def _parse_atom_site_label(self, block): """Obtain atoms in asymmetric unit from a CifBlock. This method inserts Atom instances to self.stru and @@ -387,19 +412,20 @@ def _parse_atom_site_label(self, block): No return value. """ # process _atom_site_label - atom_site_loop = block.GetLoop('_atom_site_label') - does_adp_type = ('_atom_site_adp_type' in atom_site_loop or - '_atom_site_thermal_displace_type' in atom_site_loop) + atom_site_loop = block.GetLoop("_atom_site_label") + does_adp_type = ( + "_atom_site_adp_type" in atom_site_loop or "_atom_site_thermal_displace_type" in atom_site_loop + ) # get a list of setters for atom_site values prop_setters = P_cif._get_atom_setters(atom_site_loop) # index of the _atom_site_label item for the labelindex dictionary - ilb = atom_site_loop.keys().index('_atom_site_label') + ilb = atom_site_loop.keys().index("_atom_site_label") # loop through the values and pass them to the setters sitedatalist = zip(*atom_site_loop.values()) for values in sitedatalist: curlabel = values[ilb] # skip entries that have invalid label - if curlabel == '?': + if curlabel == "?": continue self.labelindex[curlabel] = len(self.stru) self.stru.addNewAtom() @@ -410,7 +436,6 @@ def _parse_atom_site_label(self, block): self.anisotropy[curlabel] = a.anisotropy return - def _parse_atom_site_aniso_label(self, block): """Obtain value of anisotropic thermal displacements from a CifBlock. This method updates U members of Atom instances in self.stru. @@ -420,17 +445,18 @@ def _parse_atom_site_aniso_label(self, block): No return value. """ - if '_atom_site_aniso_label' not in block: return + if "_atom_site_aniso_label" not in block: + return # something to do here: - adp_loop = block.GetLoop('_atom_site_aniso_label') + adp_loop = block.GetLoop("_atom_site_aniso_label") # index of the _atom_site_label column - ilb = adp_loop.keys().index('_atom_site_aniso_label') + ilb = adp_loop.keys().index("_atom_site_aniso_label") # get a list of setters for this loop prop_setters = P_cif._get_atom_setters(adp_loop) sitedatalist = zip(*adp_loop.values()) for values in sitedatalist: lb = values[ilb] - if lb == '?': + if lb == "?": break idx = self.labelindex[lb] a = self.stru[idx] @@ -441,7 +467,6 @@ def _parse_atom_site_aniso_label(self, block): fset(a, val) return - def _parse_space_group_symop_operation_xyz(self, block): """Process symmetry operations from a CifBlock. The method updates spacegroup and eau data according to symmetry @@ -452,12 +477,10 @@ def _parse_space_group_symop_operation_xyz(self, block): No return value. """ - from diffpy.structure.spacegroups import IsSpaceGroupIdentifier - from diffpy.structure.spacegroups import SpaceGroup, GetSpaceGroup - from diffpy.structure.spacegroups import FindSpaceGroup + from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, IsSpaceGroupIdentifier, SpaceGroup + self.asymmetric_unit = list(self.stru) - sym_synonyms = ('_space_group_symop_operation_xyz', - '_symmetry_equiv_pos_as_xyz') + sym_synonyms = ("_space_group_symop_operation_xyz", "_symmetry_equiv_pos_as_xyz") sym_loop_name = [n for n in sym_synonyms if n in block] # recover explicit list of symmetry operations symop_list = [] @@ -469,15 +492,14 @@ def _parse_space_group_symop_operation_xyz(self, block): opcif = getSymOp(eqxyz) symop_list.append(opcif) # determine space group number - sg_nameHall = (block.get('_space_group_name_Hall', '') or - block.get('_symmetry_space_group_name_Hall', '')) - sg_nameHM = (block.get('_space_group_name_H-M_alt', '') or - block.get('_space_group_name_H-M_ref', '') or - block.get('_symmetry_space_group_name_H-M', '')) - self.cif_sgname = (sg_nameHall or sg_nameHM or None) - sgid = (block.get('_space_group_IT_number', '') or - block.get('_symmetry_Int_Tables_number', '') or - sg_nameHM) + sg_nameHall = block.get("_space_group_name_Hall", "") or block.get("_symmetry_space_group_name_Hall", "") + sg_nameHM = ( + block.get("_space_group_name_H-M_alt", "") + or block.get("_space_group_name_H-M_ref", "") + or block.get("_symmetry_space_group_name_H-M", "") + ) + self.cif_sgname = sg_nameHall or sg_nameHM or None + sgid = block.get("_space_group_IT_number", "") or block.get("_symmetry_Int_Tables_number", "") or sg_nameHM self.spacegroup = None # try to reuse existing space group from symmetry operations if symop_list: @@ -491,22 +513,19 @@ def _parse_space_group_symop_operation_xyz(self, block): # define new spacegroup when symmetry operations were listed, but # there is no match to an existing definition if symop_list and self.spacegroup is None: - new_short_name = "CIF " + (sg_nameHall or 'data') + new_short_name = "CIF " + (sg_nameHall or "data") new_crystal_system = ( - block.get('_space_group_crystal_system') or - block.get('_symmetry_cell_setting') or - 'TRICLINIC' ).upper() + block.get("_space_group_crystal_system") or block.get("_symmetry_cell_setting") or "TRICLINIC" + ).upper() self.spacegroup = SpaceGroup( - short_name=new_short_name, - crystal_system=new_crystal_system, - symop_list=symop_list) + short_name=new_short_name, crystal_system=new_crystal_system, symop_list=symop_list + ) if self.spacegroup is None: emsg = "CIF file has unknown space group identifier {!r}." raise StructureFormatError(emsg.format(sgid)) self._expandAsymmetricUnit(block) return - def _expandAsymmetricUnit(self, block): """Perform symmetry expansion of self.stru using self.spacegroup. @@ -518,10 +537,10 @@ def _expandAsymmetricUnit(self, block): The top-level block containing crystal structure data. """ from diffpy.structure.symmetryutilities import ExpandAsymmetricUnit + corepos = [a.xyz for a in self.stru] coreUijs = [a.U for a in self.stru] - self.eau = ExpandAsymmetricUnit(self.spacegroup, corepos, coreUijs, - eps=self.eps) + self.eau = ExpandAsymmetricUnit(self.spacegroup, corepos, coreUijs, eps=self.eps) # setup anisotropy according to symmetry requirements # unless it was already explicitly set for ca, uisotropy in zip(self.stru, self.eau.Uisotropy): @@ -531,12 +550,12 @@ def _expandAsymmetricUnit(self, block): # build a nested list of new atoms: newatoms = [] for i, ca in enumerate(self.stru): - eca = [] # expanded core atom + eca = [] # expanded core atom for j in range(self.eau.multiplicity[i]): a = Atom(ca) a.xyz = self.eau.expandedpos[i][j] if j > 0: - a.label += '_' + str(j + 1) + a.label += "_" + str(j + 1) if a.anisotropy: a.U = self.eau.expandedUijs[i][j] eca.append(a) @@ -553,87 +572,115 @@ def toLines(self, stru): Return list of strings. """ import time + lines = [] # may be replaced with filtered Structure.title # for now, we can add the title as a comment if stru.title.strip() != "": - title_lines = stru.title.split('\n') - lines.extend([ "# " + line.strip() for line in title_lines ]) + title_lines = stru.title.split("\n") + lines.extend(["# " + line.strip() for line in title_lines]) lines.append("") lines.append("data_3D") - iso_date = "%04i-%02i-%02i" % time.gmtime()[:3] - lines.extend([ - "%-31s %s" % ("_audit_creation_date", iso_date), - "%-31s %s" % ("_audit_creation_method", "P_cif.py"), - "", - "%-31s %s" % ("_symmetry_space_group_name_H-M", "'P1'"), - "%-31s %s" % ("_symmetry_Int_Tables_number", "1"), - "%-31s %s" % ("_symmetry_cell_setting", "triclinic"), - "" ]) + iso_date = "%04i-%02i-%02i" % time.gmtime()[:3] + lines.extend( + [ + "%-31s %s" % ("_audit_creation_date", iso_date), + "%-31s %s" % ("_audit_creation_method", "P_cif.py"), + "", + "%-31s %s" % ("_symmetry_space_group_name_H-M", "'P1'"), + "%-31s %s" % ("_symmetry_Int_Tables_number", "1"), + "%-31s %s" % ("_symmetry_cell_setting", "triclinic"), + "", + ] + ) # there should be no need to specify equivalent positions for P1 # _symmetry_equiv_posi_as_xyz x,y,z - lines.extend([ - "%-31s %.6g" % ("_cell_length_a", stru.lattice.a), - "%-31s %.6g" % ("_cell_length_b", stru.lattice.b), - "%-31s %.6g" % ("_cell_length_c", stru.lattice.c), - "%-31s %.6g" % ("_cell_angle_alpha", stru.lattice.alpha), - "%-31s %.6g" % ("_cell_angle_beta", stru.lattice.beta), - "%-31s %.6g" % ("_cell_angle_gamma", stru.lattice.gamma), - "" ]) + lines.extend( + [ + "%-31s %.6g" % ("_cell_length_a", stru.lattice.a), + "%-31s %.6g" % ("_cell_length_b", stru.lattice.b), + "%-31s %.6g" % ("_cell_length_c", stru.lattice.c), + "%-31s %.6g" % ("_cell_angle_alpha", stru.lattice.alpha), + "%-31s %.6g" % ("_cell_angle_beta", stru.lattice.beta), + "%-31s %.6g" % ("_cell_angle_gamma", stru.lattice.gamma), + "", + ] + ) # build a list of site labels and adp (displacement factor) types element_count = {} a_site_label = [] a_adp_type = [] for a in stru: - cnt = element_count[a.element] = element_count.get(a.element,0)+1 - a_site_label.append( "%s%i" % (a.element, cnt) ) - if numpy.all(a.U == a.U[0,0]*numpy.identity(3)): + cnt = element_count[a.element] = element_count.get(a.element, 0) + 1 + a_site_label.append("%s%i" % (a.element, cnt)) + if numpy.all(a.U == a.U[0, 0] * numpy.identity(3)): a_adp_type.append("Uiso") else: a_adp_type.append("Uani") # list all atoms - lines.extend([ - "loop_", - " _atom_site_label", - " _atom_site_type_symbol", - " _atom_site_fract_x", - " _atom_site_fract_y", - " _atom_site_fract_z", - " _atom_site_U_iso_or_equiv", - " _atom_site_adp_type", - " _atom_site_occupancy" ]) + lines.extend( + [ + "loop_", + " _atom_site_label", + " _atom_site_type_symbol", + " _atom_site_fract_x", + " _atom_site_fract_y", + " _atom_site_fract_z", + " _atom_site_U_iso_or_equiv", + " _atom_site_adp_type", + " _atom_site_occupancy", + ] + ) for i in range(len(stru)): a = stru[i] line = " %-5s %-3s %11.6f %11.6f %11.6f %11.6f %-5s %.4f" % ( - a_site_label[i], a.element, a.xyz[0], a.xyz[1], a.xyz[2], - a.Uisoequiv, a_adp_type[i], a.occupancy ) + a_site_label[i], + a.element, + a.xyz[0], + a.xyz[1], + a.xyz[2], + a.Uisoequiv, + a_adp_type[i], + a.occupancy, + ) lines.append(line) # find anisotropic atoms - idx_aniso = [ i for i in range(len(stru)) if a_adp_type[i] != "Uiso" ] + idx_aniso = [i for i in range(len(stru)) if a_adp_type[i] != "Uiso"] if idx_aniso != []: - lines.extend([ - "loop_", - " _atom_site_aniso_label", - " _atom_site_aniso_U_11", - " _atom_site_aniso_U_22", - " _atom_site_aniso_U_33", - " _atom_site_aniso_U_12", - " _atom_site_aniso_U_13", - " _atom_site_aniso_U_23" ]) + lines.extend( + [ + "loop_", + " _atom_site_aniso_label", + " _atom_site_aniso_U_11", + " _atom_site_aniso_U_22", + " _atom_site_aniso_U_33", + " _atom_site_aniso_U_12", + " _atom_site_aniso_U_13", + " _atom_site_aniso_U_23", + ] + ) for i in idx_aniso: a = stru[i] line = " %-5s %9.6f %9.6f %9.6f %9.6f %9.6f %9.6f" % ( - a_site_label[i], a.U[0,0], a.U[1,1], a.U[2,2], - a.U[0,1], a.U[0,2], a.U[1,2] ) + a_site_label[i], + a.U[0, 0], + a.U[1, 1], + a.U[2, 2], + a.U[0, 1], + a.U[0, 2], + a.U[1, 2], + ) lines.append(line) return lines + # End of class P_cif # Routines ------------------------------------------------------------------- # constant regular expression for leading_float() -rx_float = re.compile(r'[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?') +rx_float = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?") + def leading_float(s, d=0.0): """Extract the first float from a string and ignore trailing characters. @@ -662,7 +709,7 @@ def leading_float(s, d=0.0): mx = rx_float.match(sbare) if mx: rv = float(mx.group()) - elif sbare == '.' or sbare == '?': + elif sbare == "." or sbare == "?": # CIF files may contain "." or "?" for unknown values rv = d else: @@ -672,16 +719,17 @@ def leading_float(s, d=0.0): # helper dictionary for getSymOp() symvec = { - 'x' : numpy.array([1, 0, 0], dtype=float), - 'y' : numpy.array([0, 1, 0], dtype=float), - 'z' : numpy.array([0, 0, 1], dtype=float), - '-x' : numpy.array([-1, 0, 0], dtype=float), - '-y' : numpy.array([0, -1, 0], dtype=float), - '-z' : numpy.array([0, 0, -1], dtype=float), + "x": numpy.array([1, 0, 0], dtype=float), + "y": numpy.array([0, 1, 0], dtype=float), + "z": numpy.array([0, 0, 1], dtype=float), + "-x": numpy.array([-1, 0, 0], dtype=float), + "-y": numpy.array([0, -1, 0], dtype=float), + "-z": numpy.array([0, 0, -1], dtype=float), } -symvec['+x'] = symvec['x'] -symvec['+y'] = symvec['y'] -symvec['+z'] = symvec['z'] +symvec["+x"] = symvec["x"] +symvec["+y"] = symvec["y"] +symvec["+z"] = symvec["z"] + def getSymOp(s): """Create SpaceGroups.SymOp instance from a string. @@ -691,20 +739,22 @@ def getSymOp(s): Return instance of SymOp. """ from diffpy.structure.spacegroups import SymOp - snoblanks = s.replace(' ','') - eqlist = snoblanks.split(',') - R = numpy.zeros((3,3), dtype=float) + + snoblanks = s.replace(" ", "") + eqlist = snoblanks.split(",") + R = numpy.zeros((3, 3), dtype=float) t = numpy.zeros(3, dtype=float) for i in (0, 1, 2): - eqparts = re.split('(?i)([+-]?[xyz])', eqlist[i]) + eqparts = re.split("(?i)([+-]?[xyz])", eqlist[i]) for Rpart in eqparts[1::2]: - R[i,:] += symvec[Rpart.lower()] + R[i, :] += symvec[Rpart.lower()] for tpart in eqparts[::2]: - t[i] += eval('1.0*%s+0' % tpart) + t[i] += eval("1.0*%s+0" % tpart) t -= numpy.floor(t) rv = SymOp(R, t) return rv + def getParser(eps=None): """Return new parser object for CIF structure format. @@ -713,17 +763,20 @@ def getParser(eps=None): """ return P_cif(eps=eps) + # Local Helpers -------------------------------------------------------------- + @contextmanager def _suppressCifParserOutput(): """\ Context manager which suppresses diagnostic messages from CIF parser. """ from CifFile import yapps3_compiled_rt + print_error = yapps3_compiled_rt.print_error # replace the print_error function with no-operation - yapps3_compiled_rt.print_error = lambda *a, **kw : None + yapps3_compiled_rt.print_error = lambda *a, **kw: None try: yield print_error finally: diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index d0334736..0d8014f9 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -18,12 +18,13 @@ import sys from functools import reduce + import six -from diffpy.structure import PDFFitStructure, Lattice -from diffpy.structure import StructureFormatError +from diffpy.structure import Lattice, PDFFitStructure, StructureFormatError from diffpy.structure.parsers import StructureParser + class P_discus(StructureParser): """Parser for DISCUS structure format. The parser chokes on molecule and generator records. @@ -42,7 +43,6 @@ def __init__(self): self.ncell_read = False return - def parseLines(self, lines): """Parse list of lines in DISCUS format. @@ -52,22 +52,24 @@ def parseLines(self, lines): ilines = self._linesIterator() self.stru = PDFFitStructure() record_parsers = { - "cell" : self._parse_cell, - "format" : self._parse_format, - "generator" : self._parse_not_implemented, - "molecule" : self._parse_not_implemented, - "ncell" : self._parse_ncell, - "spcgr" : self._parse_spcgr, - "symmetry" : self._parse_not_implemented, - "title" : self._parse_title, - "shape" : self._parse_shape, + "cell": self._parse_cell, + "format": self._parse_format, + "generator": self._parse_not_implemented, + "molecule": self._parse_not_implemented, + "ncell": self._parse_ncell, + "spcgr": self._parse_spcgr, + "symmetry": self._parse_not_implemented, + "title": self._parse_title, + "shape": self._parse_shape, } try: # parse header for self.line in ilines: words = self.line.split() - if not words or words[0][0] == '#': continue - if words[0] == 'atoms': break + if not words or words[0][0] == "#": + continue + if words[0] == "atoms": + break rp = record_parsers.get(words[0], self._parse_unknown_record) rp(words) # check if cell has been defined @@ -76,24 +78,23 @@ def parseLines(self, lines): raise StructureFormatError(emsg) # parse atoms for self.line in ilines: - words = self.line.replace(',', ' ').split() - if not words or words[0][0] == '#': continue + words = self.line.replace(",", " ").split() + if not words or words[0][0] == "#": + continue self._parse_atom(words) # self consistency check - exp_natoms = reduce(lambda x,y : x*y, self.stru.pdffit['ncell']) + exp_natoms = reduce(lambda x, y: x * y, self.stru.pdffit["ncell"]) # only check if ncell record exists if self.ncell_read and exp_natoms != len(self.stru): - emsg = 'Expected %d atoms, read %d.' % \ - (exp_natoms, len(self.stru)) + emsg = "Expected %d atoms, read %d." % (exp_natoms, len(self.stru)) raise StructureFormatError(emsg) # take care of superlattice - if self.stru.pdffit['ncell'][:3] != [1,1,1]: + if self.stru.pdffit["ncell"][:3] != [1, 1, 1]: latpars = list(self.stru.lattice.abcABG()) - superlatpars = [ latpars[i]*self.stru.pdffit['ncell'][i] - for i in range(3) ] + latpars[3:] + superlatpars = [latpars[i] * self.stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] superlattice = Lattice(*superlatpars) self.stru.placeInLattice(superlattice) - self.stru.pdffit['ncell'] = [1, 1, 1, exp_natoms] + self.stru.pdffit["ncell"] = [1, 1, 1, exp_natoms] except (ValueError, IndexError): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = "%d: file is not in DISCUS format" % self.nl @@ -101,7 +102,6 @@ def parseLines(self, lines): six.reraise(StructureFormatError, e, exc_traceback) return self.stru - def toLines(self, stru): """Convert Structure stru to a list of lines in DISCUS format. Return list of strings. @@ -118,29 +118,27 @@ def toLines(self, stru): # here we can start self.lines = lines = [] lines.append(("title " + self.stru.title).strip()) - lines.append( "spcgr " + stru_pdffit["spcgr"] ) - if stru_pdffit.get('spdiameter', 0.0) > 0.0: - line = 'shape sphere, %g' % stru_pdffit['spdiameter'] + lines.append("spcgr " + stru_pdffit["spcgr"]) + if stru_pdffit.get("spdiameter", 0.0) > 0.0: + line = "shape sphere, %g" % stru_pdffit["spdiameter"] lines.append(line) - if stru_pdffit.get('stepcut', 0.0) > 0.0: - line = 'shape stepcut, %g' % stru_pdffit['stepcut'] + if stru_pdffit.get("stepcut", 0.0) > 0.0: + line = "shape stepcut, %g" % stru_pdffit["stepcut"] lines.append(line) - lines.append( "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % - self.stru.lattice.abcABG() ) - lines.append( "ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(self.stru)) ) - lines.append( "atoms" ) + lines.append("cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % self.stru.lattice.abcABG()) + lines.append("ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(self.stru))) + lines.append("atoms") for a in self.stru: - lines.append( "%-4s %17.8f %17.8f %17.8f %12.4f" % ( - a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.Bisoequiv)) + lines.append( + "%-4s %17.8f %17.8f %17.8f %12.4f" % (a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.Bisoequiv) + ) return lines - def _linesIterator(self): - """Iterator over self.lines, which increments self.nl - """ + """Iterator over self.lines, which increments self.nl""" # ignore trailing empty lines stop = len(self.lines) - while stop > 0 and self.lines[stop-1].strip() == "": + while stop > 0 and self.lines[stop - 1].strip() == "": stop -= 1 self.nl = 0 # read header of PDFFit file @@ -149,76 +147,61 @@ def _linesIterator(self): yield self.line pass - def _parse_cell(self, words): - """Process the cell record from DISCUS structure file. - """ + """Process the cell record from DISCUS structure file.""" # split again on spaces or commas - words = self.line.replace(',', ' ').split() - latpars = [ float(w) for w in words[1:7] ] + words = self.line.replace(",", " ").split() + latpars = [float(w) for w in words[1:7]] try: self.stru.lattice.setLatPar(*latpars) except ZeroDivisionError: - emsg = "%d: Invalid lattice parameters - zero cell volume" % \ - self.nl + emsg = "%d: Invalid lattice parameters - zero cell volume" % self.nl raise StructureFormatError(emsg) self.cell_read = True return - def _parse_format(self, words): - """Process the format record from DISCUS structure file. - """ - if words[1] == 'pdffit': + """Process the format record from DISCUS structure file.""" + if words[1] == "pdffit": emsg = "%d: file is not in DISCUS format" % self.nl raise StructureFormatError(emsg) return - def _parse_ncell(self, words): - """Process the ncell record from DISCUS structure file. - """ + """Process the ncell record from DISCUS structure file.""" # split again on spaces or commas - words = self.line.replace(',', ' ').split() - self.stru.pdffit['ncell'] = [ int(w) for w in words[1:5] ] + words = self.line.replace(",", " ").split() + self.stru.pdffit["ncell"] = [int(w) for w in words[1:5]] self.ncell_read = True return - def _parse_spcgr(self, words): - """Process the spcgr record from DISCUS structure file. - """ - self.stru.pdffit['spcgr'] = ''.join(words[1:]) + """Process the spcgr record from DISCUS structure file.""" + self.stru.pdffit["spcgr"] = "".join(words[1:]) return - def _parse_title(self, words): - """Process the title record from DISCUS structure file. - """ + """Process the title record from DISCUS structure file.""" self.stru.title = self.line.lstrip()[5:].strip() return - def _parse_shape(self, words): - """Process the shape record from DISCUS structure file. - """ + """Process the shape record from DISCUS structure file.""" # strip away any commas - linefixed = " ".join(words).replace(',', ' ') + linefixed = " ".join(words).replace(",", " ") wordsfixed = linefixed.split() shapetype = wordsfixed[1] - if shapetype == 'sphere': - self.stru.pdffit['spdiameter'] = float(words[2]) - elif shapetype == 'stepcut': - self.stru.pdffit['stepcut'] = float(words[2]) + if shapetype == "sphere": + self.stru.pdffit["spdiameter"] = float(words[2]) + elif shapetype == "stepcut": + self.stru.pdffit["stepcut"] = float(words[2]) else: - emsg = 'Invalid type of particle shape correction %r' % shapetype + emsg = "Invalid type of particle shape correction %r" % shapetype raise StructureFormatError(emsg) return - def _parse_atom(self, words): - """Process atom records in DISCUS structure file. - """ + """Process atom records in DISCUS structure file.""" element = words[0][0:1].upper() + words[0][1:].lower() xyz = [float(w) for w in words[1:4]] Biso = float(words[4]) @@ -227,7 +210,6 @@ def _parse_atom(self, words): a.Bisoequiv = Biso return - def _parse_unknown_record(self, words): """Process unknown record in DISCUS structure file. Silently ignores the line and adds it to self.ignored_lines @@ -236,18 +218,18 @@ def _parse_unknown_record(self, words): self.ignored_lines.append(self.line) return - def _parse_not_implemented(self, words): """Process the unimplemented records from DISCUS structure file. Raises NotImplementedError. """ - emsg = "%d: reading of DISCUS record %r is not implemented." % \ - (self.nl, words[0]) + emsg = "%d: reading of DISCUS record %r is not implemented." % (self.nl, words[0]) raise NotImplementedError(emsg) + # End of class P_pdffit # Routines ------------------------------------------------------------------- + def getParser(): return P_discus() diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 6e325ded..3f6574ce 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -22,14 +22,15 @@ """ import sys -import six + import numpy +import six from numpy import pi -from diffpy.structure import Structure -from diffpy.structure import StructureFormatError +from diffpy.structure import Structure, StructureFormatError from diffpy.structure.parsers import StructureParser + class P_pdb(StructureParser): """Simple parser for PDB format. The parser understands following PDB records: TITLE, CRYST1, SCALE1, @@ -43,24 +44,69 @@ class P_pdb(StructureParser): # Static data members orderOfRecords = [ - "HEADER", "OBSLTE", "TITLE", "CAVEAT", "COMPND", "SOURCE", "KEYWDS", - "EXPDTA", "AUTHOR", "REVDAT", "SPRSDE", "JRNL", "REMARK", "REMARK", - "REMARK", "REMARK", "DBREF", "SEQADV", "SEQRES", "MODRES", "HET", - "HETNAM", "HETSYN", "FORMUL", "HELIX", "SHEET", "TURN", "SSBOND", - "LINK", "HYDBND", "SLTBRG", "CISPEP", "SITE", "CRYST1", "ORIGX1", - "ORIGX2", "ORIGX3", "SCALE1", "SCALE2", "SCALE3", "MTRIX1", - "MTRIX2", "MTRIX3", "TVECT", "MODEL", "ATOM", "SIGATM", "ANISOU", - "SIGUIJ", "TER", "HETATM", "ENDMDL", "CONECT", "MASTER", "END", + "HEADER", + "OBSLTE", + "TITLE", + "CAVEAT", + "COMPND", + "SOURCE", + "KEYWDS", + "EXPDTA", + "AUTHOR", + "REVDAT", + "SPRSDE", + "JRNL", + "REMARK", + "REMARK", + "REMARK", + "REMARK", + "DBREF", + "SEQADV", + "SEQRES", + "MODRES", + "HET", + "HETNAM", + "HETSYN", + "FORMUL", + "HELIX", + "SHEET", + "TURN", + "SSBOND", + "LINK", + "HYDBND", + "SLTBRG", + "CISPEP", + "SITE", + "CRYST1", + "ORIGX1", + "ORIGX2", + "ORIGX3", + "SCALE1", + "SCALE2", + "SCALE3", + "MTRIX1", + "MTRIX2", + "MTRIX3", + "TVECT", + "MODEL", + "ATOM", + "SIGATM", + "ANISOU", + "SIGUIJ", + "TER", + "HETATM", + "ENDMDL", + "CONECT", + "MASTER", + "END", ] validRecords = dict.fromkeys(orderOfRecords) - def __init__(self): StructureParser.__init__(self) self.format = "pdb" return - def parseLines(self, lines): """Parse list of lines in PDB format. @@ -74,7 +120,8 @@ def parseLines(self, lines): for line in lines: p_nl += 1 # skip blank lines - if not line.strip(): continue + if not line.strip(): + continue # make sure line has 80 characters if len(line) < 80: line = "%-80s" % line @@ -96,23 +143,22 @@ def parseLines(self, lines): stru.lattice.setLatPar(a, b, c, alpha, beta, gamma) scale = numpy.transpose(stru.lattice.recbase) elif record == "SCALE1": - sc = numpy.zeros((3,3), dtype=float) - sc[0,:] = [float(x) for x in line[10:40].split()] + sc = numpy.zeros((3, 3), dtype=float) + sc[0, :] = [float(x) for x in line[10:40].split()] scaleU[0] = float(line[45:55]) elif record == "SCALE2": - sc[1,:] = [float(x) for x in line[10:40].split()] + sc[1, :] = [float(x) for x in line[10:40].split()] scaleU[1] = float(line[45:55]) elif record == "SCALE3": - sc[2,:] = [float(x) for x in line[10:40].split()] + sc[2, :] = [float(x) for x in line[10:40].split()] scaleU[2] = float(line[45:55]) base = numpy.transpose(numpy.linalg.inv(sc)) abcABGcryst = numpy.array(stru.lattice.abcABG()) stru.lattice.setLatBase(base) abcABGscale = numpy.array(stru.lattice.abcABG()) - reldiff = numpy.fabs(1.0 - abcABGscale/abcABGcryst) + reldiff = numpy.fabs(1.0 - abcABGscale / abcABGcryst) if not numpy.all(reldiff < 1.0e-4): - emsg = "%d: " % p_nl + \ - "SCALE and CRYST1 are not consistent." + emsg = "%d: " % p_nl + "SCALE and CRYST1 are not consistent." raise StructureFormatError(emsg) if numpy.any(scaleU != 0.0): emsg = "Origin offset not yet implemented." @@ -126,7 +172,7 @@ def parseLines(self, lines): occupancy = 1.0 try: B = float(line[60:66]) - uiso = B/(8*pi**2) + uiso = B / (8 * pi**2) except ValueError: uiso = 0.0 element = line[76:78].strip() @@ -134,8 +180,7 @@ def parseLines(self, lines): # get element from the first 2 characters of name element = line[12:14].strip() element = element[0].upper() + element[1:].lower() - stru.addNewAtom(element, - occupancy=occupancy, label=name) + stru.addNewAtom(element, occupancy=occupancy, label=name) last_atom = stru.getLastAtom() last_atom.xyz_cartn = rc last_atom.Uisoequiv = uiso @@ -148,28 +193,28 @@ def parseLines(self, lines): sigo = 0.0 try: sigB = float(line[60:66]) - sigU = numpy.identity(3)*sigB/(8*pi**2) + sigU = numpy.identity(3) * sigB / (8 * pi**2) except ValueError: - sigU = numpy.zeros((3,3), dtype=float) + sigU = numpy.zeros((3, 3), dtype=float) last_atom.sigxyz = sigxyz last_atom.sigo = sigo last_atom.sigU = sigU elif record == "ANISOU": last_atom.anisotropy = True - Uij = [ float(x)*1.0e-4 for x in line[28:70].split() ] + Uij = [float(x) * 1.0e-4 for x in line[28:70].split()] Ua = last_atom.U for i in range(3): - Ua[i,i] = Uij[i] - Ua[0,1] = Ua[1,0] = Uij[3] - Ua[0,2] = Ua[2,0] = Uij[4] - Ua[1,2] = Ua[2,1] = Uij[5] + Ua[i, i] = Uij[i] + Ua[0, 1] = Ua[1, 0] = Uij[3] + Ua[0, 2] = Ua[2, 0] = Uij[4] + Ua[1, 2] = Ua[2, 1] = Uij[5] elif record == "SIGUIJ": - sigUij = [ float(x)*1.0e-4 for x in line[28:70].split() ] + sigUij = [float(x) * 1.0e-4 for x in line[28:70].split()] for i in range(3): - last_atom.sigU[i,i] = sigUij[i] - last_atom.sigU[0,1] = last_atom.sigU[1,0] = sigUij[3] - last_atom.sigU[0,2] = last_atom.sigU[2,0] = sigUij[4] - last_atom.sigU[1,2] = last_atom.sigU[2,1] = sigUij[5] + last_atom.sigU[i, i] = sigUij[i] + last_atom.sigU[0, 1] = last_atom.sigU[1, 0] = sigUij[3] + last_atom.sigU[0, 2] = last_atom.sigU[2, 0] = sigUij[4] + last_atom.sigU[1, 2] = last_atom.sigU[2, 1] = sigUij[5] elif record in P_pdb.validRecords: pass else: @@ -182,7 +227,6 @@ def parseLines(self, lines): six.reraise(StructureFormatError, e, exc_traceback) return stru - def titleLines(self, stru): """build lines corresponding to TITLE record""" lines = [] @@ -191,28 +235,33 @@ def titleLines(self, stru): stop = len(title) # maximum length of title record is 60 if stop > 60: - stop = title.rfind(' ', 10, 60) - if stop < 0: stop = 60 + stop = title.rfind(" ", 10, 60) + if stop < 0: + stop = 60 if len(lines) == 0: continuation = " " else: - continuation = "%2i" % (len(lines)+1) - lines.append( "%-80s" % ("TITLE "+continuation+title[0:stop]) ) + continuation = "%2i" % (len(lines) + 1) + lines.append("%-80s" % ("TITLE " + continuation + title[0:stop])) title = title[stop:] return lines - def cryst1Lines(self, stru): """build lines corresponding to CRYST1 record""" lines = [] - latpar = ( stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ) + latpar = ( + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ) if latpar != (1.0, 1.0, 1.0, 90.0, 90.0, 90.0): line = "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f" % latpar - lines.append( "%-80s" % line ) + lines.append("%-80s" % line) return lines - def atomLines(self, stru, idx): """build ATOM records and possibly SIGATM, ANISOU or SIGUIJ records for structure stru atom number aidx @@ -222,89 +271,102 @@ def atomLines(self, stru, idx): ad = a.__dict__ rc = a.xyz_cartn B = a.Bisoequiv - atomline = ( "ATOM " + # 1-6 - "%(serial)5i " + # 7-11, 12 - "%(name)-4s" + # 13-16 - "%(altLoc)c" + # 17 - "%(resName)-3s " + # 18-20, 21 - "%(chainID)c" + # 22 - "%(resSeq)4i" + # 23-26 - "%(iCode)c " + # 27, 28-30 - "%(x)8.3f%(y)8.3f%(z)8.3f" + # 31-54 - "%(occupancy)6.2f" + # 55-60 - "%(tempFactor)6.2f " + # 61-66, 67-72 - "%(segID)-4s" + # 73-76 - "%(element)2s" + # 77-78 - "%(charge)-2s" # 79-80 - ) % { - "serial" : idx+1, - "name" : a.label or a.element, "altLoc" : " ", - "resName" : "", "chainID" : " ", "resSeq" : 1, - "iCode" : " ", "x" : rc[0], "y" : rc[1], "z" : rc[2], - "occupancy" : a.occupancy, "tempFactor" : B, "segID" : "", - "element" : a.element, "charge" : "" } + atomline = ( + "ATOM " # 1-6 + + "%(serial)5i " # 7-11, 12 + + "%(name)-4s" # 13-16 + + "%(altLoc)c" # 17 + + "%(resName)-3s " # 18-20, 21 + + "%(chainID)c" # 22 + + "%(resSeq)4i" # 23-26 + + "%(iCode)c " # 27, 28-30 + + "%(x)8.3f%(y)8.3f%(z)8.3f" # 31-54 + + "%(occupancy)6.2f" # 55-60 + + "%(tempFactor)6.2f " # 61-66, 67-72 + + "%(segID)-4s" # 73-76 + + "%(element)2s" # 77-78 + + "%(charge)-2s" # 79-80 + ) % { + "serial": idx + 1, + "name": a.label or a.element, + "altLoc": " ", + "resName": "", + "chainID": " ", + "resSeq": 1, + "iCode": " ", + "x": rc[0], + "y": rc[1], + "z": rc[2], + "occupancy": a.occupancy, + "tempFactor": B, + "segID": "", + "element": a.element, + "charge": "", + } lines.append(atomline) - isotropic = numpy.all(a.U == a.U[0,0]*numpy.identity(3)) + isotropic = numpy.all(a.U == a.U[0, 0] * numpy.identity(3)) if not isotropic: - mid = " %7i%7i%7i%7i%7i%7i " % tuple( numpy.around(1e4 * - numpy.array([ a.U[0,0], a.U[1,1], a.U[2,2], - a.U[0,1], a.U[0,2], a.U[1,2] ])) ) + mid = " %7i%7i%7i%7i%7i%7i " % tuple( + numpy.around(1e4 * numpy.array([a.U[0, 0], a.U[1, 1], a.U[2, 2], a.U[0, 1], a.U[0, 2], a.U[1, 2]])) + ) line = "ANISOU" + atomline[6:27] + mid + atomline[72:80] lines.append(line) # default values of standard deviations d_sigxyz = numpy.zeros(3, dtype=float) d_sigo = 0.0 - d_sigU = numpy.zeros((3,3), dtype=float) + d_sigU = numpy.zeros((3, 3), dtype=float) sigxyz = ad.get("sigxyz", d_sigxyz) sigo = [ad.get("sigo", d_sigo)] sigU = ad.get("sigU", d_sigU) - sigB = [8*pi**2*numpy.average( [sigU[i,i] for i in range(3)] )] - sigmas = numpy.concatenate( (sigxyz, sigo, sigB) ) + sigB = [8 * pi**2 * numpy.average([sigU[i, i] for i in range(3)])] + sigmas = numpy.concatenate((sigxyz, sigo, sigB)) # no need to print sigmas if they all round to zero - hassigmas = \ - numpy.any(numpy.fabs(sigmas) >= numpy.array(3*[5e-4]+2*[5e-3])) \ - or numpy.any(numpy.fabs(sigU) > 5.0e-5) + hassigmas = numpy.any(numpy.fabs(sigmas) >= numpy.array(3 * [5e-4] + 2 * [5e-3])) or numpy.any( + numpy.fabs(sigU) > 5.0e-5 + ) if hassigmas: mid = " %8.3f%8.3f%8.3f%6.2f%6.2f " % tuple(sigmas) line = "SIGATM" + atomline[6:27] + mid + atomline[72:80] lines.append(line) # do we need SIGUIJ record? - if not numpy.all(sigU == sigU[0,0]*numpy.identity(3)): - mid = " %7i%7i%7i%7i%7i%7i " % tuple( numpy.around(1e4 * - numpy.array([ sigU[0,0], sigU[1,1], sigU[2,2], - sigU[0,1], sigU[0,2], sigU[1,2] ])) ) + if not numpy.all(sigU == sigU[0, 0] * numpy.identity(3)): + mid = " %7i%7i%7i%7i%7i%7i " % tuple( + numpy.around( + 1e4 * numpy.array([sigU[0, 0], sigU[1, 1], sigU[2, 2], sigU[0, 1], sigU[0, 2], sigU[1, 2]]) + ) + ) line = "SIGUIJ" + atomline[6:27] + mid + atomline[72:80] lines.append(line) return lines - def toLines(self, stru): """Convert Structure stru to a list of lines in PDFFit format. Return list of strings. """ lines = [] - lines.extend( self.titleLines(stru) ) - lines.extend( self.cryst1Lines(stru) ) + lines.extend(self.titleLines(stru)) + lines.extend(self.cryst1Lines(stru)) for idx in range(len(stru)): - lines.extend( self.atomLines(stru, idx) ) - line = ( "TER " + # 1-6 - "%(serial)5i " + # 7-11, 12-17 - "%(resName)-3s " + # 18-20, 21 - "%(chainID)c" + # 22 - "%(resSeq)4i" + # 23-26 - "%(iCode)c" + # 27 - "%(blank)53s" # 28-80 - ) % { - "serial" : len(stru)+1, "resName" : "", "chainID" : " ", - "resSeq" : 1, "iCode" : " ", "blank" : " " } + lines.extend(self.atomLines(stru, idx)) + line = ( + "TER " # 1-6 + + "%(serial)5i " # 7-11, 12-17 + + "%(resName)-3s " # 18-20, 21 + + "%(chainID)c" # 22 + + "%(resSeq)4i" # 23-26 + + "%(iCode)c" # 27 + + "%(blank)53s" # 28-80 + ) % {"serial": len(stru) + 1, "resName": "", "chainID": " ", "resSeq": 1, "iCode": " ", "blank": " "} lines.append(line) lines.append("%-80s" % "END") return lines + # End of class P_pdb # Routines ------------------------------------------------------------------- + def getParser(): return P_pdb() diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 0ef532d2..c01b9f05 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -17,13 +17,14 @@ """ import sys +from functools import reduce + import numpy import six -from diffpy.structure import PDFFitStructure, Lattice -from diffpy.structure import StructureFormatError +from diffpy.structure import Lattice, PDFFitStructure, StructureFormatError from diffpy.structure.parsers import StructureParser -from functools import reduce + class P_pdffit(StructureParser): """Parser for PDFfit structure format. @@ -38,7 +39,6 @@ def __init__(self): self.stru = None return - def parseLines(self, lines): """Parse list of lines in PDFfit format. @@ -50,54 +50,54 @@ def parseLines(self, lines): stru = self.stru cell_line_read = False stop = len(lines) - while stop>0 and lines[stop-1].strip() == "": + while stop > 0 and lines[stop - 1].strip() == "": stop -= 1 ilines = iter(lines[:stop]) # read header of PDFFit file for l in ilines: p_nl += 1 words = l.split() - if len(words) == 0 or words[0][0] == '#': + if len(words) == 0 or words[0][0] == "#": continue - elif words[0] == 'title': + elif words[0] == "title": stru.title = l.lstrip()[5:].strip() - elif words[0] == 'scale': - stru.pdffit['scale'] = float(words[1]) - elif words[0] == 'sharp': - l1 = l.replace(',', ' ') - sharp_pars = [ float(w) for w in l1.split()[1:] ] + elif words[0] == "scale": + stru.pdffit["scale"] = float(words[1]) + elif words[0] == "sharp": + l1 = l.replace(",", " ") + sharp_pars = [float(w) for w in l1.split()[1:]] if len(sharp_pars) < 4: - stru.pdffit['delta2'] = sharp_pars[0] - stru.pdffit['sratio'] = sharp_pars[1] - stru.pdffit['rcut'] = sharp_pars[2] + stru.pdffit["delta2"] = sharp_pars[0] + stru.pdffit["sratio"] = sharp_pars[1] + stru.pdffit["rcut"] = sharp_pars[2] else: - stru.pdffit['delta2'] = sharp_pars[0] - stru.pdffit['delta1'] = sharp_pars[1] - stru.pdffit['sratio'] = sharp_pars[2] - stru.pdffit['rcut'] = sharp_pars[3] - elif words[0] == 'spcgr': - key = 'spcgr' + stru.pdffit["delta2"] = sharp_pars[0] + stru.pdffit["delta1"] = sharp_pars[1] + stru.pdffit["sratio"] = sharp_pars[2] + stru.pdffit["rcut"] = sharp_pars[3] + elif words[0] == "spcgr": + key = "spcgr" start = l.find(key) + len(key) value = l[start:].strip() - stru.pdffit['spcgr'] = value - elif words[0] == 'shape': + stru.pdffit["spcgr"] = value + elif words[0] == "shape": self._parse_shape(l) - elif words[0] == 'cell': + elif words[0] == "cell": cell_line_read = True - l1 = l.replace(',', ' ') - latpars = [ float(w) for w in l1.split()[1:7] ] + l1 = l.replace(",", " ") + latpars = [float(w) for w in l1.split()[1:7]] stru.lattice = Lattice(*latpars) - elif words[0] == 'dcell': - l1 = l.replace(',', ' ') - stru.pdffit['dcell'] = [ float(w) for w in l1.split()[1:7] ] - elif words[0] == 'ncell': - l1 = l.replace(',', ' ') - stru.pdffit['ncell'] = [ int(w) for w in l1.split()[1:5] ] - elif words[0] == 'format': - if words[1] != 'pdffit': + elif words[0] == "dcell": + l1 = l.replace(",", " ") + stru.pdffit["dcell"] = [float(w) for w in l1.split()[1:7]] + elif words[0] == "ncell": + l1 = l.replace(",", " ") + stru.pdffit["ncell"] = [int(w) for w in l1.split()[1:5]] + elif words[0] == "format": + if words[1] != "pdffit": emsg = "%d: file is not in PDFfit format" % p_nl raise StructureFormatError(emsg) - elif words[0] == 'atoms' and cell_line_read: + elif words[0] == "atoms" and cell_line_read: break else: self.ignored_lines.append(l) @@ -106,19 +106,19 @@ def parseLines(self, lines): emsg = "%d: file is not in PDFfit format" % p_nl raise StructureFormatError(emsg) # Load data from atom entries. - p_natoms = reduce(lambda x,y : x*y, stru.pdffit['ncell']) + p_natoms = reduce(lambda x, y: x * y, stru.pdffit["ncell"]) # we are now inside data block for l in ilines: p_nl += 1 wl1 = l.split() element = wl1[0][0].upper() + wl1[0][1:].lower() - xyz = [ float(w) for w in wl1[1:4] ] + xyz = [float(w) for w in wl1[1:4]] occ = float(wl1[4]) stru.addNewAtom(element, xyz=xyz, occupancy=occ) a = stru.getLastAtom() p_nl += 1 wl2 = next(ilines).split() - a.sigxyz = [ float(w) for w in wl2[0:3] ] + a.sigxyz = [float(w) for w in wl2[0:3]] a.sigo = float(wl2[3]) p_nl += 1 wl3 = next(ilines).split() @@ -128,32 +128,31 @@ def parseLines(self, lines): wl5 = next(ilines).split() p_nl += 1 wl6 = next(ilines).split() - U = numpy.zeros((3,3), dtype=float) - sigU = numpy.zeros((3,3), dtype=float) - U[0,0] = float(wl3[0]) - U[1,1] = float(wl3[1]) - U[2,2] = float(wl3[2]) - sigU[0,0] = float(wl4[0]) - sigU[1,1] = float(wl4[1]) - sigU[2,2] = float(wl4[2]) - U[0,1] = U[1,0] = float(wl5[0]) - U[0,2] = U[2,0] = float(wl5[1]) - U[1,2] = U[2,1] = float(wl5[2]) - sigU[0,1] = sigU[1,0] = float(wl6[0]) - sigU[0,2] = sigU[2,0] = float(wl6[1]) - sigU[1,2] = sigU[2,1] = float(wl6[2]) + U = numpy.zeros((3, 3), dtype=float) + sigU = numpy.zeros((3, 3), dtype=float) + U[0, 0] = float(wl3[0]) + U[1, 1] = float(wl3[1]) + U[2, 2] = float(wl3[2]) + sigU[0, 0] = float(wl4[0]) + sigU[1, 1] = float(wl4[1]) + sigU[2, 2] = float(wl4[2]) + U[0, 1] = U[1, 0] = float(wl5[0]) + U[0, 2] = U[2, 0] = float(wl5[1]) + U[1, 2] = U[2, 1] = float(wl5[2]) + sigU[0, 1] = sigU[1, 0] = float(wl6[0]) + sigU[0, 2] = sigU[2, 0] = float(wl6[1]) + sigU[1, 2] = sigU[2, 1] = float(wl6[2]) a.anisotropy = stru.lattice.isanisotropic(U) a.U = U a.sigU = sigU if len(stru) != p_natoms: emsg = "expected %d atoms, read %d" % (p_natoms, len(stru)) raise StructureFormatError(emsg) - if stru.pdffit['ncell'][:3] != [1,1,1]: - superlatpars = [ latpars[i]*stru.pdffit['ncell'][i] - for i in range(3) ] + latpars[3:] + if stru.pdffit["ncell"][:3] != [1, 1, 1]: + superlatpars = [latpars[i] * stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] superlattice = Lattice(*superlatpars) stru.placeInLattice(superlattice) - stru.pdffit['ncell'] = [1, 1, 1, p_natoms] + stru.pdffit["ncell"] = [1, 1, 1, p_natoms] except (ValueError, IndexError): emsg = "%d: file is not in PDFfit format" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() @@ -161,7 +160,6 @@ def parseLines(self, lines): six.reraise(StructureFormatError, e, exc_traceback) return stru - def toLines(self, stru): """Convert Structure stru to a list of lines in PDFfit format. @@ -176,47 +174,47 @@ def toLines(self, stru): # default values of standard deviations d_sigxyz = numpy.zeros(3, dtype=float) d_sigo = 0.0 - d_sigU = numpy.zeros((3,3), dtype=float) + d_sigU = numpy.zeros((3, 3), dtype=float) # here we can start l = "title " + stru.title - lines.append( l.strip() ) - lines.append( "format pdffit" ) - lines.append( "scale %9.6f" % stru_pdffit["scale"] ) - lines.append( "sharp %9.6f, %9.6f, %9.6f, %9.6f" % ( - stru_pdffit["delta2"], - stru_pdffit["delta1"], - stru_pdffit["sratio"], - stru_pdffit["rcut"]) ) - lines.append( "spcgr " + stru_pdffit["spcgr"] ) - if stru_pdffit.get('spdiameter', 0.0) > 0.0: - line = 'shape sphere, %g' % stru_pdffit['spdiameter'] + lines.append(l.strip()) + lines.append("format pdffit") + lines.append("scale %9.6f" % stru_pdffit["scale"]) + lines.append( + "sharp %9.6f, %9.6f, %9.6f, %9.6f" + % (stru_pdffit["delta2"], stru_pdffit["delta1"], stru_pdffit["sratio"], stru_pdffit["rcut"]) + ) + lines.append("spcgr " + stru_pdffit["spcgr"]) + if stru_pdffit.get("spdiameter", 0.0) > 0.0: + line = "shape sphere, %g" % stru_pdffit["spdiameter"] lines.append(line) - if stru_pdffit.get('stepcut', 0.0) > 0.0: - line = 'shape stepcut, %g' % stru_pdffit['stepcut'] + if stru_pdffit.get("stepcut", 0.0) > 0.0: + line = "shape stepcut, %g" % stru_pdffit["stepcut"] lines.append(line) lat = stru.lattice - lines.append( "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % ( - lat.a, lat.b, lat.c, lat.alpha, lat.beta, lat.gamma) ) - lines.append( "dcell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % - tuple(stru_pdffit["dcell"]) ) - lines.append( "ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(stru)) ) - lines.append( "atoms" ) + lines.append( + "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" + % (lat.a, lat.b, lat.c, lat.alpha, lat.beta, lat.gamma) + ) + lines.append("dcell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % tuple(stru_pdffit["dcell"])) + lines.append("ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(stru))) + lines.append("atoms") for a in stru: ad = a.__dict__ - lines.append( "%-4s %17.8f %17.8f %17.8f %12.4f" % ( - a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.occupancy) ) - sigmas = numpy.concatenate( - ( ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)] ) ) - lines.append( " %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas) ) + lines.append( + "%-4s %17.8f %17.8f %17.8f %12.4f" % (a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.occupancy) + ) + sigmas = numpy.concatenate((ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)])) + lines.append(" %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas)) sigU = ad.get("sigU", d_sigU) - Uii = ( a.U[0][0], a.U[1][1], a.U[2][2] ) - Uij = ( a.U[0][1], a.U[0][2], a.U[1][2] ) - sigUii = ( sigU[0][0], sigU[1][1], sigU[2][2] ) - sigUij = ( sigU[0][1], sigU[0][2], sigU[1][2] ) - lines.append( " %18.8f %17.8f %17.8f" % Uii ) - lines.append( " %18.8f %17.8f %17.8f" % sigUii ) - lines.append( " %18.8f %17.8f %17.8f" % Uij ) - lines.append( " %18.8f %17.8f %17.8f" % sigUij ) + Uii = (a.U[0][0], a.U[1][1], a.U[2][2]) + Uij = (a.U[0][1], a.U[0][2], a.U[1][2]) + sigUii = (sigU[0][0], sigU[1][1], sigU[2][2]) + sigUij = (sigU[0][1], sigU[0][2], sigU[1][2]) + lines.append(" %18.8f %17.8f %17.8f" % Uii) + lines.append(" %18.8f %17.8f %17.8f" % sigUii) + lines.append(" %18.8f %17.8f %17.8f" % Uij) + lines.append(" %18.8f %17.8f %17.8f" % sigUij) return lines # Protected methods ------------------------------------------------------ @@ -229,22 +227,24 @@ def _parse_shape(self, line): No return value. Raise StructureFormatError for invalid record. """ - line_nocommas = line.replace(',', ' ') + line_nocommas = line.replace(",", " ") words = line_nocommas.split() - assert words[0] == 'shape' + assert words[0] == "shape" shapetype = words[1] - if shapetype == 'sphere': - self.stru.pdffit['spdiameter'] = float(words[2]) - elif shapetype == 'stepcut': - self.stru.pdffit['stepcut'] = float(words[2]) + if shapetype == "sphere": + self.stru.pdffit["spdiameter"] = float(words[2]) + elif shapetype == "stepcut": + self.stru.pdffit["stepcut"] = float(words[2]) else: - emsg = 'Invalid type of particle shape correction %r' % shapetype + emsg = "Invalid type of particle shape correction %r" % shapetype raise StructureFormatError(emsg) return + # End of class P_pdffit # Routines ------------------------------------------------------------------- + def getParser(): return P_pdffit() diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index f82221c0..efbd095b 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -19,12 +19,13 @@ """ import sys + import six -from diffpy.structure import Structure -from diffpy.structure import StructureFormatError -from diffpy.structure.utils import isfloat +from diffpy.structure import Structure, StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.utils import isfloat + class P_rawxyz(StructureParser): """Parser --> StructureParser subclass for RAWXYZ format""" @@ -34,7 +35,6 @@ def __init__(self): self.format = "rawxyz" return - def parseLines(self, lines): """Parse list of lines in RAWXYZ format. @@ -52,18 +52,17 @@ def parseLines(self, lines): break # find the last valid record stop = len(lines) - while stop > start and len(linefields[stop-1]) == 0: + while stop > start and len(linefields[stop - 1]) == 0: stop -= 1 # get out for empty structure if start >= stop: return stru # here we have at least one valid record line # figure out xyz layout from the first line for plain and raw formats - floatfields = [ isfloat(f) for f in linefields[start] ] + floatfields = [isfloat(f) for f in linefields[start]] nfields = len(linefields[start]) if nfields not in (3, 4): - emsg = ("%d: invalid RAWXYZ format, expected 3 or 4 columns" % - (start + 1)) + emsg = "%d: invalid RAWXYZ format, expected 3 or 4 columns" % (start + 1) raise StructureFormatError(emsg) if floatfields[:3] == [True, True, True]: el_idx, x_idx = (None, 0) @@ -75,16 +74,15 @@ def parseLines(self, lines): # now try to read all record lines try: p_nl = start - for fields in linefields[start:] : + for fields in linefields[start:]: p_nl += 1 if fields == []: continue elif len(fields) != nfields: - emsg = ('%d: all lines must have ' + - 'the same number of columns') % p_nl + emsg = ("%d: all lines must have " + "the same number of columns") % p_nl raise StructureFormatError(emsg) element = el_idx is not None and fields[el_idx] or "" - xyz = [ float(f) for f in fields[x_idx:x_idx+3] ] + xyz = [float(f) for f in fields[x_idx : x_idx + 3]] if len(xyz) == 2: xyz.append(0.0) stru.addNewAtom(element, xyz=xyz) @@ -95,7 +93,6 @@ def parseLines(self, lines): six.reraise(StructureFormatError, e, exc_traceback) return stru - def toLines(self, stru): """Convert Structure stru to a list of lines in XYZ format. @@ -108,9 +105,11 @@ def toLines(self, stru): lines.append(s.lstrip()) return lines + # End of class P_rawxyz # Routines ------------------------------------------------------------------- + def getParser(): return P_rawxyz() diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index c2467004..252571fc 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -15,15 +15,15 @@ """Parser for extended CFG format used by atomeye""" -import sys import re +import sys + import numpy import six -from diffpy.structure import Structure -from diffpy.structure import StructureFormatError -from diffpy.structure.utils import isfloat +from diffpy.structure import Structure, StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.utils import isfloat # Constants ------------------------------------------------------------------ @@ -31,121 +31,122 @@ # This can be later when PeriodicTable package becomes available. AtomicMass = { - "H" : 1.007947, # 1 H hydrogen 1.007947 - "He" : 4.0026022, # 2 He helium 4.0026022 - "Li" : 6.9412, # 3 Li lithium 6.9412 - "Be" : 9.0121823, # 4 Be beryllium 9.0121823 - "B" : 10.8117, # 5 B boron 10.8117 - "C" : 12.01078, # 6 C carbon 12.01078 - "N" : 14.00672, # 7 N nitrogen 14.00672 - "O" : 15.99943, # 8 O oxygen 15.99943 - "F" : 18.99840325, # 9 F fluorine 18.99840325 - "Ne" : 20.17976, # 10 Ne neon 20.17976 - "Na" : 22.9897702, # 11 Na sodium 22.9897702 - "Mg" : 24.30506, # 12 Mg magnesium 24.30506 - "Al" : 26.9815382, # 13 Al aluminium 26.9815382 - "Si" : 28.08553, # 14 Si silicon 28.08553 - "P" : 30.9737612, # 15 P phosphorus 30.9737612 - "S" : 32.0655, # 16 S sulfur 32.0655 - "Cl" : 35.4532, # 17 Cl chlorine 35.4532 - "Ar" : 39.9481, # 18 Ar argon 39.9481 - "K" : 39.09831, # 19 K potassium 39.09831 - "Ca" : 40.0784, # 20 Ca calcium 40.0784 - "Sc" : 44.9559108, # 21 Sc scandium 44.9559108 - "Ti" : 47.8671, # 22 Ti titanium 47.8671 - "V" : 50.94151, # 23 V vanadium 50.94151 - "Cr" : 51.99616, # 24 Cr chromium 51.99616 - "Mn" : 54.9380499, # 25 Mn manganese 54.9380499 - "Fe" : 55.8452, # 26 Fe iron 55.8452 - "Co" : 58.9332009, # 27 Co cobalt 58.9332009 - "Ni" : 58.69342, # 28 Ni nickel 58.69342 - "Cu" : 63.5463, # 29 Cu copper 63.5463 - "Zn" : 65.4094, # 30 Zn zinc 65.4094 - "Ga" : 69.7231, # 31 Ga gallium 69.7231 - "Ge" : 72.641, # 32 Ge germanium 72.641 - "As" : 74.921602, # 33 As arsenic 74.921602 - "Se" : 78.963, # 34 Se selenium 78.963 - "Br" : 79.9041, # 35 Br bromine 79.9041 - "Kr" : 83.7982, # 36 Kr krypton 83.7982 - "Rb" : 85.46783, # 37 Rb rubidium 85.46783 - "Sr" : 87.621, # 38 Sr strontium 87.621 - "Y" : 88.905852, # 39 Y yttrium 88.905852 - "Zr" : 91.2242, # 40 Zr zirconium 91.2242 - "Nb" : 92.906382, # 41 Nb niobium 92.906382 - "Mo" : 95.942, # 42 Mo molybdenum 95.942 - "Tc" : 98.0, # 43 Tc technetium 98 - "Ru" : 101.072, # 44 Ru ruthenium 101.072 - "Rh" : 102.905502, # 45 Rh rhodium 102.905502 - "Pd" : 106.421, # 46 Pd palladium 106.421 - "Ag" : 107.86822, # 47 Ag silver 107.86822 - "Cd" : 112.4118, # 48 Cd cadmium 112.4118 - "In" : 114.8183, # 49 In indium 114.8183 - "Sn" : 118.7107, # 50 Sn tin 118.7107 - "Sb" : 121.7601, # 51 Sb antimony 121.7601 - "Te" : 127.603, # 52 Te tellurium 127.603 - "I" : 126.904473, # 53 I iodine 126.904473 - "Xe" : 131.2936, # 54 Xe xenon 131.2936 - "Cs" : 132.905452, # 55 Cs caesium 132.905452 - "Ba" : 137.3277, # 56 Ba barium 137.3277 - "La" : 138.90552, # 57 La lanthanum 138.90552 - "Ce" : 140.1161, # 58 Ce cerium 140.1161 - "Pr" : 140.907652, # 59 Pr praseodymium 140.907652 - "Nd" : 144.243, # 60 Nd neodymium 144.243 - "Pm" : 145.0, # 61 Pm promethium 145 - "Sm" : 150.363, # 62 Sm samarium 150.363 - "Eu" : 151.9641, # 63 Eu europium 151.9641 - "Gd" : 157.253, # 64 Gd gadolinium 157.253 - "Tb" : 158.925342, # 65 Tb terbium 158.925342 - "Dy" : 162.5001, # 66 Dy dysprosium 162.5001 - "Ho" : 164.930322, # 67 Ho holmium 164.930322 - "Er" : 167.2593, # 68 Er erbium 167.2593 - "Tm" : 168.934212, # 69 Tm thulium 168.934212 - "Yb" : 173.043, # 70 Yb ytterbium 173.043 - "Lu" : 174.9671, # 71 Lu lutetium 174.9671 - "Hf" : 178.492, # 72 Hf hafnium 178.492 - "Ta" : 180.94791, # 73 Ta tantalum 180.94791 - "W" : 183.841, # 74 W tungsten 183.841 - "Re" : 186.2071, # 75 Re rhenium 186.2071 - "Os" : 190.233, # 76 Os osmium 190.233 - "Ir" : 192.2173, # 77 Ir iridium 192.2173 - "Pt" : 195.0782, # 78 Pt platinum 195.0782 - "Au" : 196.966552, # 79 Au gold 196.966552 - "Hg" : 200.592, # 80 Hg mercury 200.592 - "Tl" : 204.38332, # 81 Tl thallium 204.38332 - "Pb" : 207.21, # 82 Pb lead 207.21 - "Bi" : 208.980382, # 83 Bi bismuth 208.980382 - "Po" : 209.0, # 84 Po polonium 209 - "At" : 210.0, # 85 At astatine 210 - "Rn" : 222.0, # 86 Rn radon 222 - "Fr" : 223.0, # 87 Fr francium 223 - "Ra" : 226.0, # 88 Ra radium 226 - "Ac" : 227.0, # 89 Ac actinium 227 - "Th" : 232.03811, # 90 Th thorium 232.03811 - "Pa" : 231.035882, # 91 Pa protactinium 231.035882 - "U" : 238.028913, # 92 U uranium 238.028913 - "Np" : 237.0, # 93 Np neptunium 237 - "Pu" : 244.0, # 94 Pu plutonium 244 - "Am" : 243.0, # 95 Am americium 243 - "Cm" : 247.0, # 96 Cm curium 247 - "Bk" : 247.0, # 97 Bk berkelium 247 - "Cf" : 251.0, # 98 Cf californium 251 - "Es" : 252.0, # 99 Es einsteinium 252 - "Fm" : 257.0, # 100 Fm fermium 257 - "Md" : 258.0, # 101 Md mendelevium 258 - "No" : 259.0, # 102 No nobelium 259 - "Lr" : 262.0, # 103 Lr lawrencium 262 - "Rf" : 261.0, # 104 Rf rutherfordium 261 - "Db" : 262.0, # 105 Db dubnium 262 - "Sg" : 266.0, # 106 Sg seaborgium 266 - "Bh" : 264.0, # 107 Bh bohrium 264 - "Hs" : 277.0, # 108 Hs hassium 277 - "Mt" : 268.0, # 109 Mt meitnerium 268 - "Ds" : 281.0, # 110 Ds darmstadtium 281 - "Rg" : 272.0, # 111 Rg roentgenium 272 + "H": 1.007947, # 1 H hydrogen 1.007947 + "He": 4.0026022, # 2 He helium 4.0026022 + "Li": 6.9412, # 3 Li lithium 6.9412 + "Be": 9.0121823, # 4 Be beryllium 9.0121823 + "B": 10.8117, # 5 B boron 10.8117 + "C": 12.01078, # 6 C carbon 12.01078 + "N": 14.00672, # 7 N nitrogen 14.00672 + "O": 15.99943, # 8 O oxygen 15.99943 + "F": 18.99840325, # 9 F fluorine 18.99840325 + "Ne": 20.17976, # 10 Ne neon 20.17976 + "Na": 22.9897702, # 11 Na sodium 22.9897702 + "Mg": 24.30506, # 12 Mg magnesium 24.30506 + "Al": 26.9815382, # 13 Al aluminium 26.9815382 + "Si": 28.08553, # 14 Si silicon 28.08553 + "P": 30.9737612, # 15 P phosphorus 30.9737612 + "S": 32.0655, # 16 S sulfur 32.0655 + "Cl": 35.4532, # 17 Cl chlorine 35.4532 + "Ar": 39.9481, # 18 Ar argon 39.9481 + "K": 39.09831, # 19 K potassium 39.09831 + "Ca": 40.0784, # 20 Ca calcium 40.0784 + "Sc": 44.9559108, # 21 Sc scandium 44.9559108 + "Ti": 47.8671, # 22 Ti titanium 47.8671 + "V": 50.94151, # 23 V vanadium 50.94151 + "Cr": 51.99616, # 24 Cr chromium 51.99616 + "Mn": 54.9380499, # 25 Mn manganese 54.9380499 + "Fe": 55.8452, # 26 Fe iron 55.8452 + "Co": 58.9332009, # 27 Co cobalt 58.9332009 + "Ni": 58.69342, # 28 Ni nickel 58.69342 + "Cu": 63.5463, # 29 Cu copper 63.5463 + "Zn": 65.4094, # 30 Zn zinc 65.4094 + "Ga": 69.7231, # 31 Ga gallium 69.7231 + "Ge": 72.641, # 32 Ge germanium 72.641 + "As": 74.921602, # 33 As arsenic 74.921602 + "Se": 78.963, # 34 Se selenium 78.963 + "Br": 79.9041, # 35 Br bromine 79.9041 + "Kr": 83.7982, # 36 Kr krypton 83.7982 + "Rb": 85.46783, # 37 Rb rubidium 85.46783 + "Sr": 87.621, # 38 Sr strontium 87.621 + "Y": 88.905852, # 39 Y yttrium 88.905852 + "Zr": 91.2242, # 40 Zr zirconium 91.2242 + "Nb": 92.906382, # 41 Nb niobium 92.906382 + "Mo": 95.942, # 42 Mo molybdenum 95.942 + "Tc": 98.0, # 43 Tc technetium 98 + "Ru": 101.072, # 44 Ru ruthenium 101.072 + "Rh": 102.905502, # 45 Rh rhodium 102.905502 + "Pd": 106.421, # 46 Pd palladium 106.421 + "Ag": 107.86822, # 47 Ag silver 107.86822 + "Cd": 112.4118, # 48 Cd cadmium 112.4118 + "In": 114.8183, # 49 In indium 114.8183 + "Sn": 118.7107, # 50 Sn tin 118.7107 + "Sb": 121.7601, # 51 Sb antimony 121.7601 + "Te": 127.603, # 52 Te tellurium 127.603 + "I": 126.904473, # 53 I iodine 126.904473 + "Xe": 131.2936, # 54 Xe xenon 131.2936 + "Cs": 132.905452, # 55 Cs caesium 132.905452 + "Ba": 137.3277, # 56 Ba barium 137.3277 + "La": 138.90552, # 57 La lanthanum 138.90552 + "Ce": 140.1161, # 58 Ce cerium 140.1161 + "Pr": 140.907652, # 59 Pr praseodymium 140.907652 + "Nd": 144.243, # 60 Nd neodymium 144.243 + "Pm": 145.0, # 61 Pm promethium 145 + "Sm": 150.363, # 62 Sm samarium 150.363 + "Eu": 151.9641, # 63 Eu europium 151.9641 + "Gd": 157.253, # 64 Gd gadolinium 157.253 + "Tb": 158.925342, # 65 Tb terbium 158.925342 + "Dy": 162.5001, # 66 Dy dysprosium 162.5001 + "Ho": 164.930322, # 67 Ho holmium 164.930322 + "Er": 167.2593, # 68 Er erbium 167.2593 + "Tm": 168.934212, # 69 Tm thulium 168.934212 + "Yb": 173.043, # 70 Yb ytterbium 173.043 + "Lu": 174.9671, # 71 Lu lutetium 174.9671 + "Hf": 178.492, # 72 Hf hafnium 178.492 + "Ta": 180.94791, # 73 Ta tantalum 180.94791 + "W": 183.841, # 74 W tungsten 183.841 + "Re": 186.2071, # 75 Re rhenium 186.2071 + "Os": 190.233, # 76 Os osmium 190.233 + "Ir": 192.2173, # 77 Ir iridium 192.2173 + "Pt": 195.0782, # 78 Pt platinum 195.0782 + "Au": 196.966552, # 79 Au gold 196.966552 + "Hg": 200.592, # 80 Hg mercury 200.592 + "Tl": 204.38332, # 81 Tl thallium 204.38332 + "Pb": 207.21, # 82 Pb lead 207.21 + "Bi": 208.980382, # 83 Bi bismuth 208.980382 + "Po": 209.0, # 84 Po polonium 209 + "At": 210.0, # 85 At astatine 210 + "Rn": 222.0, # 86 Rn radon 222 + "Fr": 223.0, # 87 Fr francium 223 + "Ra": 226.0, # 88 Ra radium 226 + "Ac": 227.0, # 89 Ac actinium 227 + "Th": 232.03811, # 90 Th thorium 232.03811 + "Pa": 231.035882, # 91 Pa protactinium 231.035882 + "U": 238.028913, # 92 U uranium 238.028913 + "Np": 237.0, # 93 Np neptunium 237 + "Pu": 244.0, # 94 Pu plutonium 244 + "Am": 243.0, # 95 Am americium 243 + "Cm": 247.0, # 96 Cm curium 247 + "Bk": 247.0, # 97 Bk berkelium 247 + "Cf": 251.0, # 98 Cf californium 251 + "Es": 252.0, # 99 Es einsteinium 252 + "Fm": 257.0, # 100 Fm fermium 257 + "Md": 258.0, # 101 Md mendelevium 258 + "No": 259.0, # 102 No nobelium 259 + "Lr": 262.0, # 103 Lr lawrencium 262 + "Rf": 261.0, # 104 Rf rutherfordium 261 + "Db": 262.0, # 105 Db dubnium 262 + "Sg": 266.0, # 106 Sg seaborgium 266 + "Bh": 264.0, # 107 Bh bohrium 264 + "Hs": 277.0, # 108 Hs hassium 277 + "Mt": 268.0, # 109 Mt meitnerium 268 + "Ds": 281.0, # 110 Ds darmstadtium 281 + "Rg": 272.0, # 111 Rg roentgenium 272 } # ---------------------------------------------------------------------------- + class P_xcfg(StructureParser): """Parser for AtomEye extended CFG format. @@ -155,13 +156,11 @@ class P_xcfg(StructureParser): cluster_boundary = 2 - def __init__(self): StructureParser.__init__(self) self.format = "xcfg" return - def parseLines(self, lines): """Parse list of lines in PDB format. @@ -169,8 +168,8 @@ def parseLines(self, lines): """ xcfg_Number_of_particles = None xcfg_A = None - xcfg_H0 = numpy.zeros((3,3), dtype=float) - xcfg_H0_set = numpy.zeros((3,3), dtype=bool) + xcfg_H0 = numpy.zeros((3, 3), dtype=float) + xcfg_H0_set = numpy.zeros((3, 3), dtype=bool) xcfg_NO_VELOCITY = False xcfg_entry_count = None p_nl = 0 @@ -191,12 +190,11 @@ def parseLines(self, lines): p_nl += 1 stripped_line = line.strip() # blank lines and lines starting with # are ignored - if stripped_line == "" or line[0] == '#': + if stripped_line == "" or line[0] == "#": continue elif xcfg_Number_of_particles is None: if line.find("Number of particles =") != 0: - emsg = ("%d: first line must " + - "contain 'Number of particles ='") % p_nl + emsg = ("%d: first line must " + "contain 'Number of particles ='") % p_nl raise StructureFormatError(emsg) xcfg_Number_of_particles = int(line[21:].split(None, 1)[0]) p_natoms = xcfg_Number_of_particles @@ -204,8 +202,8 @@ def parseLines(self, lines): xcfg_A = float(line[3:].split(None, 1)[0]) elif line.find("H0(") == 0: i, j = (int(line[3]) - 1, int(line[5]) - 1) - xcfg_H0[i,j] = float(line[10:].split(None, 1)[0]) - xcfg_H0_set[i,j] = True + xcfg_H0[i, j] = float(line[10:].split(None, 1)[0]) + xcfg_H0_set[i, j] = True elif line.find(".NO_VELOCITY.") == 0: xcfg_NO_VELOCITY = True elif line.find("entry_count =") == 0: @@ -213,27 +211,23 @@ def parseLines(self, lines): elif p_auxiliary_re.match(line): m = p_auxiliary_re.match(line) idx = int(m.group(1)) - p_auxiliary[idx] = line[m.end():].split(None, 1)[0] + p_auxiliary[idx] = line[m.end() :].split(None, 1)[0] else: break # check header for consistency if numpy.any(xcfg_H0_set == False): emsg = "H0 tensor is not properly defined" raise StructureFormatError(emsg) - p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys())+1 + p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys()) + 1 for i in range(p_auxnum): if not i in p_auxiliary: p_auxiliary[i] = "aux%d" % i sorted_aux_keys = sorted(p_auxiliary.keys()) if p_auxnum != 0: - stru.xcfg = { - 'auxiliaries' : [ p_auxiliary[k] - for k in sorted_aux_keys ] - } + stru.xcfg = {"auxiliaries": [p_auxiliary[k] for k in sorted_aux_keys]} ecnt = len(p_auxiliary) + (3 if xcfg_NO_VELOCITY else 6) if ecnt != xcfg_entry_count: - emsg = ("%d: auxiliary fields are " - "not consistent with entry_count") % p_nl + emsg = ("%d: auxiliary fields are " "not consistent with entry_count") % p_nl raise StructureFormatError(emsg) # define proper lattice stru.lattice.setLatBase(xcfg_H0) @@ -254,8 +248,7 @@ def parseLines(self, lines): xyz = [xcfg_A * xi for xi in fields[:3]] stru.addNewAtom(p_element, xyz=xyz) a = stru[-1] - _assign_auxiliaries(a, fields, auxiliaries=p_auxiliary, - no_velocity=xcfg_NO_VELOCITY) + _assign_auxiliaries(a, fields, auxiliaries=p_auxiliary, no_velocity=xcfg_NO_VELOCITY) else: emsg = "%d: invalid record" % p_nl raise StructureFormatError(emsg) @@ -269,7 +262,6 @@ def parseLines(self, lines): six.reraise(StructureFormatError, e, exc_traceback) return stru - def toLines(self, stru): """Convert Structure stru to a list of lines in XCFG atomeye format. @@ -284,29 +276,28 @@ def toLines(self, stru): allxyz = numpy.array([a.xyz for a in stru]) lo_xyz = allxyz.min(axis=0) hi_xyz = allxyz.max(axis=0) - max_range_xyz = (hi_xyz-lo_xyz).max() + max_range_xyz = (hi_xyz - lo_xyz).max() if numpy.allclose(stru.lattice.abcABG(), (1, 1, 1, 90, 90, 90)): max_range_xyz += self.cluster_boundary # range of CFG coordinates must be less than 1 p_A = numpy.ceil(max_range_xyz + 1.0e-13) # atomeye draws rubbish when boxsize is less than 3.5 - hi_ucvect = max([numpy.sqrt(numpy.dot(v,v)) for v in stru.lattice.base]) - if hi_ucvect*p_A < 3.5: + hi_ucvect = max([numpy.sqrt(numpy.dot(v, v)) for v in stru.lattice.base]) + if hi_ucvect * p_A < 3.5: p_A = numpy.ceil(3.5 / hi_ucvect) lines.append("A = %.8g Angstrom" % p_A) # how much do we need to shift the coordinates? p_dxyz = numpy.zeros(3, dtype=float) for i in range(3): - if lo_xyz[i]/p_A < 0.0 or hi_xyz[i]/p_A >= 1.0 \ - or (lo_xyz[i] == hi_xyz[i] and lo_xyz[i] == 0.0) : - p_dxyz[i] = 0.5 - (hi_xyz[i]+lo_xyz[i])/2.0/p_A + if lo_xyz[i] / p_A < 0.0 or hi_xyz[i] / p_A >= 1.0 or (lo_xyz[i] == hi_xyz[i] and lo_xyz[i] == 0.0): + p_dxyz[i] = 0.5 - (hi_xyz[i] + lo_xyz[i]) / 2.0 / p_A # H0 tensor for i in range(3): for j in range(3): - lines.append("H0(%i,%i) = %.8g A" % - (i + 1, j + 1, stru.lattice.base[i, j])) + lines.append("H0(%i,%i) = %.8g A" % (i + 1, j + 1, stru.lattice.base[i, j])) # get out for empty structure - if len(stru) == 0: return lines + if len(stru) == 0: + return lines a_first = stru[0] p_NO_VELOCITY = "v" not in a_first.__dict__ if p_NO_VELOCITY: @@ -315,14 +306,13 @@ def toLines(self, stru): # if stru came from xcfg file, it would store original auxiliaries in # xcfg dictionary try: - p_auxiliaries = [ (aux, "a."+aux) - for aux in stru.xcfg['auxiliaries'] ] + p_auxiliaries = [(aux, "a." + aux) for aux in stru.xcfg["auxiliaries"]] except AttributeError: p_auxiliaries = [] # add occupancy if any atom has nonunit occupancy for a in stru: if a.occupancy != 1.0: - p_auxiliaries.append(('occupancy', 'a.occupancy')) + p_auxiliaries.append(("occupancy", "a.occupancy")) break # add temperature factor with as many terms as needed # check whether all temperature factors are zero or isotropic @@ -331,26 +321,24 @@ def toLines(self, stru): for a in stru: if p_allUzero and numpy.any(a.U != 0.0): p_allUzero = False - if not numpy.all(a.U == a.U[0,0]*numpy.identity(3)): + if not numpy.all(a.U == a.U[0, 0] * numpy.identity(3)): p_allUiso = False # here p_allUzero must be false break if p_allUzero: pass elif p_allUiso: - p_auxiliaries.append(('Uiso', 'uflat[0]')) + p_auxiliaries.append(("Uiso", "uflat[0]")) else: - p_auxiliaries.extend([('U11', 'uflat[0]'), - ('U22', 'uflat[4]'), - ('U33', 'uflat[8]')]) + p_auxiliaries.extend([("U11", "uflat[0]"), ("U22", "uflat[4]"), ("U33", "uflat[8]")]) # check if there are off-diagonal elements allU = numpy.array([a.U for a in stru]) - if numpy.any(allU[:,0,1] != 0.0): - p_auxiliaries.append(('U12', 'uflat[1]')) - if numpy.any(allU[:,0,2] != 0.0): - p_auxiliaries.append(('U13', 'uflat[2]')) - if numpy.any(allU[:,1,2] != 0.0): - p_auxiliaries.append(('U23', 'uflat[5]')) + if numpy.any(allU[:, 0, 1] != 0.0): + p_auxiliaries.append(("U12", "uflat[1]")) + if numpy.any(allU[:, 0, 2] != 0.0): + p_auxiliaries.append(("U13", "uflat[2]")) + if numpy.any(allU[:, 1, 2] != 0.0): + p_auxiliaries.append(("U23", "uflat[5]")) # count entries p_entry_count = (3 if p_NO_VELOCITY else 6) + len(p_auxiliaries) lines.append("entry_count = %d" % p_entry_count) @@ -361,8 +349,8 @@ def toLines(self, stru): fmwords = ["{pos[0]:.8g}", "{pos[1]:.8g}", "{pos[2]:.8g}"] if not p_NO_VELOCITY: fmwords += ["{v[0]:.8g}", "{v[1]:.8g}", "{v[2]:.8g}"] - fmwords += (('{' + e + ':.8g}') for p, e in p_auxiliaries) - efmt = ' '.join(fmwords) + fmwords += (("{" + e + ":.8g}") for p, e in p_auxiliaries) + efmt = " ".join(fmwords) # we are ready to output atoms: lines.append("") p_element = None @@ -378,15 +366,19 @@ def toLines(self, stru): lines.append(entry) return lines + # End of class P_xcfg # Routines ------------------------------------------------------------------- + def getParser(): return P_xcfg() + # Local Helpers -------------------------------------------------------------- + def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): """\ Assing auxiliary properties for Atom object when reading CFG format. @@ -415,9 +407,8 @@ def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): a.Uisoequiv = value elif prop == "Biso": a.Bisoequiv = value - elif prop[0] in 'BU' and all(d in '123' for d in prop[1:]): - nm = (prop if prop[1] <= prop[2] - else prop[0] + prop[2] + prop[1]) + elif prop[0] in "BU" and all(d in "123" for d in prop[1:]): + nm = prop if prop[1] <= prop[2] else prop[0] + prop[2] + prop[1] a.anisotropy = True setattr(a, nm, value) else: diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index ea33af83..16bdd319 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -20,22 +20,21 @@ """ import sys + import six -from diffpy.structure import Structure -from diffpy.structure import StructureFormatError +from diffpy.structure import Structure, StructureFormatError from diffpy.structure.parsers import StructureParser + class P_xyz(StructureParser): - """Parser for standard XYZ structure format. - """ + """Parser for standard XYZ structure format.""" def __init__(self): StructureParser.__init__(self) self.format = "xyz" return - def parseLines(self, lines): """Parse list of lines in XYZ format. @@ -57,21 +56,19 @@ def parseLines(self, lines): w1 = linefields[start][0] if len(lfs) == 1 and str(int(w1)) == w1: p_natoms = int(w1) - stru.title = lines[start+1].strip() + stru.title = lines[start + 1].strip() start += 2 else: - emsg = ("%d: invalid XYZ format, missing number of atoms" % - (start + 1)) + emsg = "%d: invalid XYZ format, missing number of atoms" % (start + 1) raise StructureFormatError(emsg) except (IndexError, ValueError): exc_type, exc_value, exc_traceback = sys.exc_info() - emsg = ("%d: invalid XYZ format, missing number of atoms" % - (start + 1)) + emsg = "%d: invalid XYZ format, missing number of atoms" % (start + 1) e = StructureFormatError(emsg) six.reraise(StructureFormatError, e, exc_traceback) # find the last valid record stop = len(lines) - while stop > start and len(linefields[stop-1]) == 0: + while stop > start and len(linefields[stop - 1]) == 0: stop -= 1 # get out for empty structure if p_natoms == 0 or start >= stop: @@ -84,17 +81,16 @@ def parseLines(self, lines): # now try to read all record lines try: p_nl = start - for fields in linefields[start:] : + for fields in linefields[start:]: p_nl += 1 if fields == []: continue elif len(fields) != nfields: - emsg = ('%d: all lines must have ' + - 'the same number of columns') % p_nl + emsg = ("%d: all lines must have " + "the same number of columns") % p_nl raise StructureFormatError(emsg) element = fields[0] element = element[0].upper() + element[1:].lower() - xyz = [ float(f) for f in fields[1:4] ] + xyz = [float(f) for f in fields[1:4]] stru.addNewAtom(element, xyz=xyz) except ValueError: exc_type, exc_value, exc_traceback = sys.exc_info() @@ -107,24 +103,25 @@ def parseLines(self, lines): raise StructureFormatError(emsg) return stru - def toLines(self, stru): """Convert Structure stru to a list of lines in XYZ format. Return list of strings. """ lines = [] - lines.append( str(len(stru)) ) - lines.append( stru.title ) + lines.append(str(len(stru))) + lines.append(stru.title) for a in stru: rc = a.xyz_cartn s = "%-3s %g %g %g" % (a.element, rc[0], rc[1], rc[2]) lines.append(s) return lines + # End of class P_xyz # Routines ------------------------------------------------------------------- + def getParser(): return P_xyz() diff --git a/src/diffpy/structure/parsers/parser_index_mod.py b/src/diffpy/structure/parsers/parser_index_mod.py index e8462d9e..48314780 100644 --- a/src/diffpy/structure/parsers/parser_index_mod.py +++ b/src/diffpy/structure/parsers/parser_index_mod.py @@ -19,76 +19,68 @@ """ parser_index = { - # automatic format detection - tries all parsers one by one - 'auto' : { - 'module' : 'p_auto', - 'file_extension' : '', - 'file_pattern' : '*.*', - 'has_input' : True, - 'has_output' : False, - }, - + "auto": { + "module": "p_auto", + "file_extension": "", + "file_pattern": "*.*", + "has_input": True, + "has_output": False, + }, # CIF format - 'cif' : { - 'module' : 'p_cif', - 'file_extension' : '.cif', - 'file_pattern' : '*.cif', - 'has_input' : True, - 'has_output' : True, - }, - + "cif": { + "module": "p_cif", + "file_extension": ".cif", + "file_pattern": "*.cif", + "has_input": True, + "has_output": True, + }, # PDB format - 'pdb' : { - 'module' : 'p_pdb', - 'file_extension' : '.pdb', - 'file_pattern' : '*.pdb', - 'has_input' : True, - 'has_output' : True, - }, - + "pdb": { + "module": "p_pdb", + "file_extension": ".pdb", + "file_pattern": "*.pdb", + "has_input": True, + "has_output": True, + }, # Discus structure format - 'discus' : { - 'module' : 'p_discus', - 'file_extension' : '.stru', - 'file_pattern' : '*.stru|*.rstr', - 'has_input' : True, - 'has_output' : True, - }, - + "discus": { + "module": "p_discus", + "file_extension": ".stru", + "file_pattern": "*.stru|*.rstr", + "has_input": True, + "has_output": True, + }, # PDFfit structure format - 'pdffit' : { - 'module' : 'p_pdffit', - 'file_extension' : '.stru', - 'file_pattern' : '*.stru|*.rstr', - 'has_input' : True, - 'has_output' : True, - }, - + "pdffit": { + "module": "p_pdffit", + "file_extension": ".stru", + "file_pattern": "*.stru|*.rstr", + "has_input": True, + "has_output": True, + }, # standard xyz file - 'xyz' : { - 'module' : 'p_xyz', - 'file_extension' : '.xyz', - 'file_pattern' : '*.xyz', - 'has_input' : True, - 'has_output' : True, - }, - + "xyz": { + "module": "p_xyz", + "file_extension": ".xyz", + "file_pattern": "*.xyz", + "has_input": True, + "has_output": True, + }, # raw xyz file (element labels optional) - 'rawxyz' : { - 'module' : 'p_rawxyz', - 'file_extension' : '.xyz', - 'file_pattern' : '*.xyz', - 'has_input' : True, - 'has_output' : True, - }, - + "rawxyz": { + "module": "p_rawxyz", + "file_extension": ".xyz", + "file_pattern": "*.xyz", + "has_input": True, + "has_output": True, + }, # AtomEye extended configuration format - 'xcfg' : { - 'module' : 'p_xcfg', - 'file_extension' : '', - 'file_pattern' : '*.xcfg|*.eye|*.cfg', - 'has_input' : True, - 'has_output' : True, - }, + "xcfg": { + "module": "p_xcfg", + "file_extension": "", + "file_pattern": "*.xcfg|*.eye|*.cfg", + "has_input": True, + "has_output": True, + }, } diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index 43326637..1637d86b 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -16,6 +16,7 @@ """Definition of StructureParser, a base class for specific parsers. """ + class StructureParser(object): """Base class for all structure parsers. @@ -29,7 +30,6 @@ def __init__(self): self.filename = None return - def parseLines(self, lines): """Create Structure instance from a list of lines. @@ -39,7 +39,6 @@ def parseLines(self, lines): raise NotImplementedError("parseLines not defined for '%s' format" % self.format) return - def toLines(self, stru): """Convert Structure stru to a list of lines. This method has to be overloaded in derived class. @@ -48,25 +47,21 @@ def toLines(self, stru): """ raise NotImplementedError("toLines not defined for '%s' format" % self.format) - def parse(self, s): """Create Structure instance from a string. Return Structure object or raise StructureFormatError exception. """ - lines = s.rstrip('\r\n').split('\n') + lines = s.rstrip("\r\n").split("\n") stru = self.parseLines(lines) return stru - def tostring(self, stru): - """Convert Structure instance to a string. - """ + """Convert Structure instance to a string.""" lines = self.toLines(stru) - s = '\n'.join(lines) + '\n' + s = "\n".join(lines) + "\n" return s - def parseFile(self, filename): """Create Structure instance from an existing file. @@ -81,4 +76,5 @@ def parseFile(self, filename): stru = self.parse(s) return stru + # End of class StructureParser diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index afafc314..c2ed21a1 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -21,6 +21,7 @@ # ---------------------------------------------------------------------------- + class PDFFitStructure(Structure): """PDFFitStructure --> Structure with extra pdffit member @@ -33,22 +34,21 @@ class PDFFitStructure(Structure): def __init__(self, *args, **kwargs): self.pdffit = { - 'scale' : 1.0, - 'delta1' : 0.0, - 'delta2' : 0.0, - 'sratio' : 1.0, - 'rcut' : 0.0, - 'spcgr' : 'P1', - 'spdiameter' : 0.0, - 'stepcut' : 0.0, - 'dcell' : 6*[0.0], - 'ncell' : [1, 1, 1, 0], + "scale": 1.0, + "delta1": 0.0, + "delta2": 0.0, + "sratio": 1.0, + "rcut": 0.0, + "spcgr": "P1", + "spdiameter": 0.0, + "stepcut": 0.0, + "dcell": 6 * [0.0], + "ncell": [1, 1, 1, 0], } Structure.__init__(self, *args, **kwargs) return - - def read(self, filename, format='auto'): + def read(self, filename, format="auto"): """Same as Structure.read, but update spcgr value in self.pdffit when parser can get spacegroup. @@ -56,12 +56,12 @@ def read(self, filename, format='auto'): See Structure.read() for more info. """ p = Structure.read(self, filename, format) - sg = getattr(p, 'spacegroup', None) - if sg: self.pdffit['spcgr'] = sg.short_name + sg = getattr(p, "spacegroup", None) + if sg: + self.pdffit["spcgr"] = sg.short_name return p - - def readStr(self, s, format='auto'): + def readStr(self, s, format="auto"): """Same as Structure.readStr, but update spcgr value in self.pdffit when parser can get spacegroup. @@ -69,8 +69,10 @@ def readStr(self, s, format='auto'): See Structure.readStr() for more info. """ p = Structure.readStr(self, s, format) - sg = getattr(p, 'spacegroup', None) - if sg: self.pdffit['spcgr'] = sg.short_name + sg = getattr(p, "spacegroup", None) + if sg: + self.pdffit["spcgr"] = sg.short_name return p + # End of class PDFFitStructure diff --git a/src/diffpy/structure/sgtbxspacegroups.py b/src/diffpy/structure/sgtbxspacegroups.py index 1cf198ff..0b5c382a 100644 --- a/src/diffpy/structure/sgtbxspacegroups.py +++ b/src/diffpy/structure/sgtbxspacegroups.py @@ -13,689 +13,704 @@ # ############################################################################## -'''Extra space group representations generated using sgtbx module from cctbx. +"""Extra space group representations generated using sgtbx module from cctbx. Import of this module extends the SpaceGroupList in the SpaceGroups module. Notable variables: sgtbxSpaceGroupList -- list of space group instances defined in this module -''' +""" -from diffpy.structure.spacegroupmod import SpaceGroup, SymOp from diffpy.structure.spacegroupmod import ( - Rot_X_Y_Z, Rot_mX_mY_mZ, Rot_mX_Y_mZ, Rot_X_mY_Z, - Rot_mX_mY_Z, Rot_X_mY_mZ, Rot_mX_Y_Z, Rot_X_Y_mZ, - Tr_0_0_0, Tr_0_12_0, Tr_12_12_0, Tr_0_0_12, - Tr_12_12_12, Tr_0_12_12, Tr_12_0_12, Tr_12_0_0, - Tr_14_14_14, Tr_14_34_34, Tr_34_14_34, Tr_34_34_14, + Rot_mX_mY_mZ, + Rot_mX_mY_Z, + Rot_mX_Y_mZ, + Rot_mX_Y_Z, + Rot_X_mY_mZ, + Rot_X_mY_Z, + Rot_X_Y_mZ, + Rot_X_Y_Z, + SpaceGroup, + SymOp, + Tr_0_0_0, + Tr_0_0_12, + Tr_0_12_0, + Tr_0_12_12, + Tr_12_0_0, + Tr_12_0_12, + Tr_12_12_0, + Tr_12_12_12, + Tr_14_14_14, + Tr_14_34_34, + Tr_34_14_34, + Tr_34_34_14, ) - ############################################################################## # generated using sgtbx_extra_groups.py ############################################################################## sg2003 = SpaceGroup( - number = 2003, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P211', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 2 1 1', - symop_list = [ + number=2003, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P211", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="P 2 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), - ] + ], ) sg2004 = SpaceGroup( - number = 2004, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P2111', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 21 1 1', - symop_list = [ + number=2004, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P2111", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="P 21 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), - ] + ], ) sg4005 = SpaceGroup( - number = 4005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A121', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 2 1', - symop_list = [ + number=4005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A121", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="A 1 2 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), - ] + ], ) sg5005 = SpaceGroup( - number = 5005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I121', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 2 1', - symop_list = [ + number=5005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I121", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="I 1 2 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), - ] + ], ) sg6005 = SpaceGroup( - number = 6005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A112', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 2', - symop_list = [ + number=6005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A112", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_mX_mY_Z, Tr_0_12_12), - ] + ], ) sg7005 = SpaceGroup( - number = 7005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I112', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 2', - symop_list = [ + number=7005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I112", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_mX_mY_Z, Tr_12_12_12), - ] + ], ) sg8005 = SpaceGroup( - number = 8005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'B211', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 2 1 1', - symop_list = [ + number=8005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="B211", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="B 2 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_mZ, Tr_12_0_12), - ] + ], ) sg9005 = SpaceGroup( - number = 9005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'C211', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 2 1 1', - symop_list = [ + number=9005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="C211", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="C 2 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), - ] + ], ) sg10005 = SpaceGroup( - number = 10005, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I211', - point_group_name = 'PG2', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 2 1 1', - symop_list = [ + number=10005, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I211", + point_group_name="PG2", + crystal_system="MONOCLINIC", + pdb_name="I 2 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_mZ, Tr_12_12_12), - ] + ], ) sg2006 = SpaceGroup( - number = 2006, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'Pm11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P m 1 1', - symop_list = [ + number=2006, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pm11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), - ] + ], ) sg2007 = SpaceGroup( - number = 2007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P1n1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 n 1', - symop_list = [ + number=2007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P1n1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg3007 = SpaceGroup( - number = 3007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P1a1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 a 1', - symop_list = [ + number=3007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P1a1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), - ] + ], ) sg4007 = SpaceGroup( - number = 4007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P11a', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 a', - symop_list = [ + number=4007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P11a", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg5007 = SpaceGroup( - number = 5007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'P11n', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 n', - symop_list = [ + number=5007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="P11n", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg6007 = SpaceGroup( - number = 6007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'Pb11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P b 1 1', - symop_list = [ + number=6007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pb11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), - ] + ], ) sg7007 = SpaceGroup( - number = 7007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'Pn11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P n 1 1', - symop_list = [ + number=7007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pn11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg8007 = SpaceGroup( - number = 8007, - num_sym_equiv = 2, - num_primitive_sym_equiv = 2, - short_name = 'Pc11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'P c 1 1', - symop_list = [ + number=8007, + num_sym_equiv=2, + num_primitive_sym_equiv=2, + short_name="Pc11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="P c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), - ] + ], ) sg2008 = SpaceGroup( - number = 2008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A1m1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 m 1', - symop_list = [ + number=2008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A1m1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 m 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg3008 = SpaceGroup( - number = 3008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I1m1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 m 1', - symop_list = [ + number=3008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I1m1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 m 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg4008 = SpaceGroup( - number = 4008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A11m', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 m', - symop_list = [ + number=4008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A11m", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg5008 = SpaceGroup( - number = 5008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I11m', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 m', - symop_list = [ + number=5008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I11m", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg6008 = SpaceGroup( - number = 6008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Bm11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'B m 1 1', - symop_list = [ + number=6008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Bm11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="B m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), - ] + ], ) sg7008 = SpaceGroup( - number = 7008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Cm11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'C m 1 1', - symop_list = [ + number=7008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Cm11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), - ] + ], ) sg8008 = SpaceGroup( - number = 8008, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Im11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I m 1 1', - symop_list = [ + number=8008, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Im11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg2009 = SpaceGroup( - number = 2009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A1n1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 n 1', - symop_list = [ + number=2009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A1n1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg3009 = SpaceGroup( - number = 3009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I1a1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 a 1', - symop_list = [ + number=3009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I1a1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg4009 = SpaceGroup( - number = 4009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A1a1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 a 1', - symop_list = [ + number=4009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A1a1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg5009 = SpaceGroup( - number = 5009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'C1n1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 1 n 1', - symop_list = [ + number=5009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="C1n1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C 1 n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg6009 = SpaceGroup( - number = 6009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I1c1', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 c 1', - symop_list = [ + number=6009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I1c1", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 c 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), - ] + ], ) sg7009 = SpaceGroup( - number = 7009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A11a', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 a', - symop_list = [ + number=7009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A11a", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg8009 = SpaceGroup( - number = 8009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'B11n', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 1 1 n', - symop_list = [ + number=8009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="B11n", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), SymOp(Rot_X_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg9009 = SpaceGroup( - number = 9009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I11b', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 b', - symop_list = [ + number=9009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I11b", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg10009 = SpaceGroup( - number = 10009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'A11n', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 n', - symop_list = [ + number=10009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="A11n", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), SymOp(Rot_X_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg11009 = SpaceGroup( - number = 11009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'I11a', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 a', - symop_list = [ + number=11009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="I11a", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg12009 = SpaceGroup( - number = 12009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Bb11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'B b 1 1', - symop_list = [ + number=12009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Bb11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="B b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_Y_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg13009 = SpaceGroup( - number = 13009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Cn11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'C n 1 1', - symop_list = [ + number=13009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Cn11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_Z, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg14009 = SpaceGroup( - number = 14009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Ic11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I c 1 1', - symop_list = [ + number=14009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Ic11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_0), - ] + ], ) sg15009 = SpaceGroup( - number = 15009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Cc11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'C c 1 1', - symop_list = [ + number=15009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Cc11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="C c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_Y_Z, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg16009 = SpaceGroup( - number = 16009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Bn11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'B n 1 1', - symop_list = [ + number=16009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Bn11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="B n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg17009 = SpaceGroup( - number = 17009, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Ib11', - point_group_name = 'PGm', - crystal_system = 'MONOCLINIC', - pdb_name = 'I b 1 1', - symop_list = [ + number=17009, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Ib11", + point_group_name="PGm", + crystal_system="MONOCLINIC", + pdb_name="I b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_Y_Z, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), - ] + ], ) sg2010 = SpaceGroup( - number = 2010, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2/m11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 2/m 1 1', - symop_list = [ + number=2010, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/m11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 2/m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), - ] + ], ) sg2011 = SpaceGroup( - number = 2011, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21/m11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 21/m 1 1', - symop_list = [ + number=2011, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/m11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 21/m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), - ] + ], ) sg2012 = SpaceGroup( - number = 2012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A12/m1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 2/m 1', - symop_list = [ + number=2012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A12/m1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 2/m 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -704,18 +719,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg3012 = SpaceGroup( - number = 3012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I12/m1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 2/m 1', - symop_list = [ + number=3012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I12/m1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 2/m 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -724,18 +739,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg4012 = SpaceGroup( - number = 4012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A112/m', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 2/m', - symop_list = [ + number=4012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A112/m", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 2/m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -744,18 +759,18 @@ SymOp(Rot_mX_mY_Z, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg5012 = SpaceGroup( - number = 5012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I112/m', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 2/m', - symop_list = [ + number=5012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I112/m", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 2/m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -764,18 +779,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg6012 = SpaceGroup( - number = 6012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2/m11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 2/m 1 1', - symop_list = [ + number=6012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2/m11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="B 2/m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -784,18 +799,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), - ] + ], ) sg7012 = SpaceGroup( - number = 7012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2/m11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 2/m 1 1', - symop_list = [ + number=7012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2/m11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 2/m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -804,18 +819,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), - ] + ], ) sg8012 = SpaceGroup( - number = 8012, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2/m11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 2/m 1 1', - symop_list = [ + number=8012, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2/m11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 2/m 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -824,242 +839,242 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg2013 = SpaceGroup( - number = 2013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P12/n1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 2/n 1', - symop_list = [ + number=2013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P12/n1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 2/n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg3013 = SpaceGroup( - number = 3013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P12/a1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 2/a 1', - symop_list = [ + number=3013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P12/a1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 2/a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), - ] + ], ) sg4013 = SpaceGroup( - number = 4013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P112/a', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 2/a', - symop_list = [ + number=4013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P112/a", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 2/a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg5013 = SpaceGroup( - number = 5013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P112/n', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 2/n', - symop_list = [ + number=5013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P112/n", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 2/n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg6013 = SpaceGroup( - number = 6013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2/b11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 2/b 1 1', - symop_list = [ + number=6013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/b11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 2/b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), - ] + ], ) sg7013 = SpaceGroup( - number = 7013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2/n11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 2/n 1 1', - symop_list = [ + number=7013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/n11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 2/n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg8013 = SpaceGroup( - number = 8013, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2/c11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 2/c 1 1', - symop_list = [ + number=8013, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2/c11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 2/c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), - ] + ], ) sg2014 = SpaceGroup( - number = 2014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P121/n1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 21/n 1', - symop_list = [ + number=2014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P121/n1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 21/n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg3014 = SpaceGroup( - number = 3014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P121/a1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 21/a 1', - symop_list = [ + number=3014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P121/a1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 21/a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), - ] + ], ) sg4014 = SpaceGroup( - number = 4014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P1121/a', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 21/a', - symop_list = [ + number=4014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P1121/a", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 21/a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5014 = SpaceGroup( - number = 5014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P1121/n', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 1 1 21/n', - symop_list = [ + number=5014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P1121/n", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 1 1 21/n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg6014 = SpaceGroup( - number = 6014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21/b11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 21/b 1 1', - symop_list = [ + number=6014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/b11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 21/b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), - ] + ], ) sg7014 = SpaceGroup( - number = 7014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21/n11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 21/n 1 1', - symop_list = [ + number=7014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/n11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 21/n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg8014 = SpaceGroup( - number = 8014, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21/c11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'P 21/c 1 1', - symop_list = [ + number=8014, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21/c11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="P 21/c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), - ] + ], ) sg2015 = SpaceGroup( - number = 2015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A12/n1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 2/n 1', - symop_list = [ + number=2015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A12/n1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 2/n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1068,18 +1083,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg3015 = SpaceGroup( - number = 3015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I12/a1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 2/a 1', - symop_list = [ + number=3015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I12/a1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 2/a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1088,18 +1103,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg4015 = SpaceGroup( - number = 4015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A12/a1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 2/a 1', - symop_list = [ + number=4015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A12/a1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 2/a 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1108,18 +1123,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg5015 = SpaceGroup( - number = 5015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C12/n1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 1 2/n 1', - symop_list = [ + number=5015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C12/n1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 1 2/n 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1128,18 +1143,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg6015 = SpaceGroup( - number = 6015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I12/c1', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 2/c 1', - symop_list = [ + number=6015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I12/c1", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 2/c 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1148,18 +1163,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), - ] + ], ) sg7015 = SpaceGroup( - number = 7015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A112/a', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 2/a', - symop_list = [ + number=7015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A112/a", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 2/a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1168,18 +1183,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg8015 = SpaceGroup( - number = 8015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B112/n', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 1 1 2/n', - symop_list = [ + number=8015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B112/n", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="B 1 1 2/n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1188,18 +1203,18 @@ SymOp(Rot_mX_mY_Z, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg9015 = SpaceGroup( - number = 9015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I112/b', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 2/b', - symop_list = [ + number=9015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I112/b", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 2/b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1208,18 +1223,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg10015 = SpaceGroup( - number = 10015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A112/n', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'A 1 1 2/n', - symop_list = [ + number=10015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A112/n", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="A 1 1 2/n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1228,18 +1243,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg11015 = SpaceGroup( - number = 11015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I112/a', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 1 1 2/a', - symop_list = [ + number=11015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I112/a", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 1 1 2/a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_12_0_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1248,18 +1263,18 @@ SymOp(Rot_mX_mY_Z, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg12015 = SpaceGroup( - number = 12015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2/b11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 2/b 1 1', - symop_list = [ + number=12015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2/b11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="B 2/b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1268,18 +1283,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg13015 = SpaceGroup( - number = 13015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2/n11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 2/n 1 1', - symop_list = [ + number=13015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2/n11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 2/n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1288,18 +1303,18 @@ SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg14015 = SpaceGroup( - number = 14015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2/c11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 2/c 1 1', - symop_list = [ + number=14015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2/c11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 2/c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1308,18 +1323,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_0), - ] + ], ) sg15015 = SpaceGroup( - number = 15015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2/c11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'C 2/c 1 1', - symop_list = [ + number=15015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2/c11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="C 2/c 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1328,18 +1343,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), - ] + ], ) sg16015 = SpaceGroup( - number = 16015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2/n11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'B 2/n 1 1', - symop_list = [ + number=16015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2/n11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="B 2/n 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1348,18 +1363,18 @@ SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), - ] + ], ) sg17015 = SpaceGroup( - number = 17015, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2/b11', - point_group_name = 'PG2/m', - crystal_system = 'MONOCLINIC', - pdb_name = 'I 2/b 1 1', - symop_list = [ + number=17015, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2/b11", + point_group_name="PG2/m", + crystal_system="MONOCLINIC", + pdb_name="I 2/b 1 1", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_mY_mZ, Tr_0_0_0), @@ -1368,18 +1383,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), - ] + ], ) sg2020 = SpaceGroup( - number = 2020, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A2122', - point_group_name = 'PG222', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 21 2 2', - symop_list = [ + number=2020, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A2122", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="A 21 2 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -1388,18 +1403,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_Z, Tr_12_12_12), - ] + ], ) sg3020 = SpaceGroup( - number = 3020, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2212', - point_group_name = 'PG222', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 21 2', - symop_list = [ + number=3020, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2212", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 21 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -1408,18 +1423,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_mY_Z, Tr_12_0_12), - ] + ], ) sg2021 = SpaceGroup( - number = 2021, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A222', - point_group_name = 'PG222', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 2 2 2', - symop_list = [ + number=2021, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="A 2 2 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -1428,18 +1443,18 @@ SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_mY_Z, Tr_0_12_12), - ] + ], ) sg3021 = SpaceGroup( - number = 3021, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B222', - point_group_name = 'PG222', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 2 2', - symop_list = [ + number=3021, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B222", + point_group_name="PG222", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 2 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -1448,626 +1463,626 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_mY_Z, Tr_12_0_12), - ] + ], ) sg1025 = SpaceGroup( - number = 1025, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 m m', - symop_list = [ + number=1025, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg2025 = SpaceGroup( - number = 2025, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pm2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m 2 m', - symop_list = [ + number=2025, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pm2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg1026 = SpaceGroup( - number = 1026, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pcm21', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c m 21', - symop_list = [ + number=1026, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pcm21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c m 21", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_12), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), - ] + ], ) sg2026 = SpaceGroup( - number = 2026, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21ma', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 m a', - symop_list = [ + number=2026, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21ma", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg3026 = SpaceGroup( - number = 3026, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21am', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 a m', - symop_list = [ + number=3026, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21am", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg4026 = SpaceGroup( - number = 4026, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pb21m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b 21 m', - symop_list = [ + number=4026, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pb21m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b 21 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg5026 = SpaceGroup( - number = 5026, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pm21b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m 21 b', - symop_list = [ + number=5026, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pm21b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m 21 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg1027 = SpaceGroup( - number = 1027, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2aa', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 a a', - symop_list = [ + number=1027, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2aa", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg2027 = SpaceGroup( - number = 2027, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pb2b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b 2 b', - symop_list = [ + number=2027, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pb2b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b 2 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg1028 = SpaceGroup( - number = 1028, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pbm2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b m 2', - symop_list = [ + number=1028, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pbm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b m 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), - ] + ], ) sg2028 = SpaceGroup( - number = 2028, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2mb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 m b', - symop_list = [ + number=2028, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2mb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg3028 = SpaceGroup( - number = 3028, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2cm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 c m', - symop_list = [ + number=3028, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2cm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg4028 = SpaceGroup( - number = 4028, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pc2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c 2 m', - symop_list = [ + number=4028, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pc2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg5028 = SpaceGroup( - number = 5028, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pm2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m 2 a', - symop_list = [ + number=5028, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pm2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg1029 = SpaceGroup( - number = 1029, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pbc21', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b c 21', - symop_list = [ + number=1029, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pbc21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b c 21", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_12), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg2029 = SpaceGroup( - number = 2029, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21ab', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 a b', - symop_list = [ + number=2029, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21ab", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg3029 = SpaceGroup( - number = 3029, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21ca', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 c a', - symop_list = [ + number=3029, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21ca", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 c a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg4029 = SpaceGroup( - number = 4029, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pc21b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c 21 b', - symop_list = [ + number=4029, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pc21b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c 21 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg5029 = SpaceGroup( - number = 5029, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pb21a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b 21 a', - symop_list = [ + number=5029, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pb21a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b 21 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg1030 = SpaceGroup( - number = 1030, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pcn2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n 2', - symop_list = [ + number=1030, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pcn2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg2030 = SpaceGroup( - number = 2030, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2na', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 n a', - symop_list = [ + number=2030, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2na", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 n a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3030 = SpaceGroup( - number = 3030, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2an', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 a n', - symop_list = [ + number=3030, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2an", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 a n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg4030 = SpaceGroup( - number = 4030, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pb2n', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b 2 n', - symop_list = [ + number=4030, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pb2n", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b 2 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg5030 = SpaceGroup( - number = 5030, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pn2b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n 2 b', - symop_list = [ + number=5030, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pn2b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n 2 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1031 = SpaceGroup( - number = 1031, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pnm21', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n m 21', - symop_list = [ + number=1031, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pnm21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n m 21", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), - ] + ], ) sg2031 = SpaceGroup( - number = 2031, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21mn', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 m n', - symop_list = [ + number=2031, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21mn", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 m n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg3031 = SpaceGroup( - number = 3031, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21nm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 n m', - symop_list = [ + number=3031, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21nm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 n m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg4031 = SpaceGroup( - number = 4031, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pn21m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n 21 m', - symop_list = [ + number=4031, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pn21m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n 21 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg5031 = SpaceGroup( - number = 5031, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pm21n', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m 21 n', - symop_list = [ + number=5031, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pm21n", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P m 21 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg1032 = SpaceGroup( - number = 1032, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2cb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 c b', - symop_list = [ + number=1032, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2cb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2032 = SpaceGroup( - number = 2032, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pc2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c 2 a', - symop_list = [ + number=2032, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pc2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1033 = SpaceGroup( - number = 1033, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pbn21', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b n 21', - symop_list = [ + number=1033, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pbn21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P b n 21", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_12), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg2033 = SpaceGroup( - number = 2033, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21nb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 n b', - symop_list = [ + number=2033, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21nb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 n b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg3033 = SpaceGroup( - number = 3033, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P21cn', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 21 c n', - symop_list = [ + number=3033, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P21cn", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 21 c n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg4033 = SpaceGroup( - number = 4033, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pc21n', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c 21 n', - symop_list = [ + number=4033, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pc21n", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P c 21 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg5033 = SpaceGroup( - number = 5033, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pn21a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n 21 a', - symop_list = [ + number=5033, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pn21a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n 21 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1034 = SpaceGroup( - number = 1034, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'P2nn', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P 2 n n', - symop_list = [ + number=1034, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="P2nn", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P 2 n n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2034 = SpaceGroup( - number = 2034, - num_sym_equiv = 4, - num_primitive_sym_equiv = 4, - short_name = 'Pn2n', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n 2 n', - symop_list = [ + number=2034, + num_sym_equiv=4, + num_primitive_sym_equiv=4, + short_name="Pn2n", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="P n 2 n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1035 = SpaceGroup( - number = 1035, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 2 m m', - symop_list = [ + number=1035, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2076,18 +2091,18 @@ SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2035 = SpaceGroup( - number = 2035, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bm2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m 2 m', - symop_list = [ + number=2035, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bm2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2096,18 +2111,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1036 = SpaceGroup( - number = 1036, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ccm21', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c m 21', - symop_list = [ + number=1036, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ccm21", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C c m 21", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_12), SymOp(Rot_mX_Y_Z, Tr_0_0_12), @@ -2116,18 +2131,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), - ] + ], ) sg2036 = SpaceGroup( - number = 2036, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A21ma', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 21 m a', - symop_list = [ + number=2036, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A21ma", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A 21 m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2136,18 +2151,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg3036 = SpaceGroup( - number = 3036, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A21am', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 21 a m', - symop_list = [ + number=3036, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A21am", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A 21 a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), @@ -2156,18 +2171,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4036 = SpaceGroup( - number = 4036, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bb21m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b 21 m', - symop_list = [ + number=4036, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bb21m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B b 21 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2176,18 +2191,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5036 = SpaceGroup( - number = 5036, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bm21b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m 21 b', - symop_list = [ + number=5036, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bm21b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B m 21 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2196,18 +2211,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1037 = SpaceGroup( - number = 1037, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'A2aa', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A 2 a a', - symop_list = [ + number=1037, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="A2aa", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A 2 a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), @@ -2216,18 +2231,18 @@ SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2037 = SpaceGroup( - number = 2037, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bb2b', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b 2 b', - symop_list = [ + number=2037, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bb2b", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B b 2 b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2236,18 +2251,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1038 = SpaceGroup( - number = 1038, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bmm2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m m 2', - symop_list = [ + number=1038, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bmm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B m m 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2256,18 +2271,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg2038 = SpaceGroup( - number = 2038, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 m m', - symop_list = [ + number=2038, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2276,18 +2291,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3038 = SpaceGroup( - number = 3038, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C 2 m m', - symop_list = [ + number=3038, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2296,18 +2311,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg4038 = SpaceGroup( - number = 4038, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Cm2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C m 2 m', - symop_list = [ + number=4038, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Cm2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2316,18 +2331,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg5038 = SpaceGroup( - number = 5038, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Am2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m 2 m', - symop_list = [ + number=5038, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Am2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2336,18 +2351,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1039 = SpaceGroup( - number = 1039, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bma2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m a 2', - symop_list = [ + number=1039, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bma2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B m a 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), @@ -2356,18 +2371,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), - ] + ], ) sg2039 = SpaceGroup( - number = 2039, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2cm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 c m', - symop_list = [ + number=2039, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2cm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), @@ -2376,18 +2391,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg3039 = SpaceGroup( - number = 3039, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2mb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C 2 m b', - symop_list = [ + number=3039, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2mb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), @@ -2396,18 +2411,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg4039 = SpaceGroup( - number = 4039, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Cm2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C m 2 a', - symop_list = [ + number=4039, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Cm2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C m 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), @@ -2416,18 +2431,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg5039 = SpaceGroup( - number = 5039, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ac2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A c 2 m', - symop_list = [ + number=5039, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ac2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A c 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2436,18 +2451,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg1040 = SpaceGroup( - number = 1040, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bbm2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b m 2', - symop_list = [ + number=1040, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bbm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B b m 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2456,18 +2471,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), - ] + ], ) sg2040 = SpaceGroup( - number = 2040, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2mb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 m b', - symop_list = [ + number=2040, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2mb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), @@ -2476,18 +2491,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg3040 = SpaceGroup( - number = 3040, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2cm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C 2 c m', - symop_list = [ + number=3040, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2cm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), @@ -2496,18 +2511,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg4040 = SpaceGroup( - number = 4040, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Cc2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c 2 m', - symop_list = [ + number=4040, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Cc2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C c 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), @@ -2516,18 +2531,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg5040 = SpaceGroup( - number = 5040, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Am2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m 2 a', - symop_list = [ + number=5040, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Am2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A m 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), @@ -2536,18 +2551,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1041 = SpaceGroup( - number = 1041, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Bba2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b a 2', - symop_list = [ + number=1041, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Bba2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B b a 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), @@ -2556,18 +2571,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_0_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), - ] + ], ) sg2041 = SpaceGroup( - number = 2041, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'B2cb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B 2 c b', - symop_list = [ + number=2041, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="B2cb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="B 2 c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), @@ -2576,18 +2591,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg3041 = SpaceGroup( - number = 3041, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'C2cb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C 2 c b', - symop_list = [ + number=3041, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="C2cb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C 2 c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), @@ -2596,18 +2611,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4041 = SpaceGroup( - number = 4041, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Cc2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c 2 a', - symop_list = [ + number=4041, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Cc2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="C c 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_12), @@ -2616,18 +2631,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg5041 = SpaceGroup( - number = 5041, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ac2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A c 2 a', - symop_list = [ + number=5041, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ac2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="A c 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), @@ -2636,18 +2651,18 @@ SymOp(Rot_mX_Y_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1042 = SpaceGroup( - number = 1042, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'F2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'F 2 m m', - symop_list = [ + number=1042, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="F2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2664,18 +2679,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg2042 = SpaceGroup( - number = 2042, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Fm2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'F m 2 m', - symop_list = [ + number=2042, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Fm2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2692,18 +2707,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg1043 = SpaceGroup( - number = 1043, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'F2dd', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'F 2 d d', - symop_list = [ + number=1043, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="F2dd", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F 2 d d", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_14_14_14), @@ -2720,18 +2735,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_34_34_14), SymOp(Rot_X_Y_mZ, Tr_34_34_14), - ] + ], ) sg2043 = SpaceGroup( - number = 2043, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Fd2d', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'F d 2 d', - symop_list = [ + number=2043, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Fd2d", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="F d 2 d", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_14_14_14), @@ -2748,18 +2763,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_Z, Tr_34_34_14), SymOp(Rot_X_Y_mZ, Tr_34_34_14), - ] + ], ) sg1044 = SpaceGroup( - number = 1044, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2mm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I 2 m m', - symop_list = [ + number=1044, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2mm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), @@ -2768,18 +2783,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2044 = SpaceGroup( - number = 2044, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Im2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m 2 m', - symop_list = [ + number=2044, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Im2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I m 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_0), @@ -2788,18 +2803,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1045 = SpaceGroup( - number = 1045, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2cb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I 2 c b', - symop_list = [ + number=1045, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2cb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), @@ -2808,18 +2823,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2045 = SpaceGroup( - number = 2045, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ic2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I c 2 a', - symop_list = [ + number=2045, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ic2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I c 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2828,18 +2843,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1046 = SpaceGroup( - number = 1046, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ibm2', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I b m 2', - symop_list = [ + number=1046, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ibm2", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I b m 2", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_mY_Z, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_12_0), @@ -2848,18 +2863,18 @@ SymOp(Rot_mX_mY_Z, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), - ] + ], ) sg2046 = SpaceGroup( - number = 2046, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2mb', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I 2 m b', - symop_list = [ + number=2046, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2mb", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), @@ -2868,18 +2883,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3046 = SpaceGroup( - number = 3046, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'I2cm', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I 2 c m', - symop_list = [ + number=3046, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="I2cm", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I 2 c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), @@ -2888,18 +2903,18 @@ SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg4046 = SpaceGroup( - number = 4046, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Ic2m', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I c 2 m', - symop_list = [ + number=4046, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Ic2m", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I c 2 m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_0_0_12), @@ -2908,18 +2923,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg5046 = SpaceGroup( - number = 5046, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Im2a', - point_group_name = 'PGmm2', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m 2 a', - symop_list = [ + number=5046, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Im2a", + point_group_name="PGmm2", + crystal_system="ORTHORHOMBIC", + pdb_name="I m 2 a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_Z, Tr_12_0_0), @@ -2928,18 +2943,18 @@ SymOp(Rot_mX_Y_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1049 = SpaceGroup( - number = 1049, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m a a', - symop_list = [ + number=1049, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -2948,18 +2963,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg2049 = SpaceGroup( - number = 2049, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b m b', - symop_list = [ + number=2049, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -2968,18 +2983,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg1050 = SpaceGroup( - number = 1050, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pncb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n c b', - symop_list = [ + number=1050, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pncb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -2988,18 +3003,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2050 = SpaceGroup( - number = 2050, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pncb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n c b', - symop_list = [ + number=2050, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pncb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -3008,18 +3023,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg3050 = SpaceGroup( - number = 3050, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcna', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n a', - symop_list = [ + number=3050, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcna", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3028,18 +3043,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg4050 = SpaceGroup( - number = 4050, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcna', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n a', - symop_list = [ + number=4050, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcna", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3048,18 +3063,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg1051 = SpaceGroup( - number = 1051, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m m b', - symop_list = [ + number=1051, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3068,18 +3083,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg2051 = SpaceGroup( - number = 2051, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b m m', - symop_list = [ + number=2051, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3088,18 +3103,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg3051 = SpaceGroup( - number = 3051, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c m m', - symop_list = [ + number=3051, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3108,18 +3123,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg4051 = SpaceGroup( - number = 4051, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmcm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m c m', - symop_list = [ + number=4051, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -3128,18 +3143,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg5051 = SpaceGroup( - number = 5051, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m a m', - symop_list = [ + number=5051, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3148,18 +3163,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg1052 = SpaceGroup( - number = 1052, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnnb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n n b', - symop_list = [ + number=1052, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnnb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n n b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3168,18 +3183,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg2052 = SpaceGroup( - number = 2052, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbnn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b n n', - symop_list = [ + number=2052, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbnn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b n n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3188,18 +3203,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg3052 = SpaceGroup( - number = 3052, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcnn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n n', - symop_list = [ + number=3052, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcnn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3208,18 +3223,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg4052 = SpaceGroup( - number = 4052, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pncn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n c n', - symop_list = [ + number=4052, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pncn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -3228,18 +3243,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg5052 = SpaceGroup( - number = 5052, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnan', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n a n', - symop_list = [ + number=5052, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnan", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n a n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3248,18 +3263,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1053 = SpaceGroup( - number = 1053, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n m b', - symop_list = [ + number=1053, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3268,18 +3283,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2053 = SpaceGroup( - number = 2053, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbmn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b m n', - symop_list = [ + number=2053, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbmn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b m n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3288,18 +3303,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg3053 = SpaceGroup( - number = 3053, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcnm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n m', - symop_list = [ + number=3053, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcnm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3308,18 +3323,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg4053 = SpaceGroup( - number = 4053, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pncm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n c m', - symop_list = [ + number=4053, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pncm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3328,18 +3343,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg5053 = SpaceGroup( - number = 5053, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pman', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m a n', - symop_list = [ + number=5053, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pman", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m a n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3348,18 +3363,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg1054 = SpaceGroup( - number = 1054, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pccb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c c b', - symop_list = [ + number=1054, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pccb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3368,18 +3383,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg2054 = SpaceGroup( - number = 2054, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b a a', - symop_list = [ + number=2054, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3388,18 +3403,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg3054 = SpaceGroup( - number = 3054, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c a a', - symop_list = [ + number=3054, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3408,18 +3423,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg4054 = SpaceGroup( - number = 4054, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbcb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b c b', - symop_list = [ + number=4054, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbcb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -3428,18 +3443,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg5054 = SpaceGroup( - number = 5054, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b a b', - symop_list = [ + number=5054, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3448,18 +3463,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg1055 = SpaceGroup( - number = 1055, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmcb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m c b', - symop_list = [ + number=1055, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmcb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3468,18 +3483,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2055 = SpaceGroup( - number = 2055, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcma', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c m a', - symop_list = [ + number=2055, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3488,18 +3503,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1056 = SpaceGroup( - number = 1056, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n a a', - symop_list = [ + number=1056, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3508,18 +3523,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg2056 = SpaceGroup( - number = 2056, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbnb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b n b', - symop_list = [ + number=2056, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbnb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b n b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3528,18 +3543,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1057 = SpaceGroup( - number = 1057, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c a m', - symop_list = [ + number=1057, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3548,18 +3563,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg2057 = SpaceGroup( - number = 2057, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmca', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m c a', - symop_list = [ + number=2057, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m c a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -3568,18 +3583,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3057 = SpaceGroup( - number = 3057, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m a b', - symop_list = [ + number=3057, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3588,18 +3603,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg4057 = SpaceGroup( - number = 4057, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbma', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b m a', - symop_list = [ + number=4057, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3608,18 +3623,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg5057 = SpaceGroup( - number = 5057, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c m b', - symop_list = [ + number=5057, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3628,18 +3643,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1058 = SpaceGroup( - number = 1058, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmnn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m n n', - symop_list = [ + number=1058, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmnn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m n n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3648,18 +3663,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2058 = SpaceGroup( - number = 2058, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnmn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n m n', - symop_list = [ + number=2058, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnmn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n m n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3668,18 +3683,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2059 = SpaceGroup( - number = 2059, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n m m', - symop_list = [ + number=2059, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3688,18 +3703,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_0), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg3059 = SpaceGroup( - number = 3059, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n m m', - symop_list = [ + number=3059, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3708,18 +3723,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg4059 = SpaceGroup( - number = 4059, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmnm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m n m', - symop_list = [ + number=4059, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmnm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m n m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3728,18 +3743,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_0), - ] + ], ) sg5059 = SpaceGroup( - number = 5059, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmnm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m n m', - symop_list = [ + number=5059, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmnm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m n m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -3748,18 +3763,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg1060 = SpaceGroup( - number = 1060, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcan', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c a n', - symop_list = [ + number=1060, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcan", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c a n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3768,18 +3783,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2060 = SpaceGroup( - number = 2060, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnca', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n c a', - symop_list = [ + number=2060, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnca", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n c a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3788,18 +3803,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_0), - ] + ], ) sg3060 = SpaceGroup( - number = 3060, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n a b', - symop_list = [ + number=3060, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -3808,18 +3823,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4060 = SpaceGroup( - number = 4060, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbna', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b n a', - symop_list = [ + number=4060, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbna", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b n a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3828,18 +3843,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5060 = SpaceGroup( - number = 5060, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcnb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c n b', - symop_list = [ + number=5060, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcnb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c n b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3848,18 +3863,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg1061 = SpaceGroup( - number = 1061, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c a b', - symop_list = [ + number=1061, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3868,18 +3883,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1062 = SpaceGroup( - number = 1062, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmnb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m n b', - symop_list = [ + number=1062, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmnb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m n b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3888,18 +3903,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2062 = SpaceGroup( - number = 2062, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pbnm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P b n m', - symop_list = [ + number=2062, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pbnm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P b n m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_12), @@ -3908,18 +3923,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg3062 = SpaceGroup( - number = 3062, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pcmn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P c m n', - symop_list = [ + number=3062, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pcmn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P c m n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -3928,18 +3943,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg4062 = SpaceGroup( - number = 4062, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pmcn', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P m c n', - symop_list = [ + number=4062, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pmcn", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P m c n", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_12), @@ -3948,18 +3963,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_0), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg5062 = SpaceGroup( - number = 5062, - num_sym_equiv = 8, - num_primitive_sym_equiv = 8, - short_name = 'Pnam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'P n a m', - symop_list = [ + number=5062, + num_sym_equiv=8, + num_primitive_sym_equiv=8, + short_name="Pnam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="P n a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_12), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -3968,18 +3983,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg1063 = SpaceGroup( - number = 1063, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Ccmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c m m', - symop_list = [ + number=1063, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Ccmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C c m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -3996,18 +4011,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2063 = SpaceGroup( - number = 2063, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Amma', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m m a', - symop_list = [ + number=2063, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Amma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A m m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4024,18 +4039,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg3063 = SpaceGroup( - number = 3063, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Amam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m a m', - symop_list = [ + number=3063, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Amam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A m a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4052,18 +4067,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4063 = SpaceGroup( - number = 4063, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b m m', - symop_list = [ + number=4063, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -4080,18 +4095,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5063 = SpaceGroup( - number = 5063, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bmmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m m b', - symop_list = [ + number=5063, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bmmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B m m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -4108,18 +4123,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1064 = SpaceGroup( - number = 1064, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Ccmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c m b', - symop_list = [ + number=1064, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Ccmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C c m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4136,18 +4151,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2064 = SpaceGroup( - number = 2064, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Abma', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A b m a', - symop_list = [ + number=2064, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Abma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A b m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4164,18 +4179,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3064 = SpaceGroup( - number = 3064, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Acam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A c a m', - symop_list = [ + number=3064, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Acam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A c a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -4192,18 +4207,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4064 = SpaceGroup( - number = 4064, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbcm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b c m', - symop_list = [ + number=4064, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -4220,18 +4235,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5064 = SpaceGroup( - number = 5064, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bmab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m a b', - symop_list = [ + number=5064, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bmab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B m a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -4248,18 +4263,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1065 = SpaceGroup( - number = 1065, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Ammm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m m m', - symop_list = [ + number=1065, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Ammm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A m m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4276,18 +4291,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2065 = SpaceGroup( - number = 2065, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bmmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m m m', - symop_list = [ + number=2065, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bmmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B m m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4304,18 +4319,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1066 = SpaceGroup( - number = 1066, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Amaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A m a a', - symop_list = [ + number=1066, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Amaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A m a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4332,18 +4347,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg2066 = SpaceGroup( - number = 2066, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b m b', - symop_list = [ + number=2066, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4360,18 +4375,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1067 = SpaceGroup( - number = 1067, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Cmmb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C m m b', - symop_list = [ + number=1067, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Cmmb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C m m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4388,18 +4403,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg2067 = SpaceGroup( - number = 2067, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Abmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A b m m', - symop_list = [ + number=2067, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Abmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A b m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4416,18 +4431,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg3067 = SpaceGroup( - number = 3067, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Acmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A c m m', - symop_list = [ + number=3067, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Acmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A c m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -4444,18 +4459,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg4067 = SpaceGroup( - number = 4067, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bmcm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m c m', - symop_list = [ + number=4067, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bmcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B m c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4472,18 +4487,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5067 = SpaceGroup( - number = 5067, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bmam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B m a m', - symop_list = [ + number=5067, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bmam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B m a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4500,18 +4515,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_0_12), - ] + ], ) sg1068 = SpaceGroup( - number = 1068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Cccb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'C c c b', - symop_list = [ + number=1068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Cccb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="C c c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_12_0_12), @@ -4528,18 +4543,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_0), - ] + ], ) sg2068 = SpaceGroup( - number = 2068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Abaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A b a a', - symop_list = [ + number=2068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Abaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A b a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4556,18 +4571,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg3068 = SpaceGroup( - number = 3068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Abaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A b a a', - symop_list = [ + number=3068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Abaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A b a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_12_0), @@ -4584,18 +4599,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg4068 = SpaceGroup( - number = 4068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Acaa', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'A c a a', - symop_list = [ + number=4068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Acaa", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="A c a a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4612,18 +4627,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg5068 = SpaceGroup( - number = 5068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbcb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b c b', - symop_list = [ + number=5068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbcb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4640,18 +4655,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg6068 = SpaceGroup( - number = 6068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbcb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b c b', - symop_list = [ + number=6068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbcb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4668,18 +4683,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg7068 = SpaceGroup( - number = 7068, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Bbab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'B b a b', - symop_list = [ + number=7068, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Bbab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="B b a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_12_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4696,18 +4711,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg1072 = SpaceGroup( - number = 1072, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Imcb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m c b', - symop_list = [ + number=1072, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Imcb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I m c b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4724,18 +4739,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2072 = SpaceGroup( - number = 2072, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Icma', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I c m a', - symop_list = [ + number=2072, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Icma", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I c m a", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4752,18 +4767,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_0_12), - ] + ], ) sg1073 = SpaceGroup( - number = 1073, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Icab', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I c a b', - symop_list = [ + number=1073, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Icab", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I c a b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -4780,18 +4795,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg1074 = SpaceGroup( - number = 1074, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Immb', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m m b', - symop_list = [ + number=1074, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Immb", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I m m b", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4808,18 +4823,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_0_12_12), - ] + ], ) sg2074 = SpaceGroup( - number = 2074, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Ibmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I b m m', - symop_list = [ + number=2074, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Ibmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I b m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_12), SymOp(Rot_mX_Y_mZ, Tr_0_0_0), @@ -4836,18 +4851,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_0), SymOp(Rot_X_mY_Z, Tr_12_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) sg3074 = SpaceGroup( - number = 3074, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Icmm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I c m m', - symop_list = [ + number=3074, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Icmm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I c m m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_12_0), SymOp(Rot_mX_Y_mZ, Tr_0_12_0), @@ -4864,18 +4879,18 @@ SymOp(Rot_mX_Y_Z, Tr_12_0_12), SymOp(Rot_X_mY_Z, Tr_12_0_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg4074 = SpaceGroup( - number = 4074, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Imcm', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m c m', - symop_list = [ + number=4074, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Imcm", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I m c m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_12_0_0), SymOp(Rot_mX_Y_mZ, Tr_12_0_0), @@ -4892,18 +4907,18 @@ SymOp(Rot_mX_Y_Z, Tr_0_12_12), SymOp(Rot_X_mY_Z, Tr_0_12_12), SymOp(Rot_X_Y_mZ, Tr_12_12_12), - ] + ], ) sg5074 = SpaceGroup( - number = 5074, - num_sym_equiv = 16, - num_primitive_sym_equiv = 16, - short_name = 'Imam', - point_group_name = 'PGmmm', - crystal_system = 'ORTHORHOMBIC', - pdb_name = 'I m a m', - symop_list = [ + number=5074, + num_sym_equiv=16, + num_primitive_sym_equiv=16, + short_name="Imam", + point_group_name="PGmmm", + crystal_system="ORTHORHOMBIC", + pdb_name="I m a m", + symop_list=[ SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_X_mY_mZ, Tr_0_0_0), SymOp(Rot_mX_Y_mZ, Tr_0_0_12), @@ -4920,7 +4935,7 @@ SymOp(Rot_mX_Y_Z, Tr_12_12_12), SymOp(Rot_X_mY_Z, Tr_12_12_0), SymOp(Rot_X_Y_mZ, Tr_12_12_0), - ] + ], ) ############################################################################## @@ -4929,36 +4944,253 @@ # list of all groups in this module sgtbxSpaceGroupList = [ - sg2003, sg2004, sg4005, sg5005, sg6005, sg7005, sg8005, sg9005, - sg10005, sg2006, sg2007, sg3007, sg4007, sg5007, sg6007, sg7007, - sg8007, sg2008, sg3008, sg4008, sg5008, sg6008, sg7008, sg8008, - sg2009, sg3009, sg4009, sg5009, sg6009, sg7009, sg8009, sg9009, - sg10009, sg11009, sg12009, sg13009, sg14009, sg15009, sg16009, - sg17009, sg2010, sg2011, sg2012, sg3012, sg4012, sg5012, sg6012, - sg7012, sg8012, sg2013, sg3013, sg4013, sg5013, sg6013, sg7013, - sg8013, sg2014, sg3014, sg4014, sg5014, sg6014, sg7014, sg8014, - sg2015, sg3015, sg4015, sg5015, sg6015, sg7015, sg8015, sg9015, - sg10015, sg11015, sg12015, sg13015, sg14015, sg15015, sg16015, - sg17015, sg2020, sg3020, sg2021, sg3021, sg1025, sg2025, sg1026, - sg2026, sg3026, sg4026, sg5026, sg1027, sg2027, sg1028, sg2028, - sg3028, sg4028, sg5028, sg1029, sg2029, sg3029, sg4029, sg5029, - sg1030, sg2030, sg3030, sg4030, sg5030, sg1031, sg2031, sg3031, - sg4031, sg5031, sg1032, sg2032, sg1033, sg2033, sg3033, sg4033, - sg5033, sg1034, sg2034, sg1035, sg2035, sg1036, sg2036, sg3036, - sg4036, sg5036, sg1037, sg2037, sg1038, sg2038, sg3038, sg4038, - sg5038, sg1039, sg2039, sg3039, sg4039, sg5039, sg1040, sg2040, - sg3040, sg4040, sg5040, sg1041, sg2041, sg3041, sg4041, sg5041, - sg1042, sg2042, sg1043, sg2043, sg1044, sg2044, sg1045, sg2045, - sg1046, sg2046, sg3046, sg4046, sg5046, sg1049, sg2049, sg1050, - sg2050, sg3050, sg4050, sg1051, sg2051, sg3051, sg4051, sg5051, - sg1052, sg2052, sg3052, sg4052, sg5052, sg1053, sg2053, sg3053, - sg4053, sg5053, sg1054, sg2054, sg3054, sg4054, sg5054, sg1055, - sg2055, sg1056, sg2056, sg1057, sg2057, sg3057, sg4057, sg5057, - sg1058, sg2058, sg2059, sg3059, sg4059, sg5059, sg1060, sg2060, - sg3060, sg4060, sg5060, sg1061, sg1062, sg2062, sg3062, sg4062, - sg5062, sg1063, sg2063, sg3063, sg4063, sg5063, sg1064, sg2064, - sg3064, sg4064, sg5064, sg1065, sg2065, sg1066, sg2066, sg1067, - sg2067, sg3067, sg4067, sg5067, sg1068, sg2068, sg3068, sg4068, - sg5068, sg6068, sg7068, sg1072, sg2072, sg1073, sg1074, sg2074, - sg3074, sg4074, sg5074, + sg2003, + sg2004, + sg4005, + sg5005, + sg6005, + sg7005, + sg8005, + sg9005, + sg10005, + sg2006, + sg2007, + sg3007, + sg4007, + sg5007, + sg6007, + sg7007, + sg8007, + sg2008, + sg3008, + sg4008, + sg5008, + sg6008, + sg7008, + sg8008, + sg2009, + sg3009, + sg4009, + sg5009, + sg6009, + sg7009, + sg8009, + sg9009, + sg10009, + sg11009, + sg12009, + sg13009, + sg14009, + sg15009, + sg16009, + sg17009, + sg2010, + sg2011, + sg2012, + sg3012, + sg4012, + sg5012, + sg6012, + sg7012, + sg8012, + sg2013, + sg3013, + sg4013, + sg5013, + sg6013, + sg7013, + sg8013, + sg2014, + sg3014, + sg4014, + sg5014, + sg6014, + sg7014, + sg8014, + sg2015, + sg3015, + sg4015, + sg5015, + sg6015, + sg7015, + sg8015, + sg9015, + sg10015, + sg11015, + sg12015, + sg13015, + sg14015, + sg15015, + sg16015, + sg17015, + sg2020, + sg3020, + sg2021, + sg3021, + sg1025, + sg2025, + sg1026, + sg2026, + sg3026, + sg4026, + sg5026, + sg1027, + sg2027, + sg1028, + sg2028, + sg3028, + sg4028, + sg5028, + sg1029, + sg2029, + sg3029, + sg4029, + sg5029, + sg1030, + sg2030, + sg3030, + sg4030, + sg5030, + sg1031, + sg2031, + sg3031, + sg4031, + sg5031, + sg1032, + sg2032, + sg1033, + sg2033, + sg3033, + sg4033, + sg5033, + sg1034, + sg2034, + sg1035, + sg2035, + sg1036, + sg2036, + sg3036, + sg4036, + sg5036, + sg1037, + sg2037, + sg1038, + sg2038, + sg3038, + sg4038, + sg5038, + sg1039, + sg2039, + sg3039, + sg4039, + sg5039, + sg1040, + sg2040, + sg3040, + sg4040, + sg5040, + sg1041, + sg2041, + sg3041, + sg4041, + sg5041, + sg1042, + sg2042, + sg1043, + sg2043, + sg1044, + sg2044, + sg1045, + sg2045, + sg1046, + sg2046, + sg3046, + sg4046, + sg5046, + sg1049, + sg2049, + sg1050, + sg2050, + sg3050, + sg4050, + sg1051, + sg2051, + sg3051, + sg4051, + sg5051, + sg1052, + sg2052, + sg3052, + sg4052, + sg5052, + sg1053, + sg2053, + sg3053, + sg4053, + sg5053, + sg1054, + sg2054, + sg3054, + sg4054, + sg5054, + sg1055, + sg2055, + sg1056, + sg2056, + sg1057, + sg2057, + sg3057, + sg4057, + sg5057, + sg1058, + sg2058, + sg2059, + sg3059, + sg4059, + sg5059, + sg1060, + sg2060, + sg3060, + sg4060, + sg5060, + sg1061, + sg1062, + sg2062, + sg3062, + sg4062, + sg5062, + sg1063, + sg2063, + sg3063, + sg4063, + sg5063, + sg1064, + sg2064, + sg3064, + sg4064, + sg5064, + sg1065, + sg2065, + sg1066, + sg2066, + sg1067, + sg2067, + sg3067, + sg4067, + sg5067, + sg1068, + sg2068, + sg3068, + sg4068, + sg5068, + sg6068, + sg7068, + sg1072, + sg2072, + sg1073, + sg1074, + sg2074, + sg3074, + sg4074, + sg5074, ] diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 2b2a31d8..7a20ba15 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -9,104 +9,104 @@ import numpy ## 64 unique rotation matricies -Rot_Z_mY_X = numpy.array([[ 0.0, 0.0, 1.0], [ 0.0,-1.0, 0.0], [ 1.0, 0.0, 0.0]], float) -Rot_Y_mX_mZ = numpy.array([[ 0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_XmY_X_mZ = numpy.array([[ 1.0,-1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mX_Y_mZ = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_X_mZ_Y = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0], [ 0.0, 1.0, 0.0]], float) -Rot_Y_mXY_Z = numpy.array([[ 0.0, 1.0, 0.0], [-1.0, 1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Y_mX_Z = numpy.array([[ 0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_XmY_X_Z = numpy.array([[ 1.0,-1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mX_mXY_mZ = numpy.array([[-1.0, 0.0, 0.0], [-1.0, 1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_Y_Z_X = numpy.array([[ 0.0, 1.0, 0.0], [ 0.0, 0.0, 1.0], [ 1.0, 0.0, 0.0]], float) -Rot_mY_mZ_X = numpy.array([[ 0.0,-1.0, 0.0], [ 0.0, 0.0,-1.0], [ 1.0, 0.0, 0.0]], float) -Rot_X_Z_mY = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0], [ 0.0,-1.0, 0.0]], float) -Rot_XmY_mY_Z = numpy.array([[ 1.0,-1.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Y_X_mZ = numpy.array([[ 0.0, 1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_Y_mZ_X = numpy.array([[ 0.0, 1.0, 0.0], [ 0.0, 0.0,-1.0], [ 1.0, 0.0, 0.0]], float) -Rot_mXY_Y_Z = numpy.array([[-1.0, 1.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mX_mY_mZ = numpy.array([[-1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_X_Y_mZ = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mXY_mX_Z = numpy.array([[-1.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mZ_mY_mX = numpy.array([[ 0.0, 0.0,-1.0], [ 0.0,-1.0, 0.0], [-1.0, 0.0, 0.0]], float) -Rot_X_mZ_mY = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0], [ 0.0,-1.0, 0.0]], float) -Rot_X_Y_Z = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mY_mX_mZ = numpy.array([[ 0.0,-1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mY_X_Z = numpy.array([[ 0.0,-1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Z_X_Y = numpy.array([[ 0.0, 0.0, 1.0], [ 1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0]], float) -Rot_X_XmY_Z = numpy.array([[ 1.0, 0.0, 0.0], [ 1.0,-1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mY_X_mZ = numpy.array([[ 0.0,-1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mY_Z_mX = numpy.array([[ 0.0,-1.0, 0.0], [ 0.0, 0.0, 1.0], [-1.0, 0.0, 0.0]], float) -Rot_mY_Z_X = numpy.array([[ 0.0,-1.0, 0.0], [ 0.0, 0.0, 1.0], [ 1.0, 0.0, 0.0]], float) -Rot_mX_mZ_mY = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0], [ 0.0,-1.0, 0.0]], float) -Rot_mX_Z_Y = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0], [ 0.0, 1.0, 0.0]], float) -Rot_mZ_mX_mY = numpy.array([[ 0.0, 0.0,-1.0], [-1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0]], float) -Rot_X_XmY_mZ = numpy.array([[ 1.0, 0.0, 0.0], [ 1.0,-1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mY_XmY_mZ = numpy.array([[ 0.0,-1.0, 0.0], [ 1.0,-1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_Z_X_mY = numpy.array([[ 0.0, 0.0, 1.0], [ 1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0]], float) -Rot_mZ_mY_X = numpy.array([[ 0.0, 0.0,-1.0], [ 0.0,-1.0, 0.0], [ 1.0, 0.0, 0.0]], float) -Rot_X_Z_Y = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0], [ 0.0, 1.0, 0.0]], float) -Rot_Z_mX_mY = numpy.array([[ 0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0]], float) -Rot_mX_Z_mY = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0], [ 0.0,-1.0, 0.0]], float) -Rot_X_mY_Z = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mY_mX_Z = numpy.array([[ 0.0,-1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Z_mY_mX = numpy.array([[ 0.0, 0.0, 1.0], [ 0.0,-1.0, 0.0], [-1.0, 0.0, 0.0]], float) -Rot_mX_mY_Z = numpy.array([[-1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Z_Y_X = numpy.array([[ 0.0, 0.0, 1.0], [ 0.0, 1.0, 0.0], [ 1.0, 0.0, 0.0]], float) -Rot_mZ_Y_mX = numpy.array([[ 0.0, 0.0,-1.0], [ 0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]], float) -Rot_Y_Z_mX = numpy.array([[ 0.0, 1.0, 0.0], [ 0.0, 0.0, 1.0], [-1.0, 0.0, 0.0]], float) -Rot_mY_XmY_Z = numpy.array([[ 0.0,-1.0, 0.0], [ 1.0,-1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_mXY_Y_mZ = numpy.array([[-1.0, 1.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mZ_mX_Y = numpy.array([[ 0.0, 0.0,-1.0], [-1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0]], float) -Rot_mX_mZ_Y = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0], [ 0.0, 1.0, 0.0]], float) -Rot_mX_Y_Z = numpy.array([[-1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_X_mY_mZ = numpy.array([[ 1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mZ_X_Y = numpy.array([[ 0.0, 0.0,-1.0], [ 1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0]], float) -Rot_Y_mZ_mX = numpy.array([[ 0.0, 1.0, 0.0], [ 0.0, 0.0,-1.0], [-1.0, 0.0, 0.0]], float) -Rot_mY_mZ_mX = numpy.array([[ 0.0,-1.0, 0.0], [ 0.0, 0.0,-1.0], [-1.0, 0.0, 0.0]], float) -Rot_mZ_Y_X = numpy.array([[ 0.0, 0.0,-1.0], [ 0.0, 1.0, 0.0], [ 1.0, 0.0, 0.0]], float) -Rot_Z_Y_mX = numpy.array([[ 0.0, 0.0, 1.0], [ 0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]], float) -Rot_mXY_mX_mZ = numpy.array([[-1.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_XmY_mY_mZ = numpy.array([[ 1.0,-1.0, 0.0], [ 0.0,-1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_Z_mX_Y = numpy.array([[ 0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [ 0.0, 1.0, 0.0]], float) -Rot_mX_mXY_Z = numpy.array([[-1.0, 0.0, 0.0], [-1.0, 1.0, 0.0], [ 0.0, 0.0, 1.0]], float) -Rot_Y_mXY_mZ = numpy.array([[ 0.0, 1.0, 0.0], [-1.0, 1.0, 0.0], [ 0.0, 0.0,-1.0]], float) -Rot_mZ_X_mY = numpy.array([[ 0.0, 0.0,-1.0], [ 1.0, 0.0, 0.0], [ 0.0,-1.0, 0.0]], float) -Rot_Y_X_Z = numpy.array([[ 0.0, 1.0, 0.0], [ 1.0, 0.0, 0.0], [ 0.0, 0.0, 1.0]], float) +Rot_Z_mY_X = numpy.array([[0.0, 0.0, 1.0], [0.0, -1.0, 0.0], [1.0, 0.0, 0.0]], float) +Rot_Y_mX_mZ = numpy.array([[0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_XmY_X_mZ = numpy.array([[1.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mX_Y_mZ = numpy.array([[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_X_mZ_Y = numpy.array([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]], float) +Rot_Y_mXY_Z = numpy.array([[0.0, 1.0, 0.0], [-1.0, 1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Y_mX_Z = numpy.array([[0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_XmY_X_Z = numpy.array([[1.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mX_mXY_mZ = numpy.array([[-1.0, 0.0, 0.0], [-1.0, 1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_Y_Z_X = numpy.array([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]], float) +Rot_mY_mZ_X = numpy.array([[0.0, -1.0, 0.0], [0.0, 0.0, -1.0], [1.0, 0.0, 0.0]], float) +Rot_X_Z_mY = numpy.array([[1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, -1.0, 0.0]], float) +Rot_XmY_mY_Z = numpy.array([[1.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Y_X_mZ = numpy.array([[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_Y_mZ_X = numpy.array([[0.0, 1.0, 0.0], [0.0, 0.0, -1.0], [1.0, 0.0, 0.0]], float) +Rot_mXY_Y_Z = numpy.array([[-1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mX_mY_mZ = numpy.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_X_Y_mZ = numpy.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mXY_mX_Z = numpy.array([[-1.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mZ_mY_mX = numpy.array([[0.0, 0.0, -1.0], [0.0, -1.0, 0.0], [-1.0, 0.0, 0.0]], float) +Rot_X_mZ_mY = numpy.array([[1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, -1.0, 0.0]], float) +Rot_X_Y_Z = numpy.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mY_mX_mZ = numpy.array([[0.0, -1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mY_X_Z = numpy.array([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Z_X_Y = numpy.array([[0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], float) +Rot_X_XmY_Z = numpy.array([[1.0, 0.0, 0.0], [1.0, -1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mY_X_mZ = numpy.array([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mY_Z_mX = numpy.array([[0.0, -1.0, 0.0], [0.0, 0.0, 1.0], [-1.0, 0.0, 0.0]], float) +Rot_mY_Z_X = numpy.array([[0.0, -1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]], float) +Rot_mX_mZ_mY = numpy.array([[-1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, -1.0, 0.0]], float) +Rot_mX_Z_Y = numpy.array([[-1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]], float) +Rot_mZ_mX_mY = numpy.array([[0.0, 0.0, -1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]], float) +Rot_X_XmY_mZ = numpy.array([[1.0, 0.0, 0.0], [1.0, -1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mY_XmY_mZ = numpy.array([[0.0, -1.0, 0.0], [1.0, -1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_Z_X_mY = numpy.array([[0.0, 0.0, 1.0], [1.0, 0.0, 0.0], [0.0, -1.0, 0.0]], float) +Rot_mZ_mY_X = numpy.array([[0.0, 0.0, -1.0], [0.0, -1.0, 0.0], [1.0, 0.0, 0.0]], float) +Rot_X_Z_Y = numpy.array([[1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]], float) +Rot_Z_mX_mY = numpy.array([[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]], float) +Rot_mX_Z_mY = numpy.array([[-1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, -1.0, 0.0]], float) +Rot_X_mY_Z = numpy.array([[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mY_mX_Z = numpy.array([[0.0, -1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Z_mY_mX = numpy.array([[0.0, 0.0, 1.0], [0.0, -1.0, 0.0], [-1.0, 0.0, 0.0]], float) +Rot_mX_mY_Z = numpy.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Z_Y_X = numpy.array([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]], float) +Rot_mZ_Y_mX = numpy.array([[0.0, 0.0, -1.0], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]], float) +Rot_Y_Z_mX = numpy.array([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [-1.0, 0.0, 0.0]], float) +Rot_mY_XmY_Z = numpy.array([[0.0, -1.0, 0.0], [1.0, -1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_mXY_Y_mZ = numpy.array([[-1.0, 1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mZ_mX_Y = numpy.array([[0.0, 0.0, -1.0], [-1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], float) +Rot_mX_mZ_Y = numpy.array([[-1.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]], float) +Rot_mX_Y_Z = numpy.array([[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_X_mY_mZ = numpy.array([[1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mZ_X_Y = numpy.array([[0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], float) +Rot_Y_mZ_mX = numpy.array([[0.0, 1.0, 0.0], [0.0, 0.0, -1.0], [-1.0, 0.0, 0.0]], float) +Rot_mY_mZ_mX = numpy.array([[0.0, -1.0, 0.0], [0.0, 0.0, -1.0], [-1.0, 0.0, 0.0]], float) +Rot_mZ_Y_X = numpy.array([[0.0, 0.0, -1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]], float) +Rot_Z_Y_mX = numpy.array([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [-1.0, 0.0, 0.0]], float) +Rot_mXY_mX_mZ = numpy.array([[-1.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_XmY_mY_mZ = numpy.array([[1.0, -1.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_Z_mX_Y = numpy.array([[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], float) +Rot_mX_mXY_Z = numpy.array([[-1.0, 0.0, 0.0], [-1.0, 1.0, 0.0], [0.0, 0.0, 1.0]], float) +Rot_Y_mXY_mZ = numpy.array([[0.0, 1.0, 0.0], [-1.0, 1.0, 0.0], [0.0, 0.0, -1.0]], float) +Rot_mZ_X_mY = numpy.array([[0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [0.0, -1.0, 0.0]], float) +Rot_Y_X_Z = numpy.array([[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) ## 32 unique translation vectors -Tr_0_0_34 = numpy.array([ 0.0, 0.0, 3.0/4.0 ], float) -Tr_12_0_34 = numpy.array([ 1.0/2.0, 0.0, 3.0/4.0 ], float) -Tr_0_0_56 = numpy.array([ 0.0, 0.0, 5.0/6.0 ], float) -Tr_12_0_12 = numpy.array([ 1.0/2.0, 0.0, 1.0/2.0 ], float) -Tr_0_12_12 = numpy.array([ 0.0, 1.0/2.0, 1.0/2.0 ], float) -Tr_12_0_14 = numpy.array([ 1.0/2.0, 0.0, 1.0/4.0 ], float) -Tr_0_12_14 = numpy.array([ 0.0, 1.0/2.0, 1.0/4.0 ], float) -Tr_14_14_14 = numpy.array([ 1.0/4.0, 1.0/4.0, 1.0/4.0 ], float) -Tr_0_12_34 = numpy.array([ 0.0, 1.0/2.0, 3.0/4.0 ], float) -Tr_34_14_14 = numpy.array([ 3.0/4.0, 1.0/4.0, 1.0/4.0 ], float) -Tr_0_0_0 = numpy.array([ 0.0, 0.0, 0.0 ], float) -Tr_23_13_56 = numpy.array([ 2.0/3.0, 1.0/3.0, 5.0/6.0 ], float) -Tr_14_14_34 = numpy.array([ 1.0/4.0, 1.0/4.0, 3.0/4.0 ], float) -Tr_12_12_0 = numpy.array([ 1.0/2.0, 1.0/2.0, 0.0 ], float) -Tr_23_13_13 = numpy.array([ 2.0/3.0, 1.0/3.0, 1.0/3.0 ], float) -Tr_13_23_23 = numpy.array([ 1.0/3.0, 2.0/3.0, 2.0/3.0 ], float) -Tr_12_12_12 = numpy.array([ 1.0/2.0, 1.0/2.0, 1.0/2.0 ], float) -Tr_12_12_14 = numpy.array([ 1.0/2.0, 1.0/2.0, 1.0/4.0 ], float) -Tr_14_34_14 = numpy.array([ 1.0/4.0, 3.0/4.0, 1.0/4.0 ], float) -Tr_12_12_34 = numpy.array([ 1.0/2.0, 1.0/2.0, 3.0/4.0 ], float) -Tr_0_0_23 = numpy.array([ 0.0, 0.0, 2.0/3.0 ], float) -Tr_0_12_0 = numpy.array([ 0.0, 1.0/2.0, 0.0 ], float) -Tr_14_34_34 = numpy.array([ 1.0/4.0, 3.0/4.0, 3.0/4.0 ], float) -Tr_34_34_14 = numpy.array([ 3.0/4.0, 3.0/4.0, 1.0/4.0 ], float) -Tr_12_0_0 = numpy.array([ 1.0/2.0, 0.0, 0.0 ], float) -Tr_34_34_34 = numpy.array([ 3.0/4.0, 3.0/4.0, 3.0/4.0 ], float) -Tr_0_0_13 = numpy.array([ 0.0, 0.0, 1.0/3.0 ], float) -Tr_0_0_12 = numpy.array([ 0.0, 0.0, 1.0/2.0 ], float) -Tr_13_23_16 = numpy.array([ 1.0/3.0, 2.0/3.0, 1.0/6.0 ], float) -Tr_0_0_14 = numpy.array([ 0.0, 0.0, 1.0/4.0 ], float) -Tr_0_0_16 = numpy.array([ 0.0, 0.0, 1.0/6.0 ], float) -Tr_34_14_34 = numpy.array([ 3.0/4.0, 1.0/4.0, 3.0/4.0 ], float) +Tr_0_0_34 = numpy.array([0.0, 0.0, 3.0 / 4.0], float) +Tr_12_0_34 = numpy.array([1.0 / 2.0, 0.0, 3.0 / 4.0], float) +Tr_0_0_56 = numpy.array([0.0, 0.0, 5.0 / 6.0], float) +Tr_12_0_12 = numpy.array([1.0 / 2.0, 0.0, 1.0 / 2.0], float) +Tr_0_12_12 = numpy.array([0.0, 1.0 / 2.0, 1.0 / 2.0], float) +Tr_12_0_14 = numpy.array([1.0 / 2.0, 0.0, 1.0 / 4.0], float) +Tr_0_12_14 = numpy.array([0.0, 1.0 / 2.0, 1.0 / 4.0], float) +Tr_14_14_14 = numpy.array([1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0], float) +Tr_0_12_34 = numpy.array([0.0, 1.0 / 2.0, 3.0 / 4.0], float) +Tr_34_14_14 = numpy.array([3.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0], float) +Tr_0_0_0 = numpy.array([0.0, 0.0, 0.0], float) +Tr_23_13_56 = numpy.array([2.0 / 3.0, 1.0 / 3.0, 5.0 / 6.0], float) +Tr_14_14_34 = numpy.array([1.0 / 4.0, 1.0 / 4.0, 3.0 / 4.0], float) +Tr_12_12_0 = numpy.array([1.0 / 2.0, 1.0 / 2.0, 0.0], float) +Tr_23_13_13 = numpy.array([2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0], float) +Tr_13_23_23 = numpy.array([1.0 / 3.0, 2.0 / 3.0, 2.0 / 3.0], float) +Tr_12_12_12 = numpy.array([1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0], float) +Tr_12_12_14 = numpy.array([1.0 / 2.0, 1.0 / 2.0, 1.0 / 4.0], float) +Tr_14_34_14 = numpy.array([1.0 / 4.0, 3.0 / 4.0, 1.0 / 4.0], float) +Tr_12_12_34 = numpy.array([1.0 / 2.0, 1.0 / 2.0, 3.0 / 4.0], float) +Tr_0_0_23 = numpy.array([0.0, 0.0, 2.0 / 3.0], float) +Tr_0_12_0 = numpy.array([0.0, 1.0 / 2.0, 0.0], float) +Tr_14_34_34 = numpy.array([1.0 / 4.0, 3.0 / 4.0, 3.0 / 4.0], float) +Tr_34_34_14 = numpy.array([3.0 / 4.0, 3.0 / 4.0, 1.0 / 4.0], float) +Tr_12_0_0 = numpy.array([1.0 / 2.0, 0.0, 0.0], float) +Tr_34_34_34 = numpy.array([3.0 / 4.0, 3.0 / 4.0, 3.0 / 4.0], float) +Tr_0_0_13 = numpy.array([0.0, 0.0, 1.0 / 3.0], float) +Tr_0_0_12 = numpy.array([0.0, 0.0, 1.0 / 2.0], float) +Tr_13_23_16 = numpy.array([1.0 / 3.0, 2.0 / 3.0, 1.0 / 6.0], float) +Tr_0_0_14 = numpy.array([0.0, 0.0, 1.0 / 4.0], float) +Tr_0_0_16 = numpy.array([0.0, 0.0, 1.0 / 6.0], float) +Tr_34_14_34 = numpy.array([3.0 / 4.0, 1.0 / 4.0, 3.0 / 4.0], float) class SymOp(object): @@ -137,19 +137,13 @@ def __init__(self, R, t): self.t = t return - def __str__(self): - """Printable representation of this SymOp object. - """ - x = "[%6.3f %6.3f %6.3f %6.3f]\n" % ( - self.R[0,0], self.R[0,1], self.R[0,2], self.t[0]) - x += "[%6.3f %6.3f %6.3f %6.3f]\n" % ( - self.R[1,0], self.R[1,1], self.R[1,2], self.t[1]) - x += "[%6.3f %6.3f %6.3f %6.3f]\n" % ( - self.R[2,0], self.R[2,1], self.R[2,2], self.t[2]) + """Printable representation of this SymOp object.""" + x = "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[0, 0], self.R[0, 1], self.R[0, 2], self.t[0]) + x += "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[1, 0], self.R[1, 1], self.R[1, 2], self.t[1]) + x += "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[2, 0], self.R[2, 1], self.R[2, 2], self.t[2]) return x - def __call__(self, vec): """Return symmetry-related position for the specified coordinates. @@ -165,7 +159,6 @@ def __call__(self, vec): """ return numpy.dot(self.R, vec) + self.t - def __eq__(self, symop): """Implement the ``(self == symop)`` test of equality. @@ -174,7 +167,6 @@ def __eq__(self, symop): """ return numpy.allclose(self.R, symop.R) and numpy.allclose(self.t, symop.t) - def is_identity(self): """Check if this SymOp is an identity operation. @@ -184,10 +176,10 @@ def is_identity(self): ``True`` if this is an identity operation within a small round-off. Return ``False`` otherwise. """ - rv = (numpy.allclose(self.R, numpy.identity(3, float)) and - numpy.allclose(self.t, numpy.zeros(3, float))) + rv = numpy.allclose(self.R, numpy.identity(3, float)) and numpy.allclose(self.t, numpy.zeros(3, float)) return rv + # End of class SymOp @@ -243,31 +235,30 @@ class SpaceGroup(object): in this space group. """ - def __init__(self, - number = None, - num_sym_equiv = None, - num_primitive_sym_equiv = None, - short_name = None, - point_group_name = None, - crystal_system = None, - pdb_name = None, - symop_list = None): - - self.number = number - self.num_sym_equiv = num_sym_equiv + def __init__( + self, + number=None, + num_sym_equiv=None, + num_primitive_sym_equiv=None, + short_name=None, + point_group_name=None, + crystal_system=None, + pdb_name=None, + symop_list=None, + ): + + self.number = number + self.num_sym_equiv = num_sym_equiv self.num_primitive_sym_equiv = num_primitive_sym_equiv - self.short_name = short_name - self.point_group_name = point_group_name - self.crystal_system = crystal_system - self.pdb_name = pdb_name - self.symop_list = symop_list + self.short_name = short_name + self.point_group_name = point_group_name + self.crystal_system = crystal_system + self.pdb_name = pdb_name + self.symop_list = symop_list def __repr__(self): """Return a string representation of the space group.""" - return ( - "SpaceGroup #%i (%s, %s). Symmetry matrices: %i, " - "point sym. matr.: %i" - ) % ( + return ("SpaceGroup #%i (%s, %s). Symmetry matrices: %i, " "point sym. matr.: %i") % ( self.number, self.short_name, self.crystal_system[0] + self.crystal_system[1:].lower(), @@ -275,7 +266,6 @@ def __repr__(self): self.num_primitive_sym_equiv, ) - def iter_symops(self): """Iterate over all symmetry operations in the space group. @@ -286,7 +276,6 @@ def iter_symops(self): """ return iter(self.symop_list) - def check_group_name(self, name): """Check if given name matches this space group. @@ -303,13 +292,16 @@ def check_group_name(self, name): Return ``False`` otherwise. """ - if name == self.short_name: return True - if name == self.pdb_name: return True - if name == self.point_group_name: return True - if name == self.number: return True + if name == self.short_name: + return True + if name == self.pdb_name: + return True + if name == self.point_group_name: + return True + if name == self.number: + return True return False - def iter_equivalent_positions(self, vec): """Generate symmetry equivalent positions for the specified position. @@ -334,4 +326,5 @@ def iter_equivalent_positions(self, vec): yield symop(vec) pass + # End of class SpaceGroup diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index 7f4b0748..b864e9c5 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -13,14 +13,14 @@ # ############################################################################## -'''Space group classes and definitions from mmLib and sgtbx. -''' +"""Space group classes and definitions from mmLib and sgtbx. +""" import six -from diffpy.structure.spacegroupmod import SymOp, SpaceGroup from diffpy.structure.mmlibspacegroups import mmLibSpaceGroupList from diffpy.structure.sgtbxspacegroups import sgtbxSpaceGroupList +from diffpy.structure.spacegroupmod import SpaceGroup, SymOp # all spacegroup definitions SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList @@ -45,7 +45,7 @@ def GetSpaceGroup(sgid): raise ValueError(emsg) sgbare = sgid.strip() # short_name case adjusted - sgkey = sgbare.replace(' ', '') + sgkey = sgbare.replace(" ", "") sgkey = sgkey[:1].upper() + sgkey[1:].lower() if sgkey in _sg_lookup_table: return _sg_lookup_table[sgkey] @@ -95,14 +95,16 @@ def FindSpaceGroup(symops, shuffle=False): When `symops` do not match any known SpaceGroup. """ import copy + from six.moves import zip_longest + tb = _getSGHashLookupTable() hh = _hashSymOpList(symops) if not hh in tb: - raise ValueError('Cannot find SpaceGroup for the specified symops.') + raise ValueError("Cannot find SpaceGroup for the specified symops.") rv = tb[hh] if not shuffle: - zz = zip_longest(rv.iter_symops(), symops, fillvalue='') + zz = zip_longest(rv.iter_symops(), symops, fillvalue="") sameorder = all(str(o0) == str(o1) for o0, o1 in zz) if not sameorder: rv = copy.copy(rv) @@ -145,36 +147,37 @@ def _buildSGLookupTable(): # extra aliases obtained from matching code in # cctbx::sgtbx::symbols::find_main_symbol_dict_entry alias_hmname = [ - ('Pm3', 'P m -3'), - ('Pn3', 'P n -3'), - ('Fm3', 'F m -3'), - ('Fd3', 'F d -3'), - ('Im3', 'I m -3'), - ('Pa3', 'P a -3'), - ('Ia3', 'I a -3'), - ('Pm3m', 'P m -3 m'), - ('Pn3n', 'P n -3 n'), - ('Pm3n', 'P m -3 n'), - ('Pn3m', 'P n -3 m'), - ('Fm3m', 'F m -3 m'), - ('Fm3c', 'F m -3 c'), - ('Fd3m', 'F d -3 m'), - ('Fd3c', 'F d -3 c'), - ('Im3m', 'I m -3 m'), - ('Ia3d', 'I a -3 d'), + ("Pm3", "P m -3"), + ("Pn3", "P n -3"), + ("Fm3", "F m -3"), + ("Fd3", "F d -3"), + ("Im3", "I m -3"), + ("Pa3", "P a -3"), + ("Ia3", "I a -3"), + ("Pm3m", "P m -3 m"), + ("Pn3n", "P n -3 n"), + ("Pm3n", "P m -3 n"), + ("Pn3m", "P n -3 m"), + ("Fm3m", "F m -3 m"), + ("Fm3c", "F m -3 c"), + ("Fd3m", "F d -3 m"), + ("Fd3c", "F d -3 c"), + ("Im3m", "I m -3 m"), + ("Ia3d", "I a -3 d"), ] for a, hm in alias_hmname: - hmbare = hm.replace(' ', '') + hmbare = hm.replace(" ", "") _sg_lookup_table.setdefault(a, _sg_lookup_table[hmbare]) # make sure None does not sneak into the dictionary assert not None in _sg_lookup_table return + + _sg_lookup_table = {} def _getSGHashLookupTable(): - """Return lookup table of symop hashes to standard SpaceGroup objects. - """ + """Return lookup table of symop hashes to standard SpaceGroup objects.""" if _sg_hash_lookup_table: return _sg_hash_lookup_table for sg in SpaceGroupList: @@ -182,199 +185,1244 @@ def _getSGHashLookupTable(): _sg_hash_lookup_table[h] = sg assert len(_sg_hash_lookup_table) == len(SpaceGroupList) return _getSGHashLookupTable() + + _sg_hash_lookup_table = {} # Import SpaceGroup objects -------------------------------------------------- -from diffpy.structure.spacegroupmod import ( - Rot_X_Y_Z, Rot_mX_mY_mZ, Rot_mX_Y_mZ, Rot_X_mY_Z, - Rot_mX_mY_Z, Rot_X_mY_mZ, Rot_mX_Y_Z, Rot_X_Y_mZ, - Rot_mY_X_Z, Rot_Y_mX_Z, Rot_Y_mX_mZ, Rot_mY_X_mZ, - Rot_Y_X_mZ, Rot_mY_mX_mZ, Rot_mY_mX_Z, Rot_Y_X_Z, - Rot_mY_XmY_Z, Rot_mXY_mX_Z, Rot_Z_X_Y, Rot_Y_Z_X, - Rot_Y_mXY_mZ, Rot_XmY_X_mZ, Rot_mZ_mX_mY, Rot_mY_mZ_mX, - Rot_mXY_Y_mZ, Rot_X_XmY_mZ, Rot_XmY_mY_mZ, Rot_mX_mXY_mZ, - Rot_mX_mZ_mY, Rot_mZ_mY_mX, Rot_mXY_Y_Z, Rot_X_XmY_Z, - Rot_XmY_mY_Z, Rot_mX_mXY_Z, Rot_X_Z_Y, Rot_Z_Y_X, - Rot_Y_mXY_Z, Rot_XmY_X_Z, Rot_mY_XmY_mZ, Rot_mXY_mX_mZ, - Rot_Z_mX_mY, Rot_mZ_mX_Y, Rot_mZ_X_mY, Rot_mY_Z_mX, - Rot_Y_mZ_mX, Rot_mY_mZ_X, Rot_mZ_X_Y, Rot_Z_X_mY, - Rot_Z_mX_Y, Rot_Y_mZ_X, Rot_mY_Z_X, Rot_Y_Z_mX, - Rot_X_Z_mY, Rot_mX_Z_Y, Rot_X_mZ_Y, Rot_Z_Y_mX, - Rot_Z_mY_X, Rot_mZ_Y_X, Rot_mX_Z_mY, Rot_mX_mZ_Y, - Rot_X_mZ_mY, Rot_Z_mY_mX, Rot_mZ_Y_mX, Rot_mZ_mY_X, - Tr_0_0_0, Tr_0_12_0, Tr_12_12_0, Tr_0_0_12, - Tr_12_12_12, Tr_0_12_12, Tr_12_0_12, Tr_12_0_0, - Tr_14_14_14, Tr_14_34_34, Tr_34_14_34, Tr_34_34_14, - Tr_0_0_14, Tr_0_0_34, Tr_0_12_14, Tr_12_0_34, - Tr_12_12_14, Tr_12_12_34, Tr_0_12_34, Tr_12_0_14, - Tr_0_0_13, Tr_0_0_23, Tr_23_13_13, Tr_13_23_23, - Tr_23_13_56, Tr_13_23_16, Tr_0_0_56, Tr_0_0_16, - Tr_34_14_14, Tr_34_34_34, Tr_14_14_34, Tr_14_34_14, -) - from diffpy.structure.mmlibspacegroups import ( - sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8, - sg9, sg10, sg11, sg12, sg13, sg14, sg15, sg16, - sg17, sg18, sg19, sg20, sg21, sg22, sg23, sg24, - sg25, sg26, sg27, sg28, sg29, sg30, sg31, sg32, - sg33, sg34, sg35, sg36, sg37, sg38, sg39, sg40, - sg41, sg42, sg43, sg44, sg45, sg46, sg47, sg48, - sg49, sg50, sg51, sg52, sg53, sg54, sg55, sg56, - sg57, sg58, sg59, sg60, sg61, sg62, sg63, sg64, - sg65, sg66, sg67, sg68, sg69, sg70, sg71, sg72, - sg73, sg74, sg75, sg76, sg77, sg78, sg79, sg80, - sg81, sg82, sg83, sg84, sg85, sg86, sg87, sg88, - sg89, sg90, sg91, sg92, sg93, sg94, sg95, sg96, - sg97, sg98, sg99, sg100, sg101, sg102, sg103, sg104, - sg105, sg106, sg107, sg108, sg109, sg110, sg111, sg112, - sg113, sg114, sg115, sg116, sg117, sg118, sg119, sg120, - sg121, sg122, sg123, sg124, sg125, sg126, sg127, sg128, - sg129, sg130, sg131, sg132, sg133, sg134, sg135, sg136, - sg137, sg138, sg139, sg140, sg141, sg142, sg143, sg144, - sg145, sg146, sg1146, sg147, sg148, sg1148, sg149, sg150, - sg151, sg152, sg153, sg154, sg155, sg1155, sg156, sg157, - sg158, sg159, sg160, sg1160, sg161, sg1161, sg162, sg163, - sg164, sg165, sg166, sg1166, sg167, sg1167, sg168, sg169, - sg170, sg171, sg172, sg173, sg174, sg175, sg176, sg177, - sg178, sg179, sg180, sg181, sg182, sg183, sg184, sg185, - sg186, sg187, sg188, sg189, sg190, sg191, sg192, sg193, - sg194, sg195, sg196, sg197, sg198, sg199, sg200, sg201, - sg202, sg203, sg204, sg205, sg206, sg207, sg208, sg209, - sg210, sg211, sg212, sg213, sg214, sg215, sg216, sg217, - sg218, sg219, sg220, sg221, sg222, sg223, sg224, sg225, - sg226, sg227, sg228, sg229, sg230, sg1003, sg1004, sg3004, - sg1005, sg2005, sg3005, sg1006, sg1007, sg1008, sg1009, sg1010, - sg1011, sg1012, sg1013, sg1014, sg1015, sg1017, sg2017, sg1018, - sg2018, sg3018, sg1020, sg1021, sg1022, sg1023, sg1059, sg1094, + sg1, + sg2, + sg3, + sg4, + sg5, + sg6, + sg7, + sg8, + sg9, + sg10, + sg11, + sg12, + sg13, + sg14, + sg15, + sg16, + sg17, + sg18, + sg19, + sg20, + sg21, + sg22, + sg23, + sg24, + sg25, + sg26, + sg27, + sg28, + sg29, + sg30, + sg31, + sg32, + sg33, + sg34, + sg35, + sg36, + sg37, + sg38, + sg39, + sg40, + sg41, + sg42, + sg43, + sg44, + sg45, + sg46, + sg47, + sg48, + sg49, + sg50, + sg51, + sg52, + sg53, + sg54, + sg55, + sg56, + sg57, + sg58, + sg59, + sg60, + sg61, + sg62, + sg63, + sg64, + sg65, + sg66, + sg67, + sg68, + sg69, + sg70, + sg71, + sg72, + sg73, + sg74, + sg75, + sg76, + sg77, + sg78, + sg79, + sg80, + sg81, + sg82, + sg83, + sg84, + sg85, + sg86, + sg87, + sg88, + sg89, + sg90, + sg91, + sg92, + sg93, + sg94, + sg95, + sg96, + sg97, + sg98, + sg99, + sg100, + sg101, + sg102, + sg103, + sg104, + sg105, + sg106, + sg107, + sg108, + sg109, + sg110, + sg111, + sg112, + sg113, + sg114, + sg115, + sg116, + sg117, + sg118, + sg119, + sg120, + sg121, + sg122, + sg123, + sg124, + sg125, + sg126, + sg127, + sg128, + sg129, + sg130, + sg131, + sg132, + sg133, + sg134, + sg135, + sg136, + sg137, + sg138, + sg139, + sg140, + sg141, + sg142, + sg143, + sg144, + sg145, + sg146, + sg147, + sg148, + sg149, + sg150, + sg151, + sg152, + sg153, + sg154, + sg155, + sg156, + sg157, + sg158, + sg159, + sg160, + sg161, + sg162, + sg163, + sg164, + sg165, + sg166, + sg167, + sg168, + sg169, + sg170, + sg171, + sg172, + sg173, + sg174, + sg175, + sg176, + sg177, + sg178, + sg179, + sg180, + sg181, + sg182, + sg183, + sg184, + sg185, + sg186, + sg187, + sg188, + sg189, + sg190, + sg191, + sg192, + sg193, + sg194, + sg195, + sg196, + sg197, + sg198, + sg199, + sg200, + sg201, + sg202, + sg203, + sg204, + sg205, + sg206, + sg207, + sg208, + sg209, + sg210, + sg211, + sg212, + sg213, + sg214, + sg215, + sg216, + sg217, + sg218, + sg219, + sg220, + sg221, + sg222, + sg223, + sg224, + sg225, + sg226, + sg227, + sg228, + sg229, + sg230, + sg1003, + sg1004, + sg1005, + sg1006, + sg1007, + sg1008, + sg1009, + sg1010, + sg1011, + sg1012, + sg1013, + sg1014, + sg1015, + sg1017, + sg1018, + sg1020, + sg1021, + sg1022, + sg1023, + sg1059, + sg1094, + sg1146, + sg1148, + sg1155, + sg1160, + sg1161, + sg1166, + sg1167, sg1197, + sg2005, + sg2017, + sg2018, + sg3004, + sg3005, + sg3018, ) - from diffpy.structure.sgtbxspacegroups import ( - sg2003, sg2004, sg4005, sg5005, sg6005, sg7005, sg8005, sg9005, - sg10005, sg2006, sg2007, sg3007, sg4007, sg5007, sg6007, sg7007, - sg8007, sg2008, sg3008, sg4008, sg5008, sg6008, sg7008, sg8008, - sg2009, sg3009, sg4009, sg5009, sg6009, sg7009, sg8009, sg9009, - sg10009, sg11009, sg12009, sg13009, sg14009, sg15009, sg16009, - sg17009, sg2010, sg2011, sg2012, sg3012, sg4012, sg5012, sg6012, - sg7012, sg8012, sg2013, sg3013, sg4013, sg5013, sg6013, sg7013, - sg8013, sg2014, sg3014, sg4014, sg5014, sg6014, sg7014, sg8014, - sg2015, sg3015, sg4015, sg5015, sg6015, sg7015, sg8015, sg9015, - sg10015, sg11015, sg12015, sg13015, sg14015, sg15015, sg16015, - sg17015, sg2020, sg3020, sg2021, sg3021, sg1025, sg2025, sg1026, - sg2026, sg3026, sg4026, sg5026, sg1027, sg2027, sg1028, sg2028, - sg3028, sg4028, sg5028, sg1029, sg2029, sg3029, sg4029, sg5029, - sg1030, sg2030, sg3030, sg4030, sg5030, sg1031, sg2031, sg3031, - sg4031, sg5031, sg1032, sg2032, sg1033, sg2033, sg3033, sg4033, - sg5033, sg1034, sg2034, sg1035, sg2035, sg1036, sg2036, sg3036, - sg4036, sg5036, sg1037, sg2037, sg1038, sg2038, sg3038, sg4038, - sg5038, sg1039, sg2039, sg3039, sg4039, sg5039, sg1040, sg2040, - sg3040, sg4040, sg5040, sg1041, sg2041, sg3041, sg4041, sg5041, - sg1042, sg2042, sg1043, sg2043, sg1044, sg2044, sg1045, sg2045, - sg1046, sg2046, sg3046, sg4046, sg5046, sg1049, sg2049, sg1050, - sg2050, sg3050, sg4050, sg1051, sg2051, sg3051, sg4051, sg5051, - sg1052, sg2052, sg3052, sg4052, sg5052, sg1053, sg2053, sg3053, - sg4053, sg5053, sg1054, sg2054, sg3054, sg4054, sg5054, sg1055, - sg2055, sg1056, sg2056, sg1057, sg2057, sg3057, sg4057, sg5057, - sg1058, sg2058, sg2059, sg3059, sg4059, sg5059, sg1060, sg2060, - sg3060, sg4060, sg5060, sg1061, sg1062, sg2062, sg3062, sg4062, - sg5062, sg1063, sg2063, sg3063, sg4063, sg5063, sg1064, sg2064, - sg3064, sg4064, sg5064, sg1065, sg2065, sg1066, sg2066, sg1067, - sg2067, sg3067, sg4067, sg5067, sg1068, sg2068, sg3068, sg4068, - sg5068, sg6068, sg7068, sg1072, sg2072, sg1073, sg1074, sg2074, - sg3074, sg4074, sg5074, + sg1025, + sg1026, + sg1027, + sg1028, + sg1029, + sg1030, + sg1031, + sg1032, + sg1033, + sg1034, + sg1035, + sg1036, + sg1037, + sg1038, + sg1039, + sg1040, + sg1041, + sg1042, + sg1043, + sg1044, + sg1045, + sg1046, + sg1049, + sg1050, + sg1051, + sg1052, + sg1053, + sg1054, + sg1055, + sg1056, + sg1057, + sg1058, + sg1060, + sg1061, + sg1062, + sg1063, + sg1064, + sg1065, + sg1066, + sg1067, + sg1068, + sg1072, + sg1073, + sg1074, + sg2003, + sg2004, + sg2006, + sg2007, + sg2008, + sg2009, + sg2010, + sg2011, + sg2012, + sg2013, + sg2014, + sg2015, + sg2020, + sg2021, + sg2025, + sg2026, + sg2027, + sg2028, + sg2029, + sg2030, + sg2031, + sg2032, + sg2033, + sg2034, + sg2035, + sg2036, + sg2037, + sg2038, + sg2039, + sg2040, + sg2041, + sg2042, + sg2043, + sg2044, + sg2045, + sg2046, + sg2049, + sg2050, + sg2051, + sg2052, + sg2053, + sg2054, + sg2055, + sg2056, + sg2057, + sg2058, + sg2059, + sg2060, + sg2062, + sg2063, + sg2064, + sg2065, + sg2066, + sg2067, + sg2068, + sg2072, + sg2074, + sg3007, + sg3008, + sg3009, + sg3012, + sg3013, + sg3014, + sg3015, + sg3020, + sg3021, + sg3026, + sg3028, + sg3029, + sg3030, + sg3031, + sg3033, + sg3036, + sg3038, + sg3039, + sg3040, + sg3041, + sg3046, + sg3050, + sg3051, + sg3052, + sg3053, + sg3054, + sg3057, + sg3059, + sg3060, + sg3062, + sg3063, + sg3064, + sg3067, + sg3068, + sg3074, + sg4005, + sg4007, + sg4008, + sg4009, + sg4012, + sg4013, + sg4014, + sg4015, + sg4026, + sg4028, + sg4029, + sg4030, + sg4031, + sg4033, + sg4036, + sg4038, + sg4039, + sg4040, + sg4041, + sg4046, + sg4050, + sg4051, + sg4052, + sg4053, + sg4054, + sg4057, + sg4059, + sg4060, + sg4062, + sg4063, + sg4064, + sg4067, + sg4068, + sg4074, + sg5005, + sg5007, + sg5008, + sg5009, + sg5012, + sg5013, + sg5014, + sg5015, + sg5026, + sg5028, + sg5029, + sg5030, + sg5031, + sg5033, + sg5036, + sg5038, + sg5039, + sg5040, + sg5041, + sg5046, + sg5051, + sg5052, + sg5053, + sg5054, + sg5057, + sg5059, + sg5060, + sg5062, + sg5063, + sg5064, + sg5067, + sg5068, + sg5074, + sg6005, + sg6007, + sg6008, + sg6009, + sg6012, + sg6013, + sg6014, + sg6015, + sg6068, + sg7005, + sg7007, + sg7008, + sg7009, + sg7012, + sg7013, + sg7014, + sg7015, + sg7068, + sg8005, + sg8007, + sg8008, + sg8009, + sg8012, + sg8013, + sg8014, + sg8015, + sg9005, + sg9009, + sg9015, + sg10005, + sg10009, + sg10015, + sg11009, + sg11015, + sg12009, + sg12015, + sg13009, + sg13015, + sg14009, + sg14015, + sg15009, + sg15015, + sg16009, + sg16015, + sg17009, + sg17015, +) +from diffpy.structure.spacegroupmod import ( + Rot_mX_mXY_mZ, + Rot_mX_mXY_Z, + Rot_mX_mY_mZ, + Rot_mX_mY_Z, + Rot_mX_mZ_mY, + Rot_mX_mZ_Y, + Rot_mX_Y_mZ, + Rot_mX_Y_Z, + Rot_mX_Z_mY, + Rot_mX_Z_Y, + Rot_mXY_mX_mZ, + Rot_mXY_mX_Z, + Rot_mXY_Y_mZ, + Rot_mXY_Y_Z, + Rot_mY_mX_mZ, + Rot_mY_mX_Z, + Rot_mY_mZ_mX, + Rot_mY_mZ_X, + Rot_mY_X_mZ, + Rot_mY_X_Z, + Rot_mY_XmY_mZ, + Rot_mY_XmY_Z, + Rot_mY_Z_mX, + Rot_mY_Z_X, + Rot_mZ_mX_mY, + Rot_mZ_mX_Y, + Rot_mZ_mY_mX, + Rot_mZ_mY_X, + Rot_mZ_X_mY, + Rot_mZ_X_Y, + Rot_mZ_Y_mX, + Rot_mZ_Y_X, + Rot_X_mY_mZ, + Rot_X_mY_Z, + Rot_X_mZ_mY, + Rot_X_mZ_Y, + Rot_X_XmY_mZ, + Rot_X_XmY_Z, + Rot_X_Y_mZ, + Rot_X_Y_Z, + Rot_X_Z_mY, + Rot_X_Z_Y, + Rot_XmY_mY_mZ, + Rot_XmY_mY_Z, + Rot_XmY_X_mZ, + Rot_XmY_X_Z, + Rot_Y_mX_mZ, + Rot_Y_mX_Z, + Rot_Y_mXY_mZ, + Rot_Y_mXY_Z, + Rot_Y_mZ_mX, + Rot_Y_mZ_X, + Rot_Y_X_mZ, + Rot_Y_X_Z, + Rot_Y_Z_mX, + Rot_Y_Z_X, + Rot_Z_mX_mY, + Rot_Z_mX_Y, + Rot_Z_mY_mX, + Rot_Z_mY_X, + Rot_Z_X_mY, + Rot_Z_X_Y, + Rot_Z_Y_mX, + Rot_Z_Y_X, + Tr_0_0_0, + Tr_0_0_12, + Tr_0_0_13, + Tr_0_0_14, + Tr_0_0_16, + Tr_0_0_23, + Tr_0_0_34, + Tr_0_0_56, + Tr_0_12_0, + Tr_0_12_12, + Tr_0_12_14, + Tr_0_12_34, + Tr_12_0_0, + Tr_12_0_12, + Tr_12_0_14, + Tr_12_0_34, + Tr_12_12_0, + Tr_12_12_12, + Tr_12_12_14, + Tr_12_12_34, + Tr_13_23_16, + Tr_13_23_23, + Tr_14_14_14, + Tr_14_14_34, + Tr_14_34_14, + Tr_14_34_34, + Tr_23_13_13, + Tr_23_13_56, + Tr_34_14_14, + Tr_34_14_34, + Tr_34_34_14, + Tr_34_34_34, ) # silence pyflakes checker -assert all(o is not None for o in (SpaceGroup, SymOp, - Rot_X_Y_Z, Rot_mX_mY_mZ, Rot_mX_Y_mZ, Rot_X_mY_Z, - Rot_mX_mY_Z, Rot_X_mY_mZ, Rot_mX_Y_Z, Rot_X_Y_mZ, - Rot_mY_X_Z, Rot_Y_mX_Z, Rot_Y_mX_mZ, Rot_mY_X_mZ, - Rot_Y_X_mZ, Rot_mY_mX_mZ, Rot_mY_mX_Z, Rot_Y_X_Z, - Rot_mY_XmY_Z, Rot_mXY_mX_Z, Rot_Z_X_Y, Rot_Y_Z_X, - Rot_Y_mXY_mZ, Rot_XmY_X_mZ, Rot_mZ_mX_mY, Rot_mY_mZ_mX, - Rot_mXY_Y_mZ, Rot_X_XmY_mZ, Rot_XmY_mY_mZ, Rot_mX_mXY_mZ, - Rot_mX_mZ_mY, Rot_mZ_mY_mX, Rot_mXY_Y_Z, Rot_X_XmY_Z, - Rot_XmY_mY_Z, Rot_mX_mXY_Z, Rot_X_Z_Y, Rot_Z_Y_X, - Rot_Y_mXY_Z, Rot_XmY_X_Z, Rot_mY_XmY_mZ, Rot_mXY_mX_mZ, - Rot_Z_mX_mY, Rot_mZ_mX_Y, Rot_mZ_X_mY, Rot_mY_Z_mX, - Rot_Y_mZ_mX, Rot_mY_mZ_X, Rot_mZ_X_Y, Rot_Z_X_mY, - Rot_Z_mX_Y, Rot_Y_mZ_X, Rot_mY_Z_X, Rot_Y_Z_mX, - Rot_X_Z_mY, Rot_mX_Z_Y, Rot_X_mZ_Y, Rot_Z_Y_mX, - Rot_Z_mY_X, Rot_mZ_Y_X, Rot_mX_Z_mY, Rot_mX_mZ_Y, - Rot_X_mZ_mY, Rot_Z_mY_mX, Rot_mZ_Y_mX, Rot_mZ_mY_X, - Tr_0_0_0, Tr_0_12_0, Tr_12_12_0, Tr_0_0_12, - Tr_12_12_12, Tr_0_12_12, Tr_12_0_12, Tr_12_0_0, - Tr_14_14_14, Tr_14_34_34, Tr_34_14_34, Tr_34_34_14, - Tr_0_0_14, Tr_0_0_34, Tr_0_12_14, Tr_12_0_34, - Tr_12_12_14, Tr_12_12_34, Tr_0_12_34, Tr_12_0_14, - Tr_0_0_13, Tr_0_0_23, Tr_23_13_13, Tr_13_23_23, - Tr_23_13_56, Tr_13_23_16, Tr_0_0_56, Tr_0_0_16, - Tr_34_14_14, Tr_34_34_34, Tr_14_14_34, Tr_14_34_14, - sg1, sg2, sg3, sg4, sg5, sg6, sg7, sg8, - sg9, sg10, sg11, sg12, sg13, sg14, sg15, sg16, - sg17, sg18, sg19, sg20, sg21, sg22, sg23, sg24, - sg25, sg26, sg27, sg28, sg29, sg30, sg31, sg32, - sg33, sg34, sg35, sg36, sg37, sg38, sg39, sg40, - sg41, sg42, sg43, sg44, sg45, sg46, sg47, sg48, - sg49, sg50, sg51, sg52, sg53, sg54, sg55, sg56, - sg57, sg58, sg59, sg60, sg61, sg62, sg63, sg64, - sg65, sg66, sg67, sg68, sg69, sg70, sg71, sg72, - sg73, sg74, sg75, sg76, sg77, sg78, sg79, sg80, - sg81, sg82, sg83, sg84, sg85, sg86, sg87, sg88, - sg89, sg90, sg91, sg92, sg93, sg94, sg95, sg96, - sg97, sg98, sg99, sg100, sg101, sg102, sg103, sg104, - sg105, sg106, sg107, sg108, sg109, sg110, sg111, sg112, - sg113, sg114, sg115, sg116, sg117, sg118, sg119, sg120, - sg121, sg122, sg123, sg124, sg125, sg126, sg127, sg128, - sg129, sg130, sg131, sg132, sg133, sg134, sg135, sg136, - sg137, sg138, sg139, sg140, sg141, sg142, sg143, sg144, - sg145, sg146, sg1146, sg147, sg148, sg1148, sg149, sg150, - sg151, sg152, sg153, sg154, sg155, sg1155, sg156, sg157, - sg158, sg159, sg160, sg1160, sg161, sg1161, sg162, sg163, - sg164, sg165, sg166, sg1166, sg167, sg1167, sg168, sg169, - sg170, sg171, sg172, sg173, sg174, sg175, sg176, sg177, - sg178, sg179, sg180, sg181, sg182, sg183, sg184, sg185, - sg186, sg187, sg188, sg189, sg190, sg191, sg192, sg193, - sg194, sg195, sg196, sg197, sg198, sg199, sg200, sg201, - sg202, sg203, sg204, sg205, sg206, sg207, sg208, sg209, - sg210, sg211, sg212, sg213, sg214, sg215, sg216, sg217, - sg218, sg219, sg220, sg221, sg222, sg223, sg224, sg225, - sg226, sg227, sg228, sg229, sg230, sg1003, sg1004, sg3004, - sg1005, sg2005, sg3005, sg1006, sg1007, sg1008, sg1009, sg1010, - sg1011, sg1012, sg1013, sg1014, sg1015, sg1017, sg2017, sg1018, - sg2018, sg3018, sg1020, sg1021, sg1022, sg1023, sg1059, sg1094, - sg1197, - sg2003, sg2004, sg4005, sg5005, sg6005, sg7005, sg8005, sg9005, - sg10005, sg2006, sg2007, sg3007, sg4007, sg5007, sg6007, sg7007, - sg8007, sg2008, sg3008, sg4008, sg5008, sg6008, sg7008, sg8008, - sg2009, sg3009, sg4009, sg5009, sg6009, sg7009, sg8009, sg9009, - sg10009, sg11009, sg12009, sg13009, sg14009, sg15009, sg16009, - sg17009, sg2010, sg2011, sg2012, sg3012, sg4012, sg5012, sg6012, - sg7012, sg8012, sg2013, sg3013, sg4013, sg5013, sg6013, sg7013, - sg8013, sg2014, sg3014, sg4014, sg5014, sg6014, sg7014, sg8014, - sg2015, sg3015, sg4015, sg5015, sg6015, sg7015, sg8015, sg9015, - sg10015, sg11015, sg12015, sg13015, sg14015, sg15015, sg16015, - sg17015, sg2020, sg3020, sg2021, sg3021, sg1025, sg2025, sg1026, - sg2026, sg3026, sg4026, sg5026, sg1027, sg2027, sg1028, sg2028, - sg3028, sg4028, sg5028, sg1029, sg2029, sg3029, sg4029, sg5029, - sg1030, sg2030, sg3030, sg4030, sg5030, sg1031, sg2031, sg3031, - sg4031, sg5031, sg1032, sg2032, sg1033, sg2033, sg3033, sg4033, - sg5033, sg1034, sg2034, sg1035, sg2035, sg1036, sg2036, sg3036, - sg4036, sg5036, sg1037, sg2037, sg1038, sg2038, sg3038, sg4038, - sg5038, sg1039, sg2039, sg3039, sg4039, sg5039, sg1040, sg2040, - sg3040, sg4040, sg5040, sg1041, sg2041, sg3041, sg4041, sg5041, - sg1042, sg2042, sg1043, sg2043, sg1044, sg2044, sg1045, sg2045, - sg1046, sg2046, sg3046, sg4046, sg5046, sg1049, sg2049, sg1050, - sg2050, sg3050, sg4050, sg1051, sg2051, sg3051, sg4051, sg5051, - sg1052, sg2052, sg3052, sg4052, sg5052, sg1053, sg2053, sg3053, - sg4053, sg5053, sg1054, sg2054, sg3054, sg4054, sg5054, sg1055, - sg2055, sg1056, sg2056, sg1057, sg2057, sg3057, sg4057, sg5057, - sg1058, sg2058, sg2059, sg3059, sg4059, sg5059, sg1060, sg2060, - sg3060, sg4060, sg5060, sg1061, sg1062, sg2062, sg3062, sg4062, - sg5062, sg1063, sg2063, sg3063, sg4063, sg5063, sg1064, sg2064, - sg3064, sg4064, sg5064, sg1065, sg2065, sg1066, sg2066, sg1067, - sg2067, sg3067, sg4067, sg5067, sg1068, sg2068, sg3068, sg4068, - sg5068, sg6068, sg7068, sg1072, sg2072, sg1073, sg1074, sg2074, - sg3074, sg4074, sg5074, -)) +assert all( + o is not None + for o in ( + SpaceGroup, + SymOp, + Rot_X_Y_Z, + Rot_mX_mY_mZ, + Rot_mX_Y_mZ, + Rot_X_mY_Z, + Rot_mX_mY_Z, + Rot_X_mY_mZ, + Rot_mX_Y_Z, + Rot_X_Y_mZ, + Rot_mY_X_Z, + Rot_Y_mX_Z, + Rot_Y_mX_mZ, + Rot_mY_X_mZ, + Rot_Y_X_mZ, + Rot_mY_mX_mZ, + Rot_mY_mX_Z, + Rot_Y_X_Z, + Rot_mY_XmY_Z, + Rot_mXY_mX_Z, + Rot_Z_X_Y, + Rot_Y_Z_X, + Rot_Y_mXY_mZ, + Rot_XmY_X_mZ, + Rot_mZ_mX_mY, + Rot_mY_mZ_mX, + Rot_mXY_Y_mZ, + Rot_X_XmY_mZ, + Rot_XmY_mY_mZ, + Rot_mX_mXY_mZ, + Rot_mX_mZ_mY, + Rot_mZ_mY_mX, + Rot_mXY_Y_Z, + Rot_X_XmY_Z, + Rot_XmY_mY_Z, + Rot_mX_mXY_Z, + Rot_X_Z_Y, + Rot_Z_Y_X, + Rot_Y_mXY_Z, + Rot_XmY_X_Z, + Rot_mY_XmY_mZ, + Rot_mXY_mX_mZ, + Rot_Z_mX_mY, + Rot_mZ_mX_Y, + Rot_mZ_X_mY, + Rot_mY_Z_mX, + Rot_Y_mZ_mX, + Rot_mY_mZ_X, + Rot_mZ_X_Y, + Rot_Z_X_mY, + Rot_Z_mX_Y, + Rot_Y_mZ_X, + Rot_mY_Z_X, + Rot_Y_Z_mX, + Rot_X_Z_mY, + Rot_mX_Z_Y, + Rot_X_mZ_Y, + Rot_Z_Y_mX, + Rot_Z_mY_X, + Rot_mZ_Y_X, + Rot_mX_Z_mY, + Rot_mX_mZ_Y, + Rot_X_mZ_mY, + Rot_Z_mY_mX, + Rot_mZ_Y_mX, + Rot_mZ_mY_X, + Tr_0_0_0, + Tr_0_12_0, + Tr_12_12_0, + Tr_0_0_12, + Tr_12_12_12, + Tr_0_12_12, + Tr_12_0_12, + Tr_12_0_0, + Tr_14_14_14, + Tr_14_34_34, + Tr_34_14_34, + Tr_34_34_14, + Tr_0_0_14, + Tr_0_0_34, + Tr_0_12_14, + Tr_12_0_34, + Tr_12_12_14, + Tr_12_12_34, + Tr_0_12_34, + Tr_12_0_14, + Tr_0_0_13, + Tr_0_0_23, + Tr_23_13_13, + Tr_13_23_23, + Tr_23_13_56, + Tr_13_23_16, + Tr_0_0_56, + Tr_0_0_16, + Tr_34_14_14, + Tr_34_34_34, + Tr_14_14_34, + Tr_14_34_14, + sg1, + sg2, + sg3, + sg4, + sg5, + sg6, + sg7, + sg8, + sg9, + sg10, + sg11, + sg12, + sg13, + sg14, + sg15, + sg16, + sg17, + sg18, + sg19, + sg20, + sg21, + sg22, + sg23, + sg24, + sg25, + sg26, + sg27, + sg28, + sg29, + sg30, + sg31, + sg32, + sg33, + sg34, + sg35, + sg36, + sg37, + sg38, + sg39, + sg40, + sg41, + sg42, + sg43, + sg44, + sg45, + sg46, + sg47, + sg48, + sg49, + sg50, + sg51, + sg52, + sg53, + sg54, + sg55, + sg56, + sg57, + sg58, + sg59, + sg60, + sg61, + sg62, + sg63, + sg64, + sg65, + sg66, + sg67, + sg68, + sg69, + sg70, + sg71, + sg72, + sg73, + sg74, + sg75, + sg76, + sg77, + sg78, + sg79, + sg80, + sg81, + sg82, + sg83, + sg84, + sg85, + sg86, + sg87, + sg88, + sg89, + sg90, + sg91, + sg92, + sg93, + sg94, + sg95, + sg96, + sg97, + sg98, + sg99, + sg100, + sg101, + sg102, + sg103, + sg104, + sg105, + sg106, + sg107, + sg108, + sg109, + sg110, + sg111, + sg112, + sg113, + sg114, + sg115, + sg116, + sg117, + sg118, + sg119, + sg120, + sg121, + sg122, + sg123, + sg124, + sg125, + sg126, + sg127, + sg128, + sg129, + sg130, + sg131, + sg132, + sg133, + sg134, + sg135, + sg136, + sg137, + sg138, + sg139, + sg140, + sg141, + sg142, + sg143, + sg144, + sg145, + sg146, + sg1146, + sg147, + sg148, + sg1148, + sg149, + sg150, + sg151, + sg152, + sg153, + sg154, + sg155, + sg1155, + sg156, + sg157, + sg158, + sg159, + sg160, + sg1160, + sg161, + sg1161, + sg162, + sg163, + sg164, + sg165, + sg166, + sg1166, + sg167, + sg1167, + sg168, + sg169, + sg170, + sg171, + sg172, + sg173, + sg174, + sg175, + sg176, + sg177, + sg178, + sg179, + sg180, + sg181, + sg182, + sg183, + sg184, + sg185, + sg186, + sg187, + sg188, + sg189, + sg190, + sg191, + sg192, + sg193, + sg194, + sg195, + sg196, + sg197, + sg198, + sg199, + sg200, + sg201, + sg202, + sg203, + sg204, + sg205, + sg206, + sg207, + sg208, + sg209, + sg210, + sg211, + sg212, + sg213, + sg214, + sg215, + sg216, + sg217, + sg218, + sg219, + sg220, + sg221, + sg222, + sg223, + sg224, + sg225, + sg226, + sg227, + sg228, + sg229, + sg230, + sg1003, + sg1004, + sg3004, + sg1005, + sg2005, + sg3005, + sg1006, + sg1007, + sg1008, + sg1009, + sg1010, + sg1011, + sg1012, + sg1013, + sg1014, + sg1015, + sg1017, + sg2017, + sg1018, + sg2018, + sg3018, + sg1020, + sg1021, + sg1022, + sg1023, + sg1059, + sg1094, + sg1197, + sg2003, + sg2004, + sg4005, + sg5005, + sg6005, + sg7005, + sg8005, + sg9005, + sg10005, + sg2006, + sg2007, + sg3007, + sg4007, + sg5007, + sg6007, + sg7007, + sg8007, + sg2008, + sg3008, + sg4008, + sg5008, + sg6008, + sg7008, + sg8008, + sg2009, + sg3009, + sg4009, + sg5009, + sg6009, + sg7009, + sg8009, + sg9009, + sg10009, + sg11009, + sg12009, + sg13009, + sg14009, + sg15009, + sg16009, + sg17009, + sg2010, + sg2011, + sg2012, + sg3012, + sg4012, + sg5012, + sg6012, + sg7012, + sg8012, + sg2013, + sg3013, + sg4013, + sg5013, + sg6013, + sg7013, + sg8013, + sg2014, + sg3014, + sg4014, + sg5014, + sg6014, + sg7014, + sg8014, + sg2015, + sg3015, + sg4015, + sg5015, + sg6015, + sg7015, + sg8015, + sg9015, + sg10015, + sg11015, + sg12015, + sg13015, + sg14015, + sg15015, + sg16015, + sg17015, + sg2020, + sg3020, + sg2021, + sg3021, + sg1025, + sg2025, + sg1026, + sg2026, + sg3026, + sg4026, + sg5026, + sg1027, + sg2027, + sg1028, + sg2028, + sg3028, + sg4028, + sg5028, + sg1029, + sg2029, + sg3029, + sg4029, + sg5029, + sg1030, + sg2030, + sg3030, + sg4030, + sg5030, + sg1031, + sg2031, + sg3031, + sg4031, + sg5031, + sg1032, + sg2032, + sg1033, + sg2033, + sg3033, + sg4033, + sg5033, + sg1034, + sg2034, + sg1035, + sg2035, + sg1036, + sg2036, + sg3036, + sg4036, + sg5036, + sg1037, + sg2037, + sg1038, + sg2038, + sg3038, + sg4038, + sg5038, + sg1039, + sg2039, + sg3039, + sg4039, + sg5039, + sg1040, + sg2040, + sg3040, + sg4040, + sg5040, + sg1041, + sg2041, + sg3041, + sg4041, + sg5041, + sg1042, + sg2042, + sg1043, + sg2043, + sg1044, + sg2044, + sg1045, + sg2045, + sg1046, + sg2046, + sg3046, + sg4046, + sg5046, + sg1049, + sg2049, + sg1050, + sg2050, + sg3050, + sg4050, + sg1051, + sg2051, + sg3051, + sg4051, + sg5051, + sg1052, + sg2052, + sg3052, + sg4052, + sg5052, + sg1053, + sg2053, + sg3053, + sg4053, + sg5053, + sg1054, + sg2054, + sg3054, + sg4054, + sg5054, + sg1055, + sg2055, + sg1056, + sg2056, + sg1057, + sg2057, + sg3057, + sg4057, + sg5057, + sg1058, + sg2058, + sg2059, + sg3059, + sg4059, + sg5059, + sg1060, + sg2060, + sg3060, + sg4060, + sg5060, + sg1061, + sg1062, + sg2062, + sg3062, + sg4062, + sg5062, + sg1063, + sg2063, + sg3063, + sg4063, + sg5063, + sg1064, + sg2064, + sg3064, + sg4064, + sg5064, + sg1065, + sg2065, + sg1066, + sg2066, + sg1067, + sg2067, + sg3067, + sg4067, + sg5067, + sg1068, + sg2068, + sg3068, + sg4068, + sg5068, + sg6068, + sg7068, + sg1072, + sg2072, + sg1073, + sg1074, + sg2074, + sg3074, + sg4074, + sg5074, + ) +) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index bfec639e..2c2f3c89 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -16,18 +16,19 @@ """This module defines class Structure. """ +import codecs import copy as copymod + import numpy -import codecs import six -from diffpy.structure.lattice import Lattice from diffpy.structure.atom import Atom -from diffpy.structure.utils import _linkAtomAttribute, atomBareSymbol -from diffpy.structure.utils import isiterable +from diffpy.structure.lattice import Lattice +from diffpy.structure.utils import _linkAtomAttribute, atomBareSymbol, isiterable # ---------------------------------------------------------------------------- + class Structure(list): """Structure --> group of atoms @@ -43,13 +44,11 @@ class Structure(list): # default values for instance attributes - title = '' + title = "" _lattice = None pdffit = None - - def __init__(self, atoms=None, lattice=None, title=None, - filename=None, format=None): + def __init__(self, atoms=None, lattice=None, title=None, filename=None, format=None): """define group of atoms in a specified lattice. atoms -- list of Atom instances to be included in this Structure. @@ -75,7 +74,7 @@ def __init__(self, atoms=None, lattice=None, title=None, if any((atoms, lattice, title)): emsg = "Cannot use filename and atoms arguments together." raise ValueError(emsg) - readkwargs = (format is not None) and {'format' : format} or {} + readkwargs = (format is not None) and {"format": format} or {} self.read(filename, **readkwargs) return # copy initialization, must be first to allow lattice, title override @@ -93,22 +92,19 @@ def __init__(self, atoms=None, lattice=None, title=None, self.extend(atoms) return - def copy(self): - '''Return a copy of this Structure object. - ''' + """Return a copy of this Structure object.""" return copymod.copy(self) - def __copy__(self, target=None): - '''Create a deep copy of this instance. + """Create a deep copy of this instance. target -- optional target instance for copying, useful for copying a derived class. Defaults to new instance of the same type as self. Return a duplicate instance of this object. - ''' + """ if target is None: target = Structure() elif target is self: @@ -121,13 +117,11 @@ def __copy__(self, target=None): target[:] = self return target - def __str__(self): """simple string representation""" s_lattice = "lattice=%s" % self.lattice - s_atoms = '\n'.join([str(a) for a in self]) - return s_lattice + '\n' + s_atoms - + s_atoms = "\n".join([str(a) for a in self]) + return s_lattice + "\n" + s_atoms def addNewAtom(self, *args, **kwargs): """Add new Atom instance to the end of this Structure. @@ -136,19 +130,16 @@ def addNewAtom(self, *args, **kwargs): No return value. """ - kwargs['lattice'] = self.lattice + kwargs["lattice"] = self.lattice a = Atom(*args, **kwargs) self.append(a, copy=False) return - def getLastAtom(self): - """Return Reference to the last Atom in this structure. - """ + """Return Reference to the last Atom in this structure.""" last_atom = self[-1] return last_atom - def assignUniqueLabels(self): """Set a unique label string for each atom in this structure. The label strings are formatted as "%(baresymbol)s%(index)i", @@ -160,14 +151,14 @@ def assignUniqueLabels(self): # support duplicate atom instances islabeled = set() for a in self: - if a in islabeled: continue + if a in islabeled: + continue baresmbl = atomBareSymbol(a.element) elnum[baresmbl] = elnum.get(baresmbl, 0) + 1 a.label = baresmbl + str(elnum[baresmbl]) islabeled.add(a) return - def distance(self, aid0, aid1): """Distance between 2 atoms, no periodic boundary conditions. @@ -182,7 +173,6 @@ def distance(self, aid0, aid1): a0, a1 = self[aid0, aid1] return self.lattice.dist(a0.xyz, a1.xyz) - def angle(self, aid0, aid1, aid2): """The bond angle at the second of three atoms in degrees. @@ -200,7 +190,6 @@ def angle(self, aid0, aid1, aid2): u12 = a2.xyz - a1.xyz return self.lattice.angle(u10, u12) - def placeInLattice(self, new_lattice): """place structure into new_lattice coordinate system @@ -218,8 +207,7 @@ def placeInLattice(self, new_lattice): self.lattice = new_lattice return self - - def read(self, filename, format='auto'): + def read(self, filename, format="auto"): """Load structure from a file, any original data become lost. filename -- file to be loaded @@ -231,6 +219,7 @@ def read(self, filename, format='auto'): """ import diffpy.structure import diffpy.structure.parsers + getParser = diffpy.structure.parsers.getParser p = getParser(format) new_structure = p.parseFile(filename) @@ -242,13 +231,13 @@ def read(self, filename, format='auto'): self[:] = new_structure if not self.title: import os.path + tailname = os.path.basename(filename) tailbase = os.path.splitext(tailname)[0] self.title = tailbase return p - - def readStr(self, s, format='auto'): + def readStr(self, s, format="auto"): """Load structure from a string, any original data become lost. s -- string with structure definition @@ -259,6 +248,7 @@ def readStr(self, s, format='auto'): can be inspected for information related to particular format. """ from diffpy.structure.parsers import getParser + p = getParser(format) new_structure = p.parse(s) # reinitialize data after successful parsing @@ -269,7 +259,6 @@ def readStr(self, s, format='auto'): self[:] = new_structure return p - def write(self, filename, format): """Save structure to file in the specified format @@ -279,14 +268,14 @@ def write(self, filename, format): from parsers import formats """ from diffpy.structure.parsers import getParser + p = getParser(format) p.filename = filename s = p.tostring(self) - with codecs.open(filename, 'w', encoding='UTF-8') as fp: + with codecs.open(filename, "w", encoding="UTF-8") as fp: fp.write(s) return - def writeStr(self, format): """return string representation of the structure in specified format @@ -294,14 +283,13 @@ def writeStr(self, format): from parsers import formats """ from diffpy.structure.parsers import getParser + p = getParser(format) s = p.tostring(self) return s - def tolist(self): - '''Return atoms in this Structure as a standard Python list. - ''' + """Return atoms in this Structure as a standard Python list.""" rv = [a for a in self] return rv @@ -321,7 +309,6 @@ def append(self, a, copy=True): super(Structure, self).append(adup) return - def insert(self, idx, a, copy=True): """Insert atom a before position idx in this Structure. @@ -337,7 +324,6 @@ def insert(self, idx, a, copy=True): super(Structure, self).insert(idx, adup) return - def extend(self, atoms, copy=None): """Extend Structure with an iterable of atoms. @@ -359,19 +345,17 @@ def extend(self, atoms, copy=None): newatoms = adups else: memo = set(id(a) for a in self) - nextatom = lambda a: (a if id(a) not in memo - else copymod.copy(a)) + nextatom = lambda a: (a if id(a) not in memo else copymod.copy(a)) mark = lambda a: (memo.add(id(a)), a)[-1] newatoms = (mark(nextatom(a)) for a in atoms) elif copy: newatoms = adups else: newatoms = atoms - setlat = lambda a: (setattr(a, 'lattice', self.lattice), a)[-1] + setlat = lambda a: (setattr(a, "lattice", self.lattice), a)[-1] super(Structure, self).extend(setlat(a) for a in newatoms) return - def __getitem__(self, idx): """Get one or more atoms in this structure. @@ -406,8 +390,8 @@ def __getitem__(self, idx): # check if there is any string label that should be resolved scalarstringlabel = isinstance(idx, six.string_types) hasstringlabel = scalarstringlabel or ( - isiterable(idx) and - any(isinstance(ii, six.string_types) for ii in idx)) + isiterable(idx) and any(isinstance(ii, six.string_types) for ii in idx) + ) # if not, use numpy indexing to resolve idx if not hasstringlabel: idx1 = idx @@ -423,8 +407,8 @@ def __getitem__(self, idx): duplicate = object() labeltoindex = {} for i, a in enumerate(self): - labeltoindex[a.label] = ( - duplicate if a.label in labeltoindex else i) + labeltoindex[a.label] = duplicate if a.label in labeltoindex else i + def _resolveindex(aid): aid1 = aid if type(aid) is str: @@ -434,6 +418,7 @@ def _resolveindex(aid): if aid1 is duplicate: raise IndexError("Atom label %r is not unique." % aid) return aid1 + # generate new index object that has no strings if scalarstringlabel: idx2 = _resolveindex(idx) @@ -446,7 +431,6 @@ def _resolveindex(aid): rv = self[idx2] return rv - def __setitem__(self, idx, value, copy=True): """Assign self[idx] atom to value. @@ -459,9 +443,11 @@ def __setitem__(self, idx, value, copy=True): """ # handle slice assignment if isinstance(idx, slice): + def _fixlat(a): a.lattice = self.lattice return a + v1 = value if copy: keep = set(super(Structure, self).__getitem__(idx)) @@ -474,63 +460,58 @@ def _fixlat(a): super(Structure, self).__setitem__(idx, vfinal) return - def __add__(self, other): - '''Return new Structure object with appended atoms from other. + """Return new Structure object with appended atoms from other. other -- sequence of Atom instances Return new Structure with a copy of Atom instances. - ''' + """ rv = copymod.copy(self) rv += other return rv - def __iadd__(self, other): - '''Extend this Structure with atoms from other. + """Extend this Structure with atoms from other. other -- sequence of Atom instances Return self. - ''' + """ self.extend(other, copy=True) return self - def __sub__(self, other): - '''Return new Structure that has atoms from the other removed. + """Return new Structure that has atoms from the other removed. other -- sequence of Atom instances Return new Structure with a copy of Atom instances. - ''' + """ otherset = set(other) keepindices = [i for i, a in enumerate(self) if not a in otherset] rv = copymod.copy(self[keepindices]) return rv - def __isub__(self, other): - '''Remove other atoms if present in this structure. + """Remove other atoms if present in this structure. other -- sequence of Atom instances Return self. - ''' + """ otherset = set(other) self[:] = [a for a in self if a not in otherset] return self - def __mul__(self, n): - '''Return new Structure with n-times concatenated atoms from self. + """Return new Structure with n-times concatenated atoms from self. Atoms and lattice in the new structure are all copies. n -- integer multiple Return new Structure. - ''' + """ rv = copymod.copy(self[:0]) rv += n * self.tolist() return rv @@ -538,16 +519,15 @@ def __mul__(self, n): # right-side multiplication is the same as left-side __rmul__ = __mul__ - def __imul__(self, n): - '''Concatenate this Structure to n-times more atoms. + """Concatenate this Structure to n-times more atoms. For positive multiple the current Atom objects remain at the beginning of this Structure. n -- integer multiple Return self. - ''' + """ if n <= 0: self[:] = [] else: @@ -562,12 +542,12 @@ def _get_lattice(self): return self._lattice def _set_lattice(self, value): - for a in self: a.lattice = value + for a in self: + a.lattice = value self._lattice = value return - lattice = property(_get_lattice, _set_lattice, doc = - "Coordinate system for this Structure.") + lattice = property(_get_lattice, _set_lattice, doc="Coordinate system for this Structure.") # composition @@ -577,114 +557,160 @@ def _get_composition(self): rv[a.element] = rv.get(a.element, 0.0) + a.occupancy return rv - composition = property(_get_composition, - doc="Dictionary of chemical symbols and their total occupancies.") + composition = property(_get_composition, doc="Dictionary of chemical symbols and their total occupancies.") # linked atom attributes - element = _linkAtomAttribute('element', - '''Character array of atom types. Assignment updates - the element attribute of the respective atoms.''', - toarray=numpy.char.array) - - xyz = _linkAtomAttribute('xyz', - '''Array of fractional coordinates of all atoms. - Assignment updates xyz attribute of all atoms.''') - - x = _linkAtomAttribute('x', - '''Array of all fractional coordinates x. - Assignment updates xyz attribute of all atoms.''') - - y = _linkAtomAttribute('y', - '''Array of all fractional coordinates y. - Assignment updates xyz attribute of all atoms.''') - - z = _linkAtomAttribute('z', - '''Array of all fractional coordinates z. - Assignment updates xyz attribute of all atoms.''') - - label = _linkAtomAttribute('label', - '''Character array of atom names. Assignment updates - the label attribute of all atoms.''', - toarray=numpy.char.array) - - occupancy = _linkAtomAttribute('occupancy', - '''Array of atom occupancies. Assignment updates the - occupancy attribute of all atoms.''') - - xyz_cartn = _linkAtomAttribute('xyz_cartn', - '''Array of absolute Cartesian coordinates of all atoms. - Assignment updates the xyz attribute of all atoms.''') - - anisotropy = _linkAtomAttribute('anisotropy', - '''Boolean array for anisotropic thermal displacement flags. - Assignment updates the anisotropy attribute of all atoms.''') - - U = _linkAtomAttribute('U', - '''Array of anisotropic thermal displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - Uisoequiv = _linkAtomAttribute('Uisoequiv', - '''Array of isotropic thermal displacement or equivalent values. - Assignment updates the U attribute of all atoms.''') - - U11 = _linkAtomAttribute('U11', - '''Array of U11 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - U22 = _linkAtomAttribute('U22', - '''Array of U22 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - U33 = _linkAtomAttribute('U33', - '''Array of U33 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - U12 = _linkAtomAttribute('U12', - '''Array of U12 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - U13 = _linkAtomAttribute('U13', - '''Array of U13 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - U23 = _linkAtomAttribute('U23', - '''Array of U23 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - Bisoequiv = _linkAtomAttribute('Bisoequiv', - '''Array of Debye-Waller isotropic thermal displacement or equivalent - values. Assignment updates the U attribute of all atoms.''') - - B11 = _linkAtomAttribute('B11', - '''Array of B11 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - B22 = _linkAtomAttribute('B22', - '''Array of B22 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - B33 = _linkAtomAttribute('B33', - '''Array of B33 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - B12 = _linkAtomAttribute('B12', - '''Array of B12 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - B13 = _linkAtomAttribute('B13', - '''Array of B13 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') - - B23 = _linkAtomAttribute('B23', - '''Array of B23 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.''') + element = _linkAtomAttribute( + "element", + """Character array of atom types. Assignment updates + the element attribute of the respective atoms.""", + toarray=numpy.char.array, + ) + + xyz = _linkAtomAttribute( + "xyz", + """Array of fractional coordinates of all atoms. + Assignment updates xyz attribute of all atoms.""", + ) + + x = _linkAtomAttribute( + "x", + """Array of all fractional coordinates x. + Assignment updates xyz attribute of all atoms.""", + ) + + y = _linkAtomAttribute( + "y", + """Array of all fractional coordinates y. + Assignment updates xyz attribute of all atoms.""", + ) + + z = _linkAtomAttribute( + "z", + """Array of all fractional coordinates z. + Assignment updates xyz attribute of all atoms.""", + ) + + label = _linkAtomAttribute( + "label", + """Character array of atom names. Assignment updates + the label attribute of all atoms.""", + toarray=numpy.char.array, + ) + + occupancy = _linkAtomAttribute( + "occupancy", + """Array of atom occupancies. Assignment updates the + occupancy attribute of all atoms.""", + ) + + xyz_cartn = _linkAtomAttribute( + "xyz_cartn", + """Array of absolute Cartesian coordinates of all atoms. + Assignment updates the xyz attribute of all atoms.""", + ) + + anisotropy = _linkAtomAttribute( + "anisotropy", + """Boolean array for anisotropic thermal displacement flags. + Assignment updates the anisotropy attribute of all atoms.""", + ) + + U = _linkAtomAttribute( + "U", + """Array of anisotropic thermal displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + Uisoequiv = _linkAtomAttribute( + "Uisoequiv", + """Array of isotropic thermal displacement or equivalent values. + Assignment updates the U attribute of all atoms.""", + ) + + U11 = _linkAtomAttribute( + "U11", + """Array of U11 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + U22 = _linkAtomAttribute( + "U22", + """Array of U22 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + U33 = _linkAtomAttribute( + "U33", + """Array of U33 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + U12 = _linkAtomAttribute( + "U12", + """Array of U12 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + U13 = _linkAtomAttribute( + "U13", + """Array of U13 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + U23 = _linkAtomAttribute( + "U23", + """Array of U23 elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + Bisoequiv = _linkAtomAttribute( + "Bisoequiv", + """Array of Debye-Waller isotropic thermal displacement or equivalent + values. Assignment updates the U attribute of all atoms.""", + ) + + B11 = _linkAtomAttribute( + "B11", + """Array of B11 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + B22 = _linkAtomAttribute( + "B22", + """Array of B22 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + B33 = _linkAtomAttribute( + "B33", + """Array of B33 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + B12 = _linkAtomAttribute( + "B12", + """Array of B12 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + B13 = _linkAtomAttribute( + "B13", + """Array of B13 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) + + B23 = _linkAtomAttribute( + "B23", + """Array of B23 elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all atoms.""", + ) # Private Methods -------------------------------------------------------- def __emptySharedStructure(self): - '''Return empty Structure with standard attributes same as in self. - ''' + """Return empty Structure with standard attributes same as in self.""" rv = Structure() rv.__dict__.update([(k, getattr(self, k)) for k in rv.__dict__]) return rv @@ -702,4 +728,5 @@ def __setslice__(self, lo, hi, sequence): # ------------------------------------------------------------------------ + # End of class Structure diff --git a/src/diffpy/structure/structureerrors.py b/src/diffpy/structure/structureerrors.py index 80fdf87d..2669b6e1 100644 --- a/src/diffpy/structure/structureerrors.py +++ b/src/diffpy/structure/structureerrors.py @@ -16,19 +16,20 @@ """Exceptions used in Structure package. """ + class StructureFormatError(Exception): - """Exception for failed IO from Structure file - """ + """Exception for failed IO from Structure file""" + pass class LatticeError(Exception): - """Exception for impossible lattice parameters. - """ + """Exception for impossible lattice parameters.""" + pass class SymmetryError(Exception): - """Exception raised for invalid symmetry operations. - """ + """Exception raised for invalid symmetry operations.""" + pass diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index dfaba6be..5364f04a 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -17,8 +17,9 @@ and generation of positional constraints. """ -import sys import re +import sys + import numpy from diffpy.structure.structureerrors import SymmetryError @@ -31,10 +32,11 @@ # Standard symbols denoting elements of anisotropic thermal # displacement tensor. -stdUsymbols = ['U11', 'U22', 'U33', 'U12', 'U13', 'U23'] +stdUsymbols = ["U11", "U22", "U33", "U12", "U13", "U23"] # ---------------------------------------------------------------------------- + def isSpaceGroupLatPar(spacegroup, a, b, c, alpha, beta, gamma): """Check if space group allows passed lattice parameters. @@ -43,34 +45,41 @@ def isSpaceGroupLatPar(spacegroup, a, b, c, alpha, beta, gamma): Return bool. """ + # crystal system rules # ref: Benjamin, W. A., Introduction to crystallography, # New York (1969), p.60 def check_triclinic(): return True + def check_monoclinic(): rv = (alpha == gamma == 90) or (alpha == beta == 90) return rv + def check_orthorhombic(): - return (alpha == beta == gamma == 90) + return alpha == beta == gamma == 90 + def check_tetragonal(): - return (a == b and alpha == beta == gamma == 90) + return a == b and alpha == beta == gamma == 90 + def check_trigonal(): - rv = (a == b == c and alpha == beta == gamma) or \ - (a == b and alpha == beta == 90 and gamma == 120) + rv = (a == b == c and alpha == beta == gamma) or (a == b and alpha == beta == 90 and gamma == 120) return rv + def check_hexagonal(): - return (a == b and alpha == beta == 90 and gamma == 120) + return a == b and alpha == beta == 90 and gamma == 120 + def check_cubic(): - return (a == b == c and alpha == beta == gamma == 90) + return a == b == c and alpha == beta == gamma == 90 + crystal_system_rules = { - "TRICLINIC" : check_triclinic, - "MONOCLINIC" : check_monoclinic, - "ORTHORHOMBIC" : check_orthorhombic, - "TETRAGONAL" : check_tetragonal, - "TRIGONAL" : check_trigonal, - "HEXAGONAL" : check_hexagonal, - "CUBIC" : check_cubic + "TRICLINIC": check_triclinic, + "MONOCLINIC": check_monoclinic, + "ORTHORHOMBIC": check_orthorhombic, + "TETRAGONAL": check_tetragonal, + "TRIGONAL": check_trigonal, + "HEXAGONAL": check_hexagonal, + "CUBIC": check_cubic, } rule = crystal_system_rules[spacegroup.crystal_system] return rule() @@ -80,8 +89,8 @@ def check_cubic(): # isconstantFormula runs faster when regular expression is not # compiled per every single call. -_rx_constant_formula = re.compile( - r'[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)??(/[-+]?\d+)?$') +_rx_constant_formula = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)??(/[-+]?\d+)?$") + def isconstantFormula(s): """Check if formula string is constant. True when argument @@ -91,11 +100,13 @@ def isconstantFormula(s): Return bool. """ - res = _rx_constant_formula.match(s.replace(' ', '')) + res = _rx_constant_formula.match(s.replace(" ", "")) return bool(res) + # Helper class intended for this module only: + class _Position2Tuple(object): """Create callable object that converts fractional coordinates to a tuple of integers with given precision. For presision close to zero @@ -108,6 +119,7 @@ class _Position2Tuple(object): eps -- cutoff for equivalent coordinates. When two coordiantes map to the same tuple, they are closer than eps. """ + def __init__(self, eps=None): """Initialize _Position2Tuple @@ -119,11 +131,10 @@ def __init__(self, eps=None): self.eps = eps + 1.0 self.eps = self.eps - 1.0 # no conversions for very small eps - if self.eps == 0.0 or 1.0/self.eps > sys.maxsize: + if self.eps == 0.0 or 1.0 / self.eps > sys.maxsize: self.eps = 0.0 return - def __call__(self, xyz): """Convert array of fractional coordinates to a tuple. @@ -136,9 +147,10 @@ def __call__(self, xyz): tpl = tuple(xyz % 1.0) return tpl # here we convert to integer - tpl = tuple( [int((xi - numpy.floor(xi))/self.eps) for xi in xyz] ) + tpl = tuple([int((xi - numpy.floor(xi)) / self.eps) for xi in xyz]) return tpl + # End of class _Position2Tuple @@ -152,7 +164,7 @@ def positionDifference(xyz0, xyz1): dxyz = numpy.asarray(xyz0) - xyz1 # map differences to [0,0.5] dxyz = dxyz - numpy.floor(dxyz) - mask = (dxyz > 0.5) + mask = dxyz > 0.5 dxyz[mask] = 1.0 - dxyz[mask] return dxyz @@ -184,7 +196,7 @@ def equalPositions(xyz0, xyz1, eps): return numpy.all(dxyz <= eps) -def expandPosition(spacegroup, xyz, sgoffset=[0,0,0], eps=None): +def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): """Obtain unique equivalent positions and corresponding operations. spacegroup -- instance of SpaceGroup @@ -200,7 +212,7 @@ def expandPosition(spacegroup, xyz, sgoffset=[0,0,0], eps=None): eps = epsilon pos2tuple = _Position2Tuple(eps) positions = [] - site_symops = {} # position tuples with [related symops] + site_symops = {} # position tuples with [related symops] for symop in spacegroup.iter_symops(): # operate on coordinates in non-shifted spacegroup pos = symop(xyz + sgoffset) - sgoffset @@ -216,9 +228,10 @@ def expandPosition(spacegroup, xyz, sgoffset=[0,0,0], eps=None): # is it an equivalent position? if equalPositions(nearpos, pos, eps): # tpl should map to the same list as nearpos - site_symops[tpl] = site_symops[ pos2tuple(nearpos) ] + site_symops[tpl] = site_symops[pos2tuple(nearpos)] pos_is_new = False - if pos_is_new: positions.append(pos) + if pos_is_new: + positions.append(pos) # here tpl is inside site_symops site_symops[tpl].append(symop) # pos_symops is nested list of symops associated with each position @@ -228,9 +241,9 @@ def expandPosition(spacegroup, xyz, sgoffset=[0,0,0], eps=None): def nullSpace(A): - """Null space of matrix A. - """ + """Null space of matrix A.""" from numpy import linalg + u, s, v = linalg.svd(A) # s may have smaller dimension than v vnrows = numpy.shape(v)[0] @@ -256,14 +269,17 @@ def _findInvariants(symops): if numpy.all(op.R == R0) and numpy.all(op.t == t0): invrnts = ops break - if invrnts: break + if invrnts: + break if invrnts is None: emsg = "Could not find identity operation." raise ValueError(emsg) return invrnts + # ---------------------------------------------------------------------------- + class GeneratorSite(object): """Storage of data related to a generator positions. @@ -286,19 +302,20 @@ class GeneratorSite(object): Uparameters -- list of (U symbol, value) pairs """ - Ucomponents = numpy.array([ - [[1, 0, 0], [0, 0, 0], [0, 0, 0]], - [[0, 0, 0], [0, 1, 0], [0, 0, 0]], - [[0, 0, 0], [0, 0, 0], [0, 0, 1]], - [[0, 1, 0], [1, 0, 0], [0, 0, 0]], - [[0, 0, 1], [0, 0, 0], [1, 0, 0]], - [[0, 0, 0], [0, 0, 1], [0, 1, 0]],], dtype=float) - idx2Usymbol = { 0 : 'U11', 1 : 'U12', 2 : 'U13', - 3 : 'U12', 4 : 'U22', 5 : 'U23', - 6 : 'U13', 7 : 'U23', 8 : 'U33' } - - def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3,3)), - sgoffset=[0,0,0], eps=None): + Ucomponents = numpy.array( + [ + [[1, 0, 0], [0, 0, 0], [0, 0, 0]], + [[0, 0, 0], [0, 1, 0], [0, 0, 0]], + [[0, 0, 0], [0, 0, 0], [0, 0, 1]], + [[0, 1, 0], [1, 0, 0], [0, 0, 0]], + [[0, 0, 1], [0, 0, 0], [1, 0, 0]], + [[0, 0, 0], [0, 0, 1], [0, 1, 0]], + ], + dtype=float, + ) + idx2Usymbol = {0: "U11", 1: "U12", 2: "U13", 3: "U12", 4: "U22", 5: "U23", 6: "U13", 7: "U23", 8: "U33"} + + def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3, 3)), sgoffset=[0, 0, 0], eps=None): """Initialize GeneratorSite. spacegroup -- instance of SpaceGroup @@ -331,16 +348,14 @@ def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3,3)), invariants = _findInvariants(ops) # shift self.xyz exactly to the special position if mult > 1: - xyzdups = numpy.array([op(xyz + self.sgoffset) - self.sgoffset - for op in invariants]) + xyzdups = numpy.array([op(xyz + self.sgoffset) - self.sgoffset for op in invariants]) dxyz = xyzdups - xyz dxyz = numpy.mean(dxyz - dxyz.round(), axis=0) # recalculate if needed if numpy.any(dxyz != 0.0): self.xyz = xyz + dxyz self.xyz[numpy.fabs(self.xyz) < self.eps] = 0.0 - sites, ops, mult = expandPosition(spacegroup, - self.xyz, self.sgoffset, eps) + sites, ops, mult = expandPosition(spacegroup, self.xyz, self.sgoffset, eps) invariants = _findInvariants(ops) # self.xyz, sites, ops are all adjusted here self.eqxyz = sites @@ -354,7 +369,6 @@ def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3,3)), self._findeqUij() return - def signedRatStr(self, x): """Convert floating point number to signed rational representation. Possible fractional are multiples of 1/3, 1/6, 1/7, 1/9, if these @@ -363,30 +377,32 @@ def signedRatStr(self, x): Return string. """ s = "{:.8g}".format(x) - if len(s) < 6: return "%+g" % x + if len(s) < 6: + return "%+g" % x den = numpy.array([3.0, 6.0, 7.0, 9.0]) nom = x * den idx = numpy.where(numpy.fabs(nom - nom.round()) < self.eps)[0] - if idx.size == 0: return "%+g" % x + if idx.size == 0: + return "%+g" % x # here we have fraction return "%+.0f/%.0f" % (nom[idx[0]], den[idx[0]]) - def _findNullSpace(self): """Calculate self.null_space from self.invariants. Try to represent self.null_space using small integers. """ R0 = self.invariants[0].R - Rdiff = [ (symop.R - R0) for symop in self.invariants ] + Rdiff = [(symop.R - R0) for symop in self.invariants] Rdiff = numpy.concatenate(Rdiff, axis=0) self.null_space = nullSpace(Rdiff) - if self.null_space.size == 0: return + if self.null_space.size == 0: + return # reverse sort rows of null_space rows by absolute value key = tuple(numpy.fabs(numpy.transpose(self.null_space))[::-1]) order = numpy.lexsort(key) self.null_space = self.null_space[order[::-1]] # rationalize by the smallest element larger than cutoff - cutoff = 1.0/32 + cutoff = 1.0 / 32 for row in self.null_space: abrow = numpy.abs(row) sgrow = numpy.sign(row) @@ -402,25 +418,22 @@ def _findNullSpace(self): row[:] = (sgrow * abrow) / sgrow[idx] / abrow[idx] return - def _findPosParameters(self): - """Find pparameters and their values for expressing self.xyz. - """ + """Find pparameters and their values for expressing self.xyz.""" usedsymbol = {} # parameter values depend on offset of self.xyz txyz = self.xyz # define txyz such that most of its elements are zero for nvec in self.null_space: idx = numpy.where(numpy.fabs(nvec) >= epsilon)[0][0] - varvalue = txyz[idx]/nvec[idx] - txyz = txyz - varvalue*nvec + varvalue = txyz[idx] / nvec[idx] + txyz = txyz - varvalue * nvec # determine standard parameter name vname = [s for s in "xyz"[idx:] if not s in usedsymbol][0] - self.pparameters.append( (vname, varvalue) ) + self.pparameters.append((vname, varvalue)) usedsymbol[vname] = True return - def _findUSpace(self): """Find independent U components with respect to invariant rotations. @@ -428,64 +441,57 @@ def _findUSpace(self): n = len(self.invariants) R6zall = numpy.tile(-numpy.identity(6, dtype=float), (n, 1)) R6zall_iter = numpy.split(R6zall, n, axis=0) - i6kl = ((0, (0, 0)), (1, (1, 1)), (2, (2, 2)), - (3, (0, 1)), (4, (0, 2)), (5, (1, 2))) + i6kl = ((0, (0, 0)), (1, (1, 1)), (2, (2, 2)), (3, (0, 1)), (4, (0, 2)), (5, (1, 2))) for op, R6z in zip(self.invariants, R6zall_iter): R = op.R for j, Ucj in enumerate(self.Ucomponents): Ucj2 = numpy.dot(R, numpy.dot(Ucj, R.T)) for i, kl in i6kl: - R6z[i,j] += Ucj2[kl] + R6z[i, j] += Ucj2[kl] Usp6 = nullSpace(R6zall) # normalize Usp6 by its maximum component mxcols = numpy.argmax(numpy.fabs(Usp6), axis=1) mxrows = numpy.arange(len(mxcols)) - Usp6 /= Usp6[mxrows,mxcols].reshape(-1, 1) + Usp6 /= Usp6[mxrows, mxcols].reshape(-1, 1) Usp6 = numpy.around(Usp6, 2) # normalize again after rounding to get correct signs mxcols = numpy.argmax(numpy.fabs(Usp6), axis=1) - Usp6 /= Usp6[mxrows,mxcols].reshape(-1, 1) + Usp6 /= Usp6[mxrows, mxcols].reshape(-1, 1) self.Uspace = numpy.tensordot(Usp6, self.Ucomponents, axes=(1, 0)) - self.Uisotropy = (len(self.Uspace) == 1) + self.Uisotropy = len(self.Uspace) == 1 return - def _findUParameters(self): - """Find Uparameters and their values for expressing self.Uij. - """ + """Find Uparameters and their values for expressing self.Uij.""" # permute indices as 00 11 22 01 02 12 10 20 21 diagorder = numpy.array((0, 4, 8, 1, 2, 5, 3, 6, 7)) Uijflat = self.Uij.flatten() for Usp in self.Uspace: Uspflat = Usp.flatten() Uspnorm2 = numpy.dot(Uspflat, Uspflat) - permidx = next(i for i, x in enumerate(Uspflat[diagorder]) - if x == 1) + permidx = next(i for i, x in enumerate(Uspflat[diagorder]) if x == 1) idx = diagorder[permidx] vname = self.idx2Usymbol[idx] varvalue = numpy.dot(Uijflat, Uspflat) / Uspnorm2 - self.Uparameters.append( (vname, varvalue) ) + self.Uparameters.append((vname, varvalue)) return - def _findeqUij(self): - """Adjust self.Uij and self.eqUij to be consistent with spacegroup - """ - self.Uij = numpy.zeros((3,3), dtype=float) + """Adjust self.Uij and self.eqUij to be consistent with spacegroup""" + self.Uij = numpy.zeros((3, 3), dtype=float) for i in range(len(self.Uparameters)): Usp = self.Uspace[i] varvalue = self.Uparameters[i][1] - self.Uij += varvalue*Usp + self.Uij += varvalue * Usp # now determine eqUij for ops in self.symops: # take first rotation matrix R = ops[0].R Rt = R.transpose() - self.eqUij.append( numpy.dot(R, numpy.dot(self.Uij, Rt)) ) + self.eqUij.append(numpy.dot(R, numpy.dot(self.Uij, Rt))) return - - def positionFormula(self, pos, xyzsymbols=("x","y","z")): + def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): """Formula of equivalent position with respect to generator site pos -- fractional coordinates of possibly equivalent site @@ -499,7 +505,8 @@ def positionFormula(self, pos, xyzsymbols=("x","y","z")): # find pos in eqxyz idx = nearestSiteIndex(self.eqxyz, pos) eqpos = self.eqxyz[idx] - if not equalPositions(eqpos, pos, self.eps): return {} + if not equalPositions(eqpos, pos, self.eps): + return {} # any rotation matrix should do fine R = self.symops[idx][0].R nsrotated = numpy.dot(self.null_space, numpy.transpose(R)) @@ -510,22 +517,21 @@ def positionFormula(self, pos, xyzsymbols=("x","y","z")): teqpos -= nvec * varvalue # map varnames to xyzsymbols name2sym = dict(zip(("x", "y", "z"), xyzsymbols)) - xyzformula = 3*[""] + xyzformula = 3 * [""] for nvec, (vname, ignore) in zip(nsrotated, self.pparameters): for i in range(3): - if abs(nvec[i]) < epsilon: continue - xyzformula[i] += "%s*%s " % \ - (self.signedRatStr(nvec[i]), name2sym[vname]) + if abs(nvec[i]) < epsilon: + continue + xyzformula[i] += "%s*%s " % (self.signedRatStr(nvec[i]), name2sym[vname]) # add constant offset teqpos to all formulas for i in range(3): - if xyzformula[i] and abs(teqpos[i]) < epsilon: continue + if xyzformula[i] and abs(teqpos[i]) < epsilon: + continue xyzformula[i] += self.signedRatStr(teqpos[i]) # reduce unnecessary +1* and -1* - xyzformula = [ re.sub('^[+]1[*]|(?<=[+-])1[*]', '', f).strip() - for f in xyzformula ] + xyzformula = [re.sub("^[+]1[*]|(?<=[+-])1[*]", "", f).strip() for f in xyzformula] return dict(zip(("x", "y", "z"), xyzformula)) - def UFormula(self, pos, Usymbols=stdUsymbols): """List of atom displacement formulas with custom parameter symbols. @@ -539,12 +545,13 @@ def UFormula(self, pos, Usymbols=stdUsymbols): # find pos in eqxyz idx = nearestSiteIndex(self.eqxyz, pos) eqpos = self.eqxyz[idx] - if not equalPositions(eqpos, pos, self.eps): return {} + if not equalPositions(eqpos, pos, self.eps): + return {} # any rotation matrix should do fine R = self.symops[idx][0].R Rt = R.transpose() Usrotated = [numpy.dot(R, numpy.dot(Us, Rt)) for Us in self.Uspace] - Uformula = dict.fromkeys(stdUsymbols, '') + Uformula = dict.fromkeys(stdUsymbols, "") name2sym = dict(zip(stdUsymbols, Usymbols)) for Usr, (vname, ignore) in zip(Usrotated, self.Uparameters): # avoid adding off-diagonal elements twice @@ -552,16 +559,16 @@ def UFormula(self, pos, Usymbols=stdUsymbols): Usr -= numpy.tril(Usr, -1) Usrflat = Usr.flatten() for i in numpy.where(Usrflat)[0]: - f = '%+g*%s' % (Usrflat[i], name2sym[vname]) + f = "%+g*%s" % (Usrflat[i], name2sym[vname]) smbl = self.idx2Usymbol[i] Uformula[smbl] += f for smbl, f in Uformula.items(): - if not f: f = '0' - f = re.sub(r'^[+]?1[*]|^[+](?=\d)|(?<=[+-])1[*]', '', f).strip() + if not f: + f = "0" + f = re.sub(r"^[+]?1[*]|^[+](?=\d)|(?<=[+-])1[*]", "", f).strip() Uformula[smbl] = f return Uformula - def eqIndex(self, pos): """Index of the nearest generator equivalent site @@ -571,10 +578,12 @@ def eqIndex(self, pos): """ return nearestSiteIndex(self.eqxyz, pos) + # End of class GeneratorSite # ---------------------------------------------------------------------------- + class ExpandAsymmetricUnit(object): """Expand asymmetric unit and anisotropic thermal displacement @@ -594,8 +603,7 @@ class ExpandAsymmetricUnit(object): # By design Atom instances are not accepted as arguments to keep # number of required imports low. - def __init__(self, spacegroup, corepos, coreUijs=None, - sgoffset=[0,0,0], eps=None): + def __init__(self, spacegroup, corepos, coreUijs=None, sgoffset=[0, 0, 0], eps=None): """Initialize and calculate instance of ExpandAsymmetricUnit spacegroup -- instance of SpaceGroup @@ -622,22 +630,23 @@ def __init__(self, spacegroup, corepos, coreUijs=None, if coreUijs: self.coreUijs = coreUijs else: - self.coreUijs = numpy.zeros((corelen,3,3), dtype=float) + self.coreUijs = numpy.zeros((corelen, 3, 3), dtype=float) for cpos, cUij in zip(self.corepos, self.coreUijs): - gen = GeneratorSite(self.spacegroup, cpos, cUij, - self.sgoffset, self.eps) + gen = GeneratorSite(self.spacegroup, cpos, cUij, self.sgoffset, self.eps) self.multiplicity.append(gen.multiplicity) self.Uisotropy.append(gen.Uisotropy) self.expandedpos.append(gen.eqxyz) self.expandedUijs.append(gen.eqUij) return + # End of class ExpandAsymmetricUnit # Helper function for SymmetryConstraints class. It may be useful # elsewhere therefore its name does not start with underscore. + def pruneFormulaDictionary(eqdict): """Remove constant items from formula dictionary. @@ -648,7 +657,8 @@ def pruneFormulaDictionary(eqdict): """ pruned = {} for smb, eq in eqdict.items(): - if not isconstantFormula(eq): pruned[smb] = eq + if not isconstantFormula(eq): + pruned[smb] = eq return pruned @@ -679,8 +689,7 @@ class SymmetryConstraints(object): Uisotropy -- list of bool flags for isotropic thermal displacements """ - def __init__(self, spacegroup, positions, Uijs=None, - sgoffset=[0, 0, 0], eps=None): + def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=None): """Initialize and calculate SymmetryConstraints. spacegroup -- instance of SpaceGroup @@ -721,46 +730,45 @@ def __init__(self, spacegroup, positions, Uijs=None, self.Uijs = numpy.array(Uijs, dtype=float) else: self.Uijs = numpy.zeros((numpos, 3, 3), dtype=float) - self.poseqns = numpos*[None] - self.Ueqns = numpos*[None] - self.Uisotropy = numpos*[False] + self.poseqns = numpos * [None] + self.Ueqns = numpos * [None] + self.Uisotropy = numpos * [False] # all members should be initialized here self._findConstraints() return - def _findConstraints(self): - """Find constraints for positions and anisotropic displacements Uij - """ + """Find constraints for positions and anisotropic displacements Uij""" numpos = len(self.positions) # canonical xyzsymbols and Usymbols - xyzsymbols = [ smbl+str(i) for i in range(numpos) for smbl in "xyz" ] - Usymbols = [smbl+str(i) for i in range(numpos) for smbl in stdUsymbols] + xyzsymbols = [smbl + str(i) for i in range(numpos) for smbl in "xyz"] + Usymbols = [smbl + str(i) for i in range(numpos) for smbl in stdUsymbols] independent = set(range(numpos)) for genidx in range(numpos): - if not genidx in independent: continue + if not genidx in independent: + continue # it is a generator self.coremap[genidx] = [] genpos = self.positions[genidx] genUij = self.Uijs[genidx] - gen = GeneratorSite(self.spacegroup, genpos, genUij, - self.sgoffset, self.eps) + gen = GeneratorSite(self.spacegroup, genpos, genUij, self.sgoffset, self.eps) # append new pparameters if there are any - gxyzsymbols = xyzsymbols[3*genidx : 3*(genidx+1)] + gxyzsymbols = xyzsymbols[3 * genidx : 3 * (genidx + 1)] for k, v in gen.pparameters: smbl = gxyzsymbols["xyz".index(k)] - self.pospars.append( (smbl, v) ) - gUsymbols = Usymbols[6*genidx : 6*(genidx+1)] + self.pospars.append((smbl, v)) + gUsymbols = Usymbols[6 * genidx : 6 * (genidx + 1)] for k, v in gen.Uparameters: smbl = gUsymbols[stdUsymbols.index(k)] - self.Upars.append( (smbl, v) ) + self.Upars.append((smbl, v)) # search for equivalents inside indies indies = sorted(independent) for indidx in indies: indpos = self.positions[indidx] formula = gen.positionFormula(indpos, gxyzsymbols) # formula is empty when indidx is independent - if not formula: continue + if not formula: + continue # indidx is dependent here independent.remove(indidx) self.coremap[genidx].append(indidx) @@ -777,19 +785,14 @@ def _findConstraints(self): self.corepos = [self.positions[i] for i in coreidx] return - def posparSymbols(self): - """Return list of standard position parameter symbols. - """ + """Return list of standard position parameter symbols.""" return [n for n, v in self.pospars] - def posparValues(self): - """Return list of position parameters values. - """ + """Return list of position parameters values.""" return [v for n, v in self.pospars] - def positionFormulas(self, xyzsymbols=None): """List of position formulas with custom parameter symbols. @@ -799,17 +802,19 @@ def positionFormulas(self, xyzsymbols=None): keys are from ("x", "y", "z") and the values are formatted as [[-]{symbol}] [{+|-}%g], for example: "x0", "-sym", "@7 +0.5", "0.25". """ - if not xyzsymbols: return list(self.poseqns) + if not xyzsymbols: + return list(self.poseqns) # check xyzsymbols if len(xyzsymbols) < len(self.pospars): - emsg = ("Not enough symbols for %i position parameters" % - len(self.pospars)) + emsg = "Not enough symbols for %i position parameters" % len(self.pospars) raise SymmetryError(emsg) # build translation dictionary trsmbl = dict(zip(self.posparSymbols(), xyzsymbols)) + def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] - pat = re.compile(r'\b[xyz]\d+') + + pat = re.compile(r"\b[xyz]\d+") rv = [] for eqns in self.poseqns: treqns = {} @@ -818,7 +823,6 @@ def translatesymbol(matchobj): rv.append(treqns) return rv - def positionFormulasPruned(self, xyzsymbols=None): """List of position formula dictionaries with constant items removed. See also positionFormulas(). @@ -827,23 +831,17 @@ def positionFormulasPruned(self, xyzsymbols=None): Return list of coordinate formula dictionaries. """ - rv = [pruneFormulaDictionary(eqns) - for eqns in self.positionFormulas(xyzsymbols)] + rv = [pruneFormulaDictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] return rv - def UparSymbols(self): - """Return list of standard atom displacement parameter symbols. - """ + """Return list of standard atom displacement parameter symbols.""" return [n for n, v in self.Upars] - def UparValues(self): - """Return list of atom displacement parameters values. - """ + """Return list of atom displacement parameters values.""" return [v for n, v in self.Upars] - def UFormulas(self, Usymbols=None): """List of atom displacement formulas with custom parameter symbols. @@ -854,16 +852,19 @@ def UFormulas(self, Usymbols=None): and the values are formatted as {[%g*][Usymbol]|0}, for example: "U11", "0.5*@37", "0". """ - if not Usymbols: return list(self.Ueqns) + if not Usymbols: + return list(self.Ueqns) # check Usymbols if len(Usymbols) < len(self.Upars): emsg = "Not enough symbols for %i U parameters" % len(self.Upars) raise SymmetryError(emsg) # build translation dictionary trsmbl = dict(zip(self.UparSymbols(), Usymbols)) + def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] - pat = re.compile(r'\bU\d\d\d+') + + pat = re.compile(r"\bU\d\d\d+") rv = [] for eqns in self.Ueqns: treqns = {} @@ -872,7 +873,6 @@ def translatesymbol(matchobj): rv.append(treqns) return rv - def UFormulasPruned(self, Usymbols=None): """List of atom displacement formula dictionaries with constant items removed. See also UFormulas(). @@ -882,10 +882,10 @@ def UFormulasPruned(self, Usymbols=None): Return list of atom displacement formulas in tuples of (U11, U22, U33, U12, U13, U23). """ - rv = [ pruneFormulaDictionary(eqns) - for eqns in self.UFormulas(Usymbols) ] + rv = [pruneFormulaDictionary(eqns) for eqns in self.UFormulas(Usymbols)] return rv + # End of class SymmetryConstraints # ---------------------------------------------------------------------------- @@ -893,8 +893,9 @@ def UFormulasPruned(self, Usymbols=None): # basic demonstration if __name__ == "__main__": from diffpy.structure.spacegroups import sg100 - site = [.125, .625, .13] - Uij = [[1,2,3],[2,4,5],[3,5,6]] + + site = [0.125, 0.625, 0.13] + Uij = [[1, 2, 3], [2, 4, 5], [3, 5, 6]] g = GeneratorSite(sg100, site, Uij=Uij) fm100 = g.positionFormula(site) print("g = GeneratorSite(sg100, %r)" % site) diff --git a/src/diffpy/structure/tests/__init__.py b/src/diffpy/structure/tests/__init__.py index f5bfe145..fc6afec6 100644 --- a/src/diffpy/structure/tests/__init__.py +++ b/src/diffpy/structure/tests/__init__.py @@ -19,8 +19,8 @@ import unittest -def testsuite(pattern=''): - '''Create a unit tests suite for diffpy.structure package. +def testsuite(pattern=""): + """Create a unit tests suite for diffpy.structure package. Parameters ---------- @@ -33,14 +33,16 @@ def testsuite(pattern=''): ------- suite : `unittest.TestSuite` The TestSuite object containing the matching tests. - ''' + """ import re - from os.path import dirname from itertools import chain + from os.path import dirname + from pkg_resources import resource_filename + loader = unittest.defaultTestLoader - thisdir = resource_filename(__name__, '') - depth = __name__.count('.') + 1 + thisdir = resource_filename(__name__, "") + depth = __name__.count(".") + 1 topdir = thisdir for i in range(depth): topdir = dirname(topdir) @@ -50,12 +52,12 @@ def testsuite(pattern=''): rx = re.compile(pattern) tsuites = list(chain.from_iterable(suite_all)) tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover + if not tsok: # pragma: no cover return suite_all tcases = chain.from_iterable(tsuites) for tc in tcases: - tcwords = tc.id().split('.') - shortname = '.'.join(tcwords[-3:]) + tcwords = tc.id().split(".") + shortname = ".".join(tcwords[-3:]) if rx.search(shortname): suite.addTest(tc) # verify all tests are found for an empty pattern. @@ -64,12 +66,12 @@ def testsuite(pattern=''): def test(): - '''Execute all unit tests for the diffpy.structure package. + """Execute all unit tests for the diffpy.structure package. Returns ------- result : `unittest.TestResult` - ''' + """ suite = testsuite() runner = unittest.TextTestRunner() result = runner.run(suite) diff --git a/src/diffpy/structure/tests/run.py b/src/diffpy/structure/tests/run.py index 5bd8b2a8..4b9b58ee 100644 --- a/src/diffpy/structure/tests/run.py +++ b/src/diffpy/structure/tests/run.py @@ -19,14 +19,18 @@ """ -if __name__ == '__main__': +if __name__ == "__main__": import sys + # show warnings by default if not sys.warnoptions: - import os, warnings + import os + import warnings + warnings.simplefilter("default") # also affect subprocesses os.environ["PYTHONWARNINGS"] = "default" from diffpy.structure.tests import test + # produce zero exit code for a successful test sys.exit(not test().wasSuccessful()) diff --git a/src/diffpy/structure/tests/testatom.py b/src/diffpy/structure/tests/testatom.py index dc6073f6..67009e80 100644 --- a/src/diffpy/structure/tests/testatom.py +++ b/src/diffpy/structure/tests/testatom.py @@ -19,6 +19,7 @@ import unittest + import numpy from diffpy.structure.atom import Atom @@ -26,77 +27,76 @@ # ---------------------------------------------------------------------------- + class TestAtom(unittest.TestCase): def test___init__(self): - """check Atom.__init__() - """ + """check Atom.__init__()""" a = Atom() - self.assertEqual('', a.element) + self.assertEqual("", a.element) self.assertTrue((a.xyz == 0).all()) - self.assertEqual('', a.label) + self.assertEqual("", a.label) self.assertEqual(1.0, a.occupancy) self.assertFalse(a.anisotropy) self.assertTrue((a.U == 0).all()) self.assertTrue(a.lattice is None) # check initialization with arguments - a1 = Atom('C', xyz=(1, 2, 3), Uisoequiv=0.005) - self.assertEqual('C', a1.element) + a1 = Atom("C", xyz=(1, 2, 3), Uisoequiv=0.005) + self.assertEqual("C", a1.element) self.assertTrue(numpy.array_equal([1, 2, 3], a1.xyz)) self.assertFalse(a1.anisotropy) self.assertEqual(0.005, a1.Uisoequiv) # initialize with anisotropic displacement parameters - uani = numpy.identity(3, dtype=float) * numpy.array([1, 2, 3]) * .01 - a2 = Atom('C', U=uani) + uani = numpy.identity(3, dtype=float) * numpy.array([1, 2, 3]) * 0.01 + a2 = Atom("C", U=uani) self.assertTrue(numpy.array_equal(uani, a2.U)) self.assertTrue(a2.anisotropy) - a3 = Atom('C', Uisoequiv=0.02, anisotropy=True) + a3 = Atom("C", Uisoequiv=0.02, anisotropy=True) self.assertTrue(a3.anisotropy) self.assertEqual(a3.U[2, 2], 0.02) - self.assertRaises(ValueError, Atom, - 'C', Uisoequiv=0.02, U=uani) + self.assertRaises(ValueError, Atom, "C", Uisoequiv=0.02, U=uani) return -# def test_msdLat(self): -# """check Atom.msdLat() -# """ -# return -# -# def test_msdCart(self): -# """check Atom.msdCart() -# """ -# return -# -# def test___repr__(self): -# """check Atom.__repr__() -# """ -# return -# -# def test___copy__(self): -# """check Atom.__copy__() -# """ -# return + # def test_msdLat(self): + # """check Atom.msdLat() + # """ + # return + # + # def test_msdCart(self): + # """check Atom.msdCart() + # """ + # return + # + # def test___repr__(self): + # """check Atom.__repr__() + # """ + # return + # + # def test___copy__(self): + # """check Atom.__copy__() + # """ + # return def test_xyz_cartn(self): - """check Atom.xyz_cartn property - """ + """check Atom.xyz_cartn property""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) - a0 = Atom('C', [0, 0, 0], lattice=hexagonal) - a1 = Atom('C', [1, 1, 1], lattice=hexagonal) + a0 = Atom("C", [0, 0, 0], lattice=hexagonal) + a1 = Atom("C", [1, 1, 1], lattice=hexagonal) self.assertTrue(all(a0.xyz_cartn == 0)) - rc1 = numpy.array([0.75 ** 0.5, 0.5, 1]) + rc1 = numpy.array([0.75**0.5, 0.5, 1]) self.assertTrue(numpy.allclose(rc1, a1.xyz_cartn)) a1.xyz_cartn[2] = 0 self.assertTrue(numpy.allclose([1, 1, 0], a1.xyz)) a1.xyz_cartn[:2] = 0 self.assertTrue(all(a1.xyz == 0)) - a3 = Atom('C', [1, 2, 3]) + a3 = Atom("C", [1, 2, 3]) self.assertTrue(numpy.array_equal(a3.xyz, a3.xyz_cartn)) a3.xyz_cartn = 1.3 self.assertTrue(all(1.3 == a3.xyz_cartn)) self.assertTrue(all(1.3 == a3.xyz)) return + # def test__get_anisotropy(self): # """check Atom._get_anisotropy() # """ @@ -151,5 +151,5 @@ def test_xyz_cartn(self): # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testdata/CdSe_bulk.stru b/src/diffpy/structure/tests/testdata/CdSe_bulk.stru index 8ad56e85..dbd3179c 100644 --- a/src/diffpy/structure/tests/testdata/CdSe_bulk.stru +++ b/src/diffpy/structure/tests/testdata/CdSe_bulk.stru @@ -2,11 +2,11 @@ title Cell structure file of CdSe #186 format pdffit scale 0.846685 sharp 0.366927, 0.591251, 3.700000 -spcgr P63mc +spcgr P63mc cell 4.235204, 4.235204, 6.906027, 90.000000, 90.000000,120.000000 dcell 0.000493, 0.000493, 0.001368, 0.000000, 0.000000, 0.000000 ncell 1, 1, 1, 4 -atoms +atoms CD 0.33340001 0.66670001 0.00000000 1.0000 0.00000000 0.00000000 0.00000000 0.0000 0.01303035 0.01303035 0.01401959 diff --git a/src/diffpy/structure/tests/testdata/LiCl-bad.cif b/src/diffpy/structure/tests/testdata/LiCl-bad.cif index e1a30c3c..4c6f6f83 100644 --- a/src/diffpy/structure/tests/testdata/LiCl-bad.cif +++ b/src/diffpy/structure/tests/testdata/LiCl-bad.cif @@ -2,15 +2,15 @@ data_LithiumChloride -_audit_creation_method 'Crystallographica 2' -_cell_angle_alpha 90 -_cell_angle_beta 90 -_cell_angle_gamma 90 -_cell_formula_units_Z 4 -_cell_length_a 5.12952 -_cell_length_b 5.12952 -_cell_length_c 5.12952 -_cell_volume 134.968 +_audit_creation_method 'Crystallographica 2' +_cell_angle_alpha 90 +_cell_angle_beta 90 +_cell_angle_gamma 90 +_cell_formula_units_Z 4 +_cell_length_a 5.12952 +_cell_length_b 5.12952 +_cell_length_c 5.12952 +_cell_volume 134.968 _cgraph_comments 'Praezisionsbestimmung von Gitterkonstanten hygroskopischer Verbindungen (Li Cl. Na Br). ' @@ -229,4 +229,3 @@ loop_ _eof #### End of Crystallographic Information File #### - diff --git a/src/diffpy/structure/tests/testdata/Ni-bad.stru b/src/diffpy/structure/tests/testdata/Ni-bad.stru index f7b5469c..766ca134 100644 --- a/src/diffpy/structure/tests/testdata/Ni-bad.stru +++ b/src/diffpy/structure/tests/testdata/Ni-bad.stru @@ -2,11 +2,11 @@ title structure Ni FCC format pdffit scale 1.000000 sharp 0.000000, 0.000000, 1.000000, 0.000000 -spcgr Fm-3m +spcgr Fm-3m cell 3.520000, 3.520000, 3.520000, 90.000000, 90.000000, 90.000000 dcell 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ncell 1, 1, 1, 4 -atoms +atoms NI 0.00000000 0.00000000 0.00000000 1.0000 0.00000000 0.00000000 0.00000000 0.0000 0.00126651 0.00126651 0.00126651 diff --git a/src/diffpy/structure/tests/testdata/Ni-discus.stru b/src/diffpy/structure/tests/testdata/Ni-discus.stru index 8d8e64c7..3e5fab07 100644 --- a/src/diffpy/structure/tests/testdata/Ni-discus.stru +++ b/src/diffpy/structure/tests/testdata/Ni-discus.stru @@ -1,8 +1,8 @@ title structure Ni FCC -spcgr Fm-3m +spcgr Fm-3m cell 3.520000, 3.520000, 3.520000, 90.000000, 90.000000, 90.000000 ncell 1, 1, 1, 4 -atoms +atoms NI 0.00000000 0.00000000 0.00000000 0.1000 NI 0.00000000 0.50000000 0.50000000 0.1000 NI 0.50000000 0.00000000 0.50000000 0.1000 diff --git a/src/diffpy/structure/tests/testdata/Ni.stru b/src/diffpy/structure/tests/testdata/Ni.stru index 5d39b959..e13f2693 100644 --- a/src/diffpy/structure/tests/testdata/Ni.stru +++ b/src/diffpy/structure/tests/testdata/Ni.stru @@ -2,11 +2,11 @@ title structure Ni FCC format pdffit scale 1.000000 sharp 0.000000, 0.000000, 1.000000, 0.000000 -spcgr Fm-3m +spcgr Fm-3m cell 3.520000, 3.520000, 3.520000, 90.000000, 90.000000, 90.000000 dcell 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ncell 1, 1, 1, 4 -atoms +atoms NI 0.00000000 0.00000000 0.00000000 1.0000 0.00000000 0.00000000 0.00000000 0.0000 0.00126651 0.00126651 0.00126651 diff --git a/src/diffpy/structure/tests/testdata/Ni_ref.cif b/src/diffpy/structure/tests/testdata/Ni_ref.cif index 82232f42..858dd3c6 100644 --- a/src/diffpy/structure/tests/testdata/Ni_ref.cif +++ b/src/diffpy/structure/tests/testdata/Ni_ref.cif @@ -18,4 +18,3 @@ _atom_site_occupancy _atom_site_adp_type _atom_site_U_iso_or_equiv Ni Ni 0.00000000 0.00000000 0.00000000 1.00000000 Uiso 0.025 - diff --git a/src/diffpy/structure/tests/testdata/arginine.pdb b/src/diffpy/structure/tests/testdata/arginine.pdb index c0a13ae8..008c09ce 100644 --- a/src/diffpy/structure/tests/testdata/arginine.pdb +++ b/src/diffpy/structure/tests/testdata/arginine.pdb @@ -1,28 +1,28 @@ -ATOM 1 N ARG 1 0.735 2.219 1.389 1.00 0.00 -ATOM 2 CA ARG 1 2.189 2.285 1.274 1.00 0.00 -ATOM 3 C ARG 1 2.600 3.010 0.014 1.00 0.00 -ATOM 4 O ARG 1 1.774 3.463 -0.774 1.00 0.00 -ATOM 5 CB ARG 1 2.760 0.838 1.308 1.00 0.00 -ATOM 6 CG ARG 1 4.302 0.731 1.473 1.00 0.00 -ATOM 7 CD ARG 1 4.786 -0.729 1.460 1.00 0.00 -ATOM 8 NE ARG 1 6.267 -0.770 1.642 1.00 0.00 -ATOM 9 CZ ARG 1 7.007 -1.874 1.673 1.00 0.00 -ATOM 10 NH1 ARG 1 6.518 -3.074 1.538 1.00 0.00 -ATOM 11 NH2 ARG 1 8.285 -1.752 1.846 1.00 0.00 -ATOM 12 H ARG 1 0.115 2.627 0.682 1.00 0.00 -ATOM 13 H ARG 1 0.273 1.763 2.183 1.00 0.00 -ATOM 14 HA ARG 1 2.575 2.864 2.134 1.00 0.00 -ATOM 15 HB ARG 1 2.277 0.276 2.132 1.00 0.00 -ATOM 16 HB ARG 1 2.438 0.307 0.388 1.00 0.00 -ATOM 17 HG ARG 1 4.812 1.292 0.662 1.00 0.00 -ATOM 18 HG ARG 1 4.604 1.231 2.416 1.00 0.00 -ATOM 19 HD ARG 1 4.269 -1.296 2.264 1.00 0.00 -ATOM 20 HD ARG 1 4.490 -1.205 0.499 1.00 0.00 -ATOM 21 HE ARG 1 6.806 0.094 1.761 1.00 0.00 -ATOM 22 HH1 ARG 1 7.154 -3.872 1.573 1.00 0.00 -ATOM 23 HH1 ARG 1 5.505 -3.100 1.403 1.00 0.00 -ATOM 24 HH2 ARG 1 8.649 -0.803 1.949 1.00 0.00 -ATOM 25 HH2 ARG 1 8.837 -2.612 1.868 1.00 0.00 -ATOM 26 OC ARG 1 4.007 3.160 -0.192 1.00 0.00 -ATOM 27 HC ARG 1 4.448 3.496 0.676 1.00 0.00 -TER +ATOM 1 N ARG 1 0.735 2.219 1.389 1.00 0.00 +ATOM 2 CA ARG 1 2.189 2.285 1.274 1.00 0.00 +ATOM 3 C ARG 1 2.600 3.010 0.014 1.00 0.00 +ATOM 4 O ARG 1 1.774 3.463 -0.774 1.00 0.00 +ATOM 5 CB ARG 1 2.760 0.838 1.308 1.00 0.00 +ATOM 6 CG ARG 1 4.302 0.731 1.473 1.00 0.00 +ATOM 7 CD ARG 1 4.786 -0.729 1.460 1.00 0.00 +ATOM 8 NE ARG 1 6.267 -0.770 1.642 1.00 0.00 +ATOM 9 CZ ARG 1 7.007 -1.874 1.673 1.00 0.00 +ATOM 10 NH1 ARG 1 6.518 -3.074 1.538 1.00 0.00 +ATOM 11 NH2 ARG 1 8.285 -1.752 1.846 1.00 0.00 +ATOM 12 H ARG 1 0.115 2.627 0.682 1.00 0.00 +ATOM 13 H ARG 1 0.273 1.763 2.183 1.00 0.00 +ATOM 14 HA ARG 1 2.575 2.864 2.134 1.00 0.00 +ATOM 15 HB ARG 1 2.277 0.276 2.132 1.00 0.00 +ATOM 16 HB ARG 1 2.438 0.307 0.388 1.00 0.00 +ATOM 17 HG ARG 1 4.812 1.292 0.662 1.00 0.00 +ATOM 18 HG ARG 1 4.604 1.231 2.416 1.00 0.00 +ATOM 19 HD ARG 1 4.269 -1.296 2.264 1.00 0.00 +ATOM 20 HD ARG 1 4.490 -1.205 0.499 1.00 0.00 +ATOM 21 HE ARG 1 6.806 0.094 1.761 1.00 0.00 +ATOM 22 HH1 ARG 1 7.154 -3.872 1.573 1.00 0.00 +ATOM 23 HH1 ARG 1 5.505 -3.100 1.403 1.00 0.00 +ATOM 24 HH2 ARG 1 8.649 -0.803 1.949 1.00 0.00 +ATOM 25 HH2 ARG 1 8.837 -2.612 1.868 1.00 0.00 +ATOM 26 OC ARG 1 4.007 3.160 -0.192 1.00 0.00 +ATOM 27 HC ARG 1 4.448 3.496 0.676 1.00 0.00 +TER diff --git a/src/diffpy/structure/tests/testdata/bucky-bad2.xyz b/src/diffpy/structure/tests/testdata/bucky-bad2.xyz index e08b94d6..5f4012bf 100644 --- a/src/diffpy/structure/tests/testdata/bucky-bad2.xyz +++ b/src/diffpy/structure/tests/testdata/bucky-bad2.xyz @@ -60,5 +60,3 @@ bucky-ball C 1.95470 -1.42020 -2.57930 C 1.57570 -2.58660 -1.82130 C 2.33370 -2.58660 -0.59480 - - diff --git a/src/diffpy/structure/tests/testdata/bucky.xyz b/src/diffpy/structure/tests/testdata/bucky.xyz index fc75501a..539793b5 100644 --- a/src/diffpy/structure/tests/testdata/bucky.xyz +++ b/src/diffpy/structure/tests/testdata/bucky.xyz @@ -63,5 +63,3 @@ bucky-ball C 1.95470 -1.42020 -2.57930 C 1.57570 -2.58660 -1.82130 C 2.33370 -2.58660 -0.59480 - - diff --git a/src/diffpy/structure/tests/testlattice.py b/src/diffpy/structure/tests/testlattice.py index 8a724ee8..6b539634 100644 --- a/src/diffpy/structure/tests/testlattice.py +++ b/src/diffpy/structure/tests/testlattice.py @@ -17,6 +17,7 @@ """ import unittest + import numpy import numpy.linalg as numalg @@ -24,6 +25,7 @@ # ---------------------------------------------------------------------------- + class TestLattice(unittest.TestCase): """test methods of Lattice class""" @@ -32,15 +34,10 @@ def setUp(self): self.places = 12 return - def test___init__(self): - '''Check Lattice.__init__ processing of arguments. - ''' - self.assertRaises(ValueError, Lattice, - self.lattice, c=4) - self.assertRaises(ValueError, Lattice, - base=self.lattice.base, - baserot=self.lattice.baserot) + """Check Lattice.__init__ processing of arguments.""" + self.assertRaises(ValueError, Lattice, self.lattice, c=4) + self.assertRaises(ValueError, Lattice, base=self.lattice.base, baserot=self.lattice.baserot) self.assertRaises(ValueError, Lattice, 1, 2, 3) self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90) L0 = self.lattice @@ -55,30 +52,26 @@ def test___init__(self): self.assertTrue(numpy.allclose(L0.isotropicunit, L3.isotropicunit)) return - def test_setLatPar(self): """check calculation of standard unit cell vectors""" + from math import cos, radians, sqrt + from numpy import dot - from math import radians, sqrt, cos - norm = lambda x : sqrt(sum([xi**2 for xi in x])) - cosd = lambda x : cos(radians(x)) + + norm = lambda x: sqrt(sum([xi**2 for xi in x])) + cosd = lambda x: cos(radians(x)) self.lattice.setLatPar(1.0, 2.0, 3.0, 80, 100, 120) base = self.lattice.base self.assertAlmostEqual(1.0, norm(base[0]), self.places) self.assertAlmostEqual(2.0, norm(base[1]), self.places) self.assertAlmostEqual(3.0, norm(base[2]), self.places) - self.assertAlmostEqual(cosd(80.0), - dot(base[1],base[2])/(2*3), self.places) - self.assertAlmostEqual(cosd(100.0), - dot(base[0],base[2])/(1*3), self.places) - self.assertAlmostEqual(cosd(120.0), - dot(base[0],base[1])/(1*2), self.places) + self.assertAlmostEqual(cosd(80.0), dot(base[1], base[2]) / (2 * 3), self.places) + self.assertAlmostEqual(cosd(100.0), dot(base[0], base[2]) / (1 * 3), self.places) + self.assertAlmostEqual(cosd(120.0), dot(base[0], base[1]) / (1 * 2), self.places) return - def test_latpar_properties(self): - '''check assignment to a, b, c, alpha, beta, gamma. - ''' + """check assignment to a, b, c, alpha, beta, gamma.""" lat = self.lattice lat.a = 2 lat.b = 4 @@ -91,81 +84,56 @@ def test_latpar_properties(self): self.assertTrue(numpy.array_equal(lat1.base, lat.base)) return - def test_readonly_properties(self): - '''Check that read-only properties are indeed such. - ''' + """Check that read-only properties are indeed such.""" lat = self.lattice lat.b = 2 lat.c = 6 self.assertEqual(1.0, lat.unitvolume) - self.assertRaises(AttributeError, setattr, - lat, 'unitvolume', 3.33) + self.assertRaises(AttributeError, setattr, lat, "unitvolume", 3.33) self.assertEqual(12, lat.volume) - self.assertRaises(AttributeError, setattr, - lat, 'volume', 3.33) + self.assertRaises(AttributeError, setattr, lat, "volume", 3.33) self.assertEqual(0.0, lat.ca) - self.assertRaises(AttributeError, setattr, - lat, 'ca', 3.33) + self.assertRaises(AttributeError, setattr, lat, "ca", 3.33) self.assertEqual(0.0, lat.cb) - self.assertRaises(AttributeError, setattr, - lat, 'cb', 3.33) + self.assertRaises(AttributeError, setattr, lat, "cb", 3.33) self.assertEqual(0.0, lat.cg) - self.assertRaises(AttributeError, setattr, - lat, 'cg', 3.33) + self.assertRaises(AttributeError, setattr, lat, "cg", 3.33) self.assertEqual(1.0, lat.sa) - self.assertRaises(AttributeError, setattr, - lat, 'sa', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sa", 3.33) self.assertEqual(1.0, lat.sb) - self.assertRaises(AttributeError, setattr, - lat, 'sb', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sb", 3.33) self.assertEqual(1.0, lat.sg) - self.assertRaises(AttributeError, setattr, - lat, 'sg', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sg", 3.33) self.assertEqual(1.0, lat.ar) - self.assertRaises(AttributeError, setattr, - lat, 'ar', 3.33) + self.assertRaises(AttributeError, setattr, lat, "ar", 3.33) self.assertEqual(0.5, lat.br) - self.assertRaises(AttributeError, setattr, - lat, 'br', 3.33) - self.assertAlmostEqual(1.0/6, lat.cr, self.places) - self.assertRaises(AttributeError, setattr, - lat, 'cr', 3.33) + self.assertRaises(AttributeError, setattr, lat, "br", 3.33) + self.assertAlmostEqual(1.0 / 6, lat.cr, self.places) + self.assertRaises(AttributeError, setattr, lat, "cr", 3.33) self.assertEqual(90.0, lat.alphar) - self.assertRaises(AttributeError, setattr, - lat, 'alphar', 3.33) + self.assertRaises(AttributeError, setattr, lat, "alphar", 3.33) self.assertEqual(90.0, lat.betar) - self.assertRaises(AttributeError, setattr, - lat, 'betar', 3.33) + self.assertRaises(AttributeError, setattr, lat, "betar", 3.33) self.assertEqual(90.0, lat.gammar) - self.assertRaises(AttributeError, setattr, - lat, 'gammar', 3.33) + self.assertRaises(AttributeError, setattr, lat, "gammar", 3.33) self.assertEqual(0.0, lat.car) - self.assertRaises(AttributeError, setattr, - lat, 'car', 3.33) + self.assertRaises(AttributeError, setattr, lat, "car", 3.33) self.assertEqual(0.0, lat.cbr) - self.assertRaises(AttributeError, setattr, - lat, 'cbr', 3.33) + self.assertRaises(AttributeError, setattr, lat, "cbr", 3.33) self.assertEqual(0.0, lat.cgr) - self.assertRaises(AttributeError, setattr, - lat, 'cgr', 3.33) + self.assertRaises(AttributeError, setattr, lat, "cgr", 3.33) self.assertEqual(1.0, lat.sar) - self.assertRaises(AttributeError, setattr, - lat, 'sar', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sar", 3.33) self.assertEqual(1.0, lat.sbr) - self.assertRaises(AttributeError, setattr, - lat, 'sbr', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sbr", 3.33) self.assertEqual(1.0, lat.sgr) - self.assertRaises(AttributeError, setattr, - lat, 'sgr', 3.33) + self.assertRaises(AttributeError, setattr, lat, "sgr", 3.33) return - def test_setLatBase(self): """check calculation of unit cell rotation""" - base = numpy.array([[1.0, 1.0, 0.0], - [0.0, 1.0, 1.0], - [1.0, 0.0, 1.0]]) + base = numpy.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) self.lattice.setLatBase(base) self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places) self.assertAlmostEqual(self.lattice.b, numpy.sqrt(2.0), self.places) @@ -184,15 +152,12 @@ def test_setLatBase(self): self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) # try base checking - self.assertRaises(LatticeError, self.lattice.setLatBase, - [[1, 0, 0], [1,0,0], [0,0,1]]) - self.assertRaises(LatticeError, self.lattice.setLatBase, - [[1, 0, 0], [0,0,1], [0,1,0]]) + self.assertRaises(LatticeError, self.lattice.setLatBase, [[1, 0, 0], [1, 0, 0], [0, 0, 1]]) + self.assertRaises(LatticeError, self.lattice.setLatBase, [[1, 0, 0], [0, 0, 1], [0, 1, 0]]) return - def test_reciprocal(self): - '''check calculation of reciprocal lattice.''' + """check calculation of reciprocal lattice.""" r1 = self.lattice.reciprocal() self.assertEqual((1, 1, 1, 90, 90, 90), r1.abcABG()) L2 = Lattice(2, 4, 8, 90, 90, 90) @@ -202,9 +167,8 @@ def test_reciprocal(self): self.assertTrue(numpy.array_equal(L2.base, rr2.base)) return - def test_dot(self): - '''check dot product of lattice vectors.''' + """check dot product of lattice vectors.""" L = self.lattice L.setLatPar(gamma=120) self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places) @@ -215,9 +179,8 @@ def test_dot(self): self.assertTrue(numpy.array_equal(5 * [-0.5], L.dot(va5, vb5[0]))) return - def test_norm(self): - '''check norm of a lattice vector.''' + """check norm of a lattice vector.""" self.assertEqual(1, self.lattice.norm([1, 0, 0])) u = numpy.array([[3, 4, 0], [1, 1, 1]]) self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u))) @@ -225,9 +188,8 @@ def test_norm(self): self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places) return - def test_rnorm(self): - '''check norm of a reciprocal vector.''' + """check norm of a reciprocal vector.""" L = self.lattice L.setLatPar(1, 1.5, 2.3, 80, 95, 115) r = L.reciprocal() @@ -237,9 +199,8 @@ def test_rnorm(self): self.assertTrue(numpy.allclose(5 * [r.norm(hkl)], L.rnorm(hkl5))) return - def test_dist(self): - '''check dist function for distance between lattice points.''' + """check dist function for distance between lattice points.""" L = self.lattice L.setLatPar(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] @@ -254,18 +215,17 @@ def test_dist(self): self.assertTrue(numpy.allclose(5 * [d0], L.dist(v5, u5))) return - def test_angle(self): - '''check angle calculation between lattice vectors.''' - from math import degrees, acos + """check angle calculation between lattice vectors.""" + from math import acos, degrees + L = self.lattice L.setLatPar(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] v = [0.3, 0.7, 0.7] uc = L.cartesian(u) vc = L.cartesian(v) - a0 = degrees(acos(numpy.dot(uc, vc) / - (numalg.norm(uc) * numalg.norm(vc)))) + a0 = degrees(acos(numpy.dot(uc, vc) / (numalg.norm(uc) * numalg.norm(vc)))) self.assertAlmostEqual(a0, L.angle(u, v), self.places) self.assertAlmostEqual(a0, L.angle(v, u), self.places) u5 = numpy.tile(u, (5, 1)) @@ -275,8 +235,6 @@ def test_angle(self): self.assertTrue(numpy.allclose(5 * [a0], L.angle(v5, u5))) return - - def test_repr(self): """check string representation of this lattice""" r = repr(self.lattice) @@ -285,16 +243,15 @@ def test_repr(self): r = repr(self.lattice) r0 = "Lattice(a=1, b=2, c=3, alpha=10, beta=20, gamma=30)" self.assertEqual(r, r0) - base = [[1.0, 1.0, 0.0], - [0.0, 2.0, 2.0], - [3.0, 0.0, 3.0]] + base = [[1.0, 1.0, 0.0], [0.0, 2.0, 2.0], [3.0, 0.0, 3.0]] self.lattice.setLatBase(base) r = repr(self.lattice) self.assertEqual(r, "Lattice(base=%r)" % self.lattice.base) + # End of class TestLattice # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testloadstructure.py b/src/diffpy/structure/tests/testloadstructure.py index bbcaf8ad..f5bbd470 100644 --- a/src/diffpy/structure/tests/testloadstructure.py +++ b/src/diffpy/structure/tests/testloadstructure.py @@ -4,71 +4,60 @@ """ import unittest + +from diffpy.structure import PDFFitStructure, Structure, StructureFormatError, loadStructure from diffpy.structure.tests.testutils import datafile -from diffpy.structure import loadStructure -from diffpy.structure import Structure, PDFFitStructure, StructureFormatError ############################################################################## class TestLoadStructure(unittest.TestCase): def test_xcfg(self): - """check loading of atomeye xcfg format - """ - f = datafile('BubbleRaftShort.xcfg') + """check loading of atomeye xcfg format""" + f = datafile("BubbleRaftShort.xcfg") stru = loadStructure(f) self.assertTrue(type(stru) is Structure) - self.assertRaises(StructureFormatError, - loadStructure, f, 'xyz') + self.assertRaises(StructureFormatError, loadStructure, f, "xyz") return - def test_discus(self): - """check loading of discus file format - """ - f = datafile('Ni-discus.stru') + """check loading of discus file format""" + f = datafile("Ni-discus.stru") stru = loadStructure(f) self.assertTrue(type(stru) is PDFFitStructure) return - def test_cif(self): - """check loading of CIF file format - """ - f = datafile('PbTe.cif') + """check loading of CIF file format""" + f = datafile("PbTe.cif") stru = loadStructure(f) self.assertTrue(isinstance(stru, Structure)) self.assertFalse(isinstance(stru, PDFFitStructure)) return - def test_badfile(self): - """check loading of CIF file format - """ - f = datafile('Ni-bad.stru') + """check loading of CIF file format""" + f = datafile("Ni-bad.stru") self.assertRaises(StructureFormatError, loadStructure, f) return - def test_goodkwarg(self): - """check loading of CIF file and passing of parser keyword argument. - """ - f = datafile('graphite.cif') + """check loading of CIF file and passing of parser keyword argument.""" + f = datafile("graphite.cif") stru = loadStructure(f, eps=1e-10) self.assertEqual(8, len(stru)) return - def test_badkwarg(self): - """check loading of xyz file format with invalid keyword argument - """ - f = datafile('bucky.xyz') + """check loading of xyz file format with invalid keyword argument""" + f = datafile("bucky.xyz") self.assertRaises(TypeError, loadStructure, f, eps=1e-10) return + # End of class TestLoadStructure # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testoldimports.py b/src/diffpy/structure/tests/testoldimports.py index a0a3852a..9c6ff11d 100644 --- a/src/diffpy/structure/tests/testoldimports.py +++ b/src/diffpy/structure/tests/testoldimports.py @@ -18,61 +18,60 @@ """ -import sys -import warnings import importlib +import sys import unittest +import warnings import diffpy # ---------------------------------------------------------------------------- + class TestOldImports(unittest.TestCase): @classmethod def setUpClass(cls): "Uncache any already-imported old modules." for modname in tuple(sys.modules): - if modname.startswith('diffpy.Structure'): - del sys.modules[modname] # pragma: no cover + if modname.startswith("diffpy.Structure"): + del sys.modules[modname] # pragma: no cover return - def test_00TopImport(self): - """check import of diffpy.Structure - """ + """check import of diffpy.Structure""" with warnings.catch_warnings(): - warnings.simplefilter('ignore', category=DeprecationWarning) + warnings.simplefilter("ignore", category=DeprecationWarning) import diffpy.Structure as m0 self.assertIs(diffpy.structure, m0) # second import should raise no warning with warnings.catch_warnings(): - warnings.simplefilter('error') + warnings.simplefilter("error") import diffpy.Structure as m1 self.assertIs(diffpy.structure, m1) return - def test_O1SubmoduleImport(self): - """check import of diffpy.Structure submodules. - """ + """check import of diffpy.Structure submodules.""" with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter("always", category=DeprecationWarning) import diffpy.Structure.SymmetryUtilities as symutil + self.assertIs(DeprecationWarning, w[0].category) self.assertIs(diffpy.structure.symmetryutilities, symutil) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter("always", category=DeprecationWarning) import diffpy.Structure.Parsers.P_cif as pcif + self.assertIs(DeprecationWarning, w[0].category) self.assertIs(diffpy.structure.parsers.p_cif, pcif) - self.assertRaises(ImportError, importlib.import_module, - 'diffpy.Structure.SSpaceGroups') + self.assertRaises(ImportError, importlib.import_module, "diffpy.Structure.SSpaceGroups") return + # End of class TestOldImports # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/testp_cif.py index b6eb66c7..2451a632 100644 --- a/src/diffpy/structure/tests/testp_cif.py +++ b/src/diffpy/structure/tests/testp_cif.py @@ -17,17 +17,18 @@ """ import unittest + import numpy import six -from diffpy.structure.tests.testutils import datafile -from diffpy.structure.parsers.p_cif import P_cif, leading_float, getSymOp +from diffpy.structure import Structure, StructureFormatError from diffpy.structure.parsers import getParser -from diffpy.structure import Structure -from diffpy.structure import StructureFormatError +from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float +from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- + class TestRoutines(unittest.TestCase): def setUp(self): @@ -36,45 +37,43 @@ def setUp(self): def tearDown(self): return - def test_leading_float(self): - """check leading_float() - """ - self.assertEqual(0.37, leading_float('0.37(3)')) - self.assertEqual(0.37, leading_float('0.37ab\ncd')) - self.assertRaises(ValueError, leading_float, 'q1') + """check leading_float()""" + self.assertEqual(0.37, leading_float("0.37(3)")) + self.assertEqual(0.37, leading_float("0.37ab\ncd")) + self.assertRaises(ValueError, leading_float, "q1") return - def test_getSymOp(self): - """check getSymOp() - """ - from diffpy.structure.spacegroups import SymOp - from diffpy.structure.spacegroups import Rot_X_mY_Z, Tr_0_12_12 - op = getSymOp('x,1/2-y,1/2+z') + """check getSymOp()""" + from diffpy.structure.spacegroups import Rot_X_mY_Z, SymOp, Tr_0_12_12 + + op = getSymOp("x,1/2-y,1/2+z") op_std = SymOp(Rot_X_mY_Z, Tr_0_12_12) self.assertEqual(str(op_std), str(op)) from diffpy.structure.spacegroups import Rot_mX_mXY_Z, Tr_0_0_12 - op1 = getSymOp('-x,-x+y,1/2+z') + + op1 = getSymOp("-x,-x+y,1/2+z") op1_std = SymOp(Rot_mX_mXY_Z, Tr_0_0_12) self.assertEqual(str(op1_std), str(op1)) return + # End of class TestRoutines # ---------------------------------------------------------------------------- + class TestP_cif(unittest.TestCase): - pbteciffile = datafile('PbTe.cif') - badciffile = datafile('LiCl-bad.cif') - graphiteciffile = datafile('graphite.cif') - cdsebulkpdffitfile = datafile('CdSe_bulk.stru') - teiciffile = datafile('TeI.cif') - refciffile = datafile('Ni_ref.cif') + pbteciffile = datafile("PbTe.cif") + badciffile = datafile("LiCl-bad.cif") + graphiteciffile = datafile("graphite.cif") + cdsebulkpdffitfile = datafile("CdSe_bulk.stru") + teiciffile = datafile("TeI.cif") + refciffile = datafile("Ni_ref.cif") places = 6 - def setUp(self): self.ptest = P_cif() self.pfile = P_cif() @@ -83,10 +82,8 @@ def setUp(self): def tearDown(self): return - def test_parse(self): - """check P_cif.parse() - """ + """check P_cif.parse()""" with open(self.pbteciffile) as fp1: sgood = fp1.read() with open(self.badciffile) as fp2: @@ -96,17 +93,13 @@ def test_parse(self): stru = ptest.parse(sgood) self.assertEqual(str(stru_check), str(stru)) self.assertEqual(str(stru_check.lattice), str(stru.lattice)) - self.assertEqual(pfile.spacegroup.short_name, - ptest.spacegroup.short_name) + self.assertEqual(pfile.spacegroup.short_name, ptest.spacegroup.short_name) ptestb = P_cif() - self.assertRaises(StructureFormatError, - ptestb.parse, sbad) + self.assertRaises(StructureFormatError, ptestb.parse, sbad) return - def test_parseLines(self): - """check P_cif.parseLines() - """ + """check P_cif.parseLines()""" with open(self.pbteciffile) as fp1: goodlines = fp1.readlines() with open(self.badciffile) as fp2: @@ -116,17 +109,13 @@ def test_parseLines(self): stru = ptest.parseLines(goodlines) self.assertEqual(str(stru_check), str(stru)) self.assertEqual(str(stru_check.lattice), str(stru.lattice)) - self.assertEqual(pfile.spacegroup.short_name, - ptest.spacegroup.short_name) + self.assertEqual(pfile.spacegroup.short_name, ptest.spacegroup.short_name) ptest2 = P_cif() - self.assertRaises(StructureFormatError, - ptest2.parseLines, badlines) + self.assertRaises(StructureFormatError, ptest2.parseLines, badlines) return - def test_parseFile(self): - """check P_cif.parseFile() - """ + """check P_cif.parseFile()""" # pbteciffile stru = self.pfile.parseFile(self.pbteciffile) self.assertEqual(8, len(stru)) @@ -136,7 +125,7 @@ def test_parseFile(self): self.assertEqual(90.0, stru.lattice.alpha) self.assertEqual(90.0, stru.lattice.beta) self.assertEqual(90.0, stru.lattice.gamma) - self.assertEqual('Fm-3m', self.pfile.spacegroup.short_name) + self.assertEqual("Fm-3m", self.pfile.spacegroup.short_name) a0 = stru[0] self.assertEqual(0.5, a0.x) self.assertEqual(0.5, a0.y) @@ -146,134 +135,129 @@ def test_parseFile(self): self.assertEqual(0.0225566, a0.Uisoequiv) # badciffile pfile2 = P_cif() - self.assertRaises(StructureFormatError, - pfile2.parseFile, self.badciffile) + self.assertRaises(StructureFormatError, pfile2.parseFile, self.badciffile) # graphite pgraphite = P_cif() graphite = pgraphite.parseFile(self.graphiteciffile) self.assertEqual(4, len(graphite)) c1 = graphite[0] self.assertEqual(str, type(c1.element)) - self.assertEqual('C', c1.element) + self.assertEqual("C", c1.element) self.assertEqual(str, type(c1.label)) - self.assertEqual('C1', c1.label) + self.assertEqual("C1", c1.label) # filename with unicode encoding - hasbs = '\\' in self.graphiteciffile - uciffile = six.u(self.graphiteciffile.replace('\\', '/')) - if hasbs: # pragma: no cover - uciffile = uciffile.replace(u'/', u'\\') + hasbs = "\\" in self.graphiteciffile + uciffile = six.u(self.graphiteciffile.replace("\\", "/")) + if hasbs: # pragma: no cover + uciffile = uciffile.replace("/", "\\") ugraphite = P_cif().parseFile(uciffile) self.assertEqual(4, len(ugraphite)) # File with full space group name ptei = P_cif().parseFile(self.teiciffile) - self.assertEqual(16 , len(ptei)) + self.assertEqual(16, len(ptei)) return -# def test__parseCifBlock(self): -# """check P_cif._parseCifBlock() -# """ -# return -# -# def test__parse_lattice(self): -# """check P_cif._parse_lattice() -# """ -# return -# -# def test__parse_atom_site_label(self): -# """check P_cif._parse_atom_site_label() -# """ -# return -# -# def test__parse_atom_site_aniso_label(self): -# """check P_cif._parse_atom_site_aniso_label() -# """ -# return -# -# def test__parse_space_group_symop_operation_xyz(self): -# """check P_cif._parse_space_group_symop_operation_xyz() -# """ -# return -# -# def test__expandAsymmetricUnit(self): -# """check P_cif._expandAsymmetricUnit() -# """ -# return -# -# def test_toLines(self): -# """check P_cif.toLines() -# """ -# return -# -# def test_tostring(self): -# """check P_cif.tostring() -# """ -# return + # def test__parseCifBlock(self): + # """check P_cif._parseCifBlock() + # """ + # return + # + # def test__parse_lattice(self): + # """check P_cif._parse_lattice() + # """ + # return + # + # def test__parse_atom_site_label(self): + # """check P_cif._parse_atom_site_label() + # """ + # return + # + # def test__parse_atom_site_aniso_label(self): + # """check P_cif._parse_atom_site_aniso_label() + # """ + # return + # + # def test__parse_space_group_symop_operation_xyz(self): + # """check P_cif._parse_space_group_symop_operation_xyz() + # """ + # return + # + # def test__expandAsymmetricUnit(self): + # """check P_cif._expandAsymmetricUnit() + # """ + # return + # + # def test_toLines(self): + # """check P_cif.toLines() + # """ + # return + # + # def test_tostring(self): + # """check P_cif.tostring() + # """ + # return def test_write_and_read(self): - """high-level check of P_cif.tostring() - """ + """high-level check of P_cif.tostring()""" # high-level check stru_check = Structure() stru_check.read(self.cdsebulkpdffitfile) - s_s = stru_check.writeStr('cif') + s_s = stru_check.writeStr("cif") stru = Structure() - stru.readStr(s_s, 'cif') + stru.readStr(s_s, "cif") self.assertAlmostEqual(4.2352, stru.lattice.a, self.places) self.assertAlmostEqual(4.2352, stru.lattice.b, self.places) self.assertAlmostEqual(6.90603, stru.lattice.c, self.places) self.assertEqual(4, len(stru)) a0 = stru[0] - self.assertEqual('Cd', a0.element) + self.assertEqual("Cd", a0.element) self.assertTrue(numpy.allclose([0.3334, 0.6667, 0.0], a0.xyz)) self.assertTrue(a0.anisotropy) - self.assertAlmostEqual(0.01303, a0.U[0,0]) - self.assertAlmostEqual(0.01303, a0.U[1,1]) - self.assertAlmostEqual(0.01402, a0.U[2,2]) + self.assertAlmostEqual(0.01303, a0.U[0, 0]) + self.assertAlmostEqual(0.01303, a0.U[1, 1]) + self.assertAlmostEqual(0.01402, a0.U[2, 2]) a3 = stru[3] - self.assertEqual('Se', a3.element) + self.assertEqual("Se", a3.element) self.assertTrue(numpy.allclose([0.6666, 0.333300, 0.87667], a3.xyz)) - self.assertAlmostEqual(0.015673, a3.U[0,0]) - self.assertAlmostEqual(0.015673, a3.U[1,1]) - self.assertAlmostEqual(0.046164, a3.U[2,2]) + self.assertAlmostEqual(0.015673, a3.U[0, 0]) + self.assertAlmostEqual(0.015673, a3.U[1, 1]) + self.assertAlmostEqual(0.046164, a3.U[2, 2]) return - def test_eps(self): - """Test the P_cif.eps coordinates resolution. - """ + """Test the P_cif.eps coordinates resolution.""" pcif = P_cif() pcif.eps = 1e-8 grph = pcif.parseFile(self.graphiteciffile) self.assertEqual(8, len(grph)) - self.assertTrue(all(a.label.startswith('C1') for a in grph[:2])) - self.assertTrue(all(a.label.startswith('C2') for a in grph[2:])) + self.assertTrue(all(a.label.startswith("C1") for a in grph[:2])) + self.assertTrue(all(a.label.startswith("C2") for a in grph[2:])) pcif2 = P_cif() pcif2.eps = 1e-3 grph2 = pcif2.parseFile(self.graphiteciffile) self.assertEqual(4, len(grph2)) return - def test_unknown_occupancy(self): "test CIF file with unknown occupancy data" - stru = self.ptest.parseFile(datafile('TeI-unkocc.cif')) + stru = self.ptest.parseFile(datafile("TeI-unkocc.cif")) self.assertTrue(numpy.array_equal(16 * [1], stru.occupancy)) return - def test_unknown_spacegroup_number(self): "test CIF file with unknown space group symbol" from diffpy.structure.spacegroups import GetSpaceGroup, _hashSymOpList + with open(self.pbteciffile) as fp: lines = fp.readlines() - self.assertTrue(lines[16].startswith('_symmetry_space_group')) - self.assertTrue(lines[17].startswith('_symmetry_space_group')) + self.assertTrue(lines[16].startswith("_symmetry_space_group")) + self.assertTrue(lines[17].startswith("_symmetry_space_group")) lines[16:18] = [ - '_space_group_IT_number ?\n', - '_symmetry_space_group_name_H-M ?\n', - '_symmetry_space_group_name_Hall ?\n', + "_space_group_IT_number ?\n", + "_symmetry_space_group_name_H-M ?\n", + "_symmetry_space_group_name_Hall ?\n", ] - ciftxt = ''.join(lines) + ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertEqual(8, len(stru)) h225 = _hashSymOpList(GetSpaceGroup(225).iter_symops()) @@ -281,54 +265,45 @@ def test_unknown_spacegroup_number(self): self.assertEqual(h225, _hashSymOpList(sgcif.iter_symops())) return - def test_nosites_cif(self): - """Test reading of CIF file with no valid sites. - """ + """Test reading of CIF file with no valid sites.""" ptest = self.ptest - stru = ptest.parseFile(datafile('nosites.cif')) + stru = ptest.parseFile(datafile("nosites.cif")) self.assertEqual(0, len(stru)) self.assertEqual(10.413, stru.lattice.a) self.assertEqual(10.413, stru.lattice.b) self.assertEqual(10.413, stru.lattice.c) return - def test_badspacegroup_cif(self): - """Test reading of CIF file with unrecognized space group. - """ + """Test reading of CIF file with unrecognized space group.""" ptest = self.ptest - filename = datafile('badspacegroup.cif') + filename = datafile("badspacegroup.cif") self.assertRaises(StructureFormatError, ptest.parseFile, filename) return - def test_custom_spacegroup_cif(self): - """Test parsing of nonstandard symops-defined space group. - """ + """Test parsing of nonstandard symops-defined space group.""" pfile = self.pfile - filename = datafile('customsg.cif') + filename = datafile("customsg.cif") pfile.parseFile(filename) sg = pfile.spacegroup - self.assertEqual('CIF data', sg.short_name) + self.assertEqual("CIF data", sg.short_name) self.assertEqual(6, len(sg.symop_list)) return - def test_spacegroup_isotropy(self): "verify site isotropy due to site symmetry." # remove the _atom_site_thermal_displace_type field with open(self.pbteciffile) as fp: - lines = [line.replace(' Uiso ', ' ') for line in fp - if '_atom_site_thermal_displace_type' not in line] - ciftxt = ''.join(lines) + lines = [line.replace(" Uiso ", " ") for line in fp if "_atom_site_thermal_displace_type" not in line] + ciftxt = "".join(lines) ptest = self.ptest stru = ptest.parse(ciftxt) self.assertFalse(any(stru.anisotropy)) self.assertTrue(all(not a.anisotropy for a in ptest.asymmetric_unit)) return - def test_spacegroup_anisotropy(self): "verify site anisotropy due to site symmetry." stru = self.ptest.parseFile(self.graphiteciffile) @@ -340,7 +315,7 @@ def test_spacegroup_ref(self): pfile = self.pfile pfile.parseFile(self.refciffile) sg = pfile.spacegroup - self.assertEqual('Fm-3m', sg.short_name) + self.assertEqual("Fm-3m", sg.short_name) return @@ -348,72 +323,66 @@ def test_adp_type_ani(self): "verify adp type override to anisotropic" with open(self.pbteciffile) as fp: ciftxt = fp.read() - ciftxt = ciftxt.replace(' Uiso ', ' Uani ') + ciftxt = ciftxt.replace(" Uiso ", " Uani ") stru = self.ptest.parse(ciftxt) self.assertTrue(all(stru.anisotropy)) return - def test_adp_type_iso(self): "verify adp type override to isotropic" with open(self.graphiteciffile) as fp: lines = fp.readlines() - lines.insert(-2, '_atom_site_adp_type\n') - lines[-2] = lines[-2].rstrip() + ' Uiso\n' - lines[-1] = lines[-1].rstrip() + ' Uiso\n' - ciftxt = ''.join(lines) + lines.insert(-2, "_atom_site_adp_type\n") + lines[-2] = lines[-2].rstrip() + " Uiso\n" + lines[-1] = lines[-1].rstrip() + " Uiso\n" + ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertFalse(any(a.anisotropy for a in stru)) return - def test_adp_aniso_label(self): "verify ADP type setting from _atom_site_aniso_label loop" with open(self.teiciffile) as fp: - lines = [line.replace(' Uani ', ' ') for line in fp - if not '_atom_site_adp_type' in line] - ciftxt = ''.join(lines) + lines = [line.replace(" Uani ", " ") for line in fp if not "_atom_site_adp_type" in line] + ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertTrue(all(stru.anisotropy)) return - def test_unknown_aniso(self): "test CIF file with unknown values in the aniso block." with open(self.teiciffile) as fp: lines = fp.readlines() - lines[-4:] = [' ? ? ? ? ? ? ?\n'] - ciftxt = ''.join(lines) + lines[-4:] = [" ? ? ? ? ? ? ?\n"] + ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertEqual(16, len(stru)) self.assertTrue(all(stru.anisotropy)) return - def test_curly_brace(self): "verify loading of a CIF file with unquoted curly brace" ptest = self.ptest - stru = ptest.parseFile(datafile('curlybrackets.cif')) + stru = ptest.parseFile(datafile("curlybrackets.cif")) self.assertEqual(20, len(stru)) return - def test_getParser(self): - """Test passing of eps keyword argument by getParser function. - """ - pcif = getParser('cif', eps=1e-6) + """Test passing of eps keyword argument by getParser function.""" + pcif = getParser("cif", eps=1e-6) grph = pcif.parseFile(self.graphiteciffile) self.assertEqual(8, len(grph)) - self.assertTrue(all(a.label.startswith('C1') for a in grph[:2])) - self.assertTrue(all(a.label.startswith('C2') for a in grph[2:])) - pcif2 = getParser('cif') + self.assertTrue(all(a.label.startswith("C1") for a in grph[:2])) + self.assertTrue(all(a.label.startswith("C2") for a in grph[2:])) + pcif2 = getParser("cif") grph2 = pcif2.parseFile(self.graphiteciffile) self.assertEqual(4, len(grph2)) return + # End of class TestP_cif # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testp_discus.py b/src/diffpy/structure/tests/testp_discus.py index a748f452..5f30a42f 100644 --- a/src/diffpy/structure/tests/testp_discus.py +++ b/src/diffpy/structure/tests/testp_discus.py @@ -16,36 +16,35 @@ """Unit tests for diffpy.structure.parsers.p_discus module """ -import unittest import re +import unittest -from diffpy.structure.tests.testutils import datafile from diffpy.structure import Structure, StructureFormatError +from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- + class TestP_discus(unittest.TestCase): """test Parser for PDFFit file format""" - def setUp(self): self.stru = Structure() self.format = "discus" self.places = 8 - def test_read_discus_Ni(self): """check reading of Ni structure in discus format""" stru = self.stru - stru.read(datafile('Ni-discus.stru'), self.format) - f_title = 'structure Ni FCC' + stru.read(datafile("Ni-discus.stru"), self.format) + f_title = "structure Ni FCC" self.assertEqual(f_title, stru.title) - self.assertEqual('Fm-3m', stru.pdffit['spcgr']) + self.assertEqual("Fm-3m", stru.pdffit["spcgr"]) # cell record abcABG = (3.52, 3.52, 3.52, 90.0, 90.0, 90.0) self.assertEqual(abcABG, stru.lattice.abcABG()) # ncell - self.assertEqual([1, 1, 1, 4], stru.pdffit['ncell']) + self.assertEqual([1, 1, 1, 4], stru.pdffit["ncell"]) self.assertEqual(4, len(stru)) # first atom a0 = stru[0] @@ -55,39 +54,35 @@ def test_read_discus_Ni(self): self.assertAlmostEqual(Biso0, a0.Bisoequiv, self.places) return - def test_except_other_formats(self): """check exceptions when reading files in other formats""" badfiles = [ - 'LiCl-bad.cif', - 'PbTe.cif', - 'arginine.pdb', - 'ZnSb_RT_Q28X_VM_20_fxiso.rstr', - 'Ni-bad.stru', - 'Ni.stru', - 'BubbleRaftShort.xcfg', - 'bucky-bad1.xyz', - 'bucky-bad2.xyz', - 'bucky-plain-bad.xyz', - 'bucky-plain.xyz', - 'bucky-raw.xyz', - 'bucky.xyz', - 'hexagon-raw-bad.xyz', - 'hexagon-raw.xyz', + "LiCl-bad.cif", + "PbTe.cif", + "arginine.pdb", + "ZnSb_RT_Q28X_VM_20_fxiso.rstr", + "Ni-bad.stru", + "Ni.stru", + "BubbleRaftShort.xcfg", + "bucky-bad1.xyz", + "bucky-bad2.xyz", + "bucky-plain-bad.xyz", + "bucky-plain.xyz", + "bucky-raw.xyz", + "bucky.xyz", + "hexagon-raw-bad.xyz", + "hexagon-raw.xyz", ] for ft in badfiles: ff = datafile(ft) - self.assertRaises(StructureFormatError, - self.stru.read, ff, format=self.format) + self.assertRaises(StructureFormatError, self.stru.read, ff, format=self.format) return - def test_ignored_lines(self): - """check skipping of ignored lines in the header - """ - r1 = 'ignored record 1\n' - r2 = 'ignored record 2\n' - with open(datafile('Ni-discus.stru')) as fp: + """check skipping of ignored lines in the header""" + r1 = "ignored record 1\n" + r2 = "ignored record 2\n" + with open(datafile("Ni-discus.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(2, r1) ni_lines.insert(4, r2) @@ -96,56 +91,49 @@ def test_ignored_lines(self): self.assertEqual([r1.rstrip(), r2.rstrip()], p.ignored_lines) ni_lines.append(r1) s_s2 = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - s_s2, self.format) + self.assertRaises(StructureFormatError, self.stru.readStr, s_s2, self.format) return - def test_spdiameter_parsing(self): - """check parsing of spdiameter record from a file. - """ + """check parsing of spdiameter record from a file.""" stru = self.stru - stru.read(datafile('Ni-discus.stru'), self.format) - self.assertEqual(0, stru.pdffit['spdiameter']) + stru.read(datafile("Ni-discus.stru"), self.format) + self.assertEqual(0, stru.pdffit["spdiameter"]) snoshape = stru.writeStr(format=self.format) - self.assertTrue(not re.search('(?m)^shape', snoshape)) + self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero spdiameter - stru.pdffit['spdiameter'] = 13 + stru.pdffit["spdiameter"] = 13 s13 = stru.writeStr(format=self.format) - self.assertTrue(re.search('(?m)^shape +sphere, ', s13)) + self.assertTrue(re.search("(?m)^shape +sphere, ", s13)) stru13 = Structure() stru13.readStr(s13) - self.assertEqual(13, stru13.pdffit['spdiameter']) - with open(datafile('Ni.stru')) as fp: + self.assertEqual(13, stru13.pdffit["spdiameter"]) + with open(datafile("Ni.stru")) as fp: ni_lines = fp.readlines() - ni_lines.insert(3, 'shape invalid, 7\n') - sbad = ''.join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - sbad, format=self.format) + ni_lines.insert(3, "shape invalid, 7\n") + sbad = "".join(ni_lines) + self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) return - def test_stepcut_parsing(self): - """check parsing of stepcut record from a file. - """ + """check parsing of stepcut record from a file.""" stru = self.stru - stru.read(datafile('Ni-discus.stru'), self.format) - self.assertEqual(0, stru.pdffit['stepcut']) + stru.read(datafile("Ni-discus.stru"), self.format) + self.assertEqual(0, stru.pdffit["stepcut"]) snoshape = stru.writeStr(format=self.format) - self.assertTrue(not re.search('(?m)^shape', snoshape)) + self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero stepcut - stru.pdffit['stepcut'] = 13 + stru.pdffit["stepcut"] = 13 s13 = stru.writeStr(format=self.format) - self.assertTrue(re.search('(?m)^shape +stepcut, ', s13)) + self.assertTrue(re.search("(?m)^shape +stepcut, ", s13)) stru13 = Structure() stru13.readStr(s13) - self.assertEqual(13, stru13.pdffit['stepcut']) - with open(datafile('Ni.stru')) as fp: + self.assertEqual(13, stru13.pdffit["stepcut"]) + with open(datafile("Ni.stru")) as fp: ni_lines = fp.readlines() - ni_lines.insert(3, 'shape invalid, 7\n') - sbad = ''.join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - sbad, format=self.format) + ni_lines.insert(3, "shape invalid, 7\n") + sbad = "".join(ni_lines) + self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) return @@ -153,5 +141,5 @@ def test_stepcut_parsing(self): # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testp_pdffit.py b/src/diffpy/structure/tests/testp_pdffit.py index 56b9f0f7..cd9b21de 100644 --- a/src/diffpy/structure/tests/testp_pdffit.py +++ b/src/diffpy/structure/tests/testp_pdffit.py @@ -16,15 +16,17 @@ """Unit tests for diffpy.structure.parsers.p_pdffit module """ -import unittest import re +import unittest + import numpy -from diffpy.structure.tests.testutils import datafile from diffpy.structure import Structure, StructureFormatError +from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- + class TestP_pdffit(unittest.TestCase): """test Parser for PDFFit file format""" @@ -33,130 +35,138 @@ def setUp(self): self.format = "pdffit" self.places = 8 - def test_read_pdffit_ZnSb(self): """check reading of ZnSb pdffit structure file""" stru = self.stru - stru.read(datafile('ZnSb_RT_Q28X_VM_20_fxiso.rstr'), self.format) + stru.read(datafile("ZnSb_RT_Q28X_VM_20_fxiso.rstr"), self.format) f_title = "Cell structure file of Zn4Sb3 #167 interstitial" self.assertEqual(stru.title, f_title) - self.assertAlmostEqual(stru.pdffit['scale'], 0.826145) - self.assertAlmostEqual(stru.pdffit['delta2'], 4.687951) - self.assertAlmostEqual(stru.pdffit['delta1'], 0.01) - self.assertAlmostEqual(stru.pdffit['sratio'], 1.02) - self.assertAlmostEqual(stru.pdffit['rcut'], 0.03) - self.assertEqual(stru.pdffit['spcgr'], 'R-3c') - s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ] + self.assertAlmostEqual(stru.pdffit["scale"], 0.826145) + self.assertAlmostEqual(stru.pdffit["delta2"], 4.687951) + self.assertAlmostEqual(stru.pdffit["delta1"], 0.01) + self.assertAlmostEqual(stru.pdffit["sratio"], 1.02) + self.assertAlmostEqual(stru.pdffit["rcut"], 0.03) + self.assertEqual(stru.pdffit["spcgr"], "R-3c") + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [12.309436, 12.309436, 12.392839, 90.0, 90.0, 120.0] self.assertTrue(numpy.allclose(s_lat, f_lat)) - s_dcell = stru.pdffit['dcell'] + s_dcell = stru.pdffit["dcell"] f_dcell = [0.000008, 0.000008, 0.000013, 0.0, 0.0, 0.0] self.assertTrue(numpy.allclose(s_dcell, f_dcell)) - self.assertEqual(stru.pdffit['ncell'], [1,1,1,66]) + self.assertEqual(stru.pdffit["ncell"], [1, 1, 1, 66]) s_els = [a.element for a in stru] - self.assertEqual(s_els, 36*['Zn']+30*['Sb']) + self.assertEqual(s_els, 36 * ["Zn"] + 30 * ["Sb"]) a0 = stru[0] s_xyz = a0.xyz - f_xyz = [0.09094387, 0.24639539, 0.40080261]; + f_xyz = [0.09094387, 0.24639539, 0.40080261] s_o = a0.occupancy f_o = 0.9 s_sigxyz = a0.sigxyz - f_sigxyz = [ 0.00000079, 0.00000076, 0.00000064]; + f_sigxyz = [0.00000079, 0.00000076, 0.00000064] s_sigo = a0.sigo f_sigo = 0.0 - s_U = [ a0.U[i][i] for i in range(3) ] - f_U = 3*[0.01] + s_U = [a0.U[i][i] for i in range(3)] + f_U = 3 * [0.01] self.assertTrue(numpy.allclose(s_xyz, f_xyz)) self.assertTrue(numpy.allclose(s_sigxyz, f_sigxyz)) self.assertTrue(numpy.allclose(s_U, f_U)) self.assertAlmostEqual(s_o, f_o) self.assertAlmostEqual(s_sigo, f_sigo) - def test_read_pdffit_Ni(self): """check reading of Ni pdffit structure file""" stru = self.stru - stru.read(datafile('Ni.stru'), self.format) + stru.read(datafile("Ni.stru"), self.format) f_title = "structure Ni FCC" self.assertEqual(stru.title, f_title) - self.assertEqual(stru.pdffit['spcgr'], 'Fm-3m') - s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ] + self.assertEqual(stru.pdffit["spcgr"], "Fm-3m") + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [3.52, 3.52, 3.52, 90.0, 90.0, 90.0] for i in range(len(s_lat)): self.assertAlmostEqual(s_lat[i], f_lat[i]) - self.assertEqual(stru.pdffit['ncell'], [1,1,1,4]) + self.assertEqual(stru.pdffit["ncell"], [1, 1, 1, 4]) s_els = [a.element for a in stru] - self.assertEqual(s_els, 4*['Ni']) + self.assertEqual(s_els, 4 * ["Ni"]) a0 = stru[0] s_xyz = a0.xyz - f_xyz = [0.0, 0.0, 0.0]; + f_xyz = [0.0, 0.0, 0.0] s_o = a0.occupancy f_o = 1.0 - s_U = [ a0.U[i][i] for i in range(3) ] - f_U = 3*[0.00126651] + s_U = [a0.U[i][i] for i in range(3)] + f_U = 3 * [0.00126651] for i in range(3): self.assertAlmostEqual(s_xyz[i], f_xyz[i]) self.assertAlmostEqual(s_U[i], f_U[i]) self.assertAlmostEqual(s_o, f_o) - def test_read_pdffit_Ni_prim123(self): """check reading of Ni_prim supercell 1x2x3""" stru = self.stru - stru.read(datafile('Ni_prim123.stru'), self.format) - s_lat = [ stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma ] - f_lat = [2.489016, 2*2.489016, 3*2.489016, 60.0, 60.0, 60.0] + stru.read(datafile("Ni_prim123.stru"), self.format) + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] + f_lat = [2.489016, 2 * 2.489016, 3 * 2.489016, 60.0, 60.0, 60.0] for i in range(len(s_lat)): self.assertAlmostEqual(s_lat[i], f_lat[i]) s_els = [a.element for a in stru] - self.assertEqual(s_els, 6*['Ni']) + self.assertEqual(s_els, 6 * ["Ni"]) a5 = stru[5] s_xyz = a5.xyz - f_xyz = [0.0, 1.0/2.0, 2.0/3.0]; + f_xyz = [0.0, 1.0 / 2.0, 2.0 / 3.0] for i in range(3): self.assertAlmostEqual(s_xyz[i], f_xyz[i]) s_o = a5.occupancy f_o = 1.0 self.assertAlmostEqual(s_o, f_o) - s_U = [ a5.U[ij[0],ij[1]] - for ij in [(0,0), (1,1), (2,2), (0,1), (0,2), (1,2)] ] - f_U = 3*[0.00126651] + 3*[-0.00042217] + s_U = [a5.U[ij[0], ij[1]] for ij in [(0, 0), (1, 1), (2, 2), (0, 1), (0, 2), (1, 2)]] + f_U = 3 * [0.00126651] + 3 * [-0.00042217] for i in range(len(s_U)): self.assertAlmostEqual(s_U[i], f_U[i]) return - def test_read_pdffit_bad(self): """check exceptions when reading invalid pdffit file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, - datafile('Ni-bad.stru'), self.format) - self.assertRaises(StructureFormatError, stru.read, - datafile('bucky.xyz'), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("Ni-bad.stru"), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("bucky.xyz"), self.format) return - def test_writeStr_pdffit(self): """check writing of normal xyz file""" stru = self.stru - stru.read(datafile('Ni.stru'), self.format) - with open(datafile('Ni.stru')) as fp: + stru.read(datafile("Ni.stru"), self.format) + with open(datafile("Ni.stru")) as fp: f_s = fp.read() - f_s = re.sub('[ \t]+', ' ', f_s) - f_s = re.sub('[ \t]+\n', '\n', f_s) + f_s = re.sub("[ \t]+", " ", f_s) + f_s = re.sub("[ \t]+\n", "\n", f_s) s_s = stru.writeStr(self.format) - s_s = re.sub('[ \t]+', ' ', s_s) + s_s = re.sub("[ \t]+", " ", s_s) self.assertEqual(f_s, s_s) return - def test_huge_occupancy(self): - """check structure with huge occupancy can be read. - """ - self.stru.read(datafile('Ni.stru'), self.format) + """check structure with huge occupancy can be read.""" + self.stru.read(datafile("Ni.stru"), self.format) self.stru[0].occupancy = 16e16 s_s = self.stru.writeStr(self.format) stru1 = Structure() @@ -164,71 +174,62 @@ def test_huge_occupancy(self): self.assertEqual(16e16, stru1[0].occupancy) return - def test_ignored_lines(self): - """check skipping of ignored lines in the header - """ - r1 = 'ignored record 1' - r2 = 'ignored record 2' - with open(datafile('Ni.stru')) as fp: + """check skipping of ignored lines in the header""" + r1 = "ignored record 1" + r2 = "ignored record 2" + with open(datafile("Ni.stru")) as fp: ni_lines = fp.readlines() - ni_lines.insert(2, r1 + '\n') - ni_lines.insert(4, r2 + '\n') + ni_lines.insert(2, r1 + "\n") + ni_lines.insert(4, r2 + "\n") s_s1 = "".join(ni_lines) p = self.stru.readStr(s_s1, self.format) self.assertEqual([r1, r2], p.ignored_lines) - ni_lines.insert(-3, r1 + '\n') + ni_lines.insert(-3, r1 + "\n") s_s2 = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - s_s2, self.format) + self.assertRaises(StructureFormatError, self.stru.readStr, s_s2, self.format) return - def test_spdiameter_parsing(self): - """check parsing of spdiameter record from a file. - """ + """check parsing of spdiameter record from a file.""" stru = self.stru - stru.read(datafile('Ni.stru'), self.format) - self.assertEqual(0, stru.pdffit['spdiameter']) + stru.read(datafile("Ni.stru"), self.format) + self.assertEqual(0, stru.pdffit["spdiameter"]) snoshape = stru.writeStr(format=self.format) - self.assertTrue(not re.search('(?m)^shape', snoshape)) + self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero spdiameter - stru.pdffit['spdiameter'] = 13 + stru.pdffit["spdiameter"] = 13 s13 = stru.writeStr(format=self.format) - self.assertTrue(re.search('(?m)^shape +sphere, ', s13)) + self.assertTrue(re.search("(?m)^shape +sphere, ", s13)) stru13 = Structure() stru13.readStr(s13) - self.assertEqual(13, stru13.pdffit['spdiameter']) - with open(datafile('Ni.stru')) as fp: + self.assertEqual(13, stru13.pdffit["spdiameter"]) + with open(datafile("Ni.stru")) as fp: ni_lines = fp.readlines() - ni_lines.insert(3, 'shape invalid, 7\n') - sbad = ''.join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - sbad, format=self.format) + ni_lines.insert(3, "shape invalid, 7\n") + sbad = "".join(ni_lines) + self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) return - def test_stepcut_parsing(self): - """check parsing of stepcut record from a file. - """ + """check parsing of stepcut record from a file.""" stru = self.stru - stru.read(datafile('Ni.stru'), self.format) - self.assertEqual(0, stru.pdffit['stepcut']) + stru.read(datafile("Ni.stru"), self.format) + self.assertEqual(0, stru.pdffit["stepcut"]) snoshape = stru.writeStr(format=self.format) - self.assertTrue(not re.search('(?m)^shape', snoshape)) + self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero stepcut - stru.pdffit['stepcut'] = 13 + stru.pdffit["stepcut"] = 13 s13 = stru.writeStr(format=self.format) - self.assertTrue(re.search('(?m)^shape +stepcut, ', s13)) + self.assertTrue(re.search("(?m)^shape +stepcut, ", s13)) stru13 = Structure() stru13.readStr(s13) - self.assertEqual(13, stru13.pdffit['stepcut']) - with open(datafile('Ni.stru')) as fp: + self.assertEqual(13, stru13.pdffit["stepcut"]) + with open(datafile("Ni.stru")) as fp: ni_lines = fp.readlines() - ni_lines.insert(3, 'shape invalid, 7\n') - sbad = ''.join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, - sbad, format=self.format) + ni_lines.insert(3, "shape invalid, 7\n") + sbad = "".join(ni_lines) + self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) return @@ -236,5 +237,5 @@ def test_stepcut_parsing(self): # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testparsers.py b/src/diffpy/structure/tests/testparsers.py index 34cd038f..7ebe7d8a 100644 --- a/src/diffpy/structure/tests/testparsers.py +++ b/src/diffpy/structure/tests/testparsers.py @@ -16,103 +16,89 @@ """Unit tests for structure.parsers module. """ -import unittest import os import re import tempfile +import unittest + import numpy +from diffpy.structure import Atom, Lattice, Structure, StructureFormatError from diffpy.structure.tests.testutils import datafile -from diffpy.structure import Structure, StructureFormatError -from diffpy.structure import Lattice -from diffpy.structure import Atom # ---------------------------------------------------------------------------- + class TestP_xyz(unittest.TestCase): """test Parser for xyz file format""" def setUp(self): self.stru = Structure() - self.format = 'xyz' + self.format = "xyz" self.tmpnames = [] return - def tearDown(self): for f in self.tmpnames: os.remove(f) return - def mktmpfile(self): with tempfile.NamedTemporaryFile(delete=False) as ftmp: self.tmpnames.append(ftmp.name) return self.tmpnames[-1] - def test_read_xyz(self): """check reading of normal xyz file""" stru = self.stru - stru.read(datafile('bucky.xyz'), self.format) + stru.read(datafile("bucky.xyz"), self.format) s_els = [a.element for a in stru] - self.assertEqual(stru.title, 'bucky-ball') - self.assertEqual(s_els, 60*['C']) + self.assertEqual(stru.title, "bucky-ball") + self.assertEqual(s_els, 60 * ["C"]) return - def test_read_xyz_bad(self): """check exceptions when reading invalid xyz file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, - datafile('bucky-bad1.xyz'), self.format) - self.assertRaises(StructureFormatError, stru.read, - datafile('bucky-bad2.xyz'), self.format) - self.assertRaises(StructureFormatError, stru.read, - datafile('bucky-plain.xyz'), self.format) - self.assertRaises(StructureFormatError, stru.read, - datafile('hexagon-raw.xy'), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("bucky-bad1.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("bucky-bad2.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("bucky-plain.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw.xy"), self.format) return - def test_writeStr_xyz(self): """check string representation of normal xyz file""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) - stru[:] = [ - Atom('H', [1., 1., 1.]), - Atom('Cl', [3., 2., 1.]) - ] + stru[:] = [Atom("H", [1.0, 1.0, 1.0]), Atom("Cl", [3.0, 2.0, 1.0])] s1 = stru.writeStr(self.format) - s1 = re.sub('[ \t]+', ' ', s1) + s1 = re.sub("[ \t]+", " ", s1) s0 = "2\n%s\nH 1 2 3\nCl 3 4 3\n" % stru.title self.assertEqual(s1, s0) return - def test_write_xyz(self): """check writing of normal xyz file""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) - stru[:] = [ - Atom('H', [1., 1., 1.]), - Atom('Cl', [3., 2., 1.]) - ] + stru[:] = [Atom("H", [1.0, 1.0, 1.0]), Atom("Cl", [3.0, 2.0, 1.0])] filename = self.mktmpfile() stru.write(filename, self.format) with open(filename) as fp: f_s = fp.read() - f_s = re.sub('[ \t]+', ' ', f_s) + f_s = re.sub("[ \t]+", " ", f_s) s_s = "2\n%s\nH 1 2 3\nCl 3 4 3\n" % stru.title self.assertEqual(f_s, s_s) return + # End of class TestP_xyz # ---------------------------------------------------------------------------- + class TestP_rawxyz(unittest.TestCase): """test Parser for rawxyz file format""" @@ -121,57 +107,49 @@ def setUp(self): self.format = "rawxyz" return - def test_read_plainxyz(self): """check reading of a plain xyz file""" stru = self.stru - stru.read(datafile('bucky-plain.xyz'), self.format) + stru.read(datafile("bucky-plain.xyz"), self.format) s_els = [a.element for a in stru] - self.assertEqual(stru.title, 'bucky-plain') - self.assertEqual(s_els, 60*['C']) + self.assertEqual(stru.title, "bucky-plain") + self.assertEqual(s_els, 60 * ["C"]) return - def test_read_plainxyz_bad(self): """check exceptions when reading invalid plain xyz file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, - datafile('bucky-plain-bad.xyz'), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("bucky-plain-bad.xyz"), self.format) return - def test_read_rawxyz(self): """check reading of raw xyz file""" stru = self.stru - stru.read(datafile('bucky-raw.xyz'), self.format) + stru.read(datafile("bucky-raw.xyz"), self.format) s_els = [a.element for a in stru] - self.assertEqual(stru.title, 'bucky-raw') - self.assertEqual(s_els, 60*['']) - stru.read(datafile('hexagon-raw.xyz'), self.format) + self.assertEqual(stru.title, "bucky-raw") + self.assertEqual(s_els, 60 * [""]) + stru.read(datafile("hexagon-raw.xyz"), self.format) zs = [a.xyz[-1] for a in stru] - self.assertEqual(zs, 6*[0.0]) + self.assertEqual(zs, 6 * [0.0]) return - def test_read_rawxyz_bad(self): """check exceptions when reading unsupported xy file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, - datafile('hexagon-raw-bad.xyz'), self.format) - self.assertRaises(StructureFormatError, stru.read, - datafile('hexagon-raw.xy'), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw-bad.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw.xy"), self.format) return - def test_writeStr_rawxyz(self): """check writing of normal xyz file""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) # plain version - stru[:] = [Atom('H', [1., 1., 1.])] + stru[:] = [Atom("H", [1.0, 1.0, 1.0])] s1 = stru.writeStr(self.format) - s1 = re.sub('[ \t]+', ' ', s1) + s1 = re.sub("[ \t]+", " ", s1) s0 = "H 1 2 3\n" # brutal raw version stru[0].element = "" @@ -180,10 +158,12 @@ def test_writeStr_rawxyz(self): self.assertEqual(s1, s0) return + # End of class TestP_rawxyz # ---------------------------------------------------------------------------- + class TestP_pdb(unittest.TestCase): """test Parser for PDB file format""" @@ -192,57 +172,95 @@ def setUp(self): self.format = "pdb" self.places = 3 - def test_read_pdb_arginine(self): """check reading of arginine PDB file""" stru = self.stru - stru.read(datafile('arginine.pdb'), self.format) - f_els = ["N", "C", "C", "O", "C", "C", "C", "N", "C", "N", "N", "H", - "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", - "H", "O", "H"] + stru.read(datafile("arginine.pdb"), self.format) + f_els = [ + "N", + "C", + "C", + "O", + "C", + "C", + "C", + "N", + "C", + "N", + "N", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "H", + "O", + "H", + ] s_els = [a.element for a in stru] self.assertEqual(s_els, f_els) - s_lat = [stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma] + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [1.0, 1.0, 1.0, 90.0, 90.0, 90.0] self.assertEqual(s_lat, f_lat) a0 = stru[0] self.assertTrue(numpy.allclose(a0.xyz, [0.735, 2.219, 1.389])) - def test_rwStr_pdb_CdSe(self): """check conversion to PDB file format""" stru = self.stru - stru.read(datafile('CdSe_bulk.stru'), 'pdffit') + stru.read(datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) # all lines should be 80 characters long - linelens = [len(l) for l in s.split('\n') if l != ""] - self.assertEqual(linelens, len(linelens)*[80]) + linelens = [len(l) for l in s.split("\n") if l != ""] + self.assertEqual(linelens, len(linelens) * [80]) # now clean and re-read structure stru = Structure() stru.readStr(s, self.format) s_els = [a.element for a in stru] - f_els = ['Cd', 'Cd', 'Se', 'Se'] + f_els = ["Cd", "Cd", "Se", "Se"] self.assertEqual(s_els, f_els) - s_lat = [stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma] + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [4.235204, 4.235204, 6.906027, 90.0, 90.0, 120.0] self.assertTrue(numpy.allclose(s_lat, f_lat, atol=5e-4)) a0 = stru[0] - s_Uii = [a0.U[i,i] for i in range(3)] + s_Uii = [a0.U[i, i] for i in range(3)] f_Uii = [0.01303035, 0.01303035, 0.01401959] self.assertTrue(numpy.allclose(s_Uii, f_Uii, atol=5e-4)) - s_sigUii = [a0.sigU[i,i] for i in range(3)] + s_sigUii = [a0.sigU[i, i] for i in range(3)] f_sigUii = [0.00011127, 0.00011127, 0.00019575] self.assertTrue(numpy.allclose(s_sigUii, f_sigUii, atol=5e-4)) s_title = stru.title f_title = "Cell structure file of CdSe #186" self.assertEqual(s_title, f_title) + # End of class TestP_pdb # ---------------------------------------------------------------------------- + class TestP_xcfg(unittest.TestCase): """test Parser for XCFG file format""" @@ -251,44 +269,55 @@ def setUp(self): self.format = "xcfg" self.places = 6 - def test_read_xcfg(self): """check reading of BubbleRaft XCFG file""" stru = self.stru - stru.read(datafile('BubbleRaftShort.xcfg'), self.format) + stru.read(datafile("BubbleRaftShort.xcfg"), self.format) f_els = 500 * ["Ar"] s_els = [a.element for a in stru] self.assertEqual(s_els, f_els) self.assertAlmostEqual(stru.distance(82, 357), 47.5627, 3) - s_lat = [stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma] + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [127.5, 119.5, 3.0, 90.0, 90.0, 90.0] self.assertTrue(numpy.allclose(s_lat, f_lat)) return - def test_rwStr_xcfg_CdSe(self): """check conversion to XCFG file format""" stru = self.stru - stru.read(datafile('CdSe_bulk.stru'), 'pdffit') + stru.read(datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) stru = Structure() stru.readStr(s, self.format) s_els = [a.element for a in stru] - f_els = ['Cd', 'Cd', 'Se', 'Se'] + f_els = ["Cd", "Cd", "Se", "Se"] self.assertEqual(s_els, f_els) - s_lat = [stru.lattice.a, stru.lattice.b, stru.lattice.c, - stru.lattice.alpha, stru.lattice.beta, stru.lattice.gamma] + s_lat = [ + stru.lattice.a, + stru.lattice.b, + stru.lattice.c, + stru.lattice.alpha, + stru.lattice.beta, + stru.lattice.gamma, + ] f_lat = [4.235204, 4.235204, 6.906027, 90.0, 90.0, 120.0] self.assertTrue(numpy.allclose(s_lat, f_lat)) a0 = stru[0] - s_Uii = [a0.U[i,i] for i in range(3)] + s_Uii = [a0.U[i, i] for i in range(3)] f_Uii = [0.01303035, 0.01303035, 0.01401959] self.assertTrue(numpy.allclose(s_Uii, f_Uii)) + # End of class TestP_xcfg # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testspacegroups.py b/src/diffpy/structure/tests/testspacegroups.py index 40c87927..c9980e17 100644 --- a/src/diffpy/structure/tests/testspacegroups.py +++ b/src/diffpy/structure/tests/testspacegroups.py @@ -19,36 +19,46 @@ import unittest -from diffpy.structure.spacegroups import SpaceGroupList, _hashSymOpList -from diffpy.structure.spacegroups import GetSpaceGroup, FindSpaceGroup +from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, SpaceGroupList, _hashSymOpList # ---------------------------------------------------------------------------- + class TestRoutines(unittest.TestCase): def setUp(self): return - def test_old_alt_name(self): "check GetSpaceGroup lookup from deprecated alt_name values" # alt_name values which do not map to short_name or pdb_name altnames_sgnos = ( - ("P M 3", 200), ("P N 3", 201), ("F M 3", 202), - ("F D 3", 203), ("I M 3", 204), ("P A 3", 205), - ("I A 3", 206), ("P M 3 M", 221), ("P N 3 N", 222), - ("P M 3 N", 223), ("P N 3 M", 224), ("F M 3 M", 225), - ("F M 3 C", 226), ("F D 3 M", 227), ("F D 3 C", 228), - ("I M 3 M", 229), ("I A 3 D", 230) + ("P M 3", 200), + ("P N 3", 201), + ("F M 3", 202), + ("F D 3", 203), + ("I M 3", 204), + ("P A 3", 205), + ("I A 3", 206), + ("P M 3 M", 221), + ("P N 3 N", 222), + ("P M 3 N", 223), + ("P N 3 M", 224), + ("F M 3 M", 225), + ("F M 3 C", 226), + ("F D 3 M", 227), + ("F D 3 C", 228), + ("I M 3 M", 229), + ("I A 3 D", 230), ) for name, sgno in altnames_sgnos: self.assertIs(GetSpaceGroup(sgno), GetSpaceGroup(name)) return - def test_GetSpaceGroup(self): "check GetSpaceGroup function" from diffpy.structure.spacegroups import sg125 + self.assertRaises(ValueError, GetSpaceGroup, 0) self.assertRaises(ValueError, GetSpaceGroup, 300) self.assertRaises(ValueError, GetSpaceGroup, "300") @@ -62,7 +72,6 @@ def test_GetSpaceGroup(self): self.assertIs(sg125, GetSpaceGroup("P 4/N 2/B 2/M")) return - def test_FindSpaceGroup(self): "check FindSpaceGroup function" sg123 = GetSpaceGroup(123) @@ -74,12 +83,10 @@ def test_FindSpaceGroup(self): self.assertIsNot(sg123, sg123r) self.assertIsNot(sg123.symop_list, sg123r.symop_list) self.assertEqual(ops123[::-1], sg123r.symop_list) - self.assertEqual(_hashSymOpList(sg123.symop_list), - _hashSymOpList(sg123r.symop_list)) + self.assertEqual(_hashSymOpList(sg123.symop_list), _hashSymOpList(sg123r.symop_list)) self.assertIs(sg123, FindSpaceGroup(ops123[::-1], shuffle=True)) return - def test__hashSymOpList(self): "verify _hashSymOpList is unique for each spacegroup" hset = set(_hashSymOpList(sg.symop_list) for sg in SpaceGroupList) @@ -89,44 +96,34 @@ def test__hashSymOpList(self): def test_spacegroup_representation(self): """Verify SpaceGroup.__repr__().""" self.assertEqual( - repr(GetSpaceGroup(1)), - "SpaceGroup #1 (P1, Triclinic). Symmetry matrices: 1, point sym. matr.: 1" + repr(GetSpaceGroup(1)), "SpaceGroup #1 (P1, Triclinic). Symmetry matrices: 1, point sym. matr.: 1" ) self.assertEqual( - repr(GetSpaceGroup(3)), - "SpaceGroup #3 (P2, Monoclinic). Symmetry matrices: 2, point sym. matr.: 2" + repr(GetSpaceGroup(3)), "SpaceGroup #3 (P2, Monoclinic). Symmetry matrices: 2, point sym. matr.: 2" ) self.assertEqual( repr(GetSpaceGroup(16)), - ( - "SpaceGroup #16 (P222, Orthorhombic). Symmetry matrices: 4, point sym. " - "matr.: 4" - ) + ("SpaceGroup #16 (P222, Orthorhombic). Symmetry matrices: 4, point sym. " "matr.: 4"), ) self.assertEqual( - repr(GetSpaceGroup(75)), - "SpaceGroup #75 (P4, Tetragonal). Symmetry matrices: 4, point sym. matr.: 4" + repr(GetSpaceGroup(75)), "SpaceGroup #75 (P4, Tetragonal). Symmetry matrices: 4, point sym. matr.: 4" ) self.assertEqual( - repr(GetSpaceGroup(143)), - "SpaceGroup #143 (P3, Trigonal). Symmetry matrices: 3, point sym. matr.: 3" + repr(GetSpaceGroup(143)), "SpaceGroup #143 (P3, Trigonal). Symmetry matrices: 3, point sym. matr.: 3" ) self.assertEqual( - repr(GetSpaceGroup(168)), - "SpaceGroup #168 (P6, Hexagonal). Symmetry matrices: 6, point sym. matr.: 6" + repr(GetSpaceGroup(168)), "SpaceGroup #168 (P6, Hexagonal). Symmetry matrices: 6, point sym. matr.: 6" ) self.assertEqual( repr(GetSpaceGroup(229)), - ( - "SpaceGroup #229 (Im-3m, Cubic). Symmetry matrices: 96, point sym. " - "matr.: 48" - ) + ("SpaceGroup #229 (Im-3m, Cubic). Symmetry matrices: 96, point sym. " "matr.: 48"), ) return + # End of class TestRoutines # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/teststructure.py b/src/diffpy/structure/tests/teststructure.py index 5086f97d..37f89a59 100644 --- a/src/diffpy/structure/tests/teststructure.py +++ b/src/diffpy/structure/tests/teststructure.py @@ -20,50 +20,47 @@ import copy import pickle import unittest + import numpy +from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.tests.testutils import datafile -from diffpy.structure import Structure -from diffpy.structure import Lattice -from diffpy.structure import Atom # useful variables -cdsefile = datafile('CdSe_bulk.stru') -teifile = datafile('TeI.cif') -pbtefile = datafile('PbTe.cif') +cdsefile = datafile("CdSe_bulk.stru") +teifile = datafile("TeI.cif") +pbtefile = datafile("PbTe.cif") # ---------------------------------------------------------------------------- + class TestStructure(unittest.TestCase): """test methods of Structure class""" _loaded_structures = {} def setUp(self): - self.stru = Structure( [ Atom('C', [0,0,0]), Atom('C', [1,1,1]) ], - lattice=Lattice(1, 1, 1, 90, 90, 120) ) + self.stru = Structure([Atom("C", [0, 0, 0]), Atom("C", [1, 1, 1])], lattice=Lattice(1, 1, 1, 90, 90, 120)) if not self._loaded_structures: - self._loaded_structures.update([ - ('cdse', Structure(filename=cdsefile)), - ('tei', Structure(filename=teifile)), - ('pbte', Structure(filename=pbtefile)), - ]) + self._loaded_structures.update( + [ + ("cdse", Structure(filename=cdsefile)), + ("tei", Structure(filename=teifile)), + ("pbte", Structure(filename=pbtefile)), + ] + ) self.__dict__.update(self._loaded_structures) self.places = 12 return - def test___init__(self): - """check Structure.__init__() - """ - atoms = [Atom('C', [0, 0, 0]), Atom('C', [0.5, 0.5, 0.5])] + """check Structure.__init__()""" + atoms = [Atom("C", [0, 0, 0]), Atom("C", [0.5, 0.5, 0.5])] self.assertRaises(ValueError, Structure, atoms, filename=teifile) - self.assertRaises(ValueError, Structure, - lattice=Lattice(), filename=teifile) - self.assertRaises(ValueError, Structure, - title='test', filename=teifile) - stru1 = Structure(title='my title') - self.assertEqual('my title', stru1.title) + self.assertRaises(ValueError, Structure, lattice=Lattice(), filename=teifile) + self.assertRaises(ValueError, Structure, title="test", filename=teifile) + stru1 = Structure(title="my title") + self.assertEqual("my title", stru1.title) stru2a = Structure(atoms) stru2b = Structure(iter(atoms)) stru2c = Structure(a for a in atoms) @@ -72,168 +69,151 @@ def test___init__(self): self.assertEqual(s2a, str(stru2c)) return - def test_copy(self): - """check Structure.copy() - """ + """check Structure.copy()""" + class MyDerivedStructure(Structure): def __copy__(self): rv = MyDerivedStructure() Structure.__copy__(self, target=rv) return rv + pass + pbte = self.pbte pbte2 = pbte.copy() self.assertFalse(pbte2.lattice is pbte.lattice) self.assertTrue(numpy.array_equal(pbte.xyz_cartn, pbte2.xyz_cartn)) self.assertTrue(numpy.array_equal(pbte.U, pbte2.U)) stru = MyDerivedStructure() - stru += pbte2[pbte2.element.startswith('Pb')] + stru += pbte2[pbte2.element.startswith("Pb")] pb3 = stru.copy() self.assertTrue(isinstance(pb3, MyDerivedStructure)) - self.assertTrue(all(pb3.element == 'Pb2+')) + self.assertTrue(all(pb3.element == "Pb2+")) self.assertEqual(4, len(pb3)) return - def test___copy__(self): - """check Structure.__copy__() - """ + """check Structure.__copy__()""" cdse = Structure(filename=cdsefile) - cdse_str = cdse.writeStr('pdffit') + cdse_str = cdse.writeStr("pdffit") cdse2 = copy.copy(cdse) - self.assertEqual(cdse_str, cdse2.writeStr('pdffit')) + self.assertEqual(cdse_str, cdse2.writeStr("pdffit")) self.assertFalse(cdse.lattice is cdse2.lattice) sameatoms = set(cdse).intersection(cdse2) self.assertFalse(sameatoms) return -# def test___str__(self): -# """check Structure.__str__() -# """ -# return -# -# def test_addNewAtom(self): -# """check Structure.addNewAtom() -# """ -# return -# -# def test_getLastAtom(self): -# """check Structure.getLastAtom() -# """ -# return - + # def test___str__(self): + # """check Structure.__str__() + # """ + # return + # + # def test_addNewAtom(self): + # """check Structure.addNewAtom() + # """ + # return + # + # def test_getLastAtom(self): + # """check Structure.getLastAtom() + # """ + # return def test_assignUniqueLabels(self): - """check Structure.assignUniqueLabels() - """ - self.assertEqual('', ''.join([a.label for a in self.stru])) + """check Structure.assignUniqueLabels()""" + self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assignUniqueLabels() - self.assertEqual('C1', self.stru[0].label) - self.assertEqual('C2', self.stru[1].label) + self.assertEqual("C1", self.stru[0].label) + self.assertEqual("C2", self.stru[1].label) return - def test_distance(self): - """check Structure.distance() - """ + """check Structure.distance()""" from math import sqrt + self.stru.assignUniqueLabels() self.assertRaises(IndexError, self.stru.distance, 333, "C1") self.assertRaises(IndexError, self.stru.distance, "C", "C1") - self.assertAlmostEqual(sqrt(2.0), - self.stru.distance(0, 1), self.places) - self.assertAlmostEqual(sqrt(2.0), - self.stru.distance("C1", "C2"), self.places) + self.assertAlmostEqual(sqrt(2.0), self.stru.distance(0, 1), self.places) + self.assertAlmostEqual(sqrt(2.0), self.stru.distance("C1", "C2"), self.places) self.assertEqual(0, self.stru.distance(0, "C1")) return - def test_angle(self): - """check Structure.angle() - """ + """check Structure.angle()""" cdse = Structure(filename=cdsefile) cdse.assignUniqueLabels() self.assertEqual(109, round(cdse.angle(0, 2, 1))) self.assertEqual(109, round(cdse.angle("Cd1", "Se1", "Cd2"))) return - def test_placeInLattice(self): - """check Structure.placeInLattice() -- conversion of coordinates - """ + """check Structure.placeInLattice() -- conversion of coordinates""" stru = self.stru - new_lattice = Lattice(.5, .5, .5, 90, 90, 60) + new_lattice = Lattice(0.5, 0.5, 0.5, 90, 90, 60) stru.placeInLattice(new_lattice) a0 = stru[0] self.assertTrue(numpy.allclose(a0.xyz, [0.0, 0.0, 0.0])) a1 = stru[1] self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) -# def test_read(self): -# """check Structure.read() -# """ -# return -# -# def test_readStr(self): -# """check Structure.readStr() -# """ -# return -# -# def test_write(self): -# """check Structure.write() -# """ -# return -# -# def test_writeStr(self): -# """check Structure.writeStr() -# """ -# return + # def test_read(self): + # """check Structure.read() + # """ + # return + # + # def test_readStr(self): + # """check Structure.readStr() + # """ + # return + # + # def test_write(self): + # """check Structure.write() + # """ + # return + # + # def test_writeStr(self): + # """check Structure.writeStr() + # """ + # return def test_aslist(self): - """check Structure.tolist() - """ + """check Structure.tolist()""" lst = self.stru.tolist() self.assertEqual(tuple(lst), tuple(self.stru)) self.assertEqual(list, type(lst)) return - def test_append(self): - """check Structure.append() - """ + """check Structure.append()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru.append(a) alast = self.stru[-1] self.assertEqual(3, len(self.stru)) - self.assertEqual('Si', alast.element) + self.assertEqual("Si", alast.element) self.assertTrue(lat is alast.lattice) self.assertTrue(numpy.array_equal(a.xyz, alast.xyz)) self.assertFalse(a is alast) self.assertFalse(lat is a.lattice) return - def test_insert(self): - """check Structure.insert() - """ + """check Structure.insert()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru.insert(1, a) a1 = self.stru[1] self.assertEqual(3, len(self.stru)) - self.assertEqual('Si', a1.element) + self.assertEqual("Si", a1.element) self.assertTrue(lat is a1.lattice) self.assertTrue(numpy.array_equal(a.xyz, a1.xyz)) self.assertFalse(a is a1) self.assertFalse(lat is a.lattice) return - def test_extend(self): - """check Structure.extend() - """ + """check Structure.extend()""" stru = self.stru cdse = Structure(filename=cdsefile) lst = stru.tolist() @@ -244,99 +224,86 @@ def test_extend(self): self.assertFalse(stru[-1] is cdse[-1]) return - def test___getitem__(self): - """check Structure.__getitem__() - """ + """check Structure.__getitem__()""" stru = self.stru self.assertTrue(stru[0] is stru.tolist()[0]) intidx = list(range(len(stru)))[::-1] self.assertEqual(stru[intidx].tolist(), stru.tolist()[::-1]) - flagidx = (numpy.arange(len(stru)) > 0) + flagidx = numpy.arange(len(stru)) > 0 self.assertEqual(stru[flagidx].tolist(), stru.tolist()[1:]) cdse = Structure(self.cdse) self.assertEqual([cdse[0], cdse[-2]], cdse[0, -2].tolist()) cdse013 = cdse.tolist() cdse013.pop(2) - self.assertEqual(cdse013, cdse[:2,3].tolist()) - self.assertRaises(IndexError, cdse.__getitem__, 'Cd1') + self.assertEqual(cdse013, cdse[:2, 3].tolist()) + self.assertRaises(IndexError, cdse.__getitem__, "Cd1") cdse.assignUniqueLabels() - self.assertTrue(cdse[0] is cdse['Cd1']) - cdse[0].label = 'Hohenzollern' - self.assertRaises(IndexError, cdse.__getitem__, 'Cd1') - self.assertTrue(cdse[0] is cdse['Hohenzollern']) - self.assertEqual([cdse[0], cdse[3], cdse[1]], - cdse['Hohenzollern', 3:0:-2].tolist()) - stru.label = ['A', 'B'] - self.assertTrue(stru[0] is stru['A']) - self.assertTrue(stru[1] is stru['B']) - stru[1].label = 'A' - self.assertRaises(IndexError, stru.__getitem__, 'A') + self.assertTrue(cdse[0] is cdse["Cd1"]) + cdse[0].label = "Hohenzollern" + self.assertRaises(IndexError, cdse.__getitem__, "Cd1") + self.assertTrue(cdse[0] is cdse["Hohenzollern"]) + self.assertEqual([cdse[0], cdse[3], cdse[1]], cdse["Hohenzollern", 3:0:-2].tolist()) + stru.label = ["A", "B"] + self.assertTrue(stru[0] is stru["A"]) + self.assertTrue(stru[1] is stru["B"]) + stru[1].label = "A" + self.assertRaises(IndexError, stru.__getitem__, "A") return - def test___getitem__slice(self): - """check Structure.__getitem__() with a slice argument - """ + """check Structure.__getitem__() with a slice argument""" stru = self.stru self.assertEqual([stru[0]], stru[:1].tolist()) self.assertEqual([stru[1], stru[0]], stru[::-1].tolist()) return - def test___setitem__(self): - """check Structure.__setitem__() - """ + """check Structure.__setitem__()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru[1] = a a1 = self.stru[1] self.assertEqual(2, len(self.stru)) - self.assertEqual('Si', a1.element) + self.assertEqual("Si", a1.element) self.assertTrue(lat is a1.lattice) self.assertTrue(numpy.array_equal(a.xyz, a1.xyz)) self.assertFalse(a is a1) self.assertFalse(lat is a.lattice) return - def test___setitem__slice(self): - """check Structure.__setitem__() with a slice argument - """ + """check Structure.__setitem__() with a slice argument""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru[:] = [a] a0 = self.stru[0] self.assertEqual(1, len(self.stru)) - self.assertEqual('Si', a0.element) + self.assertEqual("Si", a0.element) self.assertTrue(lat is a0.lattice) self.assertTrue(numpy.array_equal(a.xyz, a0.xyz)) self.assertFalse(a is a0) self.assertFalse(lat is a.lattice) return - def test___add__(self): - """check Structure.__add__() - """ + """check Structure.__add__()""" stru = self.stru cdse = Structure(filename=cdsefile) total = stru + cdse self.assertEqual(6, len(total)) ta0 = total[0] tam1 = total[-1] - self.assertEqual('C', ta0.element) + self.assertEqual("C", ta0.element) self.assertTrue(numpy.array_equal(stru[0].xyz, ta0.xyz)) - self.assertEqual('Se', tam1.element) + self.assertEqual("Se", tam1.element) self.assertTrue(numpy.array_equal(cdse[-1].xyz, tam1.xyz)) self.assertFalse(total.lattice in (stru.lattice, cdse.lattice)) self.assertTrue(all([a.lattice is total.lattice for a in total])) return - def test___iadd__(self): - """check Structure.__iadd__() - """ + """check Structure.__iadd__()""" stru = self.stru lat0 = stru.lattice lst = stru.tolist() @@ -345,65 +312,55 @@ def test___iadd__(self): self.assertEqual(6, len(stru)) self.assertEqual(lst, stru[:2].tolist()) am1 = stru[-1] - self.assertEqual('Se', am1.element) + self.assertEqual("Se", am1.element) self.assertTrue(numpy.array_equal(cdse[-1].xyz, am1.xyz)) self.assertTrue(lat0 is stru.lattice) self.assertFalse(stru.lattice is cdse.lattice) self.assertTrue(all([a.lattice is stru.lattice for a in stru])) return - def test___sub__(self): - """check Structure.__sub__() - """ + """check Structure.__sub__()""" cdse = Structure(filename=cdsefile) cadmiums = cdse - cdse[2:] self.assertEqual(2, len(cadmiums)) - self.assertEqual('Cd', cadmiums[0].element) - self.assertEqual('Cd', cadmiums[1].element) + self.assertEqual("Cd", cadmiums[0].element) + self.assertEqual("Cd", cadmiums[1].element) self.assertTrue(numpy.array_equal(cdse[0].xyz, cadmiums[0].xyz)) self.assertTrue(numpy.array_equal(cdse[1].xyz, cadmiums[1].xyz)) self.assertFalse(cdse[0] is cadmiums[0]) self.assertFalse(cdse.lattice is cadmiums.lattice) return - def test___isub__(self): - """check Structure.__isub__() - """ + """check Structure.__isub__()""" cdse = Structure(filename=cdsefile) lat = cdse.lattice lst = cdse.tolist() cdse -= cdse[2:] self.assertEqual(2, len(cdse)) self.assertEqual(4, len(lst)) - self.assertEqual('Cd', cdse[0].element) - self.assertEqual('Cd', cdse[1].element) + self.assertEqual("Cd", cdse[0].element) + self.assertEqual("Cd", cdse[1].element) self.assertEqual(lat, cdse.lattice) self.assertEqual(lst[:2], cdse.tolist()) return - def test___mul__(self): - """check Structure.__mul__() - """ + """check Structure.__mul__()""" cdse = Structure(filename=cdsefile) self.assertEqual(12, len(set(3 * cdse))) self.assertEqual(12, len(set(cdse * 3))) cdsex3 = 3 * cdse self.assertEqual(12, len(cdsex3)) - self.assertEqual(3 * 'Cd Cd Se Se'.split(), - [a.element for a in cdsex3]) - self.assertTrue(numpy.array_equal(3 * [a.xyz for a in cdse], - [a.xyz for a in cdsex3])) + self.assertEqual(3 * "Cd Cd Se Se".split(), [a.element for a in cdsex3]) + self.assertTrue(numpy.array_equal(3 * [a.xyz for a in cdse], [a.xyz for a in cdsex3])) self.assertFalse(set(cdse).intersection(cdsex3)) self.assertFalse(cdse.lattice is cdsex3.lattice) return - def test___imul__(self): - """check Structure.__imul__() - """ + """check Structure.__imul__()""" cdse = Structure(filename=cdsefile) lat = cdse.lattice els = cdse.element @@ -420,10 +377,8 @@ def test___imul__(self): self.assertEqual(0, len(self.stru)) return - def test__get_lattice(self): - """check Structure._get_lattice() - """ + """check Structure._get_lattice()""" lat = Lattice() stru = Structure() self.assertEqual((1, 1, 1, 90, 90, 90), stru.lattice.abcABG()) @@ -431,43 +386,35 @@ def test__get_lattice(self): self.assertTrue(lat is stru2.lattice) return - def test__set_lattice(self): - """check Structure._set_lattice() - """ + """check Structure._set_lattice()""" lat = Lattice() self.stru.lattice = lat self.assertEqual(2 * [lat], [a.lattice for a in self.stru]) return - def test_composition(self): - """check Structure.composition property - """ + """check Structure.composition property""" stru = self.stru - self.assertEqual({'C' : 2}, stru.composition) + self.assertEqual({"C": 2}, stru.composition) stru *= 2 - self.assertEqual({'C' : 4}, stru.composition) + self.assertEqual({"C": 4}, stru.composition) stru[:] = [] self.assertEqual({}, stru.composition) return - def test_element(self): - """check Structure.element - """ + """check Structure.element""" stru = self.stru cdse = self.cdse - self.assertEqual('Cd Cd Se Se'.split(), cdse.element.tolist()) - self.assertEqual(cdse[:2], cdse[cdse.element == 'Cd']) - stru.element = stru.element.replace('C', 'Si') - self.assertEqual('Si', stru[0].element) + self.assertEqual("Cd Cd Se Se".split(), cdse.element.tolist()) + self.assertEqual(cdse[:2], cdse[cdse.element == "Cd"]) + stru.element = stru.element.replace("C", "Si") + self.assertEqual("Si", stru[0].element) return - def test_xyz(self): - """check Structure.xyz - """ + """check Structure.xyz""" stru = self.stru self.assertEqual((2, 3), stru.xyz.shape) self.assertTrue(numpy.array_equal([1, 1, 1], stru.xyz[1])) @@ -484,10 +431,8 @@ def test_xyz(self): self.assertTrue(numpy.array_equal(xyz0, stru.xyz)) return - def test_x(self): - """check Structure.x - """ + """check Structure.x""" cdse = self.cdse self.assertEqual((4,), cdse.x.shape) self.assertAlmostEqual(0.6666, cdse.x[3], 5) @@ -497,10 +442,8 @@ def test_x(self): self.assertEqual(4, stru[1].xyz[0]) return - def test_y(self): - """check Structure.y - """ + """check Structure.y""" cdse = self.cdse self.assertEqual((4,), cdse.y.shape) self.assertAlmostEqual(0.3333, cdse.y[3], 5) @@ -510,10 +453,8 @@ def test_y(self): self.assertEqual(4, stru[1].xyz[1]) return - def test_z(self): - """check Structure.z - """ + """check Structure.z""" cdse = self.cdse self.assertEqual((4,), cdse.z.shape) self.assertAlmostEqual(0.87667, cdse.z[3], 5) @@ -523,22 +464,18 @@ def test_z(self): self.assertEqual(4, stru[1].xyz[2]) return - def test_label(self): - """check Structure.label - """ + """check Structure.label""" cdse = Structure(filename=cdsefile) - self.assertEqual(4 * [''], cdse.label.tolist()) + self.assertEqual(4 * [""], cdse.label.tolist()) cdse.assignUniqueLabels() - self.assertEqual('Cd1 Cd2 Se1 Se2'.split(), cdse.label.tolist()) + self.assertEqual("Cd1 Cd2 Se1 Se2".split(), cdse.label.tolist()) cdse.label = cdse.label.lower() - self.assertEqual('cd1 cd2 se1 se2'.split(), cdse.label.tolist()) + self.assertEqual("cd1 cd2 se1 se2".split(), cdse.label.tolist()) return - def test_occupancy(self): - """check Structure.occupancy - """ + """check Structure.occupancy""" cdse = self.cdse self.assertTrue(numpy.array_equal(numpy.ones(4), cdse.occupancy)) self.stru.occupancy *= 0.5 @@ -547,23 +484,18 @@ def test_occupancy(self): self.assertTrue(all(isinstance(a.occupancy, int) for a in cdse)) return - def test_xyz_cartn(self): - """check Structure.xyz_cartn - """ + """check Structure.xyz_cartn""" pbte = copy.copy(self.pbte) self.assertEqual((8, 3), pbte.xyz_cartn.shape) - self.assertTrue(numpy.allclose(6.461 / 2.0 * numpy.ones(3), - pbte.xyz_cartn[0])) + self.assertTrue(numpy.allclose(6.461 / 2.0 * numpy.ones(3), pbte.xyz_cartn[0])) pbte.xyz_cartn += numpy.array([0.1, 0.2, 0.3]) * 6.461 self.assertTrue(numpy.allclose([0.6, 0.7, 0.8], pbte[0].xyz)) self.assertTrue(numpy.allclose([0.6, 0.7, 0.3], pbte[7].xyz)) return - def test_anisotropy(self): - """check Structure.anisotropy - """ + """check Structure.anisotropy""" self.assertEqual((2,), self.stru.anisotropy.shape) self.assertFalse(numpy.any(self.stru.anisotropy)) tei = copy.copy(self.tei) @@ -574,16 +506,13 @@ def test_anisotropy(self): self.assertAlmostEqual(0.019227, tei[0].U22, 6) self.assertAlmostEqual(0.019227, tei[0].U33, 6) self.assertAlmostEqual(0.0, tei[0].U12, 6) - self.assertAlmostEqual(0.019227 * -numpy.cos(numpy.radians(128.09)), - tei[0].U13, 6) + self.assertAlmostEqual(0.019227 * -numpy.cos(numpy.radians(128.09)), tei[0].U13, 6) self.assertAlmostEqual(0.0, tei[0].U23, 6) self.assertAlmostEqual(0.019227, tei[0].Uisoequiv, 6) return - def test_U(self): - """check Structure.U - """ + """check Structure.U""" stru = self.stru self.assertEqual((2, 3, 3), stru.U.shape) self.assertFalse(numpy.any(stru.anisotropy)) @@ -604,10 +533,8 @@ def test_U(self): self.assertTrue(numpy.all(stru[1].U == 1.0)) return - def test_Uisoequiv(self): - """check Structure.Uisoequiv - """ + """check Structure.Uisoequiv""" tei = copy.copy(self.tei) self.assertEqual((16,), tei.Uisoequiv.shape) self.assertAlmostEqual(0.019227, tei.Uisoequiv[0], 6) @@ -616,13 +543,11 @@ def test_Uisoequiv(self): self.assertAlmostEqual(0.026878, tei.Uisoequiv[12], 6) u11old = tei[0].U11 tei.Uisoequiv = 0.001 - self.assertAlmostEqual(u11old * 0.001/0.019227, tei[0].U[0,0]) + self.assertAlmostEqual(u11old * 0.001 / 0.019227, tei[0].U[0, 0]) return - def test_Uij(self): - """check Structure.Uij - """ + """check Structure.Uij""" stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] @@ -636,10 +561,8 @@ def test_Uij(self): self.assertFalse(numpy.any(stru.U != 0.0)) return - def test_Bisoequiv(self): - """check Structure.Bisoequiv - """ + """check Structure.Bisoequiv""" utob = 8 * numpy.pi**2 tei = copy.copy(self.tei) self.assertEqual((16,), tei.Bisoequiv.shape) @@ -649,13 +572,11 @@ def test_Bisoequiv(self): self.assertAlmostEqual(utob * 0.026878, tei.Bisoequiv[12], 4) b11old = tei[0].B11 tei.Bisoequiv = 0.1 - self.assertAlmostEqual(b11old * 0.1/(utob * 0.019227), tei[0].B11, 5) + self.assertAlmostEqual(b11old * 0.1 / (utob * 0.019227), tei[0].B11, 5) return - def test_Bij(self): - """check Structure.Bij - """ + """check Structure.Bij""" stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] @@ -670,10 +591,8 @@ def test_Bij(self): self.assertFalse(numpy.any(stru.U != 0.0)) return - def test_pickling(self): - """Make sure Atom in Structure can be consistently pickled. - """ + """Make sure Atom in Structure can be consistently pickled.""" stru = self.stru a = stru[0] self.assertTrue(a is stru[0]) @@ -681,9 +600,10 @@ def test_pickling(self): self.assertTrue(a1 is stru1[0]) return + # End of class TestStructure # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testsupercell.py b/src/diffpy/structure/tests/testsupercell.py index 52a563e2..2ca5d72e 100644 --- a/src/diffpy/structure/tests/testsupercell.py +++ b/src/diffpy/structure/tests/testsupercell.py @@ -19,18 +19,18 @@ import unittest -from diffpy.structure.tests.testutils import datafile from diffpy.structure import Structure from diffpy.structure.expansion import supercell +from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- + class TestSuperCell(unittest.TestCase): stru_cdse = None stru_ni = None - def setUp(self): # load test structures once if TestSuperCell.stru_cdse is None: @@ -44,54 +44,45 @@ def setUp(self): self.stru_ni = TestSuperCell.stru_ni return - def tearDown(self): return - def test_exceptions(self): - """check argument checking of supercell. - """ - self.assertRaises(ValueError, - supercell, self.stru_ni, (0, 1, 1)) - self.assertRaises(ValueError, - supercell, self.stru_ni, (0, 1)) - self.assertRaises(TypeError, - supercell, list(self.stru_ni), (1, 1, 1)) + """check argument checking of supercell.""" + self.assertRaises(ValueError, supercell, self.stru_ni, (0, 1, 1)) + self.assertRaises(ValueError, supercell, self.stru_ni, (0, 1)) + self.assertRaises(TypeError, supercell, list(self.stru_ni), (1, 1, 1)) return - def test_ni_supercell(self): - """check supercell expansion for Ni. - """ + """check supercell expansion for Ni.""" ni_123 = supercell(self.stru_ni, (1, 2, 3)) - self.assertEqual(6*len(self.stru_ni), len(ni_123)) + self.assertEqual(6 * len(self.stru_ni), len(ni_123)) a, b, c = self.stru_ni.lattice.abcABG()[:3] a1, b2, c3 = ni_123.lattice.abcABG()[:3] self.assertAlmostEqual(a, a1, 8) - self.assertAlmostEqual(b*2, b2, 8) - self.assertAlmostEqual(c*3, c3, 8) + self.assertAlmostEqual(b * 2, b2, 8) + self.assertAlmostEqual(c * 3, c3, 8) x, y, z = self.stru_ni[-1].xyz - x1, y2, z3 = ni_123[-1*2*3].xyz - self.assertAlmostEqual(x/1, x1, 8) - self.assertAlmostEqual(y/2, y2, 8) - self.assertAlmostEqual(z/3, z3, 8) + x1, y2, z3 = ni_123[-1 * 2 * 3].xyz + self.assertAlmostEqual(x / 1, x1, 8) + self.assertAlmostEqual(y / 2, y2, 8) + self.assertAlmostEqual(z / 3, z3, 8) return - def test_cdse_supercell(self): - """check supercell expansion for CdSe. - """ + """check supercell expansion for CdSe.""" cdse_222 = supercell(self.stru_cdse, (2, 2, 2)) # new atoms should be grouped together - elems = sum([8*[a.element] for a in self.stru_cdse], []) + elems = sum([8 * [a.element] for a in self.stru_cdse], []) elems_222 = [a.element for a in cdse_222] self.assertEqual(elems, elems_222) return + # End of class TestRoutines # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testsymmetryutilities.py b/src/diffpy/structure/tests/testsymmetryutilities.py index d607ed97..cbbe57a6 100644 --- a/src/diffpy/structure/tests/testsymmetryutilities.py +++ b/src/diffpy/structure/tests/testsymmetryutilities.py @@ -16,19 +16,27 @@ """Unit tests for SymmetryUtilities.py """ -import sys import re +import sys import unittest + import numpy from diffpy.structure.spacegroups import GetSpaceGroup -from diffpy.structure.symmetryutilities import (isSpaceGroupLatPar, - expandPosition, pruneFormulaDictionary, isconstantFormula, - GeneratorSite, ExpandAsymmetricUnit, SymmetryConstraints) -from diffpy.structure.symmetryutilities import _Position2Tuple +from diffpy.structure.symmetryutilities import ( + ExpandAsymmetricUnit, + GeneratorSite, + SymmetryConstraints, + _Position2Tuple, + expandPosition, + isconstantFormula, + isSpaceGroupLatPar, + pruneFormulaDictionary, +) # ---------------------------------------------------------------------------- + class TestRoutines(unittest.TestCase): def setUp(self): @@ -38,8 +46,7 @@ def tearDown(self): return def test_isSpaceGroupLatPar(self): - """check isSpaceGroupLatPar() - """ + """check isSpaceGroupLatPar()""" triclinic = GetSpaceGroup("P1") monoclinic = GetSpaceGroup("P2") orthorhombic = GetSpaceGroup("P222") @@ -63,18 +70,16 @@ def test_isSpaceGroupLatPar(self): return def test_sgtbx_spacegroup_aliases(self): - """check GetSpaceGroup for non-standard aliases from sgtbx. - """ - self.assertIs(GetSpaceGroup('Fm3m'), GetSpaceGroup(225)) - self.assertIs(GetSpaceGroup('Ia3d'), GetSpaceGroup('I a -3 d')) + """check GetSpaceGroup for non-standard aliases from sgtbx.""" + self.assertIs(GetSpaceGroup("Fm3m"), GetSpaceGroup(225)) + self.assertIs(GetSpaceGroup("Ia3d"), GetSpaceGroup("I a -3 d")) return def test_expandPosition(self): - """check expandPosition() - """ + """check expandPosition()""" # ok again Ni example fcc = GetSpaceGroup(225) - pos,pops,pmult = expandPosition(fcc, [0,0,0]) + pos, pops, pmult = expandPosition(fcc, [0, 0, 0]) self.assertTrue(numpy.all(pos[0] == 0.0)) self.assertEqual(4, len(pos)) self.assertEqual(192, sum([len(l) for l in pops])) @@ -82,27 +87,27 @@ def test_expandPosition(self): return def test_pruneFormulaDictionary(self): - """check pruneFormulaDictionary() - """ - fmdict = {"x" : "3*y-0.17", "y" : '0', "z" : "0.13"} + """check pruneFormulaDictionary()""" + fmdict = {"x": "3*y-0.17", "y": "0", "z": "0.13"} pruned = pruneFormulaDictionary(fmdict) - self.assertEqual({"x" : "3*y-0.17"}, pruned) + self.assertEqual({"x": "3*y-0.17"}, pruned) return def test_isconstantFormula(self): - """check isconstantFormula() - """ - self.assertFalse(isconstantFormula('x-y+z')) - self.assertTrue(isconstantFormula('6.023e23')) - self.assertTrue(isconstantFormula('22/7')) - self.assertTrue(isconstantFormula('- 22/7')) - self.assertTrue(isconstantFormula('+13/ 9')) + """check isconstantFormula()""" + self.assertFalse(isconstantFormula("x-y+z")) + self.assertTrue(isconstantFormula("6.023e23")) + self.assertTrue(isconstantFormula("22/7")) + self.assertTrue(isconstantFormula("- 22/7")) + self.assertTrue(isconstantFormula("+13/ 9")) return + # End of class TestRoutines # ---------------------------------------------------------------------------- + class Test_Position2Tuple(unittest.TestCase): def setUp(self): @@ -115,29 +120,29 @@ def tearDown(self): return def test___init__(self): - """check _Position2Tuple.__init__() - """ + """check _Position2Tuple.__init__()""" self.assertNotEqual(0.0, self.pos2tuple.eps) - self.pos2tuple = _Position2Tuple(1.0/sys.maxsize/2) + self.pos2tuple = _Position2Tuple(1.0 / sys.maxsize / 2) self.assertEqual(0.0, self.pos2tuple.eps) return def test___call__(self): - """check _Position2Tuple.__call__() - """ + """check _Position2Tuple.__call__()""" pos2tuple = self.pos2tuple - positions = numpy.zeros((100,3), dtype=float) - positions[:,0] = numpy.arange(100)/100.0*pos2tuple.eps + 0.1 + positions = numpy.zeros((100, 3), dtype=float) + positions[:, 0] = numpy.arange(100) / 100.0 * pos2tuple.eps + 0.1 positions = positions - numpy.floor(positions) # pos2tuple should generate at most 2 distinct tuples alltuples = dict.fromkeys([pos2tuple(xyz) for xyz in positions]) self.assertFalse(len(alltuples) > 2) return + # End of class Test_Position2Tuple # ---------------------------------------------------------------------------- + class TestGeneratorSite(unittest.TestCase): generators = {} @@ -151,15 +156,15 @@ def setUp(self): sg117 = GetSpaceGroup(117) sg143 = GetSpaceGroup(143) sg164 = GetSpaceGroup(164) - sg167h = GetSpaceGroup('H-3c') - sg167r = GetSpaceGroup('R-3c') + sg167h = GetSpaceGroup("H-3c") + sg167r = GetSpaceGroup("R-3c") sg186 = GetSpaceGroup(186) sg227 = GetSpaceGroup(227) g117c = GeneratorSite(sg117, [0, 0.5, 0]) - g117h = GeneratorSite(sg117, [x, x+0.5, 0.5]) + g117h = GeneratorSite(sg117, [x, x + 0.5, 0.5]) g143a = GeneratorSite(sg143, [0, 0, z]) - g143b = GeneratorSite(sg143, [1./3, 2./3, z]) - g143c = GeneratorSite(sg143, [2./3, 1./3, z]) + g143b = GeneratorSite(sg143, [1.0 / 3, 2.0 / 3, z]) + g143c = GeneratorSite(sg143, [2.0 / 3, 1.0 / 3, z]) g143d = GeneratorSite(sg143, [x, y, z]) g164e = GeneratorSite(sg164, (0.5, 0, 0)) g164f = GeneratorSite(sg164, (0.5, 0, 0.5)) @@ -169,19 +174,27 @@ def setUp(self): gr167e = GeneratorSite(sg167r, (0.1, 0.4, 0.25)) g186c = GeneratorSite(sg186, (0.1695, 1.0 - 0.1695, 0.6365)) g227a = GeneratorSite(sg227, [0, 0, 0]) - g227c = GeneratorSite(sg227, 3*[1./8]) - g227oa = GeneratorSite(sg227, 3*[1./8], sgoffset=3*[1./8]) - g227oc = GeneratorSite(sg227, [0, 0, 0], sgoffset=3*[1./8]) + g227c = GeneratorSite(sg227, 3 * [1.0 / 8]) + g227oa = GeneratorSite(sg227, 3 * [1.0 / 8], sgoffset=3 * [1.0 / 8]) + g227oc = GeneratorSite(sg227, [0, 0, 0], sgoffset=3 * [1.0 / 8]) TestGeneratorSite.generators = { - 'g117c' : g117c, 'g117h' : g117h, - 'g143a' : g143a, 'g143b' : g143b, - 'g143c' : g143c, 'g143d' : g143d, - 'g164e' : g164e, 'g164f' : g164f, - 'g164g' : g164g, 'g164h' : g164h, - 'gh167e' : gh167e, 'gr167e' : gr167e, - 'g186c' : g186c, - 'g227a' : g227a, 'g227c' : g227c, - 'g227oa' : g227oa, 'g227oc' : g227oc + "g117c": g117c, + "g117h": g117h, + "g143a": g143a, + "g143b": g143b, + "g143c": g143c, + "g143d": g143d, + "g164e": g164e, + "g164f": g164f, + "g164g": g164g, + "g164h": g164h, + "gh167e": gh167e, + "gr167e": gr167e, + "g186c": g186c, + "g227a": g227a, + "g227c": g227c, + "g227oa": g227oa, + "g227oc": g227oc, } self.__dict__.update(TestGeneratorSite.generators) return @@ -190,39 +203,35 @@ def tearDown(self): return def test___init__(self): - """check GeneratorSite.__init__() - """ + """check GeneratorSite.__init__()""" # check multiplicities - self.assertEqual(2, self.g117c.multiplicity) - self.assertEqual(4, self.g117h.multiplicity) - self.assertEqual(1, self.g143a.multiplicity) - self.assertEqual(1, self.g143b.multiplicity) - self.assertEqual(1, self.g143c.multiplicity) - self.assertEqual(3, self.g143d.multiplicity) - self.assertEqual(3, self.g164e.multiplicity) - self.assertEqual(3, self.g164f.multiplicity) - self.assertEqual(6, self.g164g.multiplicity) - self.assertEqual(6, self.g164h.multiplicity) - self.assertEqual(18, self.gh167e.multiplicity) - self.assertEqual(6, self.gr167e.multiplicity) - self.assertEqual(8, self.g227a.multiplicity) + self.assertEqual(2, self.g117c.multiplicity) + self.assertEqual(4, self.g117h.multiplicity) + self.assertEqual(1, self.g143a.multiplicity) + self.assertEqual(1, self.g143b.multiplicity) + self.assertEqual(1, self.g143c.multiplicity) + self.assertEqual(3, self.g143d.multiplicity) + self.assertEqual(3, self.g164e.multiplicity) + self.assertEqual(3, self.g164f.multiplicity) + self.assertEqual(6, self.g164g.multiplicity) + self.assertEqual(6, self.g164h.multiplicity) + self.assertEqual(18, self.gh167e.multiplicity) + self.assertEqual(6, self.gr167e.multiplicity) + self.assertEqual(8, self.g227a.multiplicity) self.assertEqual(16, self.g227c.multiplicity) - self.assertEqual(8, self.g227oa.multiplicity) + self.assertEqual(8, self.g227oa.multiplicity) self.assertEqual(16, self.g227oc.multiplicity) return - def test_signedRatStr(self): "check GeneratorSite.signedRatStr()" g = self.g117c - self.assertEqual('-1', g.signedRatStr(-1.00000000000002)) - self.assertEqual('+1', g.signedRatStr(1.00000000000002)) + self.assertEqual("-1", g.signedRatStr(-1.00000000000002)) + self.assertEqual("+1", g.signedRatStr(1.00000000000002)) return - def test_positionFormula(self): - """check GeneratorSite.positionFormula() - """ + """check GeneratorSite.positionFormula()""" # 117c self.assertEqual([], self.g117c.pparameters) self.assertEqual([("x", self.x)], self.g117h.pparameters) @@ -233,9 +242,9 @@ def test_positionFormula(self): self.assertEqual("z", pfm143c["z"]) # 143d x, y, z = self.x, self.y, self.z - pfm143d = self.g143d.positionFormula([-x+y, -x, z]) - self.assertEqual("-x+y", pfm143d["x"].replace(' ','')) - self.assertEqual("-x+1", pfm143d["y"].replace(' ','')) + pfm143d = self.g143d.positionFormula([-x + y, -x, z]) + self.assertEqual("-x+y", pfm143d["x"].replace(" ", "")) + self.assertEqual("-x+1", pfm143d["y"].replace(" ", "")) self.assertTrue(re.match("[+]?z", pfm143d["z"].strip())) # 227a self.assertEqual([], self.g227a.pparameters) @@ -245,41 +254,30 @@ def test_positionFormula(self): self.assertEqual([], self.g227oc.pparameters) return - def test_positionFormula_sg209(self): "check positionFormula at [x, 1-x, -x] site of the F432 space group." - sg209 = GetSpaceGroup('F 4 3 2') + sg209 = GetSpaceGroup("F 4 3 2") xyz = [0.05198, 0.94802, -0.05198] g209e = GeneratorSite(sg209, xyz) pfm = g209e.positionFormula(xyz) - self.assertEqual('x', pfm['x']) - self.assertEqual('-x+1', pfm['y'].replace(' ', '')) - self.assertEqual('-x+1', pfm['z'].replace(' ', '')) + self.assertEqual("x", pfm["x"]) + self.assertEqual("-x+1", pfm["y"].replace(" ", "")) + self.assertEqual("-x+1", pfm["z"].replace(" ", "")) return - def test_UFormula(self): - """check GeneratorSite.UFormula() - """ + """check GeneratorSite.UFormula()""" # Ref: Willis and Pryor, Thermal Vibrations in Crystallography, # Cambridge University Press 1975, p. 104-110 - smbl = ('A', 'B', 'C', 'D', 'E', 'F') - norule = { 'U11':'A', 'U22':'B', 'U33':'C', - 'U12':'D', 'U13':'E', 'U23':'F' } - rule05 = { 'U11':'A', 'U22':'A', 'U33':'C', - 'U12':'D', 'U13':'0', 'U23':'0' } - rule06 = { 'U11':'A', 'U22':'A', 'U33':'C', - 'U12':'D', 'U13':'E', 'U23':'E' } - rule07 = { 'U11':'A', 'U22':'A', 'U33':'C', - 'U12':'D', 'U13':'E', 'U23':'-E' } - rule15 = { 'U11':'A', 'U22':'B', 'U33':'C', - 'U12':'0.5*B', 'U13':'0.5*F', 'U23':'F' } - rule16 = { 'U11':'A', 'U22':'A', 'U33':'C', - 'U12':'0.5*A', 'U13':'0', 'U23':'0' } - rule17 = { 'U11':'A', 'U22':'A', 'U33':'A', - 'U12':'0', 'U13':'0', 'U23':'0' } - rule18 = { 'U11':'A', 'U22':'A', 'U33':'A', - 'U12':'D', 'U13':'D', 'U23':'D' } + smbl = ("A", "B", "C", "D", "E", "F") + norule = {"U11": "A", "U22": "B", "U33": "C", "U12": "D", "U13": "E", "U23": "F"} + rule05 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "0", "U23": "0"} + rule06 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "E"} + rule07 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "-E"} + rule15 = {"U11": "A", "U22": "B", "U33": "C", "U12": "0.5*B", "U13": "0.5*F", "U23": "F"} + rule16 = {"U11": "A", "U22": "A", "U33": "C", "U12": "0.5*A", "U13": "0", "U23": "0"} + rule17 = {"U11": "A", "U22": "A", "U33": "A", "U12": "0", "U13": "0", "U23": "0"} + rule18 = {"U11": "A", "U22": "A", "U33": "A", "U12": "D", "U13": "D", "U23": "D"} ufm = self.g117c.UFormula(self.g117c.xyz, smbl) self.assertEqual(rule05, ufm) ufm = self.g117h.UFormula(self.g117h.xyz, smbl) @@ -317,61 +315,47 @@ def test_UFormula(self): self.assertEqual(rule06, ufm) return - def test_UFormula_g186c_eqxyz(self): - '''Check rotated U formulas at the symmetry positions of c-site in 186. - ''' + """Check rotated U formulas at the symmetry positions of c-site in 186.""" sg186 = GetSpaceGroup(186) crules = [ - {'U11': 'A', 'U22': 'A', 'U33': 'C', - 'U12': 'D', 'U13': 'E', 'U23': '-E'}, - {'U11': 'A', 'U22': '2*A-2*D', 'U33': 'C', - 'U12': 'A-D', 'U13': 'E', 'U23': '2*E'}, - {'U11': '2*A-2*D', 'U22': 'A', 'U33': 'C', - 'U12': 'A-D', 'U13': '-2*E', 'U23': '-E'}, - {'U11': 'A', 'U22': 'A', 'U33': 'C', - 'U12': 'D', 'U13': '-E', 'U23': 'E'}, - {'U11': 'A', 'U22': '2*A-2*D', 'U33': 'C', - 'U12': 'A-D', 'U13': '-E', 'U23': '-2*E'}, - {'U11': '2*A-2*D', 'U22': 'A', 'U33': 'C', - 'U12': 'A-D', 'U13': '2*E', 'U23': 'E'}, - ] + {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "-E"}, + {"U11": "A", "U22": "2*A-2*D", "U33": "C", "U12": "A-D", "U13": "E", "U23": "2*E"}, + {"U11": "2*A-2*D", "U22": "A", "U33": "C", "U12": "A-D", "U13": "-2*E", "U23": "-E"}, + {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "-E", "U23": "E"}, + {"U11": "A", "U22": "2*A-2*D", "U33": "C", "U12": "A-D", "U13": "-E", "U23": "-2*E"}, + {"U11": "2*A-2*D", "U22": "A", "U33": "C", "U12": "A-D", "U13": "2*E", "U23": "E"}, + ] self.assertEqual(6, len(self.g186c.eqxyz)) gc = self.g186c for idx in range(6): - self.assertEqual(crules[idx], gc.UFormula(gc.eqxyz[idx], 'ABCDEF')) + self.assertEqual(crules[idx], gc.UFormula(gc.eqxyz[idx], "ABCDEF")) uiso = numpy.array([[2, 1, 0], [1, 2, 0], [0, 0, 2]]) eau = ExpandAsymmetricUnit(sg186, [gc.xyz], [uiso]) for u in eau.expandedUijs: du = numpy.linalg.norm((uiso - u).flatten()) self.assertAlmostEqual(0.0, du, 8) - symcon = SymmetryConstraints(sg186, sum(eau.expandedpos, []), - sum(eau.expandedUijs, [])) + symcon = SymmetryConstraints(sg186, sum(eau.expandedpos, []), sum(eau.expandedUijs, [])) upd = dict(symcon.Upars) - self.assertEqual(2.0, upd['U110']) - self.assertEqual(2.0, upd['U330']) - self.assertEqual(1.0, upd['U120']) - self.assertEqual(0.0, upd['U130']) - uisod = {'U11' : 2.0, 'U22' : 2.0, 'U33' : 2.0, - 'U12' : 1.0, 'U13' : 0.0, 'U23' : 0.0} + self.assertEqual(2.0, upd["U110"]) + self.assertEqual(2.0, upd["U330"]) + self.assertEqual(1.0, upd["U120"]) + self.assertEqual(0.0, upd["U130"]) + uisod = {"U11": 2.0, "U22": 2.0, "U33": 2.0, "U12": 1.0, "U13": 0.0, "U23": 0.0} for ufms in symcon.UFormulas(): for n, fm in ufms.items(): self.assertEqual(uisod[n], eval(fm, upd)) return - def test_UFormula_self_reference(self): "Ensure U formulas have no self reference such as U13=0.5*U13." for g in self.generators.values(): - badformulas = [(n, fm) for n, fm in g.UFormula(g.xyz).items() - if n in fm and n != fm] + badformulas = [(n, fm) for n, fm in g.UFormula(g.xyz).items() if n in fm and n != fm] self.assertEqual([], badformulas) return - def test__findUParameters(self): - """check GeneratorSite._findUParameters() - """ + """check GeneratorSite._findUParameters()""" # by default all Uparameters equal zero, this would fail for NaNs for gen in TestGeneratorSite.generators.values(): for usym, uval in gen.Uparameters: @@ -381,22 +365,23 @@ def test__findUParameters(self): sg117 = GetSpaceGroup(117) g117h = GeneratorSite(sg117, self.g117h.xyz, Uij) upd = dict(g117h.Uparameters) - self.assertEqual(1, upd['U11']) - self.assertEqual(2, upd['U33']) - self.assertEqual(3, upd['U12']) - self.assertEqual(4, upd['U13']) + self.assertEqual(1, upd["U11"]) + self.assertEqual(2, upd["U33"]) + self.assertEqual(3, upd["U12"]) + self.assertEqual(4, upd["U13"]) return def test_eqIndex(self): - """check GeneratorSite.eqIndex() - """ + """check GeneratorSite.eqIndex()""" self.assertEqual(13, self.g227oc.eqIndex(self.g227oc.eqxyz[13])) return + # End of class TestGeneratorSite # ---------------------------------------------------------------------------- + class TestSymmetryConstraints(unittest.TestCase): def setUp(self): @@ -406,8 +391,7 @@ def tearDown(self): return def test___init__(self): - """check SymmetryConstraints.__init__() - """ + """check SymmetryConstraints.__init__()""" sg225 = GetSpaceGroup(225) # initialize from nested lists and arrays from ExpandAsymmetricUnit eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) @@ -431,8 +415,7 @@ def test___init__(self): return def test_corepos(self): - """test_corepos - find positions in the asymmetric unit. - """ + """test_corepos - find positions in the asymmetric unit.""" sg225 = GetSpaceGroup(225) corepos = [[0, 0, 0], [0.1, 0.13, 0.17]] eau = ExpandAsymmetricUnit(sg225, corepos) @@ -444,12 +427,11 @@ def test_corepos(self): mapped_count = sum(len(idcs) for idcs in sc.coremap.values()) self.assertEqual(len(sc.positions), mapped_count) self.assertTrue(sc.coremap[0] == list(range(4))) - self.assertTrue(sc.coremap[4] == list(range(4, 4+192))) + self.assertTrue(sc.coremap[4] == list(range(4, 4 + 192))) return def test_Uisotropy(self): - """check isotropy value for ADP-s at specified sites. - """ + """check isotropy value for ADP-s at specified sites.""" sg225 = GetSpaceGroup(225) corepos = [[0, 0, 0], [0.1, 0.13, 0.17]] eau = ExpandAsymmetricUnit(sg225, corepos) @@ -458,34 +440,33 @@ def test_Uisotropy(self): self.assertEqual(4 * [True] + 192 * [False], sc.Uisotropy) return -# def test__findConstraints(self): -# """check SymmetryConstraints._findConstraints() -# """ -# return -# -# def test_posparSymbols(self): -# """check SymmetryConstraints.posparSymbols() -# """ -# return -# -# def test_posparValues(self): -# """check SymmetryConstraints.posparValues() -# """ -# return -# -# def test_positionFormulas(self): -# """check SymmetryConstraints.positionFormulas() -# """ -# return -# -# def test_positionFormulasPruned(self): -# """check SymmetryConstraints.positionFormulasPruned() -# """ -# return -# + # def test__findConstraints(self): + # """check SymmetryConstraints._findConstraints() + # """ + # return + # + # def test_posparSymbols(self): + # """check SymmetryConstraints.posparSymbols() + # """ + # return + # + # def test_posparValues(self): + # """check SymmetryConstraints.posparValues() + # """ + # return + # + # def test_positionFormulas(self): + # """check SymmetryConstraints.positionFormulas() + # """ + # return + # + # def test_positionFormulasPruned(self): + # """check SymmetryConstraints.positionFormulasPruned() + # """ + # return + # def test_UparSymbols(self): - """check SymmetryConstraints.UparSymbols() - """ + """check SymmetryConstraints.UparSymbols()""" sg1 = GetSpaceGroup(1) sg225 = GetSpaceGroup(225) pos = [[0, 0, 0]] @@ -493,19 +474,16 @@ def test_UparSymbols(self): sc1 = SymmetryConstraints(sg1, pos, Uijs) self.assertEqual(6, len(sc1.UparSymbols())) sc225 = SymmetryConstraints(sg225, pos, Uijs) - self.assertEqual(['U110'], sc225.UparSymbols()) + self.assertEqual(["U110"], sc225.UparSymbols()) return def test_UparValues(self): - """check SymmetryConstraints.UparValues() - """ + """check SymmetryConstraints.UparValues()""" places = 12 sg1 = GetSpaceGroup(1) sg225 = GetSpaceGroup(225) pos = [[0, 0, 0]] - Uijs = [[[0.1, 0.4, 0.5], - [0.4, 0.2, 0.6], - [0.5, 0.6, 0.3]]] + Uijs = [[[0.1, 0.4, 0.5], [0.4, 0.2, 0.6], [0.5, 0.6, 0.3]]] sc1 = SymmetryConstraints(sg1, pos, Uijs) duv = 0.1 * numpy.arange(1, 7) - sc1.UparValues() self.assertAlmostEqual(0, max(numpy.fabs(duv)), places) @@ -514,6 +492,7 @@ def test_UparValues(self): self.assertAlmostEqual(0.2, sc225.UparValues()[0], places) return + # def test_UFormulas(self): # """check SymmetryConstraints.UFormulas() # """ @@ -528,5 +507,5 @@ def test_UparValues(self): # ---------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/src/diffpy/structure/tests/testutils.py b/src/diffpy/structure/tests/testutils.py index 572fc537..18d64dbd 100644 --- a/src/diffpy/structure/tests/testutils.py +++ b/src/diffpy/structure/tests/testutils.py @@ -18,7 +18,9 @@ # helper functions + def datafile(filename): from pkg_resources import resource_filename + rv = resource_filename(__name__, "testdata/" + filename) return rv diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 33b83b20..d37127b2 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -16,8 +16,8 @@ """Small shared functions. """ -import six import numpy +import six if six.PY2: from collections import Iterable as _Iterable @@ -42,20 +42,22 @@ def isfloat(s): def atomBareSymbol(smbl): - '''Remove atom type string stripped of isotope and ion charge symbols. + """Remove atom type string stripped of isotope and ion charge symbols. This removes blank and leading [0-9-] or trailing [1-9][+-] characters. smbl -- atom type string such as "Cl-", "Ca2+" or "12-C". Return bare element symbol. - ''' - rv = smbl.strip().lstrip('0123456789-').rstrip('123456789+-') + """ + rv = smbl.strip().lstrip("0123456789-").rstrip("123456789+-") return rv + # Helpers for the Structure class -------------------------------------------- + def _linkAtomAttribute(attrname, doc, toarray=numpy.array): - '''Create property wrapper that maps the specified atom attribute. + """Create property wrapper that maps the specified atom attribute. The returned property object provides convenient access to atom attributes from the owner Structure class. @@ -71,13 +73,16 @@ def _linkAtomAttribute(attrname, doc, toarray=numpy.array): Use `numpy.char.array` for string attributes. Return a property object. - ''' + """ from itertools import repeat from operator import setitem + _all = slice(None) + def fget(self): va = toarray([getattr(a, attrname) for a in self]) return va + def fset(self, value): n = len(self) if n == 0: @@ -96,5 +101,6 @@ def fset(self, value): for a, v in zip(self, genvalues): setvalue(a, v) return + rv = property(fget, fset, doc=doc) return rv From 2a8e6edb9bc97f16c14438739a2c7204213f0d55 Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:20:29 -0400 Subject: [PATCH 023/226] Create environment.yml --- environment.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 environment.yml diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..c7cd23cd --- /dev/null +++ b/environment.yml @@ -0,0 +1,6 @@ +name: diffpy.structure +channels: + - conda-forge +dependencies: + - python=3 + - pip From caa23fb72713148eb4dc937eb6b4f2b7642c4a6a Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:12:25 -0400 Subject: [PATCH 024/226] Update run.txt --- requirements/run.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements/run.txt b/requirements/run.txt index e69de29b..5413a934 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -0,0 +1,2 @@ +numpy +pycifrw From 0a4a90962d8299a8bf7da184443ee9f44f5f0f57 Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:14:20 -0400 Subject: [PATCH 025/226] Update run.txt Add six (for python 2 compat) --- requirements/run.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/run.txt b/requirements/run.txt index 5413a934..55464e61 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -1,2 +1,3 @@ numpy pycifrw +six From 33ed0e9a6391d4de51606d154a1fb264628fd54f Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:27:44 -0400 Subject: [PATCH 026/226] Update lattice.py --- src/diffpy/structure/lattice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 4924850b..0139495e 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -25,7 +25,7 @@ import numpy import numpy.linalg as numalg -from diffpy.structure import LatticeError +from diffpy.structure.structureerrors import LatticeError # Helper Functions ----------------------------------------------------------- From 75470c36d6a71b5105765b03521427b4d05a17ec Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:31:03 -0400 Subject: [PATCH 027/226] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c0551e76..5d10bd1f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,6 +49,6 @@ jobs: shell: bash -l {0} run: | conda activate test - coverage run -m pytest -vv -s + coverage run -m diffpy.structure.tests.run coverage report -m codecov From 4a6f2427106200b9a4b1ceebab7155bc91556350 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 3 Jul 2024 21:31:21 -0400 Subject: [PATCH 028/226] copy paste old readme requirements part --- README.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.rst b/README.rst index 5dd3a227..2fe46560 100644 --- a/README.rst +++ b/README.rst @@ -63,6 +63,28 @@ by citing the following paper in your publication: `__, *Acta Crystallogr. A* **71**, 562-568 (2015). +Requirements +------------------------------------------------------------------------ + +The diffpy.structure package requires Python 3.7 or later or 2.7 and +the following software: + +* ``setuptools`` - software distribution tools for Python +* ``NumPy`` - numerical mathematics and fast array operations for Python + +We recommend to use `Anaconda Python `_ +as it allows to install all software dependencies together with +diffpy.structure. For other Python distributions it is necessary to +install the required software separately. As an example on Ubuntu +Linux the required software can be installed with :: + + sudo aptitude install python3-setuptools python3-numpy + +diffpy.structure also uses the +`PyCifRW `_ +library, which is automatically deployed during the +installation process. + Installation ------------ From 525c4d498b7d145915bca3dbcb12e8daa88fba44 Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:33:17 -0400 Subject: [PATCH 029/226] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5d10bd1f..3ceb7a6a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,7 +44,7 @@ jobs: conda activate test conda install --file requirements/run.txt conda install --file requirements/test.txt - pip install . + pip install -e . - name: Validate diffpy.structure shell: bash -l {0} run: | From 08fa02130725f6cace4c2577b1841a132fc347f5 Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:36:24 -0400 Subject: [PATCH 030/226] Update run.txt --- requirements/run.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/run.txt b/requirements/run.txt index 55464e61..cdc2699e 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -1,3 +1,3 @@ -numpy +numpy < 2.0.0 # Need to fix deprecations before 2.0.0 compat pycifrw six From 5635ff449ed5ec3f04f44b6c51e5bc4dd5570dc1 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 4 Jul 2024 15:43:12 -0400 Subject: [PATCH 031/226] remove pre-commit.yml --- .github/workflows/pre-commit.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/pre-commit.yml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml deleted file mode 100644 index f2ff7e42..00000000 --- a/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: pre-commit - -on: - pull_request: - push: - workflow_dispatch: - -jobs: - pre-commit: - # pull requests are a duplicate of a branch push if within the same repo. - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - - uses: pre-commit/action@v3.0.0 - with: - extra_args: --all-files From 7bed9c259df3bac101e28bab38f35153a98c8e99 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 4 Jul 2024 17:20:20 -0400 Subject: [PATCH 032/226] flake8 fixes --- devutils/makesdist | 3 +- src/diffpy/structure/__init__.py | 8 +- src/diffpy/structure/mmlibspacegroups.py | 12 +- src/diffpy/structure/parsers/p_cif.py | 4 +- src/diffpy/structure/parsers/p_pdffit.py | 30 +- src/diffpy/structure/parsers/p_rawxyz.py | 2 +- src/diffpy/structure/parsers/p_xcfg.py | 4 +- src/diffpy/structure/parsers/p_xyz.py | 2 +- src/diffpy/structure/spacegroupmod.py | 12 +- src/diffpy/structure/spacegroups.py | 332 +++++++++--------- src/diffpy/structure/structure.py | 9 +- src/diffpy/structure/symmetryutilities.py | 6 +- src/diffpy/structure/tests/testlattice.py | 5 +- src/diffpy/structure/tests/testp_cif.py | 2 +- src/diffpy/structure/tests/testparsers.py | 2 +- .../structure/tests/testsymmetryutilities.py | 2 +- src/diffpy/structure/utils.py | 6 +- 17 files changed, 221 insertions(+), 220 deletions(-) diff --git a/devutils/makesdist b/devutils/makesdist index e77257ea..ed18ef7d 100755 --- a/devutils/makesdist +++ b/devutils/makesdist @@ -10,12 +10,11 @@ import os import subprocess import sys import tarfile +from setup import FALLBACK_VERSION, versiondata BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) sys.path.insert(0, BASEDIR) -from setup import FALLBACK_VERSION, versiondata - timestamp = versiondata.getint("DEFAULT", "timestamp") vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 377a1991..ba993ba0 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -32,14 +32,13 @@ from diffpy.structure.pdffitstructure import PDFFitStructure from diffpy.structure.structure import Structure from diffpy.structure.structureerrors import LatticeError, StructureFormatError, SymmetryError - -# obtain version information - -"""Crystal structure container and parsers for structure formats.""" +from diffpy.structure.parsers import getParser # package version from diffpy.structure.version import __version__ +"""Crystal structure container and parsers for structure formats.""" + # top level routines @@ -68,7 +67,6 @@ def loadStructure(filename, fmt="auto", **kw): Return a more specific PDFFitStructure type for 'pdffit' and 'discus' formats. """ - from diffpy.structure.parsers import getParser p = getParser(fmt, **kw) rv = p.parseFile(filename) diff --git a/src/diffpy/structure/mmlibspacegroups.py b/src/diffpy/structure/mmlibspacegroups.py index 33f284d3..29e5dd0b 100644 --- a/src/diffpy/structure/mmlibspacegroups.py +++ b/src/diffpy/structure/mmlibspacegroups.py @@ -1,8 +1,8 @@ #!/usr/bin/env python -## Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ -## This code is part of the PyMMLib distribution and governed by -## its license. Please see the LICENSE_pymmlib file that should have been -## included as part of this package. +# Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ +# This code is part of the PyMMLib distribution and governed by +# its license. Please see the LICENSE_pymmlib file that should have been +# included as part of this package. """Space groups defined as a part of the pymmlib. """ @@ -107,7 +107,7 @@ Tr_34_34_34, ) -## spacegroup definitions +# spacegroup definitions sg1 = SpaceGroup( number=1, num_sym_equiv=1, @@ -7884,7 +7884,7 @@ ) -## list of the space groups +# list of the space groups mmLibSpaceGroupList = [ sg1, sg2, diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index fe87865c..141566a5 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -460,7 +460,7 @@ def _parse_atom_site_aniso_label(self, block): break idx = self.labelindex[lb] a = self.stru[idx] - if not lb in self.anisotropy: + if lb not in self.anisotropy: a.anisotropy = True self.anisotropy[lb] = True for fset, val in zip(prop_setters, values): @@ -544,7 +544,7 @@ def _expandAsymmetricUnit(self, block): # setup anisotropy according to symmetry requirements # unless it was already explicitly set for ca, uisotropy in zip(self.stru, self.eau.Uisotropy): - if not ca.label in self.anisotropy: + if ca.label not in self.anisotropy: ca.anisotropy = not uisotropy self.anisotropy[ca.label] = ca.anisotropy # build a nested list of new atoms: diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index c01b9f05..3d52d47d 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -54,17 +54,17 @@ def parseLines(self, lines): stop -= 1 ilines = iter(lines[:stop]) # read header of PDFFit file - for l in ilines: + for line in ilines: p_nl += 1 - words = l.split() + words = line.split() if len(words) == 0 or words[0][0] == "#": continue elif words[0] == "title": - stru.title = l.lstrip()[5:].strip() + stru.title = line.lstrip()[5:].strip() elif words[0] == "scale": stru.pdffit["scale"] = float(words[1]) elif words[0] == "sharp": - l1 = l.replace(",", " ") + l1 = line.replace(",", " ") sharp_pars = [float(w) for w in l1.split()[1:]] if len(sharp_pars) < 4: stru.pdffit["delta2"] = sharp_pars[0] @@ -77,21 +77,21 @@ def parseLines(self, lines): stru.pdffit["rcut"] = sharp_pars[3] elif words[0] == "spcgr": key = "spcgr" - start = l.find(key) + len(key) - value = l[start:].strip() + start = line.find(key) + len(key) + value = line[start:].strip() stru.pdffit["spcgr"] = value elif words[0] == "shape": - self._parse_shape(l) + self._parse_shape(line) elif words[0] == "cell": cell_line_read = True - l1 = l.replace(",", " ") + l1 = line.replace(",", " ") latpars = [float(w) for w in l1.split()[1:7]] stru.lattice = Lattice(*latpars) elif words[0] == "dcell": - l1 = l.replace(",", " ") + l1 = line.replace(",", " ") stru.pdffit["dcell"] = [float(w) for w in l1.split()[1:7]] elif words[0] == "ncell": - l1 = l.replace(",", " ") + l1 = line.replace(",", " ") stru.pdffit["ncell"] = [int(w) for w in l1.split()[1:5]] elif words[0] == "format": if words[1] != "pdffit": @@ -100,7 +100,7 @@ def parseLines(self, lines): elif words[0] == "atoms" and cell_line_read: break else: - self.ignored_lines.append(l) + self.ignored_lines.append(line) # Header reading finished, check if required lines were present. if not cell_line_read: emsg = "%d: file is not in PDFfit format" % p_nl @@ -108,9 +108,9 @@ def parseLines(self, lines): # Load data from atom entries. p_natoms = reduce(lambda x, y: x * y, stru.pdffit["ncell"]) # we are now inside data block - for l in ilines: + for line in ilines: p_nl += 1 - wl1 = l.split() + wl1 = line.split() element = wl1[0][0].upper() + wl1[0][1:].lower() xyz = [float(w) for w in wl1[1:4]] occ = float(wl1[4]) @@ -176,8 +176,8 @@ def toLines(self, stru): d_sigo = 0.0 d_sigU = numpy.zeros((3, 3), dtype=float) # here we can start - l = "title " + stru.title - lines.append(l.strip()) + line = "title " + stru.title + lines.append(line.strip()) lines.append("format pdffit") lines.append("scale %9.6f" % stru_pdffit["scale"]) lines.append( diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index efbd095b..4afbf7b0 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -40,7 +40,7 @@ def parseLines(self, lines): Return Structure object or raise StructureFormatError. """ - linefields = [l.split() for l in lines] + linefields = [line.split() for line in lines] # prepare output structure stru = Structure() # find first valid record diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 252571fc..080a9f64 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -215,12 +215,12 @@ def parseLines(self, lines): else: break # check header for consistency - if numpy.any(xcfg_H0_set == False): + if not numpy.all(xcfg_H0_set): emsg = "H0 tensor is not properly defined" raise StructureFormatError(emsg) p_auxnum = len(p_auxiliary) and max(p_auxiliary.keys()) + 1 for i in range(p_auxnum): - if not i in p_auxiliary: + if i not in p_auxiliary: p_auxiliary[i] = "aux%d" % i sorted_aux_keys = sorted(p_auxiliary.keys()) if p_auxnum != 0: diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index 16bdd319..f73e91b9 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -40,7 +40,7 @@ def parseLines(self, lines): Return Structure object or raise StructureFormatError. """ - linefields = [l.split() for l in lines] + linefields = [line.split() for line in lines] # prepare output structure stru = Structure() # find first valid record diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 7a20ba15..091f305d 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -1,14 +1,14 @@ #!/usr/bin/env python -## Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ -## This code is part of the PyMMLib distribution and governed by -## its license. Please see the LICENSE_pymmlib file that should have been -## included as part of this package. +# Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ +# This code is part of the PyMMLib distribution and governed by +# its license. Please see the LICENSE_pymmlib file that should have been +# included as part of this package. """Symmetry operations as functions on vectors or arrays. """ import numpy -## 64 unique rotation matricies +# 64 unique rotation matricies Rot_Z_mY_X = numpy.array([[0.0, 0.0, 1.0], [0.0, -1.0, 0.0], [1.0, 0.0, 0.0]], float) Rot_Y_mX_mZ = numpy.array([[0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) Rot_XmY_X_mZ = numpy.array([[1.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) @@ -74,7 +74,7 @@ Rot_mZ_X_mY = numpy.array([[0.0, 0.0, -1.0], [1.0, 0.0, 0.0], [0.0, -1.0, 0.0]], float) Rot_Y_X_Z = numpy.array([[0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]], float) -## 32 unique translation vectors +# 32 unique translation vectors Tr_0_0_34 = numpy.array([0.0, 0.0, 3.0 / 4.0], float) Tr_12_0_34 = numpy.array([1.0 / 2.0, 0.0, 3.0 / 4.0], float) Tr_0_0_56 = numpy.array([0.0, 0.0, 5.0 / 6.0], float) diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index b864e9c5..aae9f5a7 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -22,172 +22,8 @@ from diffpy.structure.sgtbxspacegroups import sgtbxSpaceGroupList from diffpy.structure.spacegroupmod import SpaceGroup, SymOp -# all spacegroup definitions -SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList - - -def GetSpaceGroup(sgid): - """Returns the SpaceGroup instance for the given identifier. - - sgid -- space group symbol, either short_name or pdb_name, - whatever it means in mmlib. Can be also an integer. - - Return space group instance. - Raise ValueError when not found. - """ - if not _sg_lookup_table: - _buildSGLookupTable() - if sgid in _sg_lookup_table: - return _sg_lookup_table[sgid] - # Try different versions of sgid, first make sure it is a string - emsg = "Unknown space group identifier %r" % sgid - if not isinstance(sgid, six.string_types): - raise ValueError(emsg) - sgbare = sgid.strip() - # short_name case adjusted - sgkey = sgbare.replace(" ", "") - sgkey = sgkey[:1].upper() + sgkey[1:].lower() - if sgkey in _sg_lookup_table: - return _sg_lookup_table[sgkey] - # pdb_name case adjusted - sgkey = sgbare[:1].upper() + sgbare[1:].lower() - if sgkey in _sg_lookup_table: - return _sg_lookup_table[sgkey] - # nothing worked, sgid is unknown identifier - raise ValueError(emsg) - - -def IsSpaceGroupIdentifier(sgid): - """Check if identifier can be used as an argument to GetSpaceGroup. - - Return bool. - """ - try: - GetSpaceGroup(sgid) - rv = True - except ValueError: - rv = False - return rv - - -def FindSpaceGroup(symops, shuffle=False): - """Lookup SpaceGroup from a given list of symmetry operations. - - Parameters - ---------- - symops : list - The list of `SymOp` objects for which to find SpaceGroup. - shuffle : bool, optional - Flag for allowing different order of symops in the returned - SpaceGroup. The default is ``False``. - - Returns - ------- - SpaceGroup - The SpaceGroup object with equivalent list of symmetry - operations. Return predefined SpaceGroup instance when - symmetry operations have the same order or when the - `shuffle` flag is set. - - Raises - ------ - ValueError - When `symops` do not match any known SpaceGroup. - """ - import copy - - from six.moves import zip_longest - - tb = _getSGHashLookupTable() - hh = _hashSymOpList(symops) - if not hh in tb: - raise ValueError("Cannot find SpaceGroup for the specified symops.") - rv = tb[hh] - if not shuffle: - zz = zip_longest(rv.iter_symops(), symops, fillvalue="") - sameorder = all(str(o0) == str(o1) for o0, o1 in zz) - if not sameorder: - rv = copy.copy(rv) - rv.symop_list = symops - return rv - - -def _hashSymOpList(symops): - """Return hash value for a sequence of `SymOp` objects. - - The symops are sorted so the results is independent of symops order. - - Parameters - ---------- - symops : sequence - The sequence of `SymOp` objects to be hashed - - Returns - ------- - int - The hash value. - """ - ssop = sorted(str(o) for o in symops) - rv = hash(tuple(ssop)) - return rv - - -def _buildSGLookupTable(): - """Rebuild space group lookup table from the SpaceGroupList data. - - This routine updates the global _sg_lookup_table dictionary. - No return value. - """ - _sg_lookup_table.clear() - for sg in SpaceGroupList: - _sg_lookup_table.setdefault(sg.number, sg) - _sg_lookup_table.setdefault(str(sg.number), sg) - _sg_lookup_table.setdefault(sg.short_name, sg) - _sg_lookup_table.setdefault(sg.pdb_name, sg) - # extra aliases obtained from matching code in - # cctbx::sgtbx::symbols::find_main_symbol_dict_entry - alias_hmname = [ - ("Pm3", "P m -3"), - ("Pn3", "P n -3"), - ("Fm3", "F m -3"), - ("Fd3", "F d -3"), - ("Im3", "I m -3"), - ("Pa3", "P a -3"), - ("Ia3", "I a -3"), - ("Pm3m", "P m -3 m"), - ("Pn3n", "P n -3 n"), - ("Pm3n", "P m -3 n"), - ("Pn3m", "P n -3 m"), - ("Fm3m", "F m -3 m"), - ("Fm3c", "F m -3 c"), - ("Fd3m", "F d -3 m"), - ("Fd3c", "F d -3 c"), - ("Im3m", "I m -3 m"), - ("Ia3d", "I a -3 d"), - ] - for a, hm in alias_hmname: - hmbare = hm.replace(" ", "") - _sg_lookup_table.setdefault(a, _sg_lookup_table[hmbare]) - # make sure None does not sneak into the dictionary - assert not None in _sg_lookup_table - return - - -_sg_lookup_table = {} - - -def _getSGHashLookupTable(): - """Return lookup table of symop hashes to standard SpaceGroup objects.""" - if _sg_hash_lookup_table: - return _sg_hash_lookup_table - for sg in SpaceGroupList: - h = _hashSymOpList(sg.symop_list) - _sg_hash_lookup_table[h] = sg - assert len(_sg_hash_lookup_table) == len(SpaceGroupList) - return _getSGHashLookupTable() - - -_sg_hash_lookup_table = {} +import copy +from six.moves import zip_longest # Import SpaceGroup objects -------------------------------------------------- @@ -808,6 +644,170 @@ def _getSGHashLookupTable(): Tr_34_34_34, ) +# all spacegroup definitions +SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList + + +def GetSpaceGroup(sgid): + """Returns the SpaceGroup instance for the given identifier. + + sgid -- space group symbol, either short_name or pdb_name, + whatever it means in mmlib. Can be also an integer. + + Return space group instance. + Raise ValueError when not found. + """ + if not _sg_lookup_table: + _buildSGLookupTable() + if sgid in _sg_lookup_table: + return _sg_lookup_table[sgid] + # Try different versions of sgid, first make sure it is a string + emsg = "Unknown space group identifier %r" % sgid + if not isinstance(sgid, six.string_types): + raise ValueError(emsg) + sgbare = sgid.strip() + # short_name case adjusted + sgkey = sgbare.replace(" ", "") + sgkey = sgkey[:1].upper() + sgkey[1:].lower() + if sgkey in _sg_lookup_table: + return _sg_lookup_table[sgkey] + # pdb_name case adjusted + sgkey = sgbare[:1].upper() + sgbare[1:].lower() + if sgkey in _sg_lookup_table: + return _sg_lookup_table[sgkey] + # nothing worked, sgid is unknown identifier + raise ValueError(emsg) + + +def IsSpaceGroupIdentifier(sgid): + """Check if identifier can be used as an argument to GetSpaceGroup. + + Return bool. + """ + try: + GetSpaceGroup(sgid) + rv = True + except ValueError: + rv = False + return rv + + +def FindSpaceGroup(symops, shuffle=False): + """Lookup SpaceGroup from a given list of symmetry operations. + + Parameters + ---------- + symops : list + The list of `SymOp` objects for which to find SpaceGroup. + shuffle : bool, optional + Flag for allowing different order of symops in the returned + SpaceGroup. The default is ``False``. + + Returns + ------- + SpaceGroup + The SpaceGroup object with equivalent list of symmetry + operations. Return predefined SpaceGroup instance when + symmetry operations have the same order or when the + `shuffle` flag is set. + + Raises + ------ + ValueError + When `symops` do not match any known SpaceGroup. + """ + + tb = _getSGHashLookupTable() + hh = _hashSymOpList(symops) + if hh not in tb: + raise ValueError("Cannot find SpaceGroup for the specified symops.") + rv = tb[hh] + if not shuffle: + zz = zip_longest(rv.iter_symops(), symops, fillvalue="") + sameorder = all(str(o0) == str(o1) for o0, o1 in zz) + if not sameorder: + rv = copy.copy(rv) + rv.symop_list = symops + return rv + + +def _hashSymOpList(symops): + """Return hash value for a sequence of `SymOp` objects. + + The symops are sorted so the results is independent of symops order. + + Parameters + ---------- + symops : sequence + The sequence of `SymOp` objects to be hashed + + Returns + ------- + int + The hash value. + """ + ssop = sorted(str(o) for o in symops) + rv = hash(tuple(ssop)) + return rv + + +def _buildSGLookupTable(): + """Rebuild space group lookup table from the SpaceGroupList data. + + This routine updates the global _sg_lookup_table dictionary. + No return value. + """ + _sg_lookup_table.clear() + for sg in SpaceGroupList: + _sg_lookup_table.setdefault(sg.number, sg) + _sg_lookup_table.setdefault(str(sg.number), sg) + _sg_lookup_table.setdefault(sg.short_name, sg) + _sg_lookup_table.setdefault(sg.pdb_name, sg) + # extra aliases obtained from matching code in + # cctbx::sgtbx::symbols::find_main_symbol_dict_entry + alias_hmname = [ + ("Pm3", "P m -3"), + ("Pn3", "P n -3"), + ("Fm3", "F m -3"), + ("Fd3", "F d -3"), + ("Im3", "I m -3"), + ("Pa3", "P a -3"), + ("Ia3", "I a -3"), + ("Pm3m", "P m -3 m"), + ("Pn3n", "P n -3 n"), + ("Pm3n", "P m -3 n"), + ("Pn3m", "P n -3 m"), + ("Fm3m", "F m -3 m"), + ("Fm3c", "F m -3 c"), + ("Fd3m", "F d -3 m"), + ("Fd3c", "F d -3 c"), + ("Im3m", "I m -3 m"), + ("Ia3d", "I a -3 d"), + ] + for a, hm in alias_hmname: + hmbare = hm.replace(" ", "") + _sg_lookup_table.setdefault(a, _sg_lookup_table[hmbare]) + # make sure None does not sneak into the dictionary + assert None not in _sg_lookup_table + return + + +_sg_lookup_table = {} + + +def _getSGHashLookupTable(): + """Return lookup table of symop hashes to standard SpaceGroup objects.""" + if _sg_hash_lookup_table: + return _sg_hash_lookup_table + for sg in SpaceGroupList: + h = _hashSymOpList(sg.symop_list) + _sg_hash_lookup_table[h] = sg + assert len(_sg_hash_lookup_table) == len(SpaceGroupList) + return _getSGHashLookupTable() + + +_sg_hash_lookup_table = {} + # silence pyflakes checker assert all( o is not None diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 2c2f3c89..4a7876c8 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -345,14 +345,15 @@ def extend(self, atoms, copy=None): newatoms = adups else: memo = set(id(a) for a in self) - nextatom = lambda a: (a if id(a) not in memo else copymod.copy(a)) - mark = lambda a: (memo.add(id(a)), a)[-1] + def nextatom(a): return (a if id(a) not in memo else copymod.copy(a)) + def mark(a): return (memo.add(id(a)), a)[-1] newatoms = (mark(nextatom(a)) for a in atoms) elif copy: newatoms = adups else: newatoms = atoms - setlat = lambda a: (setattr(a, "lattice", self.lattice), a)[-1] + + def setlat(a): return (setattr(a, "lattice", self.lattice), a)[-1] super(Structure, self).extend(setlat(a) for a in newatoms) return @@ -489,7 +490,7 @@ def __sub__(self, other): Return new Structure with a copy of Atom instances. """ otherset = set(other) - keepindices = [i for i, a in enumerate(self) if not a in otherset] + keepindices = [i for i, a in enumerate(self) if a not in otherset] rv = copymod.copy(self[keepindices]) return rv diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 5364f04a..efc13782 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -219,7 +219,7 @@ def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): mask = numpy.logical_or(pos < 0.0, pos >= 1.0) pos[mask] -= numpy.floor(pos[mask]) tpl = pos2tuple(pos) - if not tpl in site_symops: + if tpl not in site_symops: pos_is_new = True site_symops[tpl] = [] # double check if there is any position nearby @@ -429,7 +429,7 @@ def _findPosParameters(self): varvalue = txyz[idx] / nvec[idx] txyz = txyz - varvalue * nvec # determine standard parameter name - vname = [s for s in "xyz"[idx:] if not s in usedsymbol][0] + vname = [s for s in "xyz"[idx:] if s not in usedsymbol][0] self.pparameters.append((vname, varvalue)) usedsymbol[vname] = True return @@ -745,7 +745,7 @@ def _findConstraints(self): Usymbols = [smbl + str(i) for i in range(numpos) for smbl in stdUsymbols] independent = set(range(numpos)) for genidx in range(numpos): - if not genidx in independent: + if genidx not in independent: continue # it is a generator self.coremap[genidx] = [] diff --git a/src/diffpy/structure/tests/testlattice.py b/src/diffpy/structure/tests/testlattice.py index 6b539634..b139d805 100644 --- a/src/diffpy/structure/tests/testlattice.py +++ b/src/diffpy/structure/tests/testlattice.py @@ -58,8 +58,9 @@ def test_setLatPar(self): from numpy import dot - norm = lambda x: sqrt(sum([xi**2 for xi in x])) - cosd = lambda x: cos(radians(x)) + def norm(x): return sqrt(sum([xi**2 for xi in x])) + + def cosd(x): return cos(radians(x)) self.lattice.setLatPar(1.0, 2.0, 3.0, 80, 100, 120) base = self.lattice.base self.assertAlmostEqual(1.0, norm(base[0]), self.places) diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/testp_cif.py index 2451a632..ce96b934 100644 --- a/src/diffpy/structure/tests/testp_cif.py +++ b/src/diffpy/structure/tests/testp_cif.py @@ -343,7 +343,7 @@ def test_adp_type_iso(self): def test_adp_aniso_label(self): "verify ADP type setting from _atom_site_aniso_label loop" with open(self.teiciffile) as fp: - lines = [line.replace(" Uani ", " ") for line in fp if not "_atom_site_adp_type" in line] + lines = [line.replace(" Uani ", " ") for line in fp if "_atom_site_adp_type" not in line] ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertTrue(all(stru.anisotropy)) diff --git a/src/diffpy/structure/tests/testparsers.py b/src/diffpy/structure/tests/testparsers.py index 7ebe7d8a..e0f88bb6 100644 --- a/src/diffpy/structure/tests/testparsers.py +++ b/src/diffpy/structure/tests/testparsers.py @@ -226,7 +226,7 @@ def test_rwStr_pdb_CdSe(self): stru.read(datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) # all lines should be 80 characters long - linelens = [len(l) for l in s.split("\n") if l != ""] + linelens = [len(line) for line in s.split("\n") if line != ""] self.assertEqual(linelens, len(linelens) * [80]) # now clean and re-read structure stru = Structure() diff --git a/src/diffpy/structure/tests/testsymmetryutilities.py b/src/diffpy/structure/tests/testsymmetryutilities.py index cbbe57a6..c4de983b 100644 --- a/src/diffpy/structure/tests/testsymmetryutilities.py +++ b/src/diffpy/structure/tests/testsymmetryutilities.py @@ -82,7 +82,7 @@ def test_expandPosition(self): pos, pops, pmult = expandPosition(fcc, [0, 0, 0]) self.assertTrue(numpy.all(pos[0] == 0.0)) self.assertEqual(4, len(pos)) - self.assertEqual(192, sum([len(l) for l in pops])) + self.assertEqual(192, sum([len(line) for line in pops])) self.assertEqual(4, pmult) return diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index d37127b2..795a4db9 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -90,9 +90,11 @@ def fset(self, value): v0 = getattr(self[0], attrname) # replace scalar values, but change array attributes in place if numpy.isscalar(v0): - setvalue = lambda a, v: setattr(a, attrname, v) + + def setvalue(a, v): return setattr(a, attrname, v) else: - setvalue = lambda a, v: setitem(getattr(a, attrname), _all, v) + + def setvalue(a, v): return setitem(getattr(a, attrname), _all, v) # avoid broadcasting if the new value is a scalar if numpy.isscalar(value): genvalues = repeat(value) From bfbc2493869e2576cfc111aa5895af8faa734310 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 4 Jul 2024 17:28:35 -0400 Subject: [PATCH 033/226] fix CI --- src/diffpy/structure/apps/anyeye.py | 2 +- src/diffpy/structure/apps/transtru.py | 3 ++- src/diffpy/structure/parsers/__init__.py | 2 +- src/diffpy/structure/parsers/p_auto.py | 2 +- src/diffpy/structure/parsers/p_cif.py | 3 ++- src/diffpy/structure/parsers/p_discus.py | 3 ++- src/diffpy/structure/parsers/p_pdb.py | 3 ++- src/diffpy/structure/parsers/p_pdffit.py | 3 ++- src/diffpy/structure/parsers/p_rawxyz.py | 3 ++- src/diffpy/structure/parsers/p_xcfg.py | 3 ++- src/diffpy/structure/parsers/p_xyz.py | 3 ++- src/diffpy/structure/tests/testloadstructure.py | 3 ++- src/diffpy/structure/tests/testp_cif.py | 3 ++- src/diffpy/structure/tests/testp_discus.py | 3 ++- src/diffpy/structure/tests/testp_pdffit.py | 3 ++- src/diffpy/structure/tests/testparsers.py | 3 ++- 16 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index ff98a0c0..4466f93f 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -40,7 +40,7 @@ import signal import sys -from diffpy.structure import StructureFormatError +from diffpy.structure.structureerrors import StructureFormatError # parameter dictionary pd = { diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 902cb237..cb81f54b 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -35,7 +35,8 @@ import sys -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError def usage(style=None): diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 142a31ca..8bea2013 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -31,7 +31,7 @@ outputFormats -- list of available output formats """ -from diffpy.structure import StructureFormatError +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers.parser_index_mod import parser_index from diffpy.structure.parsers.structureparser import StructureParser diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 2142666b..578763a4 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -20,7 +20,7 @@ import os -from diffpy.structure import StructureFormatError +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser, parser_index diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 141566a5..f8d77db9 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -25,7 +25,8 @@ import numpy import six -from diffpy.structure import Atom, Lattice, Structure, StructureFormatError +from diffpy.structure import Atom, Lattice, Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser # ---------------------------------------------------------------------------- diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 0d8014f9..745295b6 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -21,7 +21,8 @@ import six -from diffpy.structure import Lattice, PDFFitStructure, StructureFormatError +from diffpy.structure import Lattice, PDFFitStructure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 3f6574ce..1b3c1252 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -27,7 +27,8 @@ import six from numpy import pi -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 3d52d47d..e6c1935e 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -22,7 +22,8 @@ import numpy import six -from diffpy.structure import Lattice, PDFFitStructure, StructureFormatError +from diffpy.structure import Lattice, PDFFitStructure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index 4afbf7b0..7e7716ad 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -22,7 +22,8 @@ import six -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser from diffpy.structure.utils import isfloat diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 080a9f64..a8b961e5 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -21,7 +21,8 @@ import numpy import six -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser from diffpy.structure.utils import isfloat diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index f73e91b9..c7ee7862 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -23,7 +23,8 @@ import six -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser diff --git a/src/diffpy/structure/tests/testloadstructure.py b/src/diffpy/structure/tests/testloadstructure.py index f5bbd470..92bd4c7f 100644 --- a/src/diffpy/structure/tests/testloadstructure.py +++ b/src/diffpy/structure/tests/testloadstructure.py @@ -5,7 +5,8 @@ import unittest -from diffpy.structure import PDFFitStructure, Structure, StructureFormatError, loadStructure +from diffpy.structure import PDFFitStructure, Structure, loadStructure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.tests.testutils import datafile diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/testp_cif.py index ce96b934..01f83b85 100644 --- a/src/diffpy/structure/tests/testp_cif.py +++ b/src/diffpy/structure/tests/testp_cif.py @@ -21,7 +21,8 @@ import numpy import six -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import getParser from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float from diffpy.structure.tests.testutils import datafile diff --git a/src/diffpy/structure/tests/testp_discus.py b/src/diffpy/structure/tests/testp_discus.py index 5f30a42f..43c44ea5 100644 --- a/src/diffpy/structure/tests/testp_discus.py +++ b/src/diffpy/structure/tests/testp_discus.py @@ -19,7 +19,8 @@ import re import unittest -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.parsers import StructureFormatError from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- diff --git a/src/diffpy/structure/tests/testp_pdffit.py b/src/diffpy/structure/tests/testp_pdffit.py index cd9b21de..586ca413 100644 --- a/src/diffpy/structure/tests/testp_pdffit.py +++ b/src/diffpy/structure/tests/testp_pdffit.py @@ -21,7 +21,8 @@ import numpy -from diffpy.structure import Structure, StructureFormatError +from diffpy.structure import Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- diff --git a/src/diffpy/structure/tests/testparsers.py b/src/diffpy/structure/tests/testparsers.py index e0f88bb6..91f0e085 100644 --- a/src/diffpy/structure/tests/testparsers.py +++ b/src/diffpy/structure/tests/testparsers.py @@ -23,7 +23,8 @@ import numpy -from diffpy.structure import Atom, Lattice, Structure, StructureFormatError +from diffpy.structure import Atom, Lattice, Structure +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- From f61364761ece0f38ae61fddcbddb026f682da805 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:29:05 +0000 Subject: [PATCH 034/226] [pre-commit.ci] auto fixes from pre-commit hooks --- devutils/makesdist | 1 + src/diffpy/structure/__init__.py | 2 +- src/diffpy/structure/parsers/__init__.py | 2 +- src/diffpy/structure/parsers/p_auto.py | 2 +- src/diffpy/structure/parsers/p_cif.py | 2 +- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 2 +- src/diffpy/structure/parsers/p_pdffit.py | 2 +- src/diffpy/structure/parsers/p_rawxyz.py | 2 +- src/diffpy/structure/parsers/p_xcfg.py | 2 +- src/diffpy/structure/parsers/p_xyz.py | 2 +- src/diffpy/structure/spacegroups.py | 17 +++++++++-------- src/diffpy/structure/structure.py | 13 ++++++++++--- src/diffpy/structure/tests/testlattice.py | 7 +++++-- src/diffpy/structure/tests/testp_cif.py | 2 +- src/diffpy/structure/utils.py | 8 ++++++-- 16 files changed, 42 insertions(+), 26 deletions(-) diff --git a/devutils/makesdist b/devutils/makesdist index ed18ef7d..dccfaa99 100755 --- a/devutils/makesdist +++ b/devutils/makesdist @@ -10,6 +10,7 @@ import os import subprocess import sys import tarfile + from setup import FALLBACK_VERSION, versiondata BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index ba993ba0..7bc43afe 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -29,10 +29,10 @@ from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice +from diffpy.structure.parsers import getParser from diffpy.structure.pdffitstructure import PDFFitStructure from diffpy.structure.structure import Structure from diffpy.structure.structureerrors import LatticeError, StructureFormatError, SymmetryError -from diffpy.structure.parsers import getParser # package version from diffpy.structure.version import __version__ diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 8bea2013..0924ff23 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -31,9 +31,9 @@ outputFormats -- list of available output formats """ -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers.parser_index_mod import parser_index from diffpy.structure.parsers.structureparser import StructureParser +from diffpy.structure.structureerrors import StructureFormatError # silence pyflakes checker assert StructureParser diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 578763a4..96409453 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -20,8 +20,8 @@ import os -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser, parser_index +from diffpy.structure.structureerrors import StructureFormatError class P_auto(StructureParser): diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index f8d77db9..bac14f55 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -26,8 +26,8 @@ import six from diffpy.structure import Atom, Lattice, Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError # ---------------------------------------------------------------------------- diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 745295b6..101801be 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -22,8 +22,8 @@ import six from diffpy.structure import Lattice, PDFFitStructure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError class P_discus(StructureParser): diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 1b3c1252..11ff9a43 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -28,8 +28,8 @@ from numpy import pi from diffpy.structure import Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError class P_pdb(StructureParser): diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index e6c1935e..659851e0 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -23,8 +23,8 @@ import six from diffpy.structure import Lattice, PDFFitStructure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError class P_pdffit(StructureParser): diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index 7e7716ad..ee199cca 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -23,8 +23,8 @@ import six from diffpy.structure import Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index a8b961e5..bbf44e83 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -22,8 +22,8 @@ import six from diffpy.structure import Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat # Constants ------------------------------------------------------------------ diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index c7ee7862..2985aa7a 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -24,8 +24,8 @@ import six from diffpy.structure import Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError class P_xyz(StructureParser): diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index aae9f5a7..f0a2957d 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -16,18 +16,13 @@ """Space group classes and definitions from mmLib and sgtbx. """ -import six - -from diffpy.structure.mmlibspacegroups import mmLibSpaceGroupList -from diffpy.structure.sgtbxspacegroups import sgtbxSpaceGroupList -from diffpy.structure.spacegroupmod import SpaceGroup, SymOp - import copy -from six.moves import zip_longest -# Import SpaceGroup objects -------------------------------------------------- +import six +from six.moves import zip_longest from diffpy.structure.mmlibspacegroups import ( + mmLibSpaceGroupList, sg1, sg2, sg3, @@ -544,6 +539,7 @@ sg16015, sg17009, sg17015, + sgtbxSpaceGroupList, ) from diffpy.structure.spacegroupmod import ( Rot_mX_mXY_mZ, @@ -610,6 +606,8 @@ Rot_Z_X_Y, Rot_Z_Y_mX, Rot_Z_Y_X, + SpaceGroup, + SymOp, Tr_0_0_0, Tr_0_0_12, Tr_0_0_13, @@ -644,6 +642,9 @@ Tr_34_34_34, ) +# Import SpaceGroup objects -------------------------------------------------- + + # all spacegroup definitions SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 4a7876c8..30eb3a31 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -345,15 +345,22 @@ def extend(self, atoms, copy=None): newatoms = adups else: memo = set(id(a) for a in self) - def nextatom(a): return (a if id(a) not in memo else copymod.copy(a)) - def mark(a): return (memo.add(id(a)), a)[-1] + + def nextatom(a): + return a if id(a) not in memo else copymod.copy(a) + + def mark(a): + return (memo.add(id(a)), a)[-1] + newatoms = (mark(nextatom(a)) for a in atoms) elif copy: newatoms = adups else: newatoms = atoms - def setlat(a): return (setattr(a, "lattice", self.lattice), a)[-1] + def setlat(a): + return (setattr(a, "lattice", self.lattice), a)[-1] + super(Structure, self).extend(setlat(a) for a in newatoms) return diff --git a/src/diffpy/structure/tests/testlattice.py b/src/diffpy/structure/tests/testlattice.py index b139d805..a2b22d38 100644 --- a/src/diffpy/structure/tests/testlattice.py +++ b/src/diffpy/structure/tests/testlattice.py @@ -58,9 +58,12 @@ def test_setLatPar(self): from numpy import dot - def norm(x): return sqrt(sum([xi**2 for xi in x])) + def norm(x): + return sqrt(sum([xi**2 for xi in x])) + + def cosd(x): + return cos(radians(x)) - def cosd(x): return cos(radians(x)) self.lattice.setLatPar(1.0, 2.0, 3.0, 80, 100, 120) base = self.lattice.base self.assertAlmostEqual(1.0, norm(base[0]), self.places) diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/testp_cif.py index 01f83b85..f066ad75 100644 --- a/src/diffpy/structure/tests/testp_cif.py +++ b/src/diffpy/structure/tests/testp_cif.py @@ -22,9 +22,9 @@ import six from diffpy.structure import Structure -from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.parsers import getParser from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float +from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 795a4db9..823ce9da 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -91,10 +91,14 @@ def fset(self, value): # replace scalar values, but change array attributes in place if numpy.isscalar(v0): - def setvalue(a, v): return setattr(a, attrname, v) + def setvalue(a, v): + return setattr(a, attrname, v) + else: - def setvalue(a, v): return setitem(getattr(a, attrname), _all, v) + def setvalue(a, v): + return setitem(getattr(a, attrname), _all, v) + # avoid broadcasting if the new value is a scalar if numpy.isscalar(value): genvalues = repeat(value) From bab485eb3b85a94e413964561d86ce2f83f98379 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 23 Jul 2024 18:17:38 -0400 Subject: [PATCH 035/226] migrate from pkg_resources to importlib.resources --- src/diffpy/structure/tests/__init__.py | 5 ++--- src/diffpy/structure/tests/{testatom.py => test_atom.py} | 0 .../structure/tests/{testlattice.py => test_lattice.py} | 0 .../tests/{testloadstructure.py => test_loadstructure.py} | 0 .../tests/{testoldimports.py => test_oldimports.py} | 0 src/diffpy/structure/tests/{testp_cif.py => test_p_cif.py} | 0 .../structure/tests/{testp_discus.py => test_p_discus.py} | 0 .../structure/tests/{testp_pdffit.py => test_p_pdffit.py} | 0 .../structure/tests/{testparsers.py => test_parsers.py} | 0 .../tests/{testspacegroups.py => test_spacegroups.py} | 0 .../tests/{teststructure.py => test_structure.py} | 0 .../tests/{testsupercell.py => test_supercell.py} | 0 ...{testsymmetryutilities.py => test_symmetryutilities.py} | 0 src/diffpy/structure/tests/testutils.py | 7 +++---- 14 files changed, 5 insertions(+), 7 deletions(-) rename src/diffpy/structure/tests/{testatom.py => test_atom.py} (100%) rename src/diffpy/structure/tests/{testlattice.py => test_lattice.py} (100%) rename src/diffpy/structure/tests/{testloadstructure.py => test_loadstructure.py} (100%) rename src/diffpy/structure/tests/{testoldimports.py => test_oldimports.py} (100%) rename src/diffpy/structure/tests/{testp_cif.py => test_p_cif.py} (100%) rename src/diffpy/structure/tests/{testp_discus.py => test_p_discus.py} (100%) rename src/diffpy/structure/tests/{testp_pdffit.py => test_p_pdffit.py} (100%) rename src/diffpy/structure/tests/{testparsers.py => test_parsers.py} (100%) rename src/diffpy/structure/tests/{testspacegroups.py => test_spacegroups.py} (100%) rename src/diffpy/structure/tests/{teststructure.py => test_structure.py} (100%) rename src/diffpy/structure/tests/{testsupercell.py => test_supercell.py} (100%) rename src/diffpy/structure/tests/{testsymmetryutilities.py => test_symmetryutilities.py} (100%) diff --git a/src/diffpy/structure/tests/__init__.py b/src/diffpy/structure/tests/__init__.py index fc6afec6..d5b0e873 100644 --- a/src/diffpy/structure/tests/__init__.py +++ b/src/diffpy/structure/tests/__init__.py @@ -35,13 +35,12 @@ def testsuite(pattern=""): The TestSuite object containing the matching tests. """ import re + from importlib import resources as importlib_resources from itertools import chain from os.path import dirname - from pkg_resources import resource_filename - loader = unittest.defaultTestLoader - thisdir = resource_filename(__name__, "") + thisdir = str(importlib_resources.files(__name__)) depth = __name__.count(".") + 1 topdir = thisdir for i in range(depth): diff --git a/src/diffpy/structure/tests/testatom.py b/src/diffpy/structure/tests/test_atom.py similarity index 100% rename from src/diffpy/structure/tests/testatom.py rename to src/diffpy/structure/tests/test_atom.py diff --git a/src/diffpy/structure/tests/testlattice.py b/src/diffpy/structure/tests/test_lattice.py similarity index 100% rename from src/diffpy/structure/tests/testlattice.py rename to src/diffpy/structure/tests/test_lattice.py diff --git a/src/diffpy/structure/tests/testloadstructure.py b/src/diffpy/structure/tests/test_loadstructure.py similarity index 100% rename from src/diffpy/structure/tests/testloadstructure.py rename to src/diffpy/structure/tests/test_loadstructure.py diff --git a/src/diffpy/structure/tests/testoldimports.py b/src/diffpy/structure/tests/test_oldimports.py similarity index 100% rename from src/diffpy/structure/tests/testoldimports.py rename to src/diffpy/structure/tests/test_oldimports.py diff --git a/src/diffpy/structure/tests/testp_cif.py b/src/diffpy/structure/tests/test_p_cif.py similarity index 100% rename from src/diffpy/structure/tests/testp_cif.py rename to src/diffpy/structure/tests/test_p_cif.py diff --git a/src/diffpy/structure/tests/testp_discus.py b/src/diffpy/structure/tests/test_p_discus.py similarity index 100% rename from src/diffpy/structure/tests/testp_discus.py rename to src/diffpy/structure/tests/test_p_discus.py diff --git a/src/diffpy/structure/tests/testp_pdffit.py b/src/diffpy/structure/tests/test_p_pdffit.py similarity index 100% rename from src/diffpy/structure/tests/testp_pdffit.py rename to src/diffpy/structure/tests/test_p_pdffit.py diff --git a/src/diffpy/structure/tests/testparsers.py b/src/diffpy/structure/tests/test_parsers.py similarity index 100% rename from src/diffpy/structure/tests/testparsers.py rename to src/diffpy/structure/tests/test_parsers.py diff --git a/src/diffpy/structure/tests/testspacegroups.py b/src/diffpy/structure/tests/test_spacegroups.py similarity index 100% rename from src/diffpy/structure/tests/testspacegroups.py rename to src/diffpy/structure/tests/test_spacegroups.py diff --git a/src/diffpy/structure/tests/teststructure.py b/src/diffpy/structure/tests/test_structure.py similarity index 100% rename from src/diffpy/structure/tests/teststructure.py rename to src/diffpy/structure/tests/test_structure.py diff --git a/src/diffpy/structure/tests/testsupercell.py b/src/diffpy/structure/tests/test_supercell.py similarity index 100% rename from src/diffpy/structure/tests/testsupercell.py rename to src/diffpy/structure/tests/test_supercell.py diff --git a/src/diffpy/structure/tests/testsymmetryutilities.py b/src/diffpy/structure/tests/test_symmetryutilities.py similarity index 100% rename from src/diffpy/structure/tests/testsymmetryutilities.py rename to src/diffpy/structure/tests/test_symmetryutilities.py diff --git a/src/diffpy/structure/tests/testutils.py b/src/diffpy/structure/tests/testutils.py index 18d64dbd..73b8f081 100644 --- a/src/diffpy/structure/tests/testutils.py +++ b/src/diffpy/structure/tests/testutils.py @@ -18,9 +18,8 @@ # helper functions +from importlib import resources as importlib_resources -def datafile(filename): - from pkg_resources import resource_filename - rv = resource_filename(__name__, "testdata/" + filename) - return rv +def datafile(filename): + return str(importlib_resources.files(__package__).joinpath("testdata/" + filename)) From 98c99337d6fe0beb9da6994de3a5978e4da2c018 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Wed, 24 Jul 2024 11:07:01 -0400 Subject: [PATCH 036/226] remove import as --- src/diffpy/structure/tests/__init__.py | 4 ++-- src/diffpy/structure/tests/testutils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diffpy/structure/tests/__init__.py b/src/diffpy/structure/tests/__init__.py index d5b0e873..98485bde 100644 --- a/src/diffpy/structure/tests/__init__.py +++ b/src/diffpy/structure/tests/__init__.py @@ -35,12 +35,12 @@ def testsuite(pattern=""): The TestSuite object containing the matching tests. """ import re - from importlib import resources as importlib_resources + from importlib import resources from itertools import chain from os.path import dirname loader = unittest.defaultTestLoader - thisdir = str(importlib_resources.files(__name__)) + thisdir = str(resources.files(__name__)) depth = __name__.count(".") + 1 topdir = thisdir for i in range(depth): diff --git a/src/diffpy/structure/tests/testutils.py b/src/diffpy/structure/tests/testutils.py index 73b8f081..461f020d 100644 --- a/src/diffpy/structure/tests/testutils.py +++ b/src/diffpy/structure/tests/testutils.py @@ -18,8 +18,8 @@ # helper functions -from importlib import resources as importlib_resources +from importlib import resources def datafile(filename): - return str(importlib_resources.files(__package__).joinpath("testdata/" + filename)) + return str(resources.files(__package__).joinpath("testdata/" + filename)) From cb0e8bfe9cc57f334928e39d3f23ea57e53df28a Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 26 Jul 2024 13:08:26 -0400 Subject: [PATCH 037/226] modify doc/conf.py, reflect changes in test file --- doc/source/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/source/conf.py b/doc/source/conf.py index f7b1c770..1a169473 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -18,6 +18,8 @@ from importlib.metadata import version from pathlib import Path +autodoc_mock_imports = ["importlib.metadata"] + # 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. From ecf14d45ca9fbe6e998e91332ae29a024e7bd60a Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 26 Jul 2024 20:10:16 -0400 Subject: [PATCH 038/226] Fix docstrings for API reference. --- doc/source/conf.py | 9 ++ src/diffpy/structure/__init__.py | 17 +- src/diffpy/structure/apps/anyeye.py | 39 +++-- src/diffpy/structure/atom.py | 22 +-- .../structure/expansion/makeellipsoid.py | 31 ++-- .../structure/expansion/supercell_mod.py | 27 +++- src/diffpy/structure/lattice.py | 56 +++---- src/diffpy/structure/parsers/p_cif.py | 57 ++++--- src/diffpy/structure/spacegroupmod.py | 16 +- src/diffpy/structure/spacegroups.py | 2 +- src/diffpy/structure/structure.py | 147 ++++++++++++------ src/diffpy/structure/symmetryutilities.py | 135 ++++++++++------ src/diffpy/structure/utils.py | 2 +- 13 files changed, 357 insertions(+), 203 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index f7b1c770..e1402780 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -116,6 +116,11 @@ # Display all warnings for missing links. nitpicky = True +nitpick_ignore = [ + ("py:class", "array_like"), + ("py:class", "Parser"), +] + # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -287,3 +292,7 @@ # Example configuration for intersphinx: refer to the Python standard library. # intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable/", None), +} diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 7bc43afe..8cb5fca9 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -13,15 +13,22 @@ # ############################################################################## -"""classes related to structure of materials +""" +Classes related to the structure of materials. + Classes: Atom + Lattice + Structure + PDFFitStructure Exceptions: StructureFormatError + LatticeError + SymmetryError """ @@ -51,13 +58,13 @@ def loadStructure(filename, fmt="auto", **kw): filename : str Path to the file to be loaded. - fmt : str, optional - Format of the structure file such as 'cif' or 'xyz'. Must be + fmt : str, Optional + Format of the structure file such as 'cif' or 'xyz'. Must be one of the formats listed by the `parsers.inputFormats` function. When 'auto', all supported formats are tried in a sequence. - kw : misc, optional + kw : Optional Extra keyword arguments that are passed to `parsers.getParser` - function. These configure the dedicated Parser object that + function. These configure the dedicated Parser object that is used to read content in filename. Returns diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index 4466f93f..d758cb7e 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -13,24 +13,37 @@ # ############################################################################## -"""anyeye view structure file in atomeye +""" +anyeye view structure file in atomeye + Usage: anyeye [options] strufile -anyeye understands more structure formats than atomeye. It converts strufile -to a temporary XCFG file which is opened in atomeye. Supported file formats: +Anyeye understands more structure formats than atomeye. It converts strufile +to a temporary XCFG file which is opened in atomeye. Supported file formats: inputFormats Options: - -f, --formula override chemical formula in strufile, formula defines - elements in the same order as in strufile, e.g, Na4Cl4 - -w, --watch watch input file for changes - --viewer=VIEWER the structure viewer program, by default "atomeye". - The program will be executed as "VIEWER structurefile" - --formats=FORMATS comma separated list of file formats that are understood - by the VIEWER, by default "xcfg,pdb". Files of other - formats will be converted to the first listed format. - -h, --help display this message and exit - -V, --version show script version and exit + -f, --formula + Override chemical formula in strufile. The formula defines + elements in the same order as in strufile, e.g., Na4Cl4. + + -w, --watch + Watch input file for changes. + + --viewer=VIEWER + The structure viewer program, by default "atomeye". + The program will be executed as "VIEWER structurefile". + + --formats=FORMATS + Comma-separated list of file formats that are understood + by the VIEWER, by default "xcfg,pdb". Files of other + formats will be converted to the first listed format. + + -h, --help + Display this message and exit. + + -V, --version + Show script version and exit. """ from __future__ import print_function diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index 3745d56a..b4454f7e 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -39,27 +39,27 @@ class Atom(object): Parameters ---------- - atype : str or Atom, optional + atype : str or Atom, Optional The string atom type to be set as the `element` attribute. By default an empty string. When of the *Atom* type, create a copy of *atype* and adjust it per other arguments. - xyz : ndarray, optional + xyz : numpy.ndarray, Optional Fractional coordinates within the associated `lattice`. By default ``[0, 0, 0]``. - label : str, optional + label : str, Optional A unique string `label` for referring to this Atom. By default an empty string. - occupancy : float, optional + occupancy : float, Optional The initial `occupancy` of this atom, by default ``1``. - anisotropy : bool, optional + anisotropy : bool, Optional The flag for anisotropic thermal displacements parameters. This overrides `anisotropy` implied by presence of the *U* or *Uisoequiv* arguments. Defaults to ``False`` when not set in any other way. - U : ndarray, optional + U : numpy.ndarray, Optional The 3x3 matrix of anisotropic thermal displacement parameters. When present `anisotropy` defaults to ``True``. - Uisoequiv: float, optional + Uisoequiv: float, Optional The isotropic atomic displacement parameter. The `anisotropy` defaults to ``False`` when present. Only one of the *U* and *Uisoequiv* arguments may be provided at the same time. Assume @@ -72,7 +72,7 @@ class Atom(object): ---------- element : str The string type of the atom. An element or ion symbol. - xyz : ndarray + xyz : numpy.ndarray The fractional coordinates in the associated `lattice`. label : str A unique string label referring to this atom, for example, "C_1". @@ -211,7 +211,7 @@ def __copy__(self, target=None): Parameters ---------- - target : Atom, optional + target : Atom, Optional An already existing Atom object to be updated to a duplicate of this Atom. Create a new Atom object when not specified. This facilitates extension of the `__copy__` method @@ -254,7 +254,7 @@ def __copy__(self, target=None): @property def xyz_cartn(self): """ - ndarray: Atom position in absolute Cartesian coordinates. + numpy.ndarray: Atom position in absolute Cartesian coordinates. This is computed from fractional coordinates `xyz` and the current `lattice` setup. Assignment to *xyz_cartn* or @@ -305,7 +305,7 @@ def anisotropy(self, value): @property def U(self): """ - ndarray : The 3x3 matrix of anisotropic atomic displacements. + numpy.ndarray : The 3x3 matrix of anisotropic atomic displacements. For isotropic displacements (when `anisotropy` is ``False``) assignment to *U* uses only the first ``Unew[0, 0]`` element diff --git a/src/diffpy/structure/expansion/makeellipsoid.py b/src/diffpy/structure/expansion/makeellipsoid.py index bfd3a8e3..8e1456a3 100644 --- a/src/diffpy/structure/expansion/makeellipsoid.py +++ b/src/diffpy/structure/expansion/makeellipsoid.py @@ -36,17 +36,26 @@ def makeSphere(S, radius): def makeEllipsoid(S, a, b=None, c=None): - """Cut a structure out of another one. - - Arguments - S -- A Structure instance - a -- primary equatorial radius (along x-axis) - b -- secondary equatorial radius (along y-axis). If b is None - (default) then it is set equal to a - c -- polar radius (along z-axis). If c is None (default), then it is - set equal to a. - - Returns a new structure instance + """ + Cut a structure out of another one. + + Parameters + ---------- + S : + A Structure instance. + a : + Primary equatorial radius (along x-axis). + b : + Secondary equatorial radius (along y-axis). If b is None + (default), then it is set equal to a. + c : + Polar radius (along z-axis). If c is None (default), then it is + set equal to a. + + Returns + ------- + Structure : + A new structure instance. """ if b is None: b = a diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index d0dc5f0a..938af7d6 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -22,19 +22,32 @@ def supercell(S, mno): - """Perform supercell expansion for a structure. + """ + Perform supercell expansion for a structure. New lattice parameters are multiplied and fractional coordinates divided by corresponding multiplier. New atoms are grouped with their source in the original cell. - S -- an instance of Structure from diffpy.structure. - mno -- sequence of 3 integers for cell multipliers along - the a, b and c axes. + Parameters + ---------- + S : + An instance of Structure from diffpy.structure. + mno : + Sequence of 3 integers for cell multipliers along + the a, b and c axes. + + Returns + ------- + Structure + A new structure instance representing the expanded supercell. - Return a new expanded structure instance. - Raise TypeError when S is not Structure instance. - Raise ValueError for invalid mno argument. + Raises + ------ + TypeError + S is not a Structure instance. + ValueError + Invalid mno argument. """ # check arguments if len(mno) != 3: diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 0139495e..db31f3f3 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -59,7 +59,7 @@ class Lattice(object): Parameters ---------- - a : float or Lattice, optional + a : float or Lattice, Optional The cell length *a*. When present, other cell parameters must be also specified. When of the *Lattice* type, create a duplicate Lattice. @@ -73,32 +73,32 @@ class Lattice(object): The angle between the *b* and *c* axes in degrees. gamma : float The angle between the *a* and *b* axes in degrees. - baserot : array_like, optional + baserot : array_like, Optional The 3x3 rotation matrix of the base vectors with respect to their standard setting. - base : array_like, optional + base : array_like, Optional The 3x3 array of row base vectors. This must be the only argument when present. Attributes ---------- - metrics : ndarray + metrics : numpy.ndarray The metrics tensor. - base : ndarray + base : numpy.ndarray The 3x3 matrix of row base vectors in Cartesian coordinates, which may be rotated, i.e., ``base = stdbase @ baserot``. - stdbase : ndarray + stdbase : numpy.ndarray The 3x3 matrix of row base vectors in standard orientation. - baserot : ndarray + baserot : numpy.ndarray The rotation matrix for the `base`. - recbase : ndarray + recbase : numpy.ndarray The inverse of the `base` matrix, where the columns give reciprocal vectors in Cartesian coordinates. - normbase : ndarray + normbase : numpy.ndarray The `base` vectors scaled by magnitudes of reciprocal cell lengths. - recnormbase : ndarray + recnormbase : numpy.ndarray The inverse of the `normbase` matrix. - isotropicunit : ndarray + isotropicunit : numpy.ndarray The 3x3 tensor for a unit isotropic displacement parameters in this coordinate system. This is an identity matrix when this Lattice is orthonormal. @@ -212,7 +212,7 @@ def unitvolume(self): sar = property(lambda self: self._sar, doc="The sine of the reciprocal angle *alpha*.") - sbr = property(lambda self: self._sbr, doc="flot: Sine of the reciprocal angle *beta*.") + sbr = property(lambda self: self._sbr, doc="The sine of the reciprocal angle *beta*.") sgr = property(lambda self: self._sgr, doc="The sine of the reciprocal angle *gamma*.") @@ -272,19 +272,19 @@ def setLatPar(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, b Parameters ---------- - a : float, optional + a : float, Optional The new value of the cell length *a*. - b : float, optional + b : float, Optional The new value of the cell length *b*. - c : float, optional + c : float, Optional The new value of the cell length *c*. - alpha : float, optional + alpha : float, Optional The new value of the cell angle *alpha* in degrees. - beta : float, optional + beta : float, Optional The new value of the cell angle *beta* in degrees. - gamma : float, optional + gamma : float, Optional The new value of the cell angle *gamma* in degrees. - baserot : array_like, optional + baserot : array_like, Optional The new 3x3 rotation matrix of the base vectors with respect to their standard setting in Cartesian coordinates. @@ -447,7 +447,7 @@ def cartesian(self, u): Returns ------- - rc : ndarray + rc : numpy.ndarray Cartesian coordinates of the *u* vector. """ rc = numpy.dot(u, self.base) @@ -464,7 +464,7 @@ def fractional(self, rc): Returns ------- - u : ndarray + u : numpy.ndarray Fractional coordinates of the Cartesian vector *rc*. """ u = numpy.dot(rc, self.recbase) @@ -483,7 +483,7 @@ def dot(self, u, v): Returns ------- - float or ndarray + float or numpy.ndarray The dot product of lattice vectors *u*, *v*. """ dp = (u * numpy.dot(v, self.metrics)).sum(axis=-1) @@ -499,7 +499,7 @@ def norm(self, xyz): Returns ------- - float or ndarray + float or numpy.ndarray The magnitude of the lattice vector *xyz*. """ # this is a few percent faster than sqrt(dot(u, u)). @@ -515,7 +515,7 @@ def rnorm(self, hkl): Returns ------- - float or ndarray + float or numpy.ndarray The magnitude of the reciprocal vector *hkl*. """ hklcartn = numpy.dot(hkl, self.recbase.T) @@ -528,7 +528,7 @@ def dist(self, u, v): ---------- u : array_like A vector or an Nx3 matrix of fractional coordinates. - v : ndarray + v : numpy.ndarray A vector or an Nx3 matrix of fractional coordinates. Note @@ -537,7 +537,7 @@ def dist(self, u, v): Returns ------- - float or ndarray + float or numpy.ndarray The distance between lattice points *u* and *v*. """ duv = numpy.asarray(u) - v @@ -617,12 +617,12 @@ def _isotropicunit(recnormbase): Parameters ---------- - recnormbase : ndarray + recnormbase : numpy.ndarray The inverse of normalized base vectors of some lattice. Returns ------- - ndarray + numpy.ndarray The 3x3 matrix of displacement parameters corresponding to a unit isotropic displacements. """ diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index bac14f55..fc8d0278 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -33,32 +33,40 @@ class P_cif(StructureParser): - """Simple parser for CIF structure format. + """ + Simple parser for CIF structure format. Reads Structure from the first block containing _atom_site_label key. - Following blocks, if any are ignored. + Following blocks, if any, are ignored. Data members: - - format -- structure format name - ciffile -- instance of CifFile from PyCifRW - stru -- Structure instance used for cif input or output + format : + Structure format name. + ciffile : + Instance of CifFile from PyCifRW. + stru : + Structure instance used for CIF input or output. Data members used for input only: - - spacegroup -- instance of SpaceGroup used for symmetry expansion - eps -- resolution in fractional coordinates for non-equal - positions. Use for expansion of asymmetric unit. - eau -- instance of ExpandAsymmetricUnit from SymmetryUtilities - asymmetric_unit -- list of atom instances for the original asymmetric - unit in the CIF file - labelindex -- dictionary mapping unique atom label to index of atom - in self.asymmetric_unit - anisotropy -- dictionary mapping unique atom label to displacement - anisotropy resolved at that site - cif_sgname -- space group name obtained by looking up the value of - _space_group_name_Hall, _symmetry_space_group_name_Hall, - _space_group_name_H-M_alt, _symmetry_space_group_name_H-M - items. None when neither is defined. + spacegroup : + Instance of SpaceGroup used for symmetry expansion. + eps : + Resolution in fractional coordinates for non-equal positions. + Used for expansion of asymmetric unit. + eau : + Instance of ExpandAsymmetricUnit from SymmetryUtilities. + asymmetric_unit : + List of atom instances for the original asymmetric unit in the CIF file. + labelindex : + Dictionary mapping unique atom label to index of atom in self.asymmetric_unit. + anisotropy : + Dictionary mapping unique atom label to displacement anisotropy resolved at that site. + cif_sgname : + Space group name obtained by looking up the value of + _space_group_name_Hall, + _symmetry_space_group_name_Hall, + _space_group_name_H-M_alt, + _symmetry_space_group_name_H-M + items. None when neither is defined. """ # static data and methods ------------------------------------------------ @@ -66,6 +74,11 @@ class P_cif(StructureParser): # dictionary set of class methods for translating CIF values # to Atom attributes + # static data and methods ------------------------------------------------ + + # dictionary set of class methods for translating CIF values + # to Atom attributes + _atom_setters = dict.fromkeys( ( "_tr_ignore", @@ -692,7 +705,7 @@ def leading_float(s, d=0.0): ---------- s : str The string to be scanned for floating point value. - d : float, optional + d : float, Optional The default value when `s` is "." or "?", which in CIF format stands for inapplicable and unknown, respectively. diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 091f305d..716fdbb4 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -117,18 +117,18 @@ class SymOp(object): Parameters ---------- - R : ndarray + R : numpy.ndarray The 3x3 matrix of rotation for this symmetry operation. - t : ndarray + t : numpy.ndarray The vector of translation in this symmetry operation. Attributes ---------- - R : ndarray + R : numpy.ndarray The 3x3 matrix of rotation pertaining to unit cell coordinates. This may be identity, simple rotation, improper rotation, mirror or inversion. The determinant of *R* is either +1 or -1. - t : ndarray + t : numpy.ndarray The translation of cell coordinates applied after rotation *R*. """ @@ -149,12 +149,12 @@ def __call__(self, vec): Parameters ---------- - vec : ndarray + vec : numpy.ndarray The initial position in fractional cell coordinates. Returns ------- - ndarray + numpy.ndarray The transformed position after this symmetry operation. """ return numpy.dot(self.R, vec) + self.t @@ -312,12 +312,12 @@ def iter_equivalent_positions(self, vec): Parameters ---------- - vec : ndarray + vec : numpy.ndarray The initial position in fractional coordinates. Yields ------ - ndarray + numpy.ndarray The symmetry equivalent positions in fractional coordinates. The positions may be duplicate or outside of the ``0 <= x < 1`` unit cell bounds. diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index f0a2957d..7bdec181 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -700,7 +700,7 @@ def FindSpaceGroup(symops, shuffle=False): ---------- symops : list The list of `SymOp` objects for which to find SpaceGroup. - shuffle : bool, optional + shuffle : bool, Optional Flag for allowing different order of symops in the returned SpaceGroup. The default is ``False``. diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 30eb3a31..761aa53a 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -56,9 +56,9 @@ def __init__(self, atoms=None, lattice=None, title=None, filename=None, format=N the new Structure is its copy. lattice -- instance of Lattice defining coordinate systems, property. title -- string description of the structure - filename -- optional, name of a file to load the structure from. + filename -- Optional, name of a file to load the structure from. Overrides atoms argument when specified. - format -- optional structure format of the loaded filename. By default + format -- Optional structure format of the loaded filename. By default all structure formats are tried one by one. Ignored when filename has not been specified. @@ -99,7 +99,7 @@ def copy(self): def __copy__(self, target=None): """Create a deep copy of this instance. - target -- optional target instance for copying, useful for + target -- Optional target instance for copying, useful for copying a derived class. Defaults to new instance of the same type as self. @@ -160,30 +160,52 @@ def assignUniqueLabels(self): return def distance(self, aid0, aid1): - """Distance between 2 atoms, no periodic boundary conditions. - - aid0 -- zero based index of the first atom or a string label - such as "Na1" - aid1 -- zero based index or string label of the second atom. + """ + Calculate distance between 2 atoms, no periodic boundary conditions. - Return float. - Raise IndexError for invalid arguments. + Parameters + ---------- + aid0 : int or str + Zero based index of the first atom or a string label such as "Na1". + aid1 : int or str + Zero based index or string label of the second atom. + + Returns + ------- + float + Distance between the two atoms in Angstroms. + + Raises + ------ + IndexError + If any of the atom indices or labels are invalid. """ # lookup by labels a0, a1 = self[aid0, aid1] return self.lattice.dist(a0.xyz, a1.xyz) def angle(self, aid0, aid1, aid2): - """The bond angle at the second of three atoms in degrees. - - aid0 -- zero based index of the first atom or a string label - such as "Na1" - aid1 -- index or string label for the second atom, - where the angle is formed - aid2 -- index or string label for the third atom + """ + The bond angle at the second of three atoms in degrees. - Return float. - Raise IndexError for invalid arguments. + Parameters + ---------- + aid0 : int or str + Zero based index of the first atom or a string label such as "Na1". + aid1 : int or str + Index or string label for the second atom, where the angle is formed. + aid2 : int or str + Index or string label for the third atom. + + Returns + ------- + float + The bond angle in degrees. + + Raises + ------ + IndexError + If any of the arguments are invalid. """ a0, a1, a2 = self[aid0, aid1, aid2] u10 = a0.xyz - a1.xyz @@ -208,14 +230,22 @@ def placeInLattice(self, new_lattice): return self def read(self, filename, format="auto"): - """Load structure from a file, any original data become lost. - - filename -- file to be loaded - format -- all structure formats are defined in parsers submodule, - when format == 'auto' all parsers are tried one by one + """ + Load structure from a file, any original data become lost. - Return instance of data Parser used to process file. This - can be inspected for information related to particular format. + Parameters + ---------- + filename : str + File to be loaded + format : str, Optional + all structure formats are defined in parsers submodule, + when format == 'auto' all parsers are tried one by one + + Returns + ------- + Parser + Return instance of data Parser used to process input string. This + can be inspected for information related to particular format. """ import diffpy.structure import diffpy.structure.parsers @@ -238,14 +268,22 @@ def read(self, filename, format="auto"): return p def readStr(self, s, format="auto"): - """Load structure from a string, any original data become lost. - - s -- string with structure definition - format -- all structure formats are defined in parsers submodule, - when format == 'auto' all parsers are tried one by one + """ + Read structure from a string. - Return instance of data Parser used to process input string. This - can be inspected for information related to particular format. + Parameters + ---------- + s : str + String with structure definition. + format : str, Optional + All structure formats are defined in parsers submodule. When format == 'auto', + all parsers are tried one by one. + + Returns + ------- + Parser + Return instance of data Parser used to process input string. This + can be inspected for information related to particular format. """ from diffpy.structure.parsers import getParser @@ -296,13 +334,19 @@ def tolist(self): # Overloaded list Methods and Operators ---------------------------------- def append(self, a, copy=True): - """Append atom to a structure and update its lattice attribute. - - a -- instance of Atom - copy -- flag for appending a copy of a. - When False, append a and update a.lattice. + """ + Append atom to a structure and update its lattice attribute. - No return value. + Parameters + ---------- + a : Atom + Instance of Atom to be appended. + copy : bool, Optional + Flag for appending a copy of a. When False, append a and update a.lattice. + + Returns + ------- + None """ adup = copy and Atom(a) or a adup.lattice = self.lattice @@ -310,14 +354,21 @@ def append(self, a, copy=True): return def insert(self, idx, a, copy=True): - """Insert atom a before position idx in this Structure. - - idx -- position in atom list - a -- instance of Atom - copy -- flag for inserting a copy of a. - When False, append a and update a.lattice. + """ + Insert atom a before position idx in this Structure. - No return value. + Parameters + ---------- + idx : int + Position in atom list. + a : Atom + Instance of Atom to be inserted. + copy : bool, Optional + Flag for inserting a copy of a. When False, append a and update a.lattice. + + Returns + ------- + None """ adup = copy and copymod.copy(a) or a adup.lattice = self.lattice @@ -331,9 +382,9 @@ def extend(self, atoms, copy=None): Parameters ---------- - atoms : iterable + atoms : Iterable The `Atom` objects to be appended to this Structure. - copy : bool, optional + copy : bool, Optional Flag for adding copies of Atom objects. Make copies when `True`, append `atoms` unchanged when ``False``. The default behavior is to make copies when `atoms` are of diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index efc13782..afad7371 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -284,22 +284,36 @@ class GeneratorSite(object): """Storage of data related to a generator positions. Data members: - xyz -- fractional coordinates of generator site - Uij -- anisotropic thermal displacement at generator site - sgoffset -- offset of space group origin [0, 0, 0] - eps -- cutoff for equal positions - eqxyz -- list of equivalent positions - eqUij -- list of displacement matrices at equivalent positions - symops -- nested list of operations per each eqxyz - multiplicity -- generator site multiplicity - Uisotropy -- bool flag for isotropic thermal factors - invariants -- list of invariant operations for generator site - null_space -- null space of all possible differences of invariant - rotational matrices, this is a base of symmetry - allowed shifts. - Uspace -- 3D array of independent components of U matrices. - pparameters -- list of (xyz symbol, value) pairs - Uparameters -- list of (U symbol, value) pairs + xyz : + Fractional coordinates of generator site + Uij : + Anisotropic thermal displacement at generator site + sgoffset : + Offset of space group origin [0, 0, 0] + eps : + Cutoff for equal positions + eqxyz : + List of equivalent positions + eqUij : + List of displacement matrices at equivalent positions + symops : + Nested list of operations per each eqxyz + multiplicity : + Generator site multiplicity + Uisotropy : + Bool flag for isotropic thermal factors + invariants : + List of invariant operations for generator site + null_space : + Null space of all possible differences of invariant + rotational matrices, this is a base of symmetry + allowed shifts. + Uspace : + 3D array of independent components of U matrices. + pparameters : + List of (xyz symbol, value) pairs + Uparameters : + List of (U symbol, value) pairs """ Ucomponents = numpy.array( @@ -585,20 +599,31 @@ def eqIndex(self, pos): class ExpandAsymmetricUnit(object): - """Expand asymmetric unit and anisotropic thermal displacement + """ + Expand asymmetric unit and anisotropic thermal displacement Data members: - spacegroup -- instance of SpaceGroup - corepos -- list of positions in asymmetric unit, - it may contain duplicates - coreUijs -- thermal factors for corepos (defaults to zeros) - sgoffset -- optional offset of space group origin [0, 0, 0] - eps -- cutoff for equivalent positions + spacegroup : + Instance of SpaceGroup + corepos : + List of positions in asymmetric unit, + it may contain duplicates + coreUijs : + Thermal factors for corepos (defaults to zeros) + sgoffset : + Optional offset of space group origin [0, 0, 0] + eps : + Cutoff for equivalent positions + Calculated data members: - multiplicity -- multiplicity of each site in corepos - Uisotropy -- bool flags for isotropic sites in corepos - expandedpos -- list of equivalent positions per each site in corepos - expandedUijs -- list of thermal factors per each site in corepos + multiplicity : + Multiplicity of each site in corepos + Uisotropy : + Bool flags for isotropic sites in corepos + expandedpos : + List of equivalent positions per each site in corepos + expandedUijs : + List of thermal factors per each site in corepos """ # By design Atom instances are not accepted as arguments to keep @@ -663,30 +688,44 @@ def pruneFormulaDictionary(eqdict): class SymmetryConstraints(object): - """Generate symmetry constraints for specified positions + """ + Generate symmetry constraints for specified positions Data members: - spacegroup -- instance of SpaceGroup - positions -- all positions to be constrained - Uijs -- thermal factors for all positions (defaults to zeros) - sgoffset -- optional offset of space group origin [0, 0, 0] - eps -- cutoff for equivalent positions + spacegroup : + Instance of SpaceGroup + positions : + All positions to be constrained + Uijs : + Thermal factors for all positions (defaults to zeros) + sgoffset : + Optional offset of space group origin [0, 0, 0] + eps : + Cutoff for equivalent positions + Calculated data members: - corepos -- list of of positions in the asymmetric unit - coremap -- dictionary mapping indices of asymmetric core positions - to indices of all symmetry related positions - poseqns -- list of coordinate formula dictionaries per each site. - Formula dictionary keys are from ("x", "y", "z") and - the values are formatted as [[-]{x|y|z}%i] [{+|-}%g], - for example: "x0", "-x3", "z7 +0.5", "0.25". - pospars -- list of (xyz symbol, value) pairs - Ueqns -- list of anisotropic atomic displacement formula - dictionaries per each position. Formula dictionary - keys are from ('U11','U22','U33','U12','U13','U23') - and the values are formatted as {[%g*][Uij%i]|0}, - for example: "U110", "0.5*U2213", "0" - Upars -- list of (U symbol, value) pairs - Uisotropy -- list of bool flags for isotropic thermal displacements + corepos : + List of of positions in the asymmetric unit + coremap : + Dictionary mapping indices of asymmetric core positions + to indices of all symmetry related positions + poseqns : + List of coordinate formula dictionaries per each site. + Formula dictionary keys are from ("x", "y", "z") and + the values are formatted as [[-]{x|y|z}%i] [{+|-}%g], + for example: "x0", "-x3", "z7 +0.5", "0.25". + pospars : + List of (xyz symbol, value) pairs + Ueqns : + List of anisotropic atomic displacement formula + dictionaries per each position. Formula dictionary + keys are from ('U11','U22','U33','U12','U13','U23') + and the values are formatted as {[%g*][Uij%i]|0}, + for example: "U110", "0.5*U2213", "0" + Upars : + List of (U symbol, value) pairs + Uisotropy : + List of bool flags for isotropic thermal displacements """ def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=None): diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 823ce9da..21320c90 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -68,7 +68,7 @@ def _linkAtomAttribute(attrname, doc, toarray=numpy.array): The string name of the Atom class attribute to be mapped. doc : str The docstring for the property wrapper. - toarray : callable, optional + toarray : callable, Optional Factory function that converts list of attributes to `numpy.ndarray`. Use `numpy.char.array` for string attributes. From 948cee03e99286477d76d37dd2645d08d9a44d0b Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 26 Jul 2024 20:22:31 -0400 Subject: [PATCH 039/226] Update old URL in docstrings for API doc --- src/diffpy/structure/parsers/p_cif.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index bac14f55..a12c2b28 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -15,7 +15,7 @@ """Parser for basic CIF file format -http://www.iucr.org/iucr-top/cif/home.html +https://www.iucr.org/resources/cif """ import re diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 11ff9a43..ddf70315 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -17,8 +17,8 @@ References - http://www.wwpdb.org/documentation/format23/v2.3.html - http://www.wwpdb.org/documentation/format30/index.html + https://www.wwpdb.org/documentation/file-format-content/format23/v2.3.html + https://www.wwpdb.org/documentation/file-format-content/format30/index.html """ import sys From c4cb68d0e0a09772ee61b893ea57c81926a1950c Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 28 Jul 2024 03:04:27 -0400 Subject: [PATCH 040/226] Remove deprecated applications module. --- .../api/diffpy.structure.applications.rst | 28 ----------------- doc/source/api/diffpy.structure.rst | 1 - src/diffpy/structure/applications/__init__.py | 30 ------------------- src/diffpy/structure/applications/anyeye.py | 14 --------- src/diffpy/structure/applications/transtru.py | 14 --------- 5 files changed, 87 deletions(-) delete mode 100644 doc/source/api/diffpy.structure.applications.rst delete mode 100644 src/diffpy/structure/applications/__init__.py delete mode 100755 src/diffpy/structure/applications/anyeye.py delete mode 100755 src/diffpy/structure/applications/transtru.py diff --git a/doc/source/api/diffpy.structure.applications.rst b/doc/source/api/diffpy.structure.applications.rst deleted file mode 100644 index 30316d0b..00000000 --- a/doc/source/api/diffpy.structure.applications.rst +++ /dev/null @@ -1,28 +0,0 @@ -:tocdepth: -1 - -diffpy.structure.applications package -===================================== - -.. automodule:: diffpy.structure.applications - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -diffpy.structure.applications.transtru module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.applications.transtru - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.applications.anyeye module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.applications.anyeye - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index e414b921..95ff1285 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -16,7 +16,6 @@ Subpackages diffpy.structure.parsers diffpy.structure.expansion - diffpy.structure.applications diffpy.structure.apps Submodules diff --git a/src/diffpy/structure/applications/__init__.py b/src/diffpy/structure/applications/__init__.py deleted file mode 100644 index bc4f87eb..00000000 --- a/src/diffpy/structure/applications/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure Complex Modeling Initiative -# (c) 2019 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. -# -############################################################################## - -""" -Import support for renamed subpackage diffpy.structure.applications. - -This module is deprecated and will be removed in version 3.1. -""" - -# TODO remove this module in version 3.1. - -from warnings import warn - -warn( - "Module 'diffpy.structure.applications' is deprecated. " "Import 'diffpy.structure.apps' instead.", - DeprecationWarning, - stacklevel=2, -) diff --git a/src/diffpy/structure/applications/anyeye.py b/src/diffpy/structure/applications/anyeye.py deleted file mode 100755 index c2b9b334..00000000 --- a/src/diffpy/structure/applications/anyeye.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -""" -Temporary support for old import name. - -This module is deprecated and will be removed in version 3.1. -""" - -# TODO remove this module in version 3.1. - -from diffpy.structure.apps.anyeye import main - -if __name__ == "__main__": - main() diff --git a/src/diffpy/structure/applications/transtru.py b/src/diffpy/structure/applications/transtru.py deleted file mode 100755 index 8c911912..00000000 --- a/src/diffpy/structure/applications/transtru.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python - -""" -Temporary support for old import name. - -This module is deprecated and will be removed in version 3.1. -""" - -# TODO remove this module in version 3.1. - -from diffpy.structure.apps.transtru import main - -if __name__ == "__main__": - main() From 4d9b61ea081f3b01430a31b67558e4480c9f9f1c Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Sun, 28 Jul 2024 03:39:03 -0400 Subject: [PATCH 041/226] Remove six usage --- README.rst | 2 +- requirements/run.txt | 1 - src/diffpy/structure/_legacy_importer.py | 34 +----------------------- src/diffpy/structure/atom.py | 11 -------- src/diffpy/structure/parsers/p_cif.py | 8 +++--- src/diffpy/structure/parsers/p_discus.py | 4 +-- src/diffpy/structure/parsers/p_pdb.py | 3 +-- src/diffpy/structure/parsers/p_pdffit.py | 3 +-- src/diffpy/structure/parsers/p_rawxyz.py | 4 +-- src/diffpy/structure/parsers/p_xcfg.py | 3 +-- src/diffpy/structure/parsers/p_xyz.py | 6 ++--- src/diffpy/structure/spacegroups.py | 6 ++--- src/diffpy/structure/structure.py | 20 ++------------ src/diffpy/structure/tests/test_p_cif.py | 3 +-- src/diffpy/structure/utils.py | 8 ++---- 15 files changed, 20 insertions(+), 96 deletions(-) diff --git a/README.rst b/README.rst index 2fe46560..42d7ef98 100644 --- a/README.rst +++ b/README.rst @@ -66,7 +66,7 @@ by citing the following paper in your publication: Requirements ------------------------------------------------------------------------ -The diffpy.structure package requires Python 3.7 or later or 2.7 and +The diffpy.structure package requires Python 3.7 or later and the following software: * ``setuptools`` - software distribution tools for Python diff --git a/requirements/run.txt b/requirements/run.txt index cdc2699e..70f81389 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -1,3 +1,2 @@ numpy < 2.0.0 # Need to fix deprecations before 2.0.0 compat pycifrw -six diff --git a/src/diffpy/structure/_legacy_importer.py b/src/diffpy/structure/_legacy_importer.py index 743de895..810e7fb0 100644 --- a/src/diffpy/structure/_legacy_importer.py +++ b/src/diffpy/structure/_legacy_importer.py @@ -25,24 +25,10 @@ """ +import importlib.abc import sys from warnings import warn -import six - -if six.PY2: - import importlib - - class mock_importlib_abc(object): - MetaPathFinder = object - Loader = object - - importlib.abc = mock_importlib_abc - sys.modules.setdefault("importlib.abc", mock_importlib_abc) - del mock_importlib_abc - -import importlib.abc - WMSG = "Module {!r} is deprecated. Use {!r} instead." # ---------------------------------------------------------------------------- @@ -63,15 +49,6 @@ def find_spec(self, fullname, path=None, target=None): spec.loader = MapRenamedStructureModule() return spec - if six.PY2: - - def find_module(self, fullname, path): - # only handle submodules of diffpy.Structure - loader = None - if fullname.startswith(self.prefix): - loader = MapRenamedStructureModule() - return loader - # end of class FindRenamedStructureModule @@ -95,15 +72,6 @@ def create_module(self, spec): def exec_module(self, module): return - if six.PY2: - from collections import namedtuple - - ModuleSpec = namedtuple("ModuleSpec", "name") - - def load_module(self, fullname): - spec = self.ModuleSpec(fullname) - return self.create_module(spec) - # end of class MapRenamedStructureModule diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index b4454f7e..40b7bfb2 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -18,7 +18,6 @@ """ import numpy -import six from diffpy.structure.lattice import cartesian as cartesian_lattice @@ -558,15 +557,5 @@ def __array_wrap__(self, out_arr, context=None): """ return out_arr.view(numpy.ndarray) - # Python 2 Compatibility ------------------------------------------------- - - if six.PY2: - - def __setslice__(self, lo, hi, sequence): - self.__setitem__(slice(lo, hi), sequence) - return - - # ------------------------------------------------------------------------ - # End of _AtomCartesianCoordinates diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index f771f901..c9a9291d 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -18,12 +18,12 @@ https://www.iucr.org/resources/cif """ +import io import re import sys from contextlib import contextmanager import numpy -import six from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.parsers import StructureParser @@ -297,7 +297,7 @@ def parse(self, s): """ self.ciffile = None self.filename = "" - fp = six.StringIO(s) + fp = io.StringIO(s) rv = self._parseCifDataSource(fp) return rv @@ -363,7 +363,7 @@ def _parseCifDataSource(self, datasource): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = str(err).strip() e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return self.stru def _parseCifBlock(self, blockname): @@ -412,7 +412,7 @@ def _parse_lattice(self, block): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = str(err) e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) self.stru.lattice = Lattice(*latpars) return diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 101801be..1867a73d 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -19,8 +19,6 @@ import sys from functools import reduce -import six - from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError @@ -100,7 +98,7 @@ def parseLines(self, lines): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = "%d: file is not in DISCUS format" % self.nl e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return self.stru def toLines(self, stru): diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index ddf70315..74b98db1 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -24,7 +24,6 @@ import sys import numpy -import six from numpy import pi from diffpy.structure import Structure @@ -225,7 +224,7 @@ def parseLines(self, lines): emsg = "%d: invalid PDB record" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return stru def titleLines(self, stru): diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 659851e0..31fd2b81 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -20,7 +20,6 @@ from functools import reduce import numpy -import six from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser @@ -158,7 +157,7 @@ def parseLines(self, lines): emsg = "%d: file is not in PDFfit format" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return stru def toLines(self, stru): diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index ee199cca..4f25cbd5 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -20,8 +20,6 @@ import sys -import six - from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError @@ -91,7 +89,7 @@ def parseLines(self, lines): emsg = "%d: invalid number" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return stru def toLines(self, stru): diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index bbf44e83..ca10246e 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -19,7 +19,6 @@ import sys import numpy -import six from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser @@ -260,7 +259,7 @@ def parseLines(self, lines): emsg = "%d: file is not in XCFG format" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) return stru def toLines(self, stru): diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index 2985aa7a..ac5be63d 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -21,8 +21,6 @@ import sys -import six - from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError @@ -66,7 +64,7 @@ def parseLines(self, lines): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = "%d: invalid XYZ format, missing number of atoms" % (start + 1) e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) # find the last valid record stop = len(lines) while stop > start and len(linefields[stop - 1]) == 0: @@ -97,7 +95,7 @@ def parseLines(self, lines): exc_type, exc_value, exc_traceback = sys.exc_info() emsg = "%d: invalid number format" % p_nl e = StructureFormatError(emsg) - six.reraise(StructureFormatError, e, exc_traceback) + raise e.with_traceback(exc_traceback) # finally check if all the atoms have been read if p_natoms is not None and len(stru) != p_natoms: emsg = "expected %d atoms, read %d" % (p_natoms, len(stru)) diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index 7bdec181..38fd39a2 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -17,9 +17,7 @@ """ import copy - -import six -from six.moves import zip_longest +from itertools import zip_longest from diffpy.structure.mmlibspacegroups import ( mmLibSpaceGroupList, @@ -664,7 +662,7 @@ def GetSpaceGroup(sgid): return _sg_lookup_table[sgid] # Try different versions of sgid, first make sure it is a string emsg = "Unknown space group identifier %r" % sgid - if not isinstance(sgid, six.string_types): + if not isinstance(sgid, str): raise ValueError(emsg) sgbare = sgid.strip() # short_name case adjusted diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 761aa53a..d8063013 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -20,7 +20,6 @@ import copy as copymod import numpy -import six from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice @@ -447,10 +446,8 @@ def __getitem__(self, idx): except TypeError: pass # check if there is any string label that should be resolved - scalarstringlabel = isinstance(idx, six.string_types) - hasstringlabel = scalarstringlabel or ( - isiterable(idx) and any(isinstance(ii, six.string_types) for ii in idx) - ) + scalarstringlabel = isinstance(idx, str) + hasstringlabel = scalarstringlabel or (isiterable(idx) and any(isinstance(ii, str) for ii in idx)) # if not, use numpy indexing to resolve idx if not hasstringlabel: idx1 = idx @@ -774,18 +771,5 @@ def __emptySharedStructure(self): rv.__dict__.update([(k, getattr(self, k)) for k in rv.__dict__]) return rv - # Python 2 Compatibility ------------------------------------------------- - - if six.PY2: - - def __getslice__(self, lo, hi): - return self.__getitem__(slice(lo, hi)) - - def __setslice__(self, lo, hi, sequence): - self.__setitem__(slice(lo, hi), sequence) - return - - # ------------------------------------------------------------------------ - # End of class Structure diff --git a/src/diffpy/structure/tests/test_p_cif.py b/src/diffpy/structure/tests/test_p_cif.py index f066ad75..edd611f6 100644 --- a/src/diffpy/structure/tests/test_p_cif.py +++ b/src/diffpy/structure/tests/test_p_cif.py @@ -19,7 +19,6 @@ import unittest import numpy -import six from diffpy.structure import Structure from diffpy.structure.parsers import getParser @@ -148,7 +147,7 @@ def test_parseFile(self): self.assertEqual("C1", c1.label) # filename with unicode encoding hasbs = "\\" in self.graphiteciffile - uciffile = six.u(self.graphiteciffile.replace("\\", "/")) + uciffile = self.graphiteciffile.replace("\\", "/") if hasbs: # pragma: no cover uciffile = uciffile.replace("/", "\\") ugraphite = P_cif().parseFile(uciffile) diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 21320c90..94cb97d3 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -16,13 +16,9 @@ """Small shared functions. """ -import numpy -import six +from collections.abc import Iterable as _Iterable -if six.PY2: - from collections import Iterable as _Iterable -else: - from collections.abc import Iterable as _Iterable +import numpy def isiterable(obj): From c8242afee1e5331bf04b8f0975d5d82ac56b8728 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 1 Aug 2024 17:23:01 -0400 Subject: [PATCH 042/226] Update all docstrings to numpydoc format. Formate api doc. --- doc/source/conf.py | 3 + src/diffpy/Structure.py | 7 +- src/diffpy/structure/__init__.py | 32 +- src/diffpy/structure/_legacy_importer.py | 16 +- src/diffpy/structure/apps/__init__.py | 2 +- src/diffpy/structure/apps/anyeye.py | 32 +- src/diffpy/structure/apps/transtru.py | 24 +- src/diffpy/structure/atom.py | 111 ++-- src/diffpy/structure/expansion/__init__.py | 5 +- .../structure/expansion/makeellipsoid.py | 36 +- src/diffpy/structure/expansion/shapeutils.py | 14 +- .../structure/expansion/supercell_mod.py | 22 +- src/diffpy/structure/lattice.py | 68 +- src/diffpy/structure/mmlibspacegroups.py | 2 +- src/diffpy/structure/parsers/__init__.py | 41 +- src/diffpy/structure/parsers/p_auto.py | 117 +++- src/diffpy/structure/parsers/p_cif.py | 264 +++++--- src/diffpy/structure/parsers/p_discus.py | 96 ++- src/diffpy/structure/parsers/p_pdb.py | 61 +- src/diffpy/structure/parsers/p_pdffit.py | 56 +- src/diffpy/structure/parsers/p_rawxyz.py | 49 +- src/diffpy/structure/parsers/p_xcfg.py | 63 +- src/diffpy/structure/parsers/p_xyz.py | 47 +- .../structure/parsers/parser_index_mod.py | 26 +- .../structure/parsers/structureparser.py | 32 +- src/diffpy/structure/pdffitstructure.py | 61 +- src/diffpy/structure/sgtbxspacegroups.py | 10 +- src/diffpy/structure/spacegroupmod.py | 17 +- src/diffpy/structure/spacegroups.py | 42 +- src/diffpy/structure/structure.py | 459 ++++++++------ src/diffpy/structure/structureerrors.py | 2 +- src/diffpy/structure/symmetryutilities.py | 582 +++++++++++------- src/diffpy/structure/utils.py | 32 +- 33 files changed, 1620 insertions(+), 811 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 51dedf4e..d3af3e37 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -48,6 +48,8 @@ "m2r", ] +autodoc_member_order = "groupwise" + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -121,6 +123,7 @@ nitpick_ignore = [ ("py:class", "array_like"), ("py:class", "Parser"), + ("py:class", "CifFile"), ] # -- Options for HTML output ---------------------------------------------- diff --git a/src/diffpy/Structure.py b/src/diffpy/Structure.py index 7847de42..1f65df4b 100644 --- a/src/diffpy/Structure.py +++ b/src/diffpy/Structure.py @@ -13,12 +13,13 @@ # ############################################################################## -""" -Support import of old camel-case module names with DeprecationWarning. +"""Support import of old camel-case module names with `DeprecationWarning`. The imported camel-case modules are aliases for the current module -instances. Their `__name__` attributes are thus all in lower-case. +instances. Their `__name__` attributes are thus all in lower-case. +Warning +------- This module is deprecated and will be removed in the future. """ diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 8cb5fca9..f8106490 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -14,22 +14,25 @@ ############################################################################## """ -Classes related to the structure of materials. +Crystal structure container and parsers for structure formats. -Classes: - Atom +Classes related to the structure of materials: + * Atom + * Lattice + * Structure + * PDFFitStructure - Lattice +Other classes: + * SpaceGroup + * SymOp + * ExpandAsymmetricUnit + * GeneratorSite + * SymmetryConstraints - Structure - - PDFFitStructure Exceptions: - StructureFormatError - - LatticeError - - SymmetryError + * StructureFormatError + * LatticeError + * SymmetryError """ # Interface definitions ------------------------------------------------------ @@ -44,14 +47,11 @@ # package version from diffpy.structure.version import __version__ -"""Crystal structure container and parsers for structure formats.""" - # top level routines def loadStructure(filename, fmt="auto", **kw): - """ - Load new structure object from the specified file. + """Load new structure object from the specified file. Parameters ---------- diff --git a/src/diffpy/structure/_legacy_importer.py b/src/diffpy/structure/_legacy_importer.py index 810e7fb0..e37a907f 100644 --- a/src/diffpy/structure/_legacy_importer.py +++ b/src/diffpy/structure/_legacy_importer.py @@ -17,11 +17,15 @@ Support import of old camel-case module names with DeprecationWarning. The imported camel-case modules are aliases for the current module -instances. Their `__name__` attributes are thus all in lower-case. +instances. Their `__name__` attributes are thus all in lower-case. -This module is deprecated and will be removed in the future. +Note +---- +this module must be only imported from `diffpy.Structure`. -NOTE: this module must be only imported from `diffpy.Structure`. +Warning +------- +This module is deprecated and will be removed in the future. """ @@ -29,7 +33,7 @@ import sys from warnings import warn -WMSG = "Module {!r} is deprecated. Use {!r} instead." +WMSG = "Module {!r} is deprecated. Use {!r} instead." # ---------------------------------------------------------------------------- @@ -56,9 +60,7 @@ def find_spec(self, fullname, path=None, target=None): class MapRenamedStructureModule(importlib.abc.Loader): - """ - Loader for old camel-case module names. - + """Loader for old camel-case module names. Import the current module and alias it under the old name. """ diff --git a/src/diffpy/structure/apps/__init__.py b/src/diffpy/structure/apps/__init__.py index 7a953806..6f0249a8 100644 --- a/src/diffpy/structure/apps/__init__.py +++ b/src/diffpy/structure/apps/__init__.py @@ -13,5 +13,5 @@ # ############################################################################## -"""Script applications that use the diffpy.structure package. +"""Script applications that use the `diffpy.structure` package. """ diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index d758cb7e..fbf549ca 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -14,18 +14,18 @@ ############################################################################## """ -anyeye view structure file in atomeye +Anyeye view structure file in atomeye. -Usage: anyeye [options] strufile +Usage: ``anyeye [options] strufile`` -Anyeye understands more structure formats than atomeye. It converts strufile -to a temporary XCFG file which is opened in atomeye. Supported file formats: - inputFormats +Anyeye understands more `Structure` formats than atomeye. It converts `strufile` +to a temporary XCFG file which is opened in atomeye. See supported file formats: +``inputFormats`` Options: -f, --formula - Override chemical formula in strufile. The formula defines - elements in the same order as in strufile, e.g., Na4Cl4. + Override chemical formula in `strufile`. The formula defines + elements in the same order as in `strufile`, e.g., ``Na4Cl4``. -w, --watch Watch input file for changes. @@ -36,7 +36,7 @@ --formats=FORMATS Comma-separated list of file formats that are understood - by the VIEWER, by default "xcfg,pdb". Files of other + by the VIEWER, by default ``"xcfg,pdb"``. Files of other formats will be converted to the first listed format. -h, --help @@ -65,7 +65,7 @@ def usage(style=None): - """show usage info, for style=="brief" show only first 2 lines""" + """Show usage info, for ``style=="brief"`` show only first 2 lines.""" import os.path myname = os.path.basename(sys.argv[0]) @@ -91,7 +91,17 @@ def version(): def loadStructureFile(filename, format="auto"): """Load structure from specified file. - Return a tuple of (Structure, fileformat). + Parameters + ---------- + filename : str + Path to the structure file. + format : str, Optional + File format, by default "auto". + + Returns + ------- + tuple + A tuple of (Structure, fileformat). """ from diffpy.structure import Structure @@ -165,7 +175,7 @@ def cleanUp(pd): def parseFormula(formula): - """parse chemical formula and return a list of elements""" + """Parse chemical formula and return a list of elements""" # remove all blanks formula = re.sub(r"\s", "", formula) if not re.match("^[A-Z]", formula): diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index cb81f54b..86c682db 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -13,22 +13,26 @@ # ############################################################################## -"""transtru translate structure file to different format -Usage: transtru INFMT..OUTFMT strufile +"""Translate structure file to different format. -translates structure file strufile from INFMT to OUTFMT format and prints it -to the screen. Use "-" as strufile to read from standard input. To save the +Usage: ``transtru INFMT..OUTFMT strufile`` + +Translates structure file strufile from `INFMT` to `OUTFMT` format and prints it +to the screen. Use "-" as `strufile` to read from standard input. To save the translated file, use - transtru INFMT..OUTFMT strufile > strufile.out + ``transtru INFMT..OUTFMT strufile > strufile.out`` Supported input and output structure formats are - INFMT: inputFormats - OUTFMT: outputFormats + * `INFMT`: ``inputFormats`` + * `OUTFMT`: ``outputFormats`` Options: - -h, --help display this message - -V, --version show script version + -h, --help + Display this message. + + -V, --version + Show script version. """ from __future__ import print_function @@ -40,7 +44,7 @@ def usage(style=None): - """show usage info, for style=="brief" show only first 2 lines""" + """Show usage info, for ``style=="brief"`` show only first 2 lines.""" import os.path myname = os.path.basename(sys.argv[0]) diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index 40b7bfb2..9693b812 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -29,8 +29,7 @@ class Atom(object): - """ - Storage of structure information relevant for a single atom. + """Storage of structure information relevant for a single atom. This class manages atom information such as element symbol, position in fractional and Cartesian coordinates, atomic displacement parameters @@ -40,37 +39,37 @@ class Atom(object): ---------- atype : str or Atom, Optional The string atom type to be set as the `element` attribute. - By default an empty string. When of the *Atom* type, create - a copy of *atype* and adjust it per other arguments. + By default an empty string. When of the `Atom` type, create + a copy of `atype` and adjust it per other arguments. xyz : numpy.ndarray, Optional Fractional coordinates within the associated `lattice`. By default ``[0, 0, 0]``. label : str, Optional - A unique string `label` for referring to this Atom. + A unique string `label` for referring to this `Atom`. By default an empty string. occupancy : float, Optional The initial `occupancy` of this atom, by default ``1``. anisotropy : bool, Optional The flag for anisotropic thermal displacements parameters. This overrides `anisotropy` implied by presence of the - *U* or *Uisoequiv* arguments. Defaults to ``False`` + *U* or *Uisoequiv* arguments. Defaults to ``False`` when not set in any other way. U : numpy.ndarray, Optional The 3x3 matrix of anisotropic thermal displacement parameters. When present `anisotropy` defaults to ``True``. Uisoequiv: float, Optional - The isotropic atomic displacement parameter. The `anisotropy` - defaults to ``False`` when present. Only one of the *U* and - *Uisoequiv* arguments may be provided at the same time. Assume + The isotropic atomic displacement parameter. The `anisotropy` + defaults to ``False`` when present. Only one of the *U* and + *Uisoequiv* arguments may be provided at the same time. Assume zero atomic displacements when *U* and *Uisoequiv* are unset. - lattice : Lattice + lattice : Lattice, Optional Coordinate system for the fractional coordinates `xyz`. Use the absolute Cartesian system when ``None``. Attributes ---------- element : str - The string type of the atom. An element or ion symbol. + The string type of the atom. An element or ion symbol. xyz : numpy.ndarray The fractional coordinates in the associated `lattice`. label : str @@ -83,6 +82,10 @@ class Atom(object): Coordinate system for the fractional coordinates `xyz` and the tensor of atomic displacement parameters `U`. Use the absolute Cartesian coordinates when ``None``. + + Note + ---- + Cannot use both U and Uisoequiv arguments at the same time. """ # Private attributes @@ -92,10 +95,17 @@ class Atom(object): # instance attributes that have immutable default values element = "" + """str: Default values of `element`.""" + label = "" + """str: Default values of `label`.""" + occupancy = 1.0 + """float: Default values of `occupancy`.""" + _anisotropy = False lattice = None + """None: Default values of `lattice`.""" def __init__( self, @@ -108,11 +118,6 @@ def __init__( Uisoequiv=None, lattice=None, ): - """ - Create atom of the specified type at the given lattice coordinates. - - Atom(a) creates a copy of Atom instance *a*. - """ # check arguments if U is not None and Uisoequiv is not None: emsg = "Cannot use both U and Uisoequiv arguments." @@ -147,8 +152,7 @@ def __init__( return def msdLat(self, vl): - """ - Calculate mean square displacement along the lattice vector. + """Calculate mean square displacement along the lattice vector. Parameters ---------- @@ -172,8 +176,7 @@ def msdLat(self, vl): return msd def msdCart(self, vc): - """ - Calculate mean square displacement along the Cartesian vector. + """Calculate mean square displacement along the Cartesian vector. Parameters ---------- @@ -197,22 +200,19 @@ def msdCart(self, vc): return msd def __repr__(self): - """ - String representation of this Atom. - """ + """String representation of this Atom.""" xyz = self.xyz s = "%-4s %8.6f %8.6f %8.6f %6.4f" % (self.element, xyz[0], xyz[1], xyz[2], self.occupancy) return s def __copy__(self, target=None): - """ - Create a copy of this instance. + """Create a copy of this instance. Parameters ---------- target : Atom, Optional - An already existing Atom object to be updated to a duplicate - of this Atom. Create a new Atom object when not specified. + An already existing `Atom` object to be updated to a duplicate + of this `Atom`. Create a new Atom object when not specified. This facilitates extension of the `__copy__` method in a derived class. @@ -252,11 +252,10 @@ def __copy__(self, target=None): @property def xyz_cartn(self): - """ - numpy.ndarray: Atom position in absolute Cartesian coordinates. + """numpy.ndarray: Atom position in absolute Cartesian coordinates. This is computed from fractional coordinates `xyz` and the - current `lattice` setup. Assignment to *xyz_cartn* or + current `lattice` setup. Assignment to *xyz_cartn* or its components is applied on fractional coordinates `xyz`. """ if not self.lattice: @@ -277,8 +276,7 @@ def xyz_cartn(self, value): @property def anisotropy(self): - """ - bool : Flag for allowing anisotropic displacement parameters. + """bool : Flag for allowing anisotropic displacement parameters. When ``False`` the tensor of thermal displacement parameters `U` must be isotropic and only its diagonal elements are taken into @@ -303,8 +301,7 @@ def anisotropy(self, value): @property def U(self): - """ - numpy.ndarray : The 3x3 matrix of anisotropic atomic displacements. + """numpy.ndarray : The 3x3 matrix of anisotropic atomic displacements. For isotropic displacements (when `anisotropy` is ``False``) assignment to *U* uses only the first ``Unew[0, 0]`` element @@ -315,7 +312,7 @@ def U(self): ---- Elements of the *U* tensor such as ``U[0, 1]`` should be considered read-only as setting them directly leads to - undefined behavior. Use the `U11`, `U22`, ..., or `B11`, + undefined behavior. Use the `U11`, `U22`, ..., or `B11`, `B22`, ..., descriptors to set only some *U* components. """ if not self.anisotropy: @@ -333,18 +330,14 @@ def U(self, value): # Uij elements def _get_Uij(self, i, j): - """ - The getter function for the `U11`, `U22`, ..., properties. - """ + """The getter function for the `U11`, `U22`, ..., properties.""" if self.anisotropy: return self._U[i, j] lat = self.lattice or cartesian_lattice return self._U[0, 0] * lat.isotropicunit[i, j] def _set_Uij(self, i, j, value): - """ - The setter function for the `U11`, `U22`, ..., properties. - """ + """The setter function for the `U11`, `U22`, ..., properties.""" self._U[i, j] = value self._U[j, i] = value if not self._anisotropy and i == j != 0: @@ -373,7 +366,7 @@ def _set_Uij(self, i, j, value): _doc_uij = """ float : The ``U[{0}, {1}]`` element of the displacement tensor `U`. - Sets ``U[{1}, {0}]`` together with ``U[{0}, {1}]``. Assignment + Sets ``U[{1}, {0}]`` together with ``U[{0}, {1}]``. Assignment has no effect when `anisotropy` is ``False``. """ @@ -394,8 +387,7 @@ def _set_Uij(self, i, j, value): @property def Uisoequiv(self): - """ - float : The isotropic displacement parameter or an equivalent value. + """float : The isotropic displacement parameter or an equivalent value. Setting a new value rescales tensor `U` so it yields equivalent direction-averaged displacements. @@ -439,15 +431,15 @@ def Uisoequiv(self, value): _doc_bii = """ float : The ``B{0}{0}`` element of the Debye-Waller matrix. - This is equivalent to ``8 * pi**2 * U{0}{0}``. When `anisotropy` + This is equivalent to ``8 * pi**2 * U{0}{0}``. When `anisotropy` is ``False`` setting a new value updates entire tensor `U`. """ _doc_bij = """ float : The ``B{0}{1}`` element of the Debye-Waller matrix. - This is equivalent to ``8 * pi**2 * U{0}{1}``. Setting a new - value updates `U` in a symmetric way. Assignment has no effect + This is equivalent to ``8 * pi**2 * U{0}{1}``. Setting a new + value updates `U` in a symmetric way. Assignment has no effect when `anisotropy` is ``False``. """ @@ -489,10 +481,9 @@ def Uisoequiv(self, value): @property def Bisoequiv(self): - """ - float : The Debye-Waller isotropic displacement or an equivalent value. + """float : The Debye-Waller isotropic displacement or an equivalent value. - This equals ``8 * pi**2 * Uisoequiv``. Setting a new value + This equals ``8 * pi**2 * Uisoequiv``. Setting a new value rescales `U` tensor to yield equivalent direction-average of Debye-Waller displacements. """ @@ -510,8 +501,7 @@ def Bisoequiv(self, value): class _AtomCartesianCoordinates(numpy.ndarray): - """ - Specialized numpy.ndarray for accessing Cartesian coordinates. + """Specialized `numpy.ndarray` for accessing Cartesian coordinates. Inplace assignments to this array are applied on the *xyz* position position of owner `Atom` as per the associated `Atom.lattice`. @@ -519,13 +509,11 @@ class _AtomCartesianCoordinates(numpy.ndarray): Parameters ---------- atom : Atom - Atom instance to be linked to these coordinate array. + `Atom` instance to be linked to these coordinate array. """ def __new__(self, atom): - """ - Create the underlying numpy array base object. - """ + """Create the underlying numpy array base object.""" return numpy.empty(3, dtype=float).view(self) def __init__(self, atom): @@ -535,14 +523,11 @@ def __init__(self, atom): @property def asarray(self): - """ - ndarray : This array viewed as standard numpy array. - """ + """ndarray : This array viewed as standard numpy array.""" return self.view(numpy.ndarray) def __setitem__(self, idx, value): - """ - Set some element or slice of this Cartesian coordinates. + """Set some element or slice of this Cartesian coordinates. This overrides inplace array assignment to update the *xyz* fractional coordinate of the linked `Atom`. @@ -552,9 +537,7 @@ def __setitem__(self, idx, value): return def __array_wrap__(self, out_arr, context=None): - """ - Ensure math operations on this type yield standard numpy array. - """ + """Ensure math operations on this type yield standard numpy array.""" return out_arr.view(numpy.ndarray) diff --git a/src/diffpy/structure/expansion/__init__.py b/src/diffpy/structure/expansion/__init__.py index a00e7fcf..faa60ca3 100644 --- a/src/diffpy/structure/expansion/__init__.py +++ b/src/diffpy/structure/expansion/__init__.py @@ -13,11 +13,10 @@ # ############################################################################## -"""Methods and classes for manipulating Structure instances. +"""Methods and classes for manipulating `Structure` instances. Package content: - -supercell -- create a supercell from an existing Structure. + * supercell -- create a supercell from an existing `Structure`. """ # Import below whatever should be available at package namespace. diff --git a/src/diffpy/structure/expansion/makeellipsoid.py b/src/diffpy/structure/expansion/makeellipsoid.py index 8e1456a3..009be577 100644 --- a/src/diffpy/structure/expansion/makeellipsoid.py +++ b/src/diffpy/structure/expansion/makeellipsoid.py @@ -26,36 +26,42 @@ def makeSphere(S, radius): """Create a spherical nanoparticle. - Arguments - S -- A Structure instance - radius -- primary equatorial radius (along x-axis) + Parameters + ---------- + S : Structure + A `Structure` instance. + radius : float + Primary equatorial radius (along x-axis). - Returns a new structure instance + Returns + ------- + Structure + A new `Structure` instance. """ return makeEllipsoid(S, radius) def makeEllipsoid(S, a, b=None, c=None): """ - Cut a structure out of another one. + Cut a `Structure` out of another one. Parameters ---------- - S : - A Structure instance. - a : + S : Structure + A `Structure` instance. + a : float Primary equatorial radius (along x-axis). - b : - Secondary equatorial radius (along y-axis). If b is None - (default), then it is set equal to a. - c : - Polar radius (along z-axis). If c is None (default), then it is - set equal to a. + b : float, Optional + Secondary equatorial radius (along y-axis). If `b` is ``None`` + (default), then it is set equal to `a`. + c : float, Optional + Polar radius (along z-axis). If `c` is ``None`` (default), then it is + set equal to `a`. Returns ------- Structure : - A new structure instance. + A new `Structure` instance. """ if b is None: b = a diff --git a/src/diffpy/structure/expansion/shapeutils.py b/src/diffpy/structure/expansion/shapeutils.py index d05daecf..0e99df05 100644 --- a/src/diffpy/structure/expansion/shapeutils.py +++ b/src/diffpy/structure/expansion/shapeutils.py @@ -17,11 +17,19 @@ def findCenter(S): - """Find the approximate center atom of a structure. + """Find the approximate center `Atom` of a `Structure`. - The center of the structure is the atom closest to (0.5, 0.5, 0.5) + The center of the `Structure` is the `Atom` closest to ``(0.5, 0.5, 0.5)``. - Returns the index of the atom. + Parameters + ---------- + S : Structure + A `Structure` instance. + + Returns + ------- + int + The index of the center `Atom`. """ best = -1 bestd = len(S) diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index 938af7d6..b5760a3b 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -13,7 +13,7 @@ # ############################################################################## -"""This module contains functions for simple structure manipulation. +"""This module contains functions for simple `Structure` manipulation. """ import numpy @@ -23,31 +23,31 @@ def supercell(S, mno): """ - Perform supercell expansion for a structure. + Perform supercell expansion for a `Structure`. - New lattice parameters are multiplied and fractional coordinates - divided by corresponding multiplier. New atoms are grouped with + New `lattice` parameters are multiplied and fractional coordinates + divided by corresponding multiplier. New `Atoms` are grouped with their source in the original cell. Parameters ---------- - S : - An instance of Structure from diffpy.structure. - mno : + S : Structure + An instance of `Structure` from `diffpy.structure`. + mno : array_like Sequence of 3 integers for cell multipliers along - the a, b and c axes. + the `a`, `b` and `c` axes. Returns ------- Structure - A new structure instance representing the expanded supercell. + A new `Structure` instance representing the expanded supercell. Raises ------ TypeError - S is not a Structure instance. + `S` is not a `Structure` instance. ValueError - Invalid mno argument. + Invalid `mno` argument. """ # check arguments if len(mno) != 3: diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index db31f3f3..fb51de04 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -13,11 +13,13 @@ # ############################################################################## -"""class Lattice stores properties and provides simple operations in lattice +"""Class Lattice stores properties and provides simple operations in lattice coordinate system. -Module variables: - cartesian -- constant instance of Lattice, default Cartesian system +Attributes +---------- +cartesian : Lattice + Constant instance of Lattice, default Cartesian system. """ import math @@ -34,8 +36,19 @@ def cosd(x): - """Return the cosine of x (measured in degrees). + """Return the cosine of *x* (measured in degrees). + Avoid round-off errors for exact cosine values. + + Parameters + ---------- + x : float + The angle in degrees. + + Returns + ------- + float + The cosine of the angle *x*. """ rv = _EXACT_COSD.get(x % 360.0) if rv is None: @@ -44,8 +57,19 @@ def cosd(x): def sind(x): - """Return the sine of x (measured in degrees). + """Return the sine of *x* (measured in degrees). + Avoid round-off errors for exact sine values. + + Parameters + ---------- + x : float + The angle in degrees. + + Returns + ------- + float + The sine of the angle *x*. """ return cosd(90.0 - x) @@ -54,14 +78,13 @@ def sind(x): class Lattice(object): - """ - General coordinate system and associated operations. + """General coordinate system and associated operations. Parameters ---------- a : float or Lattice, Optional - The cell length *a*. When present, other cell parameters - must be also specified. When of the *Lattice* type, create + The cell length *a*. When present, other cell parameters + must be also specified. When of the *Lattice* type, create a duplicate Lattice. b : float The cell length *b*. @@ -77,7 +100,7 @@ class Lattice(object): The 3x3 rotation matrix of the base vectors with respect to their standard setting. base : array_like, Optional - The 3x3 array of row base vectors. This must be the + The 3x3 array of row base vectors. This must be the only argument when present. Attributes @@ -100,32 +123,32 @@ class Lattice(object): The inverse of the `normbase` matrix. isotropicunit : numpy.ndarray The 3x3 tensor for a unit isotropic displacement parameters in this - coordinate system. This is an identity matrix when this Lattice + coordinate system. This is an identity matrix when this Lattice is orthonormal. Note ---- - The array attributes are read-only. They get updated by changing + The array attributes are read-only. They get updated by changing some lattice parameters or by calling the `setLatPar()` or `setLatBase()` methods. Examples -------- - Create a Cartesian coordinate system:: + Create a Cartesian coordinate system: >>> Lattice() - Create coordinate system with the cell lengths ``a``, ``b``, ``c`` - and cell angles ``alpha``, ``beta``, ``gamma`` in degrees:: + Create coordinate system with the cell lengths `a`, `b`, `c` + and cell angles `alpha`, `beta`, `gamma` in degrees: >>> Lattice(a, b, c, alpha, beta, gamma) - Create a duplicate of an existing Lattice ``lat``:: + Create a duplicate of an existing Lattice `lat`: >>> Lattice(lat) Create coordinate system with the base vectors given by rows - of the ``abc`` matrix:: + of the `abc` matrix: >>> Lattice(base=abc) """ @@ -169,7 +192,7 @@ class Lattice(object): @property def unitvolume(self): - """The unit cell volume when a = b = c = 1.""" + """The unit cell volume when `a = b = c = 1`.""" # Recalculate lattice cosines to ensure this is right # even if ca, cb, cg data were not yet updated. ca = cosd(self.alpha) @@ -355,7 +378,7 @@ def setLatBase(self, base): """Set new base vectors for this lattice. This updates the cell lengths and cell angles according to the - new base. The `stdbase`, `baserot`, and `metrics` attributes + new base. The `stdbase`, `baserot`, and `metrics` attributes are also updated. Parameters @@ -403,7 +426,7 @@ def setLatBase(self, base): self.stdbase = numpy.array( [[1.0 / ar, -cgr / sgr / ar, cb * a], [0.0, b * sa, b * ca], [0.0, 0.0, c]], dtype=float ) - # calculate unit cell rotation matrix, base = stdbase @ baserot + # calculate unit cell rotation matrix, base = stdbase @ baserot self.baserot = numpy.dot(numalg.inv(self.stdbase), self.base) self.recbase = numalg.inv(self.base) # bases normalized to unit reciprocal vectors @@ -418,16 +441,17 @@ def setLatBase(self, base): return def abcABG(self): - """ + """Return the cell parameters in the standard setting. Returns ------- + tuple : A tuple of ``(a, b, c, alpha, beta, gamma)``. """ rv = (self.a, self.b, self.c, self.alpha, self.beta, self.gamma) return rv def reciprocal(self): - """ + """Return the reciprocal lattice of the current lattice. Returns ------- Lattice diff --git a/src/diffpy/structure/mmlibspacegroups.py b/src/diffpy/structure/mmlibspacegroups.py index 29e5dd0b..faa5ce2d 100644 --- a/src/diffpy/structure/mmlibspacegroups.py +++ b/src/diffpy/structure/mmlibspacegroups.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ # This code is part of the PyMMLib distribution and governed by -# its license. Please see the LICENSE_pymmlib file that should have been +# its license.Please see the LICENSE_pymmlib file that should have been # included as part of this package. """Space groups defined as a part of the pymmlib. """ diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 0924ff23..0d549b80 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -13,22 +13,22 @@ # ############################################################################## -"""Conversion plugins for various structure formats +"""Conversion plugins for various structure formats. -The recognized structure formats are defined by subclassing StructureParser, -by convention these classes are named P_. The parser classes should -to override the parseLines() and toLines() methods of StructureParser. -Any structure parser needs to be registered in parser_index module. +The recognized structure formats are defined by subclassing `StructureParser`, +by convention these classes are named `P_.py`. The parser classes should +to override the `parseLines()` and `toLines()` methods of `StructureParser`. +Any structure parser needs to be registered in `parser_index` module. For normal usage it should be sufficient to use the routines provided in this module. Content: - StructureParser -- base class for a concrete Parser - parser_index -- dictionary of known structure formats - getParser -- factory for Parser at given format - inputFormats -- list of available input formats - outputFormats -- list of available output formats + * StructureParser: base class for a concrete Parser + * parser_index: dictionary of known structure formats + * getParser: factory for Parser at given format + * inputFormats: list of available input formats + * outputFormats: list of available output formats """ from diffpy.structure.parsers.parser_index_mod import parser_index @@ -42,9 +42,22 @@ def getParser(format, **kw): """Return Parser instance for a given structure format. - kw -- keyword arguments passed to the Parser init function. + Parameters + ---------- + format : str + String with the format name, see `parser_index_mod`. + **kw : dict + Keyword arguments passed to the Parser init function. - Raises StructureFormatError exception when format is not defined. + Returns + ------- + Parser + Parser instance for the given format. + + Raises + ------ + StructureFormatError + When the format is not defined. """ if format not in parser_index: emsg = "no parser for '%s' format" % format @@ -57,14 +70,14 @@ def getParser(format, **kw): def inputFormats(): - """Return list of implemented input structure formats""" + """Return list of implemented input structure formats.""" input_formats = [fmt for fmt, prop in parser_index.items() if prop["has_input"]] input_formats.sort() return input_formats def outputFormats(): - """return list of implemented output structure formats""" + """Return list of implemented output structure formats.""" output_formats = [fmt for fmt, prop in parser_index.items() if prop["has_output"]] output_formats.sort() return output_formats diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 96409453..745eb5a9 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -13,9 +13,9 @@ # ############################################################################## -"""Parser for automatic file format detection +"""Parser for automatic file format detection. -This Parser does not provide the the toLines() method. +This Parser does not provide the the `toLines()` method. """ import os @@ -26,8 +26,23 @@ class P_auto(StructureParser): """Parser with automatic detection of structure format. - When successful, it sets its format attribute to detected - structure format. + + This parser attempts to automatically detect the format of a given + structure file and parse it accordingly. When successful, it sets + its `format` attribute to the detected structure format. + + Parameters + ---------- + **kw : dict + Keyword arguments for the structure parser. + + Attributes + ---------- + format : str + Detected structure format. Initially set to "auto" and updated + after successful detection of the structure format. + pkw : dict + Keyword arguments passed to the parser. """ def __init__(self, **kw): @@ -39,7 +54,7 @@ def __init__(self, **kw): # parseLines helpers def _getOrderedFormats(self): """Build a list of relevance ordered structure formats. - This only works when self.filename has a known extension. + This only works when `self.filename` has a known extension. """ from diffpy.structure.parsers import inputFormats @@ -62,41 +77,97 @@ def _getOrderedFormats(self): return ofmts def parseLines(self, lines): - """Detect format and create Structure instance from a list of lines. + """Detect format and create `Structure` instance from a list of lines. + Set format attribute to the detected file format. - Return Structure object or raise StructureFormatError exception. + Parameters + ---------- + lines : list + List of lines with structure data. + + Returns + ------- + Structure + `Structure` object. + + Raises + ------ + StructureFormatError """ return self._wrapParseMethod("parseLines", lines) def parse(self, s): - """Detect format and create Structure instance from a string. + """Detect format and create `Structure` instance from a string. + Set format attribute to the detected file format. - Return Structure object or raise StructureFormatError exception. + Parameters + ---------- + s : str + String with structure data. + + Returns + ------- + Structure + `Structure` object. + + Raises + ------ + StructureFormatError """ return self._wrapParseMethod("parse", s) def parseFile(self, filename): """Detect format and create Structure instance from an existing file. - Set format attribute to the detected file format. - filename -- path to structure file + Set format attribute to the detected file format. - Return Structure object. - Raise StructureFormatError or IOError. + Parameters + ---------- + filename : str + Path to structure file. + + Returns + ------- + Structure + `Structure` object. + + Raises + ------ + StructureFormatError + If the structure format is unknown or invalid. + IOError + If the file cannot be read. """ self.filename = filename return self._wrapParseMethod("parseFile", filename) def _wrapParseMethod(self, method, *args, **kwargs): - """A helper evaluator method. Try the specified parse method with + """A helper evaluator method that try the specified parse method with each registered structure parser and return the first successful - resul. Structure parsers that match structure file extension are + resul. + + Structure parsers that match structure file extension are tried first. - Set format attribute to the detected file format. - Return Structure instance, or raise StructureFormatError. + Parameters + ---------- + method : str + Name of the parse method to call. + *args : tuple + Positional arguments for the parse method. + **kwargs : dict + Keyword arguments for the parse method. + + Returns + ------- + Structure + `Structure` object. + + Raises + ------ + StructureFormatError """ from diffpy.structure.parsers import getParser @@ -131,4 +202,16 @@ def _wrapParseMethod(self, method, *args, **kwargs): def getParser(**kw): + """Return a new instance of the automatic parser. + + Parameters + ---------- + **kw : dict + Keyword arguments for the structure parser + + Returns + ------- + P_auto + Instance of `P_auto`. + """ return P_auto(**kw) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index c9a9291d..6fba3b44 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -13,9 +13,18 @@ # ############################################################################## -"""Parser for basic CIF file format - -https://www.iucr.org/resources/cif +"""Parser for basic CIF file format. + +Attributes +---------- +rx_float : re.Pattern + Constant regular expression for `leading_float()`. +symvec : dict + Helper dictionary for `getSymOp()`. + +Note +---- +References: https://www.iucr.org/resources/cif """ import io @@ -33,40 +42,45 @@ class P_cif(StructureParser): - """ - Simple parser for CIF structure format. + """Simple parser for CIF structure format. + Reads Structure from the first block containing _atom_site_label key. Following blocks, if any, are ignored. - Data members: - format : - Structure format name. - ciffile : - Instance of CifFile from PyCifRW. - stru : - Structure instance used for CIF input or output. - - Data members used for input only: - spacegroup : - Instance of SpaceGroup used for symmetry expansion. - eps : - Resolution in fractional coordinates for non-equal positions. - Used for expansion of asymmetric unit. - eau : - Instance of ExpandAsymmetricUnit from SymmetryUtilities. - asymmetric_unit : - List of atom instances for the original asymmetric unit in the CIF file. - labelindex : - Dictionary mapping unique atom label to index of atom in self.asymmetric_unit. - anisotropy : - Dictionary mapping unique atom label to displacement anisotropy resolved at that site. - cif_sgname : - Space group name obtained by looking up the value of - _space_group_name_Hall, - _symmetry_space_group_name_Hall, - _space_group_name_H-M_alt, - _symmetry_space_group_name_H-M - items. None when neither is defined. + Parameters + ---------- + eps : float, Optional + Fractional coordinates cutoff for duplicate positions. + When ``None`` use the default for `ExpandAsymmetricUnit`: ``1.0e-5``. + + Attributes + ---------- + format : str + Structure format name. + ciffile : CifFile + Instance of `CifFile` from `PyCifRW`. + stru : Structure + `Structure` instance used for CIF input or output. + spacegroup : SpaceGroup + Instance of `SpaceGroup` used for symmetry expansion. + eps : float + Resolution in fractional coordinates for non-equal positions. + Used for expansion of asymmetric unit. + eau : ExpandAsymmetricUnit + Instance of `ExpandAsymmetricUnit` from `SymmetryUtilities`. + asymmetric_unit : list + List of `Atom` instances for the original asymmetric unit in the CIF file. + labelindex : dict + Dictionary mapping unique atom label to index of `Atom` in `self.asymmetric_unit`. + anisotropy : dict + Dictionary mapping unique atom label to displacement anisotropy resolved at that site. + cif_sgname : str or None + Space group name obtained by looking up the value of + `_space_group_name_Hall`, + `_symmetry_space_group_name_Hall`, + `_space_group_name_H-M_alt`, + `_symmetry_space_group_name_H-M` + items. ``None`` when neither is defined. """ # static data and methods ------------------------------------------------ @@ -115,6 +129,7 @@ class P_cif(StructureParser): del k BtoU = 1.0 / (8 * numpy.pi**2) + """float: Conversion factor from B values to U values.""" def _tr_ignore(a, value): return @@ -252,12 +267,17 @@ def _tr_atom_site_aniso_B_23(a, value): _tr_atom_site_aniso_B_23 = staticmethod(_tr_atom_site_aniso_B_23) def _get_atom_setters(cifloop): - """Find translators of CifLoop items to data in Atom instance. - Static method. + """Static method for finding translators of CifLoop items to data in `Atom` instance. - cifloop -- instance of CifLoop + Parameters + ---------- + cifloop : CifLoop + Instance of `CifLoop`. - Return a list of setter functions in the order of cifloop.keys(). + Returns + ------- + list + List of setter functions in the order of `cifloop.keys()`. """ rv = [] for p in cifloop.keys(): @@ -272,11 +292,6 @@ def _get_atom_setters(cifloop): # normal methods --------------------------------------------------------- def __init__(self, eps=None): - """Initialize the parser for CIF structure files. - - eps -- fractional coordinates cutoff for duplicate positions. - When None use the default for ExpandAsymmetricUnit. - """ StructureParser.__init__(self) self.format = "cif" self.ciffile = None @@ -291,9 +306,22 @@ def __init__(self, eps=None): pass def parse(self, s): - """Create Structure instance from a string in CIF format. + """Create `Structure` instance from a string in CIF format. + + Parameters + ---------- + s : str + A string in CIF format. + + Returns + ------- + Structure + `Structure` instance. - Return Structure instance or raise StructureFormatError. + Raises + ------ + StructureFormatError + When the data do not constitute a valid CIF format. """ self.ciffile = None self.filename = "" @@ -304,9 +332,20 @@ def parse(self, s): def parseLines(self, lines): """Parse list of lines in CIF format. - lines -- list of strings stripped of line terminator + Parameters + ---------- + lines : list + List of strings stripped of line terminator. - Return Structure instance or raise StructureFormatError. + Returns + ------- + Structure + `Structure` instance. + + Raises + ------ + StructureFormatError + When the data do not constitute a valid CIF format. """ s = "\n".join(lines) + "\n" return self.parse(s) @@ -314,10 +353,22 @@ def parseLines(self, lines): def parseFile(self, filename): """Create Structure from an existing CIF file. - filename -- path to structure file + Parameters + ---------- + filename : str + Path to structure file. + + Returns + ------- + Structure + `Structure` instance. - Return Structure object. - Raise StructureFormatError or IOError. + Raises + ------ + StructureFormatError + When the data do not constitute a valid CIF format. + IOError + When the file cannot be opened. """ self.ciffile = None self.filename = filename @@ -326,20 +377,18 @@ def parseFile(self, filename): return rv def _parseCifDataSource(self, datasource): - """\ - Open and process CIF data from the specified `datasource`. - + """Open and process CIF data from the specified `datasource`. Parameters ---------- datasource : str or a file-like object - This is used as an argument to the CifFile class. The CifFile + This is used as an argument to the `CifFile` class. The `CifFile` instance is stored in `ciffile` attribute of this Parser. Returns ------- Structure - The Structure object loaded from the specified data source. + The `Structure` object loaded from the specified data source. Raises ------ @@ -367,12 +416,13 @@ def _parseCifDataSource(self, datasource): return self.stru def _parseCifBlock(self, blockname): - """Translate CIF file block, skip blocks without _atom_site_label. - Updates data members stru, eau. - - blockname -- name of top level block in self.ciffile + """Translate CIF file block, skip blocks without `_atom_site_label`. + Updates data members `stru`, `eau`. - No return value. + Parameters + ---------- + blockname : str + Name of top level block in `self.ciffile`. """ block = self.ciffile[blockname] if "_atom_site_label" not in block: @@ -389,12 +439,14 @@ def _parseCifBlock(self, blockname): return def _parse_lattice(self, block): - """Obtain lattice parameters from a CifBlock. - This method updates self.stru.lattice. + """Obtain `lattice` parameters from a `CifBlock`. - block -- instance of CifBlock + This method updates `self.stru.lattic`e. - No return value. + Parameters + ---------- + block : CifBlock + Instance of CifBlock. """ if "_cell_length_a" not in block: return @@ -417,13 +469,15 @@ def _parse_lattice(self, block): return def _parse_atom_site_label(self, block): - """Obtain atoms in asymmetric unit from a CifBlock. - This method inserts Atom instances to self.stru and - updates labelindex dictionary. + """Obtain atoms in asymmetric unit from a `CifBlock`. - block -- instance of CifBlock + This method inserts `Atom` instances to `self.stru` and + updates `labelindex` dictionary. - No return value. + Parameters + ---------- + block : CifBlock + Instance of `CifBlock`. """ # process _atom_site_label atom_site_loop = block.GetLoop("_atom_site_label") @@ -451,13 +505,15 @@ def _parse_atom_site_label(self, block): return def _parse_atom_site_aniso_label(self, block): - """Obtain value of anisotropic thermal displacements from a CifBlock. - This method updates U members of Atom instances in self.stru. - The labelindex dictionary has to be defined beforehand. + """Obtain value of anisotropic thermal displacements from a `CifBlock`. - block -- instance of CifBlock + This method updates `U` members of `Atom` instances in `self.stru`. + The `labelindex` dictionary has to be defined beforehand. - No return value. + Parameters + ---------- + block : CifBlock + Instance of `CifBlock`. """ if "_atom_site_aniso_label" not in block: return @@ -482,14 +538,16 @@ def _parse_atom_site_aniso_label(self, block): return def _parse_space_group_symop_operation_xyz(self, block): - """Process symmetry operations from a CifBlock. The method - updates spacegroup and eau data according to symmetry - operations defined in _space_group_symop_operation_xyz or - _symmetry_equiv_pos_as_xyz items in CifBlock. + """Process symmetry operations from a CifBlock. - block -- instance of CifBlock + The method updates `spacegroup` and `eau` data according to symmetry + operations defined in `_space_group_symop_operation_xyz` or + `_symmetry_equiv_pos_as_xyz` items in `CifBlock`. - No return value. + Parameters + ---------- + block : CifBlock + Instance of `CifBlock`. """ from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, IsSpaceGroupIdentifier, SpaceGroup @@ -541,9 +599,9 @@ def _parse_space_group_symop_operation_xyz(self, block): return def _expandAsymmetricUnit(self, block): - """Perform symmetry expansion of self.stru using self.spacegroup. + """Perform symmetry expansion of `self.stru` using `self.spacegroup`. - This method updates data in stru and eau. + This method updates data in `stru` and `eau`. Parameters ---------- @@ -581,9 +639,17 @@ def _expandAsymmetricUnit(self, block): # conversion to CIF ------------------------------------------------------ def toLines(self, stru): - """Convert Structure stru to a list of lines in basic CIF format. + """Convert `Structure` to a list of lines in basic CIF format. + + Parameters + ---------- + stru : Structure + The structure to be converted. - Return list of strings. + Returns + ------- + list + List of lines in basic CIF format. """ import time @@ -746,11 +812,17 @@ def leading_float(s, d=0.0): def getSymOp(s): - """Create SpaceGroups.SymOp instance from a string. + """Create `SpaceGroups.SymOp` instance from a string. - s -- formula for equivalent coordinates, for example 'x,1/2-y,1/2+z' + Parameters + ---------- + s : str + Formula for equivalent coordinates, for example ``'x,1/2-y,1/2+z'``. - Return instance of SymOp. + Returns + ------- + SymOp + Instance of `SymOp`. """ from diffpy.structure.spacegroups import SymOp @@ -770,10 +842,18 @@ def getSymOp(s): def getParser(eps=None): - """Return new parser object for CIF structure format. + """Return new `parser` object for CIF format. - eps -- fractional coordinates cutoff for duplicate positions. - When None use the default for ExpandAsymmetricUnit. + Parameters + ---------- + eps : float, Optional + fractional coordinates cutoff for duplicate positions. + When ``None`` use the default for `ExpandAsymmetricUnit`: ``1.0e-5``. + + Returns + ------- + P_cif + Instance of `P_cif`. """ return P_cif(eps=eps) @@ -783,9 +863,7 @@ def getParser(eps=None): @contextmanager def _suppressCifParserOutput(): - """\ - Context manager which suppresses diagnostic messages from CIF parser. - """ + """Context manager which suppresses diagnostic messages from CIF parser.""" from CifFile import yapps3_compiled_rt print_error = yapps3_compiled_rt.print_error diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 1867a73d..3ee7e5fd 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -25,8 +25,27 @@ class P_discus(StructureParser): - """Parser for DISCUS structure format. The parser chokes + """Parser for DISCUS structure format. The parser chokes on molecule and generator records. + + Attributes + ---------- + format : str + File format name, default "discus". + nl : int + Line number of the current line being parsed. + lines : list of str + List of lines from the input file. + line : str + Current line being parsed. + stru : PDFFitStructure + Structure being parsed. + ignored_lines : list of str + List of lines that were ignored during parsing. + cell_read : bool + ``True`` if cell record processed. + ncell_read : bool + ``True`` if ncell record processed. """ def __init__(self): @@ -45,7 +64,20 @@ def __init__(self): def parseLines(self, lines): """Parse list of lines in DISCUS format. - Return PDFFitStructure instance or raise StructureFormatError. + Parameters + ---------- + lines : list of str + List of lines from the input file. + + Returns + ------- + PDFFitStructure + Parsed `PDFFitStructure` instance. + + Raises + ------ + StructureFormatError + If the file is not in DISCUS format. """ self.lines = lines ilines = self._linesIterator() @@ -102,8 +134,17 @@ def parseLines(self, lines): return self.stru def toLines(self, stru): - """Convert Structure stru to a list of lines in DISCUS format. - Return list of strings. + """Convert `Structure` stru to a list of lines in DISCUS format. + + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + List of lines in DISCUS format. """ self.stru = stru # if necessary, convert self.stru to PDFFitStructure @@ -134,7 +175,7 @@ def toLines(self, stru): return lines def _linesIterator(self): - """Iterator over self.lines, which increments self.nl""" + """Iterator over `self.lines`, which increments `self.nl`""" # ignore trailing empty lines stop = len(self.lines) while stop > 0 and self.lines[stop - 1].strip() == "": @@ -185,7 +226,18 @@ def _parse_title(self, words): return def _parse_shape(self, words): - """Process the shape record from DISCUS structure file.""" + """Process the shape record from DISCUS structure file. + + Parameters + ---------- + words : list of str + List of words in the line. + + Raises + ------ + StructureFormatError + Invalid type of particle shape correction. + """ # strip away any commas linefixed = " ".join(words).replace(",", " ") wordsfixed = linefixed.split() @@ -211,15 +263,34 @@ def _parse_atom(self, words): def _parse_unknown_record(self, words): """Process unknown record in DISCUS structure file. - Silently ignores the line and adds it to self.ignored_lines - Raises StructureFormatError. + + Silently ignores the line and adds it to `self.ignored_lines`. + + Parameters + ---------- + words : list of str + List of words in the line. + + Raises + ------ + StructureFormatError + Unkown record. """ self.ignored_lines.append(self.line) return def _parse_not_implemented(self, words): """Process the unimplemented records from DISCUS structure file. - Raises NotImplementedError. + + Parameters + ---------- + words : list of str + List of words in the line. + + Raises + ------ + NotImplementedError + If the record is not implemented. """ emsg = "%d: reading of DISCUS record %r is not implemented." % (self.nl, words[0]) raise NotImplementedError(emsg) @@ -231,4 +302,11 @@ def _parse_not_implemented(self, words): def getParser(): + """Return new `parser` object for DISCUS format. + + Returns + ------- + P_discus + Instance of `P_discus`. + """ return P_discus() diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 74b98db1..6d0f95aa 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -15,8 +15,9 @@ """Basic parser for PDB structure format. -References - +Note +---- +References: https://www.wwpdb.org/documentation/file-format-content/format23/v2.3.html https://www.wwpdb.org/documentation/file-format-content/format30/index.html """ @@ -33,13 +34,14 @@ class P_pdb(StructureParser): """Simple parser for PDB format. - The parser understands following PDB records: TITLE, CRYST1, SCALE1, - SCALE2, SCALE3, ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM, END - Static data members: + The parser understands following PDB records: `TITLE, CRYST1, SCALE1, + SCALE2, SCALE3, ATOM, SIGATM, ANISOU, SIGUIJ, TER, HETATM, END`. - orderOfRecords -- order of PDB record labels - validRecords -- dictionary of valid PDB records + Attributes + ---------- + format : str + Format name, default "pdb". """ # Static data members @@ -100,7 +102,10 @@ class P_pdb(StructureParser): "MASTER", "END", ] + """list: Ordered list of PDB record labels.""" + validRecords = dict.fromkeys(orderOfRecords) + """dict: Dictionary of PDB record labels.""" def __init__(self): StructureParser.__init__(self) @@ -110,7 +115,20 @@ def __init__(self): def parseLines(self, lines): """Parse list of lines in PDB format. - Return Structure instance or raise StructureFormatError. + Parameters + ---------- + lines : list of str + List of lines in PDB format. + + Returns + ------- + Structure + Parsed structure instance. + + Raises + ------ + StructureFormatError + Invalid PDB record. """ try: stru = Structure() @@ -228,7 +246,7 @@ def parseLines(self, lines): return stru def titleLines(self, stru): - """build lines corresponding to TITLE record""" + """Build lines corresponding to `TITLE` record.""" lines = [] title = stru.title while title != "": @@ -247,7 +265,7 @@ def titleLines(self, stru): return lines def cryst1Lines(self, stru): - """build lines corresponding to CRYST1 record""" + """Build lines corresponding to `CRYST1` record.""" lines = [] latpar = ( stru.lattice.a, @@ -263,8 +281,8 @@ def cryst1Lines(self, stru): return lines def atomLines(self, stru, idx): - """build ATOM records and possibly SIGATM, ANISOU or SIGUIJ records - for structure stru atom number aidx + """Build `ATOM` records and possibly `SIGATM`, `ANISOU` or `SIGUIJ` records + for `structure` stru `atom` number aidx. """ lines = [] a = stru[idx] @@ -340,9 +358,17 @@ def atomLines(self, stru, idx): return lines def toLines(self, stru): - """Convert Structure stru to a list of lines in PDFFit format. + """Convert `Structure` stru to a list of lines in PDB format. - Return list of strings. + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + List of lines in PDB format. """ lines = [] lines.extend(self.titleLines(stru)) @@ -369,4 +395,11 @@ def toLines(self, stru): def getParser(): + """Return new `parser` object for PDB format. + + Returns + ------- + P_pdb + Instance of `P_pdb`. + """ return P_pdb() diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 31fd2b81..692c417f 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -29,7 +29,14 @@ class P_pdffit(StructureParser): """Parser for PDFfit structure format. - stru -- Structure instance used for cif input or output + Attributes + ---------- + format : str + Format name, default "pdffit". + ignored_lines : list + List of lines ignored during parsing. + stru : PDFFitStructure + Structure instance used for cif input or output. """ def __init__(self): @@ -42,7 +49,20 @@ def __init__(self): def parseLines(self, lines): """Parse list of lines in PDFfit format. - Return Structure object or raise StructureFormatError. + Parameters + ---------- + lines : list of str + List of lines in PDB format. + + Returns + ------- + Structure + Parsed structure instance. + + Raises + ------ + StructureFormatError + File not in PDFfit format. """ p_nl = 0 try: @@ -161,9 +181,17 @@ def parseLines(self, lines): return stru def toLines(self, stru): - """Convert Structure stru to a list of lines in PDFfit format. + """Convert `Structure` stru to a list of lines in PDFfit format. + + Parameters + ---------- + stru : Structure + Structure to be converted. - Return list of strings. + Returns + ------- + list of str + List of lines in PDFfit format. """ # build the stru_pdffit dictionary initialized from the defaults # in PDFFitStructure @@ -220,12 +248,17 @@ def toLines(self, stru): # Protected methods ------------------------------------------------------ def _parse_shape(self, line): - """Process shape line from PDFfit file and update self.stru + """Process shape line from PDFfit file and update self.stru. - line -- line containing data for particle shape correction + Parameters + ---------- + line : str + Line containing data for particle shape correction. - No return value. - Raise StructureFormatError for invalid record. + Raises + ------ + StructureFormatError + Invalid type of particle shape correction. """ line_nocommas = line.replace(",", " ") words = line_nocommas.split() @@ -247,4 +280,11 @@ def _parse_shape(self, line): def getParser(): + """Return new `parser` object for PDFfit format. + + Returns + ------- + P_pdffit + Instance of `P_pdffit`. + """ return P_pdffit() diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index 4f25cbd5..65e9588e 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -13,9 +13,10 @@ # ############################################################################## -"""Parser for raw XYZ file format. Raw XYZ is a 3 or 4 column text -file with cartesian coordinates of atoms and an optional first column -for atom types. +"""Parser for raw XYZ file format. + +Raw XYZ is a 3 or 4 column text file with cartesian coordinates +of atoms and an optional first column for atom types. """ import sys @@ -27,7 +28,13 @@ class P_rawxyz(StructureParser): - """Parser --> StructureParser subclass for RAWXYZ format""" + """Parser --> StructureParser subclass for RAWXYZ format. + + Attributes + ---------- + format : str + Format name, default "rawxyz". + """ def __init__(self): StructureParser.__init__(self) @@ -37,7 +44,20 @@ def __init__(self): def parseLines(self, lines): """Parse list of lines in RAWXYZ format. - Return Structure object or raise StructureFormatError. + Parameters + ---------- + lines : list of str + List of lines in RAWXYZ format. + + Returns + ------- + Structure + Parsed structure instance. + + Raises + ------ + StructureFormatError + Invalid RAWXYZ format. """ linefields = [line.split() for line in lines] # prepare output structure @@ -93,9 +113,17 @@ def parseLines(self, lines): return stru def toLines(self, stru): - """Convert Structure stru to a list of lines in XYZ format. + """Convert Structure stru to a list of lines in RAWXYZ format. + + Parameters + ---------- + stru : Structure + Structure to be converted. - Return list of strings. + Returns + ------- + list of str + List of lines in RAWXYZ format. """ lines = [] for a in stru: @@ -111,4 +139,11 @@ def toLines(self, stru): def getParser(): + """Return new `parser` object for RAWXYZ format. + + Returns + ------- + P_rawxyz + Instance of `P_rawxyz`. + """ return P_rawxyz() diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index ca10246e..372e7ba8 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -13,7 +13,13 @@ # ############################################################################## -"""Parser for extended CFG format used by atomeye""" +"""Parser for extended CFG format used by atomeye. + +Attributes +---------- +AtomicMass : dict + Dictionary of atomic masses for elements. +""" import re import sys @@ -150,11 +156,16 @@ class P_xcfg(StructureParser): """Parser for AtomEye extended CFG format. - cluster_boundary -- width of boundary around corners of non-periodic - cluster to avoid PBC effects in atomeye + Attributes + ---------- + format : str + Format name, default "xcfg". """ cluster_boundary = 2 + """int: Width of boundary around corners of non-periodic + cluster to avoid PBC effects in atomeye. + """ def __init__(self): StructureParser.__init__(self) @@ -162,9 +173,22 @@ def __init__(self): return def parseLines(self, lines): - """Parse list of lines in PDB format. + """Parse list of lines in XCFG format. + + Parameters + ---------- + lines : list of str + List of lines in XCFG format. + + Returns + ------- + Structure + Parsed structure instance. - Return Structure object or raise StructureFormatError. + Raises + ------ + StructureFormatError + Invalid XCFG format. """ xcfg_Number_of_particles = None xcfg_A = None @@ -265,7 +289,20 @@ def parseLines(self, lines): def toLines(self, stru): """Convert Structure stru to a list of lines in XCFG atomeye format. - Return list of strings. + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + List of lines in XCFG format. + + Raises + ------ + StructureFormatError + Cannot convert empty structure to XCFG format. """ if len(stru) == 0: emsg = "cannot convert empty structure to XCFG format" @@ -373,6 +410,13 @@ def toLines(self, stru): def getParser(): + """Return new `parser` object for XCFG format. + + Returns + ------- + P_xcfg + Instance of `P_xcfg`. + """ return P_xcfg() @@ -380,13 +424,12 @@ def getParser(): def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): - """\ - Assing auxiliary properties for Atom object when reading CFG format. + """Assing auxiliary properties for `Atom` object when reading CFG format. Parameters ---------- a : Atom - The Atom instance for which the auxiliary properties need to be set. + The `Atom` instance for which the auxiliary properties need to be set. fields : list Floating point values for the current row of the processed CFG file. auxiliaries : dict @@ -395,8 +438,6 @@ def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): no_velocity : bool When `False` set atom velocity `a.v` to `fields[3:6]`. Use `fields[3:6]` for auxiliary values otherwise. - - No return value. """ if not no_velocity: a.v = numpy.asarray(fields[3:6], dtype=float) diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index ac5be63d..cd540a90 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -14,9 +14,10 @@ ############################################################################## """Parser for XYZ file format, where -first line gives number of atoms -second one has optional title -remaining lines contain element, x, y, z + + * First line gives number of atoms. + * Second line has optional title. + * Remaining lines contain element, `x, y, z`. """ import sys @@ -27,7 +28,13 @@ class P_xyz(StructureParser): - """Parser for standard XYZ structure format.""" + """Parser for standard XYZ structure format. + + Attributes + ---------- + format : str + Format name, default "xyz". + """ def __init__(self): StructureParser.__init__(self) @@ -37,7 +44,20 @@ def __init__(self): def parseLines(self, lines): """Parse list of lines in XYZ format. - Return Structure object or raise StructureFormatError. + Parameters + ---------- + lines : list of str + List of lines in XYZ format. + + Returns + ------- + Structure + Parsed structure instance. + + Raises + ------ + StructureFormatError + Invalid XYZ format. """ linefields = [line.split() for line in lines] # prepare output structure @@ -105,7 +125,15 @@ def parseLines(self, lines): def toLines(self, stru): """Convert Structure stru to a list of lines in XYZ format. - Return list of strings. + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + List of lines in XYZ format. """ lines = [] lines.append(str(len(stru))) @@ -123,4 +151,11 @@ def toLines(self, stru): def getParser(): + """Return new `parser` object for XYZ format. + + Returns + ------- + P_xcfg + Instance of `P_xyz`. + """ return P_xyz() diff --git a/src/diffpy/structure/parsers/parser_index_mod.py b/src/diffpy/structure/parsers/parser_index_mod.py index 48314780..5bb6ba98 100644 --- a/src/diffpy/structure/parsers/parser_index_mod.py +++ b/src/diffpy/structure/parsers/parser_index_mod.py @@ -14,8 +14,30 @@ ############################################################################## """Index of recognized structure formats, their IO capabilities and -associated modules where they are defined. Plugins for new structure -formats need to be added to the parser_index dictionary in this module. +associated modules where they are defined. + +Attributes +---------- +parser_index : dict + Dictionary of recognized structure formats. The keys are format names + and the values are dictionaries with the following keys: + + module : str + Name of the module that defines the parser class. + file_extension : str + File extension for the format, including the leading dot. + file_pattern : str + File pattern for the format, using '|' as separator for multiple + patterns. + has_input : bool + ``True`` if the parser can read the format. + has_output : bool + ``True`` if the parser can write the format. + +Note +---- +Plugins for new structure formats need to be added to the parser_index +dictionary in this module. """ parser_index = { diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index 1637d86b..2b748664 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -20,9 +20,12 @@ class StructureParser(object): """Base class for all structure parsers. - Data members: - format -- format of particular parser - filename -- path to structure file that is read or written + Attributes + ---------- + format : str + Format name of particular parser. + filename : str + Path to structure file that is read or written. """ def __init__(self): @@ -34,6 +37,9 @@ def parseLines(self, lines): """Create Structure instance from a list of lines. Return Structure object or raise StructureFormatError exception. + + Note + ---- This method has to be overloaded in derived class. """ raise NotImplementedError("parseLines not defined for '%s' format" % self.format) @@ -41,35 +47,29 @@ def parseLines(self, lines): def toLines(self, stru): """Convert Structure stru to a list of lines. - This method has to be overloaded in derived class. Return list of strings. + + Note + ---- + This method has to be overloaded in derived class. """ raise NotImplementedError("toLines not defined for '%s' format" % self.format) def parse(self, s): - """Create Structure instance from a string. - - Return Structure object or raise StructureFormatError exception. - """ + """Create `Structure` instance from a string.""" lines = s.rstrip("\r\n").split("\n") stru = self.parseLines(lines) return stru def tostring(self, stru): - """Convert Structure instance to a string.""" + """Convert `Structure` instance to a string.""" lines = self.toLines(stru) s = "\n".join(lines) + "\n" return s def parseFile(self, filename): - """Create Structure instance from an existing file. - - filename -- path to structure file - - Return Structure object. - Raise StructureFormatError or IOError. - """ + """Create Structure instance from an existing file.""" self.filename = filename with open(filename) as fp: s = fp.read() diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index c2ed21a1..cc3b66d1 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -13,7 +13,7 @@ # ############################################################################## -"""definition of PDFFitStructure class derived from Structure +"""Definition of PDFFitStructure class derived from Structure """ @@ -23,13 +23,20 @@ class PDFFitStructure(Structure): - """PDFFitStructure --> Structure with extra pdffit member + """PDFFitStructure --> Structure with extra pdffit member. - Data members: - pdffit -- dictionary for storing following extra parameters from - PDFFit structure files: - 'scale', 'delta1', 'delta2', 'sratio', - 'rcut', 'spcgr', 'dcell', 'ncell' + Parameters + ---------- + *args, **kwargs : + See `Structure` class constructor. + + Attributes + ---------- + pdffit : dict + Dictionary for storing following extra parameters from + PDFFit structure files: + `'scale', 'delta1', 'delta2', 'sratio', + 'rcut', 'spcgr', 'dcell', 'ncell'` """ def __init__(self, *args, **kwargs): @@ -49,11 +56,23 @@ def __init__(self, *args, **kwargs): return def read(self, filename, format="auto"): - """Same as Structure.read, but update spcgr value in - self.pdffit when parser can get spacegroup. + """Same as `Structure.read`, but update `spcgr` value in + `self.pdffit` when parser can get spacegroup. + + See `Structure.read()` for more info. + + Parameters + ---------- + filename : str + File to be loaded. + format : str, Optional + All structure formats are defined in parsers submodule, + when ``format == 'auto'`` all parsers are tried one by one. - Return instance of StructureParser used to load the data. - See Structure.read() for more info. + Return + ------ + StructureParser + Instance of StructureParser used to load the data. """ p = Structure.read(self, filename, format) sg = getattr(p, "spacegroup", None) @@ -62,11 +81,23 @@ def read(self, filename, format="auto"): return p def readStr(self, s, format="auto"): - """Same as Structure.readStr, but update spcgr value in - self.pdffit when parser can get spacegroup. + """Same as `Structure.readStr`, but update `spcgr` value in + `self.pdffit` when parser can get spacegroup. + + See `Structure.readStr()` for more info. + + Parameters + ---------- + s : str + String with structure definition. + format : str, Optional + All structure formats are defined in parsers submodule. When ``format == 'auto'``, + all parsers are tried one by one. - Return instance of StructureParser used to load the data. - See Structure.readStr() for more info. + Return + ------ + StructureParser + Instance of `StructureParser` used to load the data. """ p = Structure.readStr(self, s, format) sg = getattr(p, "spacegroup", None) diff --git a/src/diffpy/structure/sgtbxspacegroups.py b/src/diffpy/structure/sgtbxspacegroups.py index 0b5c382a..0ba28fc2 100644 --- a/src/diffpy/structure/sgtbxspacegroups.py +++ b/src/diffpy/structure/sgtbxspacegroups.py @@ -13,11 +13,13 @@ # ############################################################################## -"""Extra space group representations generated using sgtbx module from cctbx. -Import of this module extends the SpaceGroupList in the SpaceGroups module. -Notable variables: +"""Extra space group representations generated using `sgtbx` module from `cctbx`. +Import of this module extends the `SpaceGroupList` in the `SpaceGroups` module. -sgtbxSpaceGroupList -- list of space group instances defined in this module +Attributes +---------- +sgtbxSpaceGroupList : list + List of space group instances defined in this module. """ diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 716fdbb4..c31b7cae 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright 2002 by PyMMLib Development Group, http://pymmlib.sourceforge.net/ # This code is part of the PyMMLib distribution and governed by -# its license. Please see the LICENSE_pymmlib file that should have been +# its license. Please see the LICENSE_pymmlib file that should have been # included as part of this package. """Symmetry operations as functions on vectors or arrays. """ @@ -110,8 +110,7 @@ class SymOp(object): - """ - The transformation of coordinates to a symmetry-related position. + """The transformation of coordinates to a symmetry-related position. The SymOp operation involves rotation and translation in cell coordinates. @@ -127,7 +126,7 @@ class SymOp(object): R : numpy.ndarray The 3x3 matrix of rotation pertaining to unit cell coordinates. This may be identity, simple rotation, improper rotation, mirror - or inversion. The determinant of *R* is either +1 or -1. + or inversion. The determinant of *R* is either +1 or -1. t : numpy.ndarray The translation of cell coordinates applied after rotation *R*. """ @@ -160,7 +159,7 @@ def __call__(self, vec): return numpy.dot(self.R, vec) + self.t def __eq__(self, symop): - """Implement the ``(self == symop)`` test of equality. + """Implement the ``self == symop`` test of equality. Return ``True`` when *self* and *symop* difference is within tiny round-off errors. @@ -211,9 +210,9 @@ class SpaceGroup(object): Attributes ---------- number : int - A unique space group number. This may be incremented by + A unique space group number. This may be incremented by several thousands to facilitate unique values for multiple - settings of the same space group. Use ``number % 1000`` + settings of the same space group. Use ``number % 1000`` to get the standard space group number from International Tables. num_sym_equiv : int @@ -225,7 +224,7 @@ class SpaceGroup(object): point_group_name : str The point group to which this space group belongs to. crystal_system : str - The crystal system of this space group. The possible values are + The crystal system of this space group. The possible values are ``"TRICLINIC", "MONOCLINIC", "ORTHORHOMBIC", "TETRAGONAL", "TRIGONAL" "HEXAGONAL", "CUBIC"``. pdb_name : str @@ -271,7 +270,7 @@ def iter_symops(self): Yields ------ - `SymOp` + SymOp Generate all symmetry operations for this space group. """ return iter(self.symop_list) diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index 38fd39a2..414d56e5 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -14,6 +14,11 @@ ############################################################################## """Space group classes and definitions from mmLib and sgtbx. + +Attributes +---------- +SpaceGroupList : list + List of all spacegroup definitions. """ import copy @@ -643,18 +648,27 @@ # Import SpaceGroup objects -------------------------------------------------- -# all spacegroup definitions SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList def GetSpaceGroup(sgid): """Returns the SpaceGroup instance for the given identifier. - sgid -- space group symbol, either short_name or pdb_name, - whatever it means in mmlib. Can be also an integer. + Parameters + ---------- + sgid : str, int + space group symbol, either `short_name` or `pdb_name`, + whatever it means in mmlib. Can be also an integer. + + Returns + ------- + SpaceGroup + The SpaceGroup object for the given identifier. - Return space group instance. - Raise ValueError when not found. + Raises + ------ + ValueError + When the identifier is not found. """ if not _sg_lookup_table: _buildSGLookupTable() @@ -679,9 +693,11 @@ def GetSpaceGroup(sgid): def IsSpaceGroupIdentifier(sgid): - """Check if identifier can be used as an argument to GetSpaceGroup. + """Check if identifier can be used as an argument to `GetSpaceGroup`. - Return bool. + Returns + ------- + bool """ try: GetSpaceGroup(sgid) @@ -700,13 +716,13 @@ def FindSpaceGroup(symops, shuffle=False): The list of `SymOp` objects for which to find SpaceGroup. shuffle : bool, Optional Flag for allowing different order of symops in the returned - SpaceGroup. The default is ``False``. + SpaceGroup. The default is ``False``. Returns ------- SpaceGroup The SpaceGroup object with equivalent list of symmetry - operations. Return predefined SpaceGroup instance when + operations. Return predefined SpaceGroup instance when symmetry operations have the same order or when the `shuffle` flag is set. @@ -751,10 +767,8 @@ def _hashSymOpList(symops): def _buildSGLookupTable(): - """Rebuild space group lookup table from the SpaceGroupList data. - - This routine updates the global _sg_lookup_table dictionary. - No return value. + """Rebuild space group lookup table from the `SpaceGroupList` data. + This routine updates the global `_sg_lookup_table` dictionary. """ _sg_lookup_table.clear() for sg in SpaceGroupList: @@ -795,7 +809,7 @@ def _buildSGLookupTable(): def _getSGHashLookupTable(): - """Return lookup table of symop hashes to standard SpaceGroup objects.""" + """Return lookup table of symop hashes to standard `SpaceGroup` objects.""" if _sg_hash_lookup_table: return _sg_hash_lookup_table for sg in SpaceGroupList: diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index d8063013..5bebf4eb 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -13,7 +13,7 @@ # ############################################################################## -"""This module defines class Structure. +"""This module defines class `Structure`. """ import codecs @@ -29,45 +29,65 @@ class Structure(list): - """Structure --> group of atoms - - Structure class is inherited from Python list. It contains - a list of Atom instances. Structure overloads setitem and setslice - methods so that the lattice attribute of atoms get set to lattice. - - Data members: - title -- structure description - lattice -- coordinate system (instance of Lattice) - pdffit -- None or a dictionary of PDFFit-related metadata + """Define group of atoms in a specified lattice. Structure --> group of atoms. + + `Structure` class is inherited from Python `list`. It contains + a list of `Atom` instances. `Structure` overloads `setitem` and `setslice` + methods so that the `lattice` attribute of atoms get set to `lattice`. + + Parameters + ---------- + atoms : list of Atom or Structure, Optional + List of `Atom` instances to be included in this `Structure`. + When `atoms` argument is an existing `Structure` instance, + the new structure is its copy. + lattice : Lattice, Optional + Instance of `Lattice` defining coordinate systems, property. + title : str, Optional + String description of the structure. + filename : str, Optional + Name of a file to load the structure from. + format : str, Optional + `Structure` format of the loaded `filename`. By default + all structure formats are tried one by one. Ignored when + `filename` has not been specified. + + Note + ---- + Cannot use `filename` and `atoms` arguments together. Overrides `atoms` argument + when `filename` is specified. + + Attributes + ---------- + title : str + String description of the structure. + lattice : Lattice + Instance of `Lattice` defining coordinate systems. + pdffit : None or dict + Dictionary of PDFFit-related metadata. + + Examples + -------- + ``Structure(stru)`` create a copy of `Structure` instance stru. + + >>> stru = Structure() + >>> copystru = Structure(stru) + + `Structure` is inherited from a list it can use list expansions. + + >>> oxygen_atoms = [a for a in stru if a.element == "O" ] + >>> oxygen_stru = Structure(oxygen_atoms, lattice=stru.lattice) """ # default values for instance attributes - title = "" + """str: default values for `title`.""" + _lattice = None pdffit = None + """None: default values for `pdffit`.""" def __init__(self, atoms=None, lattice=None, title=None, filename=None, format=None): - """define group of atoms in a specified lattice. - - atoms -- list of Atom instances to be included in this Structure. - When atoms argument is an existing Structure instance, - the new Structure is its copy. - lattice -- instance of Lattice defining coordinate systems, property. - title -- string description of the structure - filename -- Optional, name of a file to load the structure from. - Overrides atoms argument when specified. - format -- Optional structure format of the loaded filename. By default - all structure formats are tried one by one. Ignored when - filename has not been specified. - - Structure(stru) create a copy of Structure instance stru. - - Because Structure is inherited from a list it can use list expansions, - for example: - oxygen_atoms = [ for a in stru if a.element == "O" ] - oxygen_stru = Structure(oxygen_atoms, lattice=stru.lattice) - """ # if filename is specified load it and return if filename is not None: if any((atoms, lattice, title)): @@ -92,17 +112,22 @@ def __init__(self, atoms=None, lattice=None, title=None, filename=None, format=N return def copy(self): - """Return a copy of this Structure object.""" + """Return a copy of this `Structure` object.""" return copymod.copy(self) def __copy__(self, target=None): """Create a deep copy of this instance. - target -- Optional target instance for copying, useful for - copying a derived class. Defaults to new instance - of the same type as self. + Parameters + ---------- + target : + Optional target instance for copying, useful for + copying a derived class. Defaults to new instance + of the same type as self. - Return a duplicate instance of this object. + Returns + ------- + A duplicate instance of this object. """ if target is None: target = Structure() @@ -117,17 +142,18 @@ def __copy__(self, target=None): return target def __str__(self): - """simple string representation""" + """Simple string representation.""" s_lattice = "lattice=%s" % self.lattice s_atoms = "\n".join([str(a) for a in self]) return s_lattice + "\n" + s_atoms def addNewAtom(self, *args, **kwargs): - """Add new Atom instance to the end of this Structure. - - All arguments are forwarded to Atom constructor. + """Add new `Atom` instance to the end of this `Structure`. - No return value. + Parameters + ---------- + *args, **kwargs : + See `Atom` class constructor. """ kwargs["lattice"] = self.lattice a = Atom(*args, **kwargs) @@ -135,16 +161,15 @@ def addNewAtom(self, *args, **kwargs): return def getLastAtom(self): - """Return Reference to the last Atom in this structure.""" + """Return Reference to the last `Atom` in this structure.""" last_atom = self[-1] return last_atom def assignUniqueLabels(self): - """Set a unique label string for each atom in this structure. + """Set a unique label string for each `Atom` in this structure. + The label strings are formatted as "%(baresymbol)s%(index)i", where baresymbol is the element right-stripped of "[0-9][+-]". - - No return value. """ elnum = {} # support duplicate atom instances @@ -159,25 +184,24 @@ def assignUniqueLabels(self): return def distance(self, aid0, aid1): - """ - Calculate distance between 2 atoms, no periodic boundary conditions. + """Calculate distance between 2 `Atoms`, no periodic boundary conditions. Parameters ---------- aid0 : int or str - Zero based index of the first atom or a string label such as "Na1". + Zero based index of the first `Atom` or a string label. aid1 : int or str Zero based index or string label of the second atom. Returns ------- float - Distance between the two atoms in Angstroms. + Distance between the two `Atoms` in Angstroms. Raises ------ IndexError - If any of the atom indices or labels are invalid. + If any of the `Atom` indices or labels are invalid. """ # lookup by labels a0, a1 = self[aid0, aid1] @@ -185,12 +209,12 @@ def distance(self, aid0, aid1): def angle(self, aid0, aid1, aid2): """ - The bond angle at the second of three atoms in degrees. + The bond angle at the second of three `Atoms` in degrees. Parameters ---------- aid0 : int or str - Zero based index of the first atom or a string label such as "Na1". + Zero based index of the first `Atom` or a string label. aid1 : int or str Index or string label for the second atom, where the angle is formed. aid2 : int or str @@ -212,12 +236,21 @@ def angle(self, aid0, aid1, aid2): return self.lattice.angle(u10, u12) def placeInLattice(self, new_lattice): - """place structure into new_lattice coordinate system + """place structure into `new_lattice` coordinate system. - sets lattice to new_lattice and recalculate fractional coordinates - of all atoms so their absolute positions remain the same + Sets `lattice` to `new_lattice` and recalculate fractional coordinates + of all `Atoms` so their absolute positions remain the same. - return self + Parameters + ---------- + new_lattice : Lattice + New `lattice` to place the structure into. + + Returns + ------- + Structure + Reference to this `Structure` object. The `lattice` attribute + is updated to `new_lattice`. """ Tx = numpy.dot(self.lattice.base, new_lattice.recbase) Tu = numpy.dot(self.lattice.normbase, new_lattice.recnormbase) @@ -229,16 +262,15 @@ def placeInLattice(self, new_lattice): return self def read(self, filename, format="auto"): - """ - Load structure from a file, any original data become lost. + """Load structure from a file, any original data become lost. Parameters ---------- filename : str - File to be loaded + File to be loaded. format : str, Optional - all structure formats are defined in parsers submodule, - when format == 'auto' all parsers are tried one by one + All structure formats are defined in parsers submodule, + when ``format == 'auto'`` all parsers are tried one by one. Returns ------- @@ -267,15 +299,14 @@ def read(self, filename, format="auto"): return p def readStr(self, s, format="auto"): - """ - Read structure from a string. + """Read structure from a string. Parameters ---------- s : str String with structure definition. format : str, Optional - All structure formats are defined in parsers submodule. When format == 'auto', + All structure formats are defined in parsers submodule. When ``format == 'auto'``, all parsers are tried one by one. Returns @@ -297,12 +328,20 @@ def readStr(self, s, format="auto"): return p def write(self, filename, format): - """Save structure to file in the specified format + """Save structure to file in the specified format. + + Parameters + ---------- + filename : str + File to save the structure to. + format : str + `Structure` format to use for saving. - No return value. + Note + ---- + Available structure formats can be obtained by: - Note: available structure formats can be obtained by: - from parsers import formats + ``from parsers import formats`` """ from diffpy.structure.parsers import getParser @@ -314,10 +353,13 @@ def write(self, filename, format): return def writeStr(self, format): - """return string representation of the structure in specified format + """return string representation of the structure in specified format. + + Note + ---- + Available structure formats can be obtained by: - Note: available structure formats can be obtained by: - from parsers import formats + ``from parsers import formats`` """ from diffpy.structure.parsers import getParser @@ -326,26 +368,21 @@ def writeStr(self, format): return s def tolist(self): - """Return atoms in this Structure as a standard Python list.""" + """Return `Atoms` in this `Structure` as a standard Python list.""" rv = [a for a in self] return rv # Overloaded list Methods and Operators ---------------------------------- def append(self, a, copy=True): - """ - Append atom to a structure and update its lattice attribute. + """Append `Atom` to a structure and update its `lattice` attribute. Parameters ---------- a : Atom - Instance of Atom to be appended. + Instance of `Atom` to be appended. copy : bool, Optional - Flag for appending a copy of a. When False, append a and update a.lattice. - - Returns - ------- - None + Flag for appending a copy of `a`. When ``False``, append `a` and update `a.lattice`. """ adup = copy and Atom(a) or a adup.lattice = self.lattice @@ -353,21 +390,16 @@ def append(self, a, copy=True): return def insert(self, idx, a, copy=True): - """ - Insert atom a before position idx in this Structure. + """Insert `Atom` a before position idx in this `Structure`. Parameters ---------- idx : int - Position in atom list. + Position in `Atom` list. a : Atom - Instance of Atom to be inserted. + Instance of `Atom` to be inserted. copy : bool, Optional - Flag for inserting a copy of a. When False, append a and update a.lattice. - - Returns - ------- - None + Flag for inserting a copy of `a`. When ``False``, append `a` and update `a.lattice`. """ adup = copy and copymod.copy(a) or a adup.lattice = self.lattice @@ -375,17 +407,17 @@ def insert(self, idx, a, copy=True): return def extend(self, atoms, copy=None): - """Extend Structure with an iterable of atoms. + """Extend `Structure` with an iterable of `atoms`. - Update the `lattice` attribute of all added atoms. + Update the `lattice` attribute of all added `atoms`. Parameters ---------- atoms : Iterable - The `Atom` objects to be appended to this Structure. + The `Atom` objects to be appended to this `Structure`. copy : bool, Optional - Flag for adding copies of Atom objects. - Make copies when `True`, append `atoms` unchanged when ``False``. + Flag for adding copies of `Atom` objects. + Make copies when ``True``, append `atoms` unchanged when ``False``. The default behavior is to make copies when `atoms` are of `Structure` type or if new atoms introduce repeated objects. """ @@ -415,25 +447,44 @@ def setlat(a): return def __getitem__(self, idx): - """Get one or more atoms in this structure. + """Get one or more `Atoms` in this structure. - idx -- atom identifier, which can be integer, string or iterable. - When integer use standard list lookup. For iterables use - numpy lookup, this supports integer or boolean flag arrays. - For string or string-containing iterables lookup the atoms - by string label. + Parameters + ---------- + idx : int ot str ot Iterable + `Atom` identifier. When integer use standard list lookup. + For iterables use numpy lookup, this supports integer or + boolean flag arrays. For string or string-containing iterables + lookup the `Atoms` by string label. - Return an Atom instance for integer or string index or a substructure - in all other cases. Raise IndexError for invalid index or for - non-unique atom label. + Returns + ------- + Atom or Structure + An `Atom` instance for integer or string index or a substructure + in all other cases. + + Raises + ------ + IndexError + If the index is invalid or the `Atom` label is not unique. + + Examples + -------- + First `Atom` in the `Structure`: + + >>> stru[0] + + Substructure of all ``'Na'`` `Atoms`: + + >>> stru[stru.element == 'Na'] + + `Atom` with a unique label ``'Na3'``: + >>> stru['Na3'] - Examples: + Substructure of three `Atoms`, lookup by label is more efficient + when done for several `Atoms` at once. - stru[0] --> first atom in the Structure - stru[stru.element == 'Na'] --> substructure of all Na atoms - stru['Na3'] --> atom with a unique label 'Na3' - stru['Na3', 2, 'Cl2'] --> substructure of three atoms, lookup by - label is more efficient when done for several atoms at once. + >>> stru['Na3', 2, 'Cl2'] """ if isinstance(idx, slice): rv = self.__emptySharedStructure() @@ -488,14 +539,18 @@ def _resolveindex(aid): return rv def __setitem__(self, idx, value, copy=True): - """Assign self[idx] atom to value. + """Assign `self[idx]` `Atom` to value. - idx -- index of atom in this Structure or a slice - value -- instance of Atom or an iterable. - copy -- flag for making a copy of the value. When False, update - the `lattice` attribute of Atom objects present in value. - - No return value. + Parameters + ---------- + idx : int or slice + Index of `Atom` in this `Structure` or a slice. + value : Atom or Iterable + Instance of `Atom` or an iterable. + copy : bool, Optional + Flag for making a copy of the value. When ``False``, update + the `lattice` attribute of `Atom` objects present in value. + Default is ``True``. """ # handle slice assignment if isinstance(idx, slice): @@ -517,32 +572,50 @@ def _fixlat(a): return def __add__(self, other): - """Return new Structure object with appended atoms from other. + """Return new `Structure` object with appended `Atoms` from other. - other -- sequence of Atom instances + Parameters + ---------- + other : sequence of Atom + Sequence of `Atom` instances. - Return new Structure with a copy of Atom instances. + Returns + ------- + Structure + New `Structure` with a copy of `Atom` instances. """ rv = copymod.copy(self) rv += other return rv def __iadd__(self, other): - """Extend this Structure with atoms from other. + """Extend this `Structure` with `Atoms` from other. - other -- sequence of Atom instances + Parameters + ---------- + other : sequence of Atom + Sequence of `Atom` instances. - Return self. + Returns + ------- + Structure + Reference to this `Structure` object. """ self.extend(other, copy=True) return self def __sub__(self, other): - """Return new Structure that has atoms from the other removed. + """Return new `Structure` that has `Atoms` from the other removed. - other -- sequence of Atom instances + Parameters + ---------- + other : sequence of Atom + Sequence of `Atom` instances. - Return new Structure with a copy of Atom instances. + Returns + ------- + Structure + New `Structure` with a copy of `Atom` instances. """ otherset = set(other) keepindices = [i for i, a in enumerate(self) if a not in otherset] @@ -550,23 +623,35 @@ def __sub__(self, other): return rv def __isub__(self, other): - """Remove other atoms if present in this structure. + """Remove other `Atoms` if present in this structure. - other -- sequence of Atom instances + Parameters + ---------- + other : sequence of Atom + Sequence of `Atom` instances. - Return self. + Returns + ------- + Structure + Reference to this `Structure` object. """ otherset = set(other) self[:] = [a for a in self if a not in otherset] return self def __mul__(self, n): - """Return new Structure with n-times concatenated atoms from self. - Atoms and lattice in the new structure are all copies. + """Return new `Structure` with n-times concatenated `Atoms` from self. + `Atoms` and `lattice` in the new structure are all copies. - n -- integer multiple + Parameters + ---------- + n : int + Integer multiple. - Return new Structure. + Returns + ------- + Structure + New `Structure` with n-times concatenated `Atoms`. """ rv = copymod.copy(self[:0]) rv += n * self.tolist() @@ -576,13 +661,19 @@ def __mul__(self, n): __rmul__ = __mul__ def __imul__(self, n): - """Concatenate this Structure to n-times more atoms. - For positive multiple the current Atom objects remain at the - beginning of this Structure. + """Concatenate this `Structure` to n-times more `Atoms`. + For positive multiple the current `Atom` objects remain at the + beginning of this `Structure`. - n -- integer multiple + Parameters + ---------- + n : int + Integer multiple. - Return self. + Returns + ------- + Structure + Reference to this `Structure` object. """ if n <= 0: self[:] = [] @@ -603,7 +694,7 @@ def _set_lattice(self, value): self._lattice = value return - lattice = property(_get_lattice, _set_lattice, doc="Coordinate system for this Structure.") + lattice = property(_get_lattice, _set_lattice, doc="Coordinate system for this `Structure`.") # composition @@ -619,154 +710,154 @@ def _get_composition(self): element = _linkAtomAttribute( "element", - """Character array of atom types. Assignment updates - the element attribute of the respective atoms.""", + """Character array of `Atom` types. Assignment updates + the element attribute of the respective `Atoms`.""", toarray=numpy.char.array, ) xyz = _linkAtomAttribute( "xyz", - """Array of fractional coordinates of all atoms. - Assignment updates xyz attribute of all atoms.""", + """Array of fractional coordinates of all `Atoms`. + Assignment updates `xyz` attribute of all `Atoms`.""", ) x = _linkAtomAttribute( "x", - """Array of all fractional coordinates x. - Assignment updates xyz attribute of all atoms.""", + """Array of all fractional coordinates `x`. + Assignment updates `xyz` attribute of all `Atoms`.""", ) y = _linkAtomAttribute( "y", - """Array of all fractional coordinates y. - Assignment updates xyz attribute of all atoms.""", + """Array of all fractional coordinates `y`. + Assignment updates `xyz` attribute of all `Atoms`.""", ) z = _linkAtomAttribute( "z", - """Array of all fractional coordinates z. - Assignment updates xyz attribute of all atoms.""", + """Array of all fractional coordinates `z`. + Assignment updates `xyz` attribute of all `Atoms`.""", ) label = _linkAtomAttribute( "label", - """Character array of atom names. Assignment updates - the label attribute of all atoms.""", + """Character array of `Atom` names. Assignment updates + the label attribute of all `Atoms`.""", toarray=numpy.char.array, ) occupancy = _linkAtomAttribute( "occupancy", - """Array of atom occupancies. Assignment updates the - occupancy attribute of all atoms.""", + """Array of `Atom` occupancies. Assignment updates the + occupancy attribute of all `Atoms`.""", ) xyz_cartn = _linkAtomAttribute( "xyz_cartn", - """Array of absolute Cartesian coordinates of all atoms. - Assignment updates the xyz attribute of all atoms.""", + """Array of absolute Cartesian coordinates of all `Atoms`. + Assignment updates the `xyz` attribute of all `Atoms`.""", ) anisotropy = _linkAtomAttribute( "anisotropy", """Boolean array for anisotropic thermal displacement flags. - Assignment updates the anisotropy attribute of all atoms.""", + Assignment updates the anisotropy attribute of all `Atoms`.""", ) U = _linkAtomAttribute( "U", """Array of anisotropic thermal displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) Uisoequiv = _linkAtomAttribute( "Uisoequiv", """Array of isotropic thermal displacement or equivalent values. - Assignment updates the U attribute of all atoms.""", + Assignment updates the U attribute of all `Atoms`.""", ) U11 = _linkAtomAttribute( "U11", - """Array of U11 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U11` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) U22 = _linkAtomAttribute( "U22", - """Array of U22 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U22` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) U33 = _linkAtomAttribute( "U33", - """Array of U33 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U33` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) U12 = _linkAtomAttribute( "U12", - """Array of U12 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U12` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) U13 = _linkAtomAttribute( "U13", - """Array of U13 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U13` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) U23 = _linkAtomAttribute( "U23", - """Array of U23 elements of the anisotropic displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `U23` elements of the anisotropic displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) Bisoequiv = _linkAtomAttribute( "Bisoequiv", """Array of Debye-Waller isotropic thermal displacement or equivalent - values. Assignment updates the U attribute of all atoms.""", + values. Assignment updates the U attribute of all `Atoms`.""", ) B11 = _linkAtomAttribute( "B11", - """Array of B11 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B11` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) B22 = _linkAtomAttribute( "B22", - """Array of B22 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B22` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) B33 = _linkAtomAttribute( "B33", - """Array of B33 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B33` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) B12 = _linkAtomAttribute( "B12", - """Array of B12 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B12` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) B13 = _linkAtomAttribute( "B13", - """Array of B13 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B13` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) B23 = _linkAtomAttribute( "B23", - """Array of B23 elements of the Debye-Waller displacement tensors. - Assignment updates the U and anisotropy attributes of all atoms.""", + """Array of `B23` elements of the Debye-Waller displacement tensors. + Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) # Private Methods -------------------------------------------------------- def __emptySharedStructure(self): - """Return empty Structure with standard attributes same as in self.""" + """Return empty `Structure` with standard attributes same as in self.""" rv = Structure() rv.__dict__.update([(k, getattr(self, k)) for k in rv.__dict__]) return rv diff --git a/src/diffpy/structure/structureerrors.py b/src/diffpy/structure/structureerrors.py index 2669b6e1..c930b9b7 100644 --- a/src/diffpy/structure/structureerrors.py +++ b/src/diffpy/structure/structureerrors.py @@ -18,7 +18,7 @@ class StructureFormatError(Exception): - """Exception for failed IO from Structure file""" + """Exception for failed IO from Structure file.""" pass diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index afad7371..b58e7c88 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -15,6 +15,16 @@ """Symmetry utility functions such as expansion of asymmetric unit, and generation of positional constraints. + +Attributes +---------- +epsilon : float + Default tolerance for equality of 2 positions, also + used for identification of special positions. + +stdUsymbols : list + Standard symbols denoting elements of anisotropic thermal + displacement tensor. """ import re @@ -26,12 +36,8 @@ # Constants ------------------------------------------------------------------ -# Default tolerance for equality of 2 positions, also -# used for identification of special positions. epsilon = 1.0e-5 -# Standard symbols denoting elements of anisotropic thermal -# displacement tensor. stdUsymbols = ["U11", "U22", "U33", "U12", "U13", "U23"] # ---------------------------------------------------------------------------- @@ -40,10 +46,23 @@ def isSpaceGroupLatPar(spacegroup, a, b, c, alpha, beta, gamma): """Check if space group allows passed lattice parameters. - spacegroup -- instance of SpaceGroup - a, b, c, alpha, beta, gamma -- lattice parameters + Parameters + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + a, b, c, alpha, beta, gamma : float + `Lattice` parameters. + + Return + ------ + bool + ``True`` when lattice parameters are allowed by space group. + + Note + ---- + Crystal system rules: - Return bool. + Benjamin, W. A., Introduction to crystallography, New York (1969), p.60. """ # crystal system rules @@ -93,12 +112,17 @@ def check_cubic(): def isconstantFormula(s): - """Check if formula string is constant. True when argument - is a floating point number or a fraction of float with integer. + """Check if formula string is constant. - s -- formula string + Parameters + ---------- + s : str + Formula string. - Return bool. + Return + ------ + bool + ``True`` when argument is a floating point number or a fraction of float with integer. """ res = _rx_constant_formula.match(s.replace(" ", "")) return bool(res) @@ -109,22 +133,26 @@ def isconstantFormula(s): class _Position2Tuple(object): """Create callable object that converts fractional coordinates to - a tuple of integers with given precision. For presision close to zero + a tuple of integers with given precision. For presision close to zero it will return a tuples of double. - Note: Helper class intended for local use only. + Note + ---- + Helper class intended for local use only. - Data members: + Parameters + ---------- + eps : float + Cutoff for equivalent coordinates. - eps -- cutoff for equivalent coordinates. When two coordiantes map to the - same tuple, they are closer than eps. + Attributes + ---------- + eps : float + Cutoff for equivalent coordinates. When two coordiantes map to the + same tuple, they are closer than `eps`. """ def __init__(self, eps=None): - """Initialize _Position2Tuple - - eps -- cutoff for equivalent coordinates - """ if eps is None: eps = epsilon # ensure self.eps has exact machine representation @@ -138,9 +166,15 @@ def __init__(self, eps=None): def __call__(self, xyz): """Convert array of fractional coordinates to a tuple. - xyz -- fractional coordinates + Parameters + ---------- + xyz : Iterable + Fractional coordinates. - Return a tuple of 3 numbers. + Return + ------ + tuple + Tuple of 3 float when `eps` is zero, otherwise tuple of 3 int. """ # no conversion case if self.eps == 0.0: @@ -157,9 +191,16 @@ def __call__(self, xyz): def positionDifference(xyz0, xyz1): """Smallest difference between two coordinates in periodic lattice. - xyz0, xyz1 -- fractional coordinates + Parameters + ---------- + xyz0, xyz1 : array_like + Fractional coordinates. - Return dxyz, a numpy.array dxyz with 0 <= dxyz <= 0.5. + Return + ------ + dxyz : numpy.ndarray + Smallest difference between two coordinates in periodic lattice + with ``0 <= dxyz <= 0.5``. """ dxyz = numpy.asarray(xyz0) - xyz1 # map differences to [0,0.5] @@ -172,10 +213,17 @@ def positionDifference(xyz0, xyz1): def nearestSiteIndex(sites, xyz): """Index of the nearest site to a specified position. - sites -- list of coordinates or a 2-dimensional numpy.array - xyz -- single position - - Return integer. + Parameters + ---------- + sites : array_like + List of coordinates. + xyz : array_like + Single position. + + Return + ------ + int + Index of the nearest site. """ # we use box distance to be consistent with _Position2Tuple conversion dbox = positionDifference(sites, xyz).max(axis=1) @@ -186,10 +234,17 @@ def nearestSiteIndex(sites, xyz): def equalPositions(xyz0, xyz1, eps): """Equality of two coordinates with optional tolerance. - xyz0, xyz1 -- fractional coordinates - eps -- tolerance for equality of coordinates - - Return bool. + Parameters + ---------- + xyz0, xyz1 : array_like + Fractional coordinates. + eps : float + Tolerance for equality of coordinates. + + Return + ------ + bool + ``True`` when two coordinates are closer than `eps`. """ # we use box distance to be consistent with _Position2Tuple conversion dxyz = positionDifference(xyz0, xyz1) @@ -199,13 +254,22 @@ def equalPositions(xyz0, xyz1, eps): def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): """Obtain unique equivalent positions and corresponding operations. - spacegroup -- instance of SpaceGroup - xyz -- position to be expanded - sgoffset -- offset of space group origin [0, 0, 0] - eps -- cutoff for equal positions - - Return a tuple with (list of unique equivalent positions, nested - list of SpaceGroups.SymOp instances, site multiplicity). + Parameters + ---------- + spacegroup : SpaceGroup + Instance of SpaceGroup. + xyz : list + Position to be expanded. + sgoffset : list, Optional + Offset of space group origin ``[0, 0, 0]``. Default is ``[0, 0, 0]``. + eps : float, Optional + Cutoff for equal positions, default is ``1.0e-5``. + + Return + ------ + tuple + A tuple with ``(list of unique equivalent positions, nested + list of `SpaceGroups.SymOp` instances, site multiplicity)``. """ sgoffset = numpy.asarray(sgoffset, dtype=float) if eps is None: @@ -256,10 +320,20 @@ def nullSpace(A): def _findInvariants(symops): """Find a list of symmetry operations which contains identity. - symops -- nested list of SymOp instances + Parameters + ---------- + symops : list of SymOp + Nested list of `SymOp` instances. - Return the list-item in symops which contains identity. - Raise ValueError when identity was not found. + Return + ------ + list + List-item in symops which contains identity. + + Raise + ----- + ValueError + When identity is not found. """ invrnts = None R0 = numpy.identity(3, dtype=float) @@ -283,37 +357,53 @@ def _findInvariants(symops): class GeneratorSite(object): """Storage of data related to a generator positions. - Data members: - xyz : - Fractional coordinates of generator site - Uij : - Anisotropic thermal displacement at generator site - sgoffset : - Offset of space group origin [0, 0, 0] - eps : - Cutoff for equal positions - eqxyz : - List of equivalent positions - eqUij : - List of displacement matrices at equivalent positions - symops : - Nested list of operations per each eqxyz - multiplicity : - Generator site multiplicity - Uisotropy : - Bool flag for isotropic thermal factors - invariants : - List of invariant operations for generator site - null_space : - Null space of all possible differences of invariant - rotational matrices, this is a base of symmetry - allowed shifts. - Uspace : - 3D array of independent components of U matrices. - pparameters : - List of (xyz symbol, value) pairs - Uparameters : - List of (U symbol, value) pairs + Parameters + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + xyz : array_like + Generating site. When `xyz` is close to special + position `self.xyz` will be adjusted. + Uij : array_like, Optional + Thermal factors at generator site. Yields `self.Uij` + after adjusting to spacegroup symmetry. Default is zeros. + sgoffset : list, Optional + Offset of space group origin ``[0, 0, 0]``. Default is ``[0, 0, 0]``. + eps : float, Optional + Cutoff for equal positions. Default is ``1.0e-5``. + + Attributes + ---------- + xyz : numpy.ndarray + Fractional coordinates of generator site. + Uij : numpy.ndarray + Anisotropic thermal displacement at generator site. + sgoffset : numpy.ndarray + Offset of space group origin ``[0, 0, 0]``. + eps : float + Cutoff for equal positions. + eqxyz : list + List of equivalent positions. + eqUij : list + List of displacement matrices at equivalent positions. + symops : list + Nested list of operations per each `eqxyz`. + multiplicity : int + Generator site multiplicity. + Uisotropy : bool + Bool flag for isotropic thermal factors. + invariants : list + List of invariant operations for generator site. + null_space : numpy.ndarray + Null space of all possible differences of invariant + rotational matrices, this is a base of symmetry + allowed shifts. + Uspace : numpy.ndarray + 3D array of independent components of U matrices. + pparameters : list + List of ``(xyz symbol, value)`` pairs. + Uparameters : list + List of ``(U symbol, value)`` pairs. """ Ucomponents = numpy.array( @@ -327,19 +417,12 @@ class GeneratorSite(object): ], dtype=float, ) + """numpy.ndarray: 6x3x3 array of independent components of U matrices.""" + idx2Usymbol = {0: "U11", 1: "U12", 2: "U13", 3: "U12", 4: "U22", 5: "U23", 6: "U13", 7: "U23", 8: "U33"} + """dict: Mapping of index to standard U symbol.""" def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3, 3)), sgoffset=[0, 0, 0], eps=None): - """Initialize GeneratorSite. - - spacegroup -- instance of SpaceGroup - xyz -- generating site. When xyz is close to special - position self.xyz will be adjusted. - Uij -- thermal factors at generator site. Yields self.Uij - after adjusting to spacegroup symmetry. - sgoffset -- offset of space group origin [0, 0, 0] - eps -- cutoff for equal positions - """ if eps is None: eps = epsilon # just declare the members @@ -385,10 +468,19 @@ def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3, 3)), sgoffset=[0, 0, 0], def signedRatStr(self, x): """Convert floating point number to signed rational representation. + Possible fractional are multiples of 1/3, 1/6, 1/7, 1/9, if these - are not close, return "%+g" format. + are not close, return `%+g` format. + + Parameters + ---------- + x : float + Floating point number. - Return string. + Return + ------ + str + Signed rational representation of `x`. """ s = "{:.8g}".format(x) if len(s) < 6: @@ -402,8 +494,8 @@ def signedRatStr(self, x): return "%+.0f/%.0f" % (nom[idx[0]], den[idx[0]]) def _findNullSpace(self): - """Calculate self.null_space from self.invariants. - Try to represent self.null_space using small integers. + """Calculate `self.null_space` from `self.invariants`. + Try to represent `self.null_space` using small integers. """ R0 = self.invariants[0].R Rdiff = [(symop.R - R0) for symop in self.invariants] @@ -433,7 +525,7 @@ def _findNullSpace(self): return def _findPosParameters(self): - """Find pparameters and their values for expressing self.xyz.""" + """Find pparameters and their values for expressing `self.xyz`.""" usedsymbol = {} # parameter values depend on offset of self.xyz txyz = self.xyz @@ -476,7 +568,7 @@ def _findUSpace(self): return def _findUParameters(self): - """Find Uparameters and their values for expressing self.Uij.""" + """Find Uparameters and their values for expressing `self.Uij`.""" # permute indices as 00 11 22 01 02 12 10 20 21 diagorder = numpy.array((0, 4, 8, 1, 2, 5, 3, 6, 7)) Uijflat = self.Uij.flatten() @@ -491,7 +583,7 @@ def _findUParameters(self): return def _findeqUij(self): - """Adjust self.Uij and self.eqUij to be consistent with spacegroup""" + """Adjust `self.Uij` and `self.eqUij` to be consistent with spacegroup.""" self.Uij = numpy.zeros((3, 3), dtype=float) for i in range(len(self.Uparameters)): Usp = self.Uspace[i] @@ -506,15 +598,22 @@ def _findeqUij(self): return def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): - """Formula of equivalent position with respect to generator site - - pos -- fractional coordinates of possibly equivalent site - xyzsymbols -- symbols for parametrized coordinates - - Return position formulas in a dictionary with keys equal ("x", "y", "z") - or an empty dictionary when pos is not equivalent to generator. - Formulas are formatted as "[[-][%g*]{x|y|z}] [{+|-}%g]", for example - "-x", "z +0.5", "0.25". + """Formula of equivalent position with respect to generator site. + + Parameters + ---------- + pos : array_like + Fractional coordinates of possibly equivalent site. + xyzsymbols : tuple, Optional + Symbols for parametrized coordinates. + + Return + ------ + dict + Position formulas in a dictionary with keys equal ``("x", "y", "z")`` + or an empty dictionary when pos is not equivalent to generator. + Formulas are formatted as ``[[-][%g*]{x|y|z}] [{+|-}%g]``, for example + ``-x``, ``z +0.5``, ``0.25``. """ # find pos in eqxyz idx = nearestSiteIndex(self.eqxyz, pos) @@ -549,12 +648,20 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): def UFormula(self, pos, Usymbols=stdUsymbols): """List of atom displacement formulas with custom parameter symbols. - pos -- fractional coordinates of possibly equivalent site - Usymbols -- 6 symbols for possible U matrix parameters - - Return U element formulas in a dictionary where keys are from - ('U11','U22','U33','U12','U13','U23') or empty dictionary when - pos is not equivalent to generator. + Parameters + ---------- + pos : array_like + Fractional coordinates of possibly equivalent site. + Usymbols : list, Optional + 6 symbols for possible U matrix parameters, default is + ``["U11", "U22", "U33", "U12", "U13", "U23"]``. + + Return + ------ + Uformula : dict + U element formulas in a dictionary where keys are from + ``('U11','U22','U33','U12','U13','U23')`` or empty dictionary when + pos is not equivalent to generator. """ # find pos in eqxyz idx = nearestSiteIndex(self.eqxyz, pos) @@ -584,11 +691,17 @@ def UFormula(self, pos, Usymbols=stdUsymbols): return Uformula def eqIndex(self, pos): - """Index of the nearest generator equivalent site + """Index of the nearest generator equivalent site. - pos -- fractional coordinates + Parameters + ---------- + pos : array_like + Fractional coordinates. - Return integer. + Return + ------ + int + Index of the nearest generator equivalent site. """ return nearestSiteIndex(self.eqxyz, pos) @@ -599,45 +712,48 @@ def eqIndex(self, pos): class ExpandAsymmetricUnit(object): - """ - Expand asymmetric unit and anisotropic thermal displacement - - Data members: - spacegroup : - Instance of SpaceGroup - corepos : - List of positions in asymmetric unit, - it may contain duplicates - coreUijs : - Thermal factors for corepos (defaults to zeros) - sgoffset : - Optional offset of space group origin [0, 0, 0] - eps : - Cutoff for equivalent positions - - Calculated data members: - multiplicity : - Multiplicity of each site in corepos - Uisotropy : - Bool flags for isotropic sites in corepos - expandedpos : - List of equivalent positions per each site in corepos - expandedUijs : - List of thermal factors per each site in corepos + """Expand asymmetric unit and anisotropic thermal displacement. + + Parameters + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + corepos : array_like + List of positions in asymmetric unit, + it may contain duplicates. + coreUijs : numpy.ndarray, Optional + Thermal factors for `corepos`. + sgoffset : list, Optional + Offset of space group origin ``[0, 0, 0]``. Default is ``[0, 0, 0]``. + eps : float, Optional + Cutoff for duplicate positions. Default is ``1.0e-5``. + + Attributes + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + corepos : array_like + List of positions in asymmetric unit, + it may contain duplicates. + coreUijs : numpy.ndarray + Thermal factors for `corepos`. Defaults to zeros. + sgoffset : numpy.ndarray + Offset of space group origin ``[0, 0, 0]``. Default to zeros. + eps : float + Cutoff for equivalent positions. Default is ``1.0e-5``. + multiplicity : list + Multiplicity of each site in `corepos`. + Uisotropy : list + Bool flags for isotropic sites in `corepos`. + expandedpos : list + List of equivalent positions per each site in `corepos`. + expandedUijs : list + List of thermal factors per each site in `corepos`. """ # By design Atom instances are not accepted as arguments to keep # number of required imports low. def __init__(self, spacegroup, corepos, coreUijs=None, sgoffset=[0, 0, 0], eps=None): - """Initialize and calculate instance of ExpandAsymmetricUnit - - spacegroup -- instance of SpaceGroup - corepos -- list of positions in asymmetric unit, - it may contain duplicates - coreUijs -- thermal factors for corepos (defaults to zeros) - sgoffset -- offset of space group origin [0, 0, 0] - eps -- cutoff for duplicate positions - """ if eps is None: eps = epsilon # declare data members @@ -668,17 +784,23 @@ def __init__(self, spacegroup, corepos, coreUijs=None, sgoffset=[0, 0, 0], eps=N # End of class ExpandAsymmetricUnit -# Helper function for SymmetryConstraints class. It may be useful +# Helper function for SymmetryConstraints class. It may be useful # elsewhere therefore its name does not start with underscore. def pruneFormulaDictionary(eqdict): """Remove constant items from formula dictionary. - eqdict -- formula dictionary which maps standard variable symbols - ("x", "U11") to string formulas ("0", "-x3", "z7 +0.5") + Parameters + ---------- + eqdict : dict + Formula dictionary which maps standard variable symbols + ``("x", "U11")`` to string formulas ``("0", "-x3", "z7 +0.5")``. - Return pruned formula dictionary. + Return + ------ + dict + Pruned formula dictionary. """ pruned = {} for smb, eq in eqdict.items(): @@ -688,55 +810,58 @@ def pruneFormulaDictionary(eqdict): class SymmetryConstraints(object): - """ - Generate symmetry constraints for specified positions - - Data members: - spacegroup : - Instance of SpaceGroup - positions : - All positions to be constrained - Uijs : - Thermal factors for all positions (defaults to zeros) - sgoffset : - Optional offset of space group origin [0, 0, 0] - eps : - Cutoff for equivalent positions - - Calculated data members: - corepos : - List of of positions in the asymmetric unit - coremap : - Dictionary mapping indices of asymmetric core positions - to indices of all symmetry related positions - poseqns : - List of coordinate formula dictionaries per each site. - Formula dictionary keys are from ("x", "y", "z") and - the values are formatted as [[-]{x|y|z}%i] [{+|-}%g], - for example: "x0", "-x3", "z7 +0.5", "0.25". - pospars : - List of (xyz symbol, value) pairs - Ueqns : - List of anisotropic atomic displacement formula - dictionaries per each position. Formula dictionary - keys are from ('U11','U22','U33','U12','U13','U23') - and the values are formatted as {[%g*][Uij%i]|0}, - for example: "U110", "0.5*U2213", "0" - Upars : - List of (U symbol, value) pairs - Uisotropy : - List of bool flags for isotropic thermal displacements + """Generate symmetry constraints for specified positions. + + Parameters + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + positions : array_like + List of all positions to be constrained. + Uijs : array_like, Optional + List of U matrices for all constrained positions. + sgoffset : list, Optional + Offset of space group origin ``[0, 0, 0]``. Default is ``[0, 0, 0]``. + eps : float, Optional + Cutoff for duplicate positions. Default is ``1.0e-5``. + + Attributes + ---------- + spacegroup : SpaceGroup + Instance of `SpaceGroup`. + positions : numpy.ndarray + All positions to be constrained. + Uijs : numpy.ndarray + Thermal factors for all positions. Defaults to zeros. + sgoffset : numpy.ndarray + Optional offset of space group origin ``[0, 0, 0]``. + eps : float + Cutoff for equivalent positions. Default is ``1.0e-5``. + corepos : list + List of of positions in the asymmetric unit. + coremap : dict + Dictionary mapping indices of asymmetric core positions + to indices of all symmetry related positions. + poseqns : list + List of coordinate formula dictionaries per each site. + Formula dictionary keys are from ``("x", "y", "z")`` and + the values are formatted as ``[[-]{x|y|z}%i] [{+|-}%g]``, + for example: ``x0``, ``-x3``, ``z7 +0.5``, ``0.25``. + pospars : list + List of ``(xyz symbol, value)`` pairs. + Ueqns : list + List of anisotropic atomic displacement formula + dictionaries per each position. Formula dictionary + keys are from ``('U11','U22','U33','U12','U13','U23')`` + and the values are formatted as ``{[%g*][Uij%i]|0}``, + for example: ``U110``, ``0.5*U2213``, ``0``. + Upars : list + List of ``(U symbol, value)`` pairs. + Uisotropy : list + List of bool flags for isotropic thermal displacements. """ def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=None): - """Initialize and calculate SymmetryConstraints. - - spacegroup -- instance of SpaceGroup - positions -- list of all positions to be constrained - Uijs -- list of U matrices for all constrained positions - sgoffset -- optional offset of space group origin [0, 0, 0] - eps -- cutoff for equivalent positions - """ if eps is None: eps = epsilon # fill in data members @@ -777,7 +902,7 @@ def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=Non return def _findConstraints(self): - """Find constraints for positions and anisotropic displacements Uij""" + """Find constraints for positions and anisotropic displacements `Uij`.""" numpos = len(self.positions) # canonical xyzsymbols and Usymbols xyzsymbols = [smbl + str(i) for i in range(numpos) for smbl in "xyz"] @@ -835,11 +960,17 @@ def posparValues(self): def positionFormulas(self, xyzsymbols=None): """List of position formulas with custom parameter symbols. - xyzsymbols -- list of custom symbols used in formula strings - - Return list of coordinate formulas dictionaries. Formulas dictionary - keys are from ("x", "y", "z") and the values are formatted as - [[-]{symbol}] [{+|-}%g], for example: "x0", "-sym", "@7 +0.5", "0.25". + Parameters + ---------- + xyzsymbols : list, Optional + List of custom symbols used in formula strings. + + Return + ------ + list + List of coordinate formulas dictionaries. Formulas dictionary + keys are from ``("x", "y", "z")`` and the values are formatted as + ``[[-]{symbol}] [{+|-}%g]``, for example: ``x0``, ``-sym``, ``@7 +0.5``, ``0.25``. """ if not xyzsymbols: return list(self.poseqns) @@ -864,11 +995,20 @@ def translatesymbol(matchobj): def positionFormulasPruned(self, xyzsymbols=None): """List of position formula dictionaries with constant items removed. - See also positionFormulas(). - xyzsymbols -- list of custom symbols used in formula strings + See also + -------- + positionFormulas() + + Parameters + ---------- + xyzsymbols : list, Optional + List of custom symbols used in formula strings. - Return list of coordinate formula dictionaries. + Return + ------ + list + List of coordinate formula dictionaries. """ rv = [pruneFormulaDictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] return rv @@ -884,12 +1024,18 @@ def UparValues(self): def UFormulas(self, Usymbols=None): """List of atom displacement formulas with custom parameter symbols. - Usymbols -- list of custom symbols used in formula strings - - Return list of atom displacement formula dictionaries per each site. - Formula dictionary keys are from ('U11','U22','U33','U12','U13','U23') - and the values are formatted as {[%g*][Usymbol]|0}, for example: - "U11", "0.5*@37", "0". + Parameters + ---------- + Usymbols : list, Optional + List of custom symbols used in formula strings. + + Return + ------ + list + List of atom displacement formula dictionaries per each site. + Formula dictionary keys are from ``('U11','U22','U33','U12','U13','U23')`` + and the values are formatted as ``{[%g*][Usymbol]|0}``, for example: + ``U11``, ``0.5*@37``, ``0``. """ if not Usymbols: return list(self.Ueqns) @@ -914,12 +1060,22 @@ def translatesymbol(matchobj): def UFormulasPruned(self, Usymbols=None): """List of atom displacement formula dictionaries with constant items - removed. See also UFormulas(). - - Usymbols -- list of custom symbols used in formula strings - - Return list of atom displacement formulas in tuples of - (U11, U22, U33, U12, U13, U23). + removed. + + See Also + -------- + UFormulas() + + Parameters + ---------- + Usymbols : list, Optional + List of custom symbols used in formula strings. + + Return + ------ + list + List of atom displacement formulas in tuples of + ``(U11, U22, U33, U12, U13, U23)``. """ rv = [pruneFormulaDictionary(eqns) for eqns in self.UFormulas(Usymbols)] return rv diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 94cb97d3..e5fa3ce3 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -22,13 +22,13 @@ def isiterable(obj): - """True if argument is iterable.""" + """``True`` if argument is iterable.""" rv = isinstance(obj, _Iterable) return rv def isfloat(s): - """True if argument can be converted to float""" + """``True`` if argument can be converted to float.""" try: float(s) return True @@ -39,12 +39,30 @@ def isfloat(s): def atomBareSymbol(smbl): """Remove atom type string stripped of isotope and ion charge symbols. - This removes blank and leading [0-9-] or trailing [1-9][+-] characters. - smbl -- atom type string such as "Cl-", "Ca2+" or "12-C". + This function removes any blank, isotope numbers (0-9), leading hyphens (-), and ion charge + symbols (1-9)(+-) from the given atom type string, returning only the bare element symbol. - Return bare element symbol. + Parameters + ---------- + smbl : str + Atom type string that may include isotope numbers, ion charges, or hyphens. + + Returns + ------- + str + The bare element symbol. + + Examples + -------- + >>> atomBareSymbol("Cl-") + 'Cl' + >>> atomBareSymbol("Ca2+") + 'Ca' + >>> atomBareSymbol("12-C") + 'C' """ + rv = smbl.strip().lstrip("0123456789-").rstrip("123456789+-") return rv @@ -56,12 +74,12 @@ def _linkAtomAttribute(attrname, doc, toarray=numpy.array): """Create property wrapper that maps the specified atom attribute. The returned property object provides convenient access to atom - attributes from the owner Structure class. + attributes from the owner `Structure` class. Parameters ---------- attrname : str - The string name of the Atom class attribute to be mapped. + The string name of the `Atom` class attribute to be mapped. doc : str The docstring for the property wrapper. toarray : callable, Optional From 6ee5bc2c32a98cdd2c07a8ad5b4a1b1d9accdc4e Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 5 Aug 2024 14:43:18 -0400 Subject: [PATCH 043/226] fix news and changelog --- CHANGELOG.rst | 17 ----------------- news/changlog.rst | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 news/changlog.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3d4b5e17..e446d478 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,23 +4,6 @@ Release Notes .. current developments -Version 3.2.0 - 2024-7-2 --------------------------- -**Added:** - -**Changed:** - -**Deprecated:** - -**Removed:** - -**Fixed:** - -- Repo structure modified to the new diffpy standard - -**Security:** - - Version 3.1.0 - 2022-12-04 -------------------------- diff --git a/news/changlog.rst b/news/changlog.rst new file mode 100644 index 00000000..fa57dae8 --- /dev/null +++ b/news/changlog.rst @@ -0,0 +1,25 @@ +**Added:** + +* + +**Changed:** + +* All docstrings style updated to numpydoc. + +**Deprecated:** + +* Deprecated the `diffpy.structure.applications` module. Use + `diffpy.structure.apps` instead. + +**Removed:** + +* Removed all `six` compatibility code. The package is now going to + Python > 3.10. + +**Fixed:** + +* Repo structure modified to the new diffpy standard. + +**Security:** + +* From 34c9c7b83770dcf37ef815305315a31b5d6a8db5 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 9 Aug 2024 14:56:49 -0400 Subject: [PATCH 044/226] Update changlog.rst --- news/changlog.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/news/changlog.rst b/news/changlog.rst index fa57dae8..cc5f014f 100644 --- a/news/changlog.rst +++ b/news/changlog.rst @@ -4,21 +4,22 @@ **Changed:** -* All docstrings style updated to numpydoc. +* Removed support for Python 2 +* This version only supporting Python 3.10, 3.11, 3.12 +* All docstrings style updated to numpydoc **Deprecated:** * Deprecated the `diffpy.structure.applications` module. Use - `diffpy.structure.apps` instead. + `diffpy.structure.apps` instead **Removed:** -* Removed all `six` compatibility code. The package is now going to - Python > 3.10. +* Removed all `six` compatibility code **Fixed:** -* Repo structure modified to the new diffpy standard. +* Repo structure modified to the new diffpy standard **Security:** From 6ebf1ae83d5d6446daa70ca73b91554ae2dfd200 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 9 Aug 2024 18:59:59 +0000 Subject: [PATCH 045/226] Update CHANGELOG.rst --- CHANGELOG.rst | 24 ++++++++++++++++++++++++ news/changlog.rst | 26 -------------------------- 2 files changed, 24 insertions(+), 26 deletions(-) delete mode 100644 news/changlog.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e446d478..cd95b867 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,30 @@ Release Notes .. current developments +3.2.0rc0 +======== + +**Changed:** + +* Removed support for Python 2 +* This version only supporting Python 3.10, 3.11, 3.12 +* All docstrings style updated to numpydoc + +**Deprecated:** + +* Deprecated the `diffpy.structure.applications` module. Use + `diffpy.structure.apps` instead + +**Removed:** + +* Removed all `six` compatibility code + +**Fixed:** + +* Repo structure modified to the new diffpy standard + + + Version 3.1.0 - 2022-12-04 -------------------------- diff --git a/news/changlog.rst b/news/changlog.rst deleted file mode 100644 index cc5f014f..00000000 --- a/news/changlog.rst +++ /dev/null @@ -1,26 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Removed support for Python 2 -* This version only supporting Python 3.10, 3.11, 3.12 -* All docstrings style updated to numpydoc - -**Deprecated:** - -* Deprecated the `diffpy.structure.applications` module. Use - `diffpy.structure.apps` instead - -**Removed:** - -* Removed all `six` compatibility code - -**Fixed:** - -* Repo structure modified to the new diffpy standard - -**Security:** - -* From 4ebbbf2c37f1273ee376277568767267cdb2fe49 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 9 Aug 2024 19:22:31 +0000 Subject: [PATCH 046/226] Update CHANGELOG.rst --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index cd95b867..a2c05370 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,11 @@ Release Notes .. current developments +3.2.0 +===== + + + 3.2.0rc0 ======== From cf875f163166262babafc963d55047c4530dbb45 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Fri, 9 Aug 2024 15:31:20 -0400 Subject: [PATCH 047/226] Remove requirement section in readme.rst --- README.rst | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/README.rst b/README.rst index 42d7ef98..5dd3a227 100644 --- a/README.rst +++ b/README.rst @@ -63,28 +63,6 @@ by citing the following paper in your publication: `__, *Acta Crystallogr. A* **71**, 562-568 (2015). -Requirements ------------------------------------------------------------------------- - -The diffpy.structure package requires Python 3.7 or later and -the following software: - -* ``setuptools`` - software distribution tools for Python -* ``NumPy`` - numerical mathematics and fast array operations for Python - -We recommend to use `Anaconda Python `_ -as it allows to install all software dependencies together with -diffpy.structure. For other Python distributions it is necessary to -install the required software separately. As an example on Ubuntu -Linux the required software can be installed with :: - - sudo aptitude install python3-setuptools python3-numpy - -diffpy.structure also uses the -`PyCifRW `_ -library, which is automatically deployed during the -installation process. - Installation ------------ From 93e22ff6bc0ed2bb847019077a2ca472efbd319c Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 9 Aug 2024 15:47:27 -0400 Subject: [PATCH 048/226] upload codecov results in action. --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3ceb7a6a..10776d37 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,6 +45,7 @@ jobs: conda install --file requirements/run.txt conda install --file requirements/test.txt pip install -e . + - name: Validate diffpy.structure shell: bash -l {0} run: | @@ -52,3 +53,8 @@ jobs: coverage run -m diffpy.structure.tests.run coverage report -m codecov + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 86d0c2bf2584c6dd66f8f7e7e43b15085cdb44d0 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 12 Aug 2024 10:35:46 -0400 Subject: [PATCH 049/226] update yml files --- .github/workflows/docs.yml | 15 ++++++++++++++- .github/workflows/main.yml | 11 +++-------- .github/workflows/pre-commit.yml | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/pre-commit.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a4661f5c..8f22d668 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,8 +36,21 @@ jobs: - name: build documents run: make -C doc html + - name: Run tests and upload coverage + shell: bash -l {0} + run: | + conda activate test + coverage run -m pytest -vv -s + coverage report -m + codecov + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./doc/build/html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 10776d37..a56262f9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,17 +44,12 @@ jobs: conda activate test conda install --file requirements/run.txt conda install --file requirements/test.txt - pip install -e . - + pip install . + - name: Validate diffpy.structure shell: bash -l {0} run: | conda activate test - coverage run -m diffpy.structure.tests.run + coverage run -m pytest -vv -s coverage report -m codecov - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000..f2ff7e42 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,19 @@ +name: pre-commit + +on: + pull_request: + push: + workflow_dispatch: + +jobs: + pre-commit: + # pull requests are a duplicate of a branch push if within the same repo. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - uses: pre-commit/action@v3.0.0 + with: + extra_args: --all-files From c8a2477e3ea0e3c66fef7895db9e0316c308c000 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Mon, 19 Aug 2024 14:16:05 -0400 Subject: [PATCH 050/226] remove pre-release from changelog --- CHANGELOG.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a2c05370..9196571a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,11 +7,6 @@ Release Notes 3.2.0 ===== - - -3.2.0rc0 -======== - **Changed:** * Removed support for Python 2 From f660310fe099b8edf73e2cf689f593fa6c1898b0 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 14:23:30 -0400 Subject: [PATCH 051/226] try new workflow ymls --- .github/workflows/codecov.yml | 53 +++++++++++++++++++++++++++++++ .github/workflows/docs.yml | 59 +++++++++++++++-------------------- .github/workflows/main.yml | 55 -------------------------------- .github/workflows/test.yml | 42 +++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 88 deletions(-) create mode 100644 .github/workflows/codecov.yml delete mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 00000000..b25d4bfb --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,53 @@ +name: Gather coverage report and upload to codecov + +on: + push: + branches: + - main + release: + types: + - prereleased + - published + workflow_dispatch: + +defaults: + run: + shell: bash -l {0} + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - name: Check out diffpy.structure + 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 + + - name: Conda config + run: >- + conda config --set always_yes yes + --set changeps1 no + + - name: Install diffpy.structure and requirements + run: | + conda install --file requirements/run.txt + conda install --file requirements/test.txt + python -m pip install -r requirements/pip.txt + python -m pip install . --no-deps + + - name: Validate diffpy.structure + run: | + coverage run -m pytest -vv -s + coverage report -m + codecov + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8f22d668..d5c882a5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,54 +1,47 @@ -name: Build Documentation +name: Build and Deploy Documentation on: - push: - branches: - - main release: + types: + - prereleased + - published + workflow_dispatch: + +defaults: + run: + shell: bash -l {0} jobs: - test: + docs: runs-on: ubuntu-latest - defaults: - run: - shell: bash -l {0} steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 + - name: Check out diffpy.structure + uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 + - name: Initialize miniconda + uses: conda-incubator/setup-miniconda@v3 with: activate-environment: build auto-update-conda: true + environment-file: environment.yml + auto-activate-base: false - - name: install requirements + - name: Conda config run: >- - conda install -n build -c conda-forge - --file requirements/build.txt - --file requirements/run.txt - --file requirements/docs.txt - --quiet --yes + conda config --set always_yes yes + --set changeps1 no - - name: install the package - run: python -m pip install . --no-deps + - name: Install diffpy.structure and build requirements + run: | + conda install --file requirements/build.txt + conda install --file requirements/run.txt + conda install --file requirements/docs.txt + python -m pip install -r requirements/pip.txt + python -m pip install . --no-deps - name: build documents run: make -C doc html - - name: Run tests and upload coverage - shell: bash -l {0} - run: | - conda activate test - coverage run -m pytest -vv -s - coverage report -m - codecov - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - name: Deploy uses: peaceiris/actions-gh-pages@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index a56262f9..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: CI - -on: - push: - branches: - - main - - CI - pull_request: - workflow_dispatch: - -jobs: - miniconda: - name: Miniconda ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: ["ubuntu-latest"] - steps: - - name: check out diffpy.structure - uses: actions/checkout@v3 - with: - repository: diffpy/diffpy.structure - path: . - fetch-depth: 0 # avoid shallow clone with no tags - - - name: initialize miniconda - # this uses a marketplace action that sets up miniconda in a way that makes - # it easier to use. I tried setting it up without this and it was a pain - uses: conda-incubator/setup-miniconda@v2 - with: - activate-environment: test - # environment.yml file is needed by this action. Because I don't want - # maintain this but rather maintain the requirements files it just has - # basic things in it like conda and pip - environment-file: ./environment.yml - python-version: 3 - auto-activate-base: false - - - name: install diffpy.structure requirements - shell: bash -l {0} - run: | - conda config --set always_yes yes --set changeps1 no - conda config --add channels conda-forge - conda activate test - conda install --file requirements/run.txt - conda install --file requirements/test.txt - pip install . - - - name: Validate diffpy.structure - shell: bash -l {0} - run: | - conda activate test - coverage run -m pytest -vv -s - coverage report -m - codecov diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..9cd4de0a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,42 @@ +name: Validate using pytest + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +defaults: + run: + shell: bash -l {0} + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Check out diffpy.structure + 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 + + - name: Conda config + run: >- + conda config --set always_yes yes + --set changeps1 no + + - name: Install diffpy.structure and requirements + run: | + conda install --file requirements/run.txt + conda install --file requirements/test.txt + python -m pip install -r requirements/pip.txt + python -m pip install . --no-deps + + - name: Validate diffpy.structure + run: python -m pytest From 6f849daaa6d3e19c1d9a24eec67a9b5af0b458bc Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 14:36:48 -0400 Subject: [PATCH 052/226] give proper job name for codecov workflow --- .github/workflows/codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index b25d4bfb..fd96a710 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -15,7 +15,7 @@ defaults: shell: bash -l {0} jobs: - docs: + coverage: runs-on: ubuntu-latest steps: - name: Check out diffpy.structure From 152d13b9c3dfa22ac527acb0ec5317a94490eb44 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 14:42:47 -0400 Subject: [PATCH 053/226] try delete pre-commit.yml --- .github/workflows/pre-commit.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/pre-commit.yml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml deleted file mode 100644 index f2ff7e42..00000000 --- a/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: pre-commit - -on: - pull_request: - push: - workflow_dispatch: - -jobs: - pre-commit: - # pull requests are a duplicate of a branch push if within the same repo. - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - - uses: pre-commit/action@v3.0.0 - with: - extra_args: --all-files From bfab9e02993ebce290a144a8b699d84e81086190 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 15:01:08 -0400 Subject: [PATCH 054/226] CI badge --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 5dd3a227..7fb0a48f 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,8 @@ .. |Black| image:: https://img.shields.io/badge/code_style-black-black :target: https://github.com/psf/black -.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml/badge.svg - :target: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml +.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/test.yml/badge.svg + :target: https://github.com/diffpy/diffpy.structure/actions/workflows/test.yml .. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/main/graph/badge.svg :target: https://codecov.io/gh/diffpy/diffpy.structure From 07ef5ddb323df64e22c439b32a94afc0acad3571 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 23:34:00 -0400 Subject: [PATCH 055/226] Rename test workflow for better badge display --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9cd4de0a..33ece6cf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Validate using pytest +name: Test on: push: From 18c44dc14d367a354ee10551d8222d4dd7082a20 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Mon, 19 Aug 2024 23:42:37 -0400 Subject: [PATCH 056/226] remove useless file --- requirements/README.txt | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 requirements/README.txt diff --git a/requirements/README.txt b/requirements/README.txt deleted file mode 100644 index dc34909d..00000000 --- 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! From 0990186aa3ac35b41e75dc23f70013a4914ea771 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 20 Aug 2024 02:46:41 -0400 Subject: [PATCH 057/226] remove prerelease from build docs workflow --- .github/workflows/docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d5c882a5..df2b392f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,7 +3,6 @@ name: Build and Deploy Documentation on: release: types: - - prereleased - published workflow_dispatch: From 61fda2450bedbc9804a073ab61ec9288aad34706 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 20 Aug 2024 11:04:18 -0400 Subject: [PATCH 058/226] Use the lates workflow file name --- .github/workflows/{test.yml => main.yml} | 0 README.rst | 4 ++-- doc/source/index.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename .github/workflows/{test.yml => main.yml} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/main.yml similarity index 100% rename from .github/workflows/test.yml rename to .github/workflows/main.yml diff --git a/README.rst b/README.rst index 7fb0a48f..5dd3a227 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,8 @@ .. |Black| image:: https://img.shields.io/badge/code_style-black-black :target: https://github.com/psf/black -.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/test.yml/badge.svg - :target: https://github.com/diffpy/diffpy.structure/actions/workflows/test.yml +.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml .. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/main/graph/badge.svg :target: https://codecov.io/gh/diffpy/diffpy.structure diff --git a/doc/source/index.rst b/doc/source/index.rst index 457e4105..4fabbaa1 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,7 +4,7 @@ .. |title| replace:: diffpy.structure documentation -diffpy.structure - Crystal structure container and parsers for structure formats.. +diffpy.structure - Crystal structure container and parsers for structure formats. | Software version |release|. | Last updated |today|. From 5d3841b5bfc4fd4330693f35fe534b7488d626ca Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 3 Sep 2024 05:52:50 -0400 Subject: [PATCH 059/226] add dynamic dependency in pyproject.toml --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 73f92e1b..0b37965c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "diffpy.structure" -dynamic=['version'] +dynamic=['version', 'dependencies'] authors = [ { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, ] @@ -48,6 +48,9 @@ include = ["*"] # package names should match these glob patterns (["*"] by defa exclude = ["diffpy.structure.tests*"] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[tool.setuptools.dynamic] +dependencies = {file = ["requirements/run.txt"]} + [tool.black] line-length = 115 include = '\.pyi?$' From b0271c03933c6c3af7c8fcd8c9503dcc3fcef40c Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Tue, 3 Sep 2024 18:59:25 +0000 Subject: [PATCH 060/226] Update CHANGELOG.rst --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9196571a..0fde0ea2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,11 @@ Release Notes .. current developments +3.2.1 +===== + + + 3.2.0 ===== From c44895208c1a7ab0611d26f8f83ae4280ab528cb Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:54:39 -0400 Subject: [PATCH 061/226] Remove test testutils func --- src/diffpy/structure/tests/testutils.py | 25 ------------------- .../structure/tests => tests}/__init__.py | 0 .../structure/tests => tests}/conftest.py | 0 .../diffpy/structure/tests => tests}/debug.py | 0 {src/diffpy/structure/tests => tests}/run.py | 0 .../structure/tests => tests}/test_atom.py | 0 .../structure/tests => tests}/test_lattice.py | 0 .../tests => tests}/test_loadstructure.py | 0 .../tests => tests}/test_oldimports.py | 0 .../structure/tests => tests}/test_p_cif.py | 0 .../tests => tests}/test_p_discus.py | 0 .../tests => tests}/test_p_pdffit.py | 0 .../structure/tests => tests}/test_parsers.py | 0 .../tests => tests}/test_spacegroups.py | 0 .../tests => tests}/test_structure.py | 0 .../tests => tests}/test_supercell.py | 0 .../tests => tests}/test_symmetryutilities.py | 0 .../testdata/BubbleRaftShort.xcfg | 0 .../tests => tests}/testdata/CdSe_bulk.stru | 0 .../tests => tests}/testdata/LiCl-bad.cif | 0 .../tests => tests}/testdata/Ni-bad.stru | 0 .../tests => tests}/testdata/Ni-discus.stru | 0 .../tests => tests}/testdata/Ni.stru | 0 .../tests => tests}/testdata/Ni_prim123.stru | 0 .../tests => tests}/testdata/Ni_ref.cif | 0 .../tests => tests}/testdata/PbTe.cif | 0 .../tests => tests}/testdata/TeI-unkocc.cif | 0 .../tests => tests}/testdata/TeI.cif | 0 .../testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr | 0 .../tests => tests}/testdata/arginine.pdb | 0 .../testdata/badspacegroup.cif | 0 .../tests => tests}/testdata/bucky-bad1.xyz | 0 .../tests => tests}/testdata/bucky-bad2.xyz | 0 .../testdata/bucky-plain-bad.xyz | 0 .../tests => tests}/testdata/bucky-plain.xyz | 0 .../tests => tests}/testdata/bucky-raw.xyz | 0 .../tests => tests}/testdata/bucky.xyz | 0 .../testdata/curlybrackets.cif | 0 .../tests => tests}/testdata/customsg.cif | 0 .../tests => tests}/testdata/graphite.cif | 0 .../testdata/hexagon-raw-bad.xyz | 0 .../tests => tests}/testdata/hexagon-raw.xy | 0 .../tests => tests}/testdata/hexagon-raw.xyz | 0 .../tests => tests}/testdata/nosites.cif | 0 44 files changed, 25 deletions(-) delete mode 100644 src/diffpy/structure/tests/testutils.py rename {src/diffpy/structure/tests => tests}/__init__.py (100%) rename {src/diffpy/structure/tests => tests}/conftest.py (100%) rename {src/diffpy/structure/tests => tests}/debug.py (100%) rename {src/diffpy/structure/tests => tests}/run.py (100%) rename {src/diffpy/structure/tests => tests}/test_atom.py (100%) rename {src/diffpy/structure/tests => tests}/test_lattice.py (100%) rename {src/diffpy/structure/tests => tests}/test_loadstructure.py (100%) rename {src/diffpy/structure/tests => tests}/test_oldimports.py (100%) rename {src/diffpy/structure/tests => tests}/test_p_cif.py (100%) rename {src/diffpy/structure/tests => tests}/test_p_discus.py (100%) rename {src/diffpy/structure/tests => tests}/test_p_pdffit.py (100%) rename {src/diffpy/structure/tests => tests}/test_parsers.py (100%) rename {src/diffpy/structure/tests => tests}/test_spacegroups.py (100%) rename {src/diffpy/structure/tests => tests}/test_structure.py (100%) rename {src/diffpy/structure/tests => tests}/test_supercell.py (100%) rename {src/diffpy/structure/tests => tests}/test_symmetryutilities.py (100%) rename {src/diffpy/structure/tests => tests}/testdata/BubbleRaftShort.xcfg (100%) rename {src/diffpy/structure/tests => tests}/testdata/CdSe_bulk.stru (100%) rename {src/diffpy/structure/tests => tests}/testdata/LiCl-bad.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/Ni-bad.stru (100%) rename {src/diffpy/structure/tests => tests}/testdata/Ni-discus.stru (100%) rename {src/diffpy/structure/tests => tests}/testdata/Ni.stru (100%) rename {src/diffpy/structure/tests => tests}/testdata/Ni_prim123.stru (100%) rename {src/diffpy/structure/tests => tests}/testdata/Ni_ref.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/PbTe.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/TeI-unkocc.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/TeI.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr (100%) rename {src/diffpy/structure/tests => tests}/testdata/arginine.pdb (100%) rename {src/diffpy/structure/tests => tests}/testdata/badspacegroup.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky-bad1.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky-bad2.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky-plain-bad.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky-plain.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky-raw.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/bucky.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/curlybrackets.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/customsg.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/graphite.cif (100%) rename {src/diffpy/structure/tests => tests}/testdata/hexagon-raw-bad.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/hexagon-raw.xy (100%) rename {src/diffpy/structure/tests => tests}/testdata/hexagon-raw.xyz (100%) rename {src/diffpy/structure/tests => tests}/testdata/nosites.cif (100%) diff --git a/src/diffpy/structure/tests/testutils.py b/src/diffpy/structure/tests/testutils.py deleted file mode 100644 index 461f020d..00000000 --- a/src/diffpy/structure/tests/testutils.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 Trustees of the Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Helper routines for running other unit tests. -""" - -# helper functions - -from importlib import resources - - -def datafile(filename): - return str(resources.files(__package__).joinpath("testdata/" + filename)) diff --git a/src/diffpy/structure/tests/__init__.py b/tests/__init__.py similarity index 100% rename from src/diffpy/structure/tests/__init__.py rename to tests/__init__.py diff --git a/src/diffpy/structure/tests/conftest.py b/tests/conftest.py similarity index 100% rename from src/diffpy/structure/tests/conftest.py rename to tests/conftest.py diff --git a/src/diffpy/structure/tests/debug.py b/tests/debug.py similarity index 100% rename from src/diffpy/structure/tests/debug.py rename to tests/debug.py diff --git a/src/diffpy/structure/tests/run.py b/tests/run.py similarity index 100% rename from src/diffpy/structure/tests/run.py rename to tests/run.py diff --git a/src/diffpy/structure/tests/test_atom.py b/tests/test_atom.py similarity index 100% rename from src/diffpy/structure/tests/test_atom.py rename to tests/test_atom.py diff --git a/src/diffpy/structure/tests/test_lattice.py b/tests/test_lattice.py similarity index 100% rename from src/diffpy/structure/tests/test_lattice.py rename to tests/test_lattice.py diff --git a/src/diffpy/structure/tests/test_loadstructure.py b/tests/test_loadstructure.py similarity index 100% rename from src/diffpy/structure/tests/test_loadstructure.py rename to tests/test_loadstructure.py diff --git a/src/diffpy/structure/tests/test_oldimports.py b/tests/test_oldimports.py similarity index 100% rename from src/diffpy/structure/tests/test_oldimports.py rename to tests/test_oldimports.py diff --git a/src/diffpy/structure/tests/test_p_cif.py b/tests/test_p_cif.py similarity index 100% rename from src/diffpy/structure/tests/test_p_cif.py rename to tests/test_p_cif.py diff --git a/src/diffpy/structure/tests/test_p_discus.py b/tests/test_p_discus.py similarity index 100% rename from src/diffpy/structure/tests/test_p_discus.py rename to tests/test_p_discus.py diff --git a/src/diffpy/structure/tests/test_p_pdffit.py b/tests/test_p_pdffit.py similarity index 100% rename from src/diffpy/structure/tests/test_p_pdffit.py rename to tests/test_p_pdffit.py diff --git a/src/diffpy/structure/tests/test_parsers.py b/tests/test_parsers.py similarity index 100% rename from src/diffpy/structure/tests/test_parsers.py rename to tests/test_parsers.py diff --git a/src/diffpy/structure/tests/test_spacegroups.py b/tests/test_spacegroups.py similarity index 100% rename from src/diffpy/structure/tests/test_spacegroups.py rename to tests/test_spacegroups.py diff --git a/src/diffpy/structure/tests/test_structure.py b/tests/test_structure.py similarity index 100% rename from src/diffpy/structure/tests/test_structure.py rename to tests/test_structure.py diff --git a/src/diffpy/structure/tests/test_supercell.py b/tests/test_supercell.py similarity index 100% rename from src/diffpy/structure/tests/test_supercell.py rename to tests/test_supercell.py diff --git a/src/diffpy/structure/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py similarity index 100% rename from src/diffpy/structure/tests/test_symmetryutilities.py rename to tests/test_symmetryutilities.py diff --git a/src/diffpy/structure/tests/testdata/BubbleRaftShort.xcfg b/tests/testdata/BubbleRaftShort.xcfg similarity index 100% rename from src/diffpy/structure/tests/testdata/BubbleRaftShort.xcfg rename to tests/testdata/BubbleRaftShort.xcfg diff --git a/src/diffpy/structure/tests/testdata/CdSe_bulk.stru b/tests/testdata/CdSe_bulk.stru similarity index 100% rename from src/diffpy/structure/tests/testdata/CdSe_bulk.stru rename to tests/testdata/CdSe_bulk.stru diff --git a/src/diffpy/structure/tests/testdata/LiCl-bad.cif b/tests/testdata/LiCl-bad.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/LiCl-bad.cif rename to tests/testdata/LiCl-bad.cif diff --git a/src/diffpy/structure/tests/testdata/Ni-bad.stru b/tests/testdata/Ni-bad.stru similarity index 100% rename from src/diffpy/structure/tests/testdata/Ni-bad.stru rename to tests/testdata/Ni-bad.stru diff --git a/src/diffpy/structure/tests/testdata/Ni-discus.stru b/tests/testdata/Ni-discus.stru similarity index 100% rename from src/diffpy/structure/tests/testdata/Ni-discus.stru rename to tests/testdata/Ni-discus.stru diff --git a/src/diffpy/structure/tests/testdata/Ni.stru b/tests/testdata/Ni.stru similarity index 100% rename from src/diffpy/structure/tests/testdata/Ni.stru rename to tests/testdata/Ni.stru diff --git a/src/diffpy/structure/tests/testdata/Ni_prim123.stru b/tests/testdata/Ni_prim123.stru similarity index 100% rename from src/diffpy/structure/tests/testdata/Ni_prim123.stru rename to tests/testdata/Ni_prim123.stru diff --git a/src/diffpy/structure/tests/testdata/Ni_ref.cif b/tests/testdata/Ni_ref.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/Ni_ref.cif rename to tests/testdata/Ni_ref.cif diff --git a/src/diffpy/structure/tests/testdata/PbTe.cif b/tests/testdata/PbTe.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/PbTe.cif rename to tests/testdata/PbTe.cif diff --git a/src/diffpy/structure/tests/testdata/TeI-unkocc.cif b/tests/testdata/TeI-unkocc.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/TeI-unkocc.cif rename to tests/testdata/TeI-unkocc.cif diff --git a/src/diffpy/structure/tests/testdata/TeI.cif b/tests/testdata/TeI.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/TeI.cif rename to tests/testdata/TeI.cif diff --git a/src/diffpy/structure/tests/testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr b/tests/testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr similarity index 100% rename from src/diffpy/structure/tests/testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr rename to tests/testdata/ZnSb_RT_Q28X_VM_20_fxiso.rstr diff --git a/src/diffpy/structure/tests/testdata/arginine.pdb b/tests/testdata/arginine.pdb similarity index 100% rename from src/diffpy/structure/tests/testdata/arginine.pdb rename to tests/testdata/arginine.pdb diff --git a/src/diffpy/structure/tests/testdata/badspacegroup.cif b/tests/testdata/badspacegroup.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/badspacegroup.cif rename to tests/testdata/badspacegroup.cif diff --git a/src/diffpy/structure/tests/testdata/bucky-bad1.xyz b/tests/testdata/bucky-bad1.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky-bad1.xyz rename to tests/testdata/bucky-bad1.xyz diff --git a/src/diffpy/structure/tests/testdata/bucky-bad2.xyz b/tests/testdata/bucky-bad2.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky-bad2.xyz rename to tests/testdata/bucky-bad2.xyz diff --git a/src/diffpy/structure/tests/testdata/bucky-plain-bad.xyz b/tests/testdata/bucky-plain-bad.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky-plain-bad.xyz rename to tests/testdata/bucky-plain-bad.xyz diff --git a/src/diffpy/structure/tests/testdata/bucky-plain.xyz b/tests/testdata/bucky-plain.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky-plain.xyz rename to tests/testdata/bucky-plain.xyz diff --git a/src/diffpy/structure/tests/testdata/bucky-raw.xyz b/tests/testdata/bucky-raw.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky-raw.xyz rename to tests/testdata/bucky-raw.xyz diff --git a/src/diffpy/structure/tests/testdata/bucky.xyz b/tests/testdata/bucky.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/bucky.xyz rename to tests/testdata/bucky.xyz diff --git a/src/diffpy/structure/tests/testdata/curlybrackets.cif b/tests/testdata/curlybrackets.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/curlybrackets.cif rename to tests/testdata/curlybrackets.cif diff --git a/src/diffpy/structure/tests/testdata/customsg.cif b/tests/testdata/customsg.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/customsg.cif rename to tests/testdata/customsg.cif diff --git a/src/diffpy/structure/tests/testdata/graphite.cif b/tests/testdata/graphite.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/graphite.cif rename to tests/testdata/graphite.cif diff --git a/src/diffpy/structure/tests/testdata/hexagon-raw-bad.xyz b/tests/testdata/hexagon-raw-bad.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/hexagon-raw-bad.xyz rename to tests/testdata/hexagon-raw-bad.xyz diff --git a/src/diffpy/structure/tests/testdata/hexagon-raw.xy b/tests/testdata/hexagon-raw.xy similarity index 100% rename from src/diffpy/structure/tests/testdata/hexagon-raw.xy rename to tests/testdata/hexagon-raw.xy diff --git a/src/diffpy/structure/tests/testdata/hexagon-raw.xyz b/tests/testdata/hexagon-raw.xyz similarity index 100% rename from src/diffpy/structure/tests/testdata/hexagon-raw.xyz rename to tests/testdata/hexagon-raw.xyz diff --git a/src/diffpy/structure/tests/testdata/nosites.cif b/tests/testdata/nosites.cif similarity index 100% rename from src/diffpy/structure/tests/testdata/nosites.cif rename to tests/testdata/nosites.cif From 1e0dca9234a865e97bd972faa6a6799beb8a1b6f Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:55:08 -0400 Subject: [PATCH 062/226] Remove exclude for diffpy.structrue.tests in pyproject --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0b37965c..66fb7f89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,6 @@ dirty_template = "{tag}" [tool.setuptools.packages.find] where = ["src"] # list of folders that contain the packages (["."] by default) include = ["*"] # package names should match these glob patterns (["*"] by default) -exclude = ["diffpy.structure.tests*"] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) [tool.setuptools.dynamic] From cf8597b7c4f5c1fe99c00f7d1fd5581c4e1260cd Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:55:35 -0400 Subject: [PATCH 063/226] Remove unittest funcs --- tests/debug.py | 35 ----------------------------------- tests/run.py | 36 ------------------------------------ 2 files changed, 71 deletions(-) delete mode 100644 tests/debug.py delete mode 100644 tests/run.py diff --git a/tests/debug.py b/tests/debug.py deleted file mode 100644 index 36d78c9e..00000000 --- a/tests/debug.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# (c) 2024 The Trustees of Columbia University in the City of New York. -# All rights reserved. -# -# File coded by: Billinge Group members and community contributors. -# -# See GitHub contributions for a more detailed list of contributors. -# https://github.com/diffpy/diffpy.structure/graphs/contributors -# -# See LICENSE.rst for license information. -# -############################################################################## - -""" -Convenience module for debugging the unit tests using - -python -m diffpy.structure.tests.debug - -Exceptions raised by failed tests or other errors are not caught. -""" - - -if __name__ == "__main__": - import sys - - from diffpy.structure.tests import testsuite - - pattern = sys.argv[1] if len(sys.argv) > 1 else "" - suite = testsuite(pattern) - suite.debug() - - -# End of file diff --git a/tests/run.py b/tests/run.py deleted file mode 100644 index 4b9b58ee..00000000 --- a/tests/run.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 Trustees of the Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Convenience module for executing all unit tests with - -python -m diffpy.structure.tests.run -""" - - -if __name__ == "__main__": - import sys - - # show warnings by default - if not sys.warnoptions: - import os - import warnings - - warnings.simplefilter("default") - # also affect subprocesses - os.environ["PYTHONWARNINGS"] = "default" - from diffpy.structure.tests import test - - # produce zero exit code for a successful test - sys.exit(not test().wasSuccessful()) From 40a42f54355e1e192a3bb10afc0047bd1e49b0b6 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:55:53 -0400 Subject: [PATCH 064/226] Include datafile util func in conftest --- tests/conftest.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index e3b63139..ff8aad16 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import json +from importlib import resources from pathlib import Path import pytest @@ -17,3 +18,17 @@ def user_filesystem(tmp_path): json.dump(home_config_data, f) yield tmp_path + + +def get_datafile(filename): + return str(resources.files(__package__).joinpath("testdata/" + filename)) + + +@pytest.fixture +def datafile(): + """Fixture to dynamically load any test file.""" + + def _load(filename): + return get_datafile(filename) + + return _load From 9f5525e9c751a65ad05d3ef7e8534e5c26e7501f Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:56:11 -0400 Subject: [PATCH 065/226] Apply pytest fixtures in unnitest classes --- tests/test_loadstructure.py | 18 +++--- tests/test_p_cif.py | 30 +++++----- tests/test_p_discus.py | 21 ++++--- tests/test_p_pdffit.py | 32 ++++++----- tests/test_parsers.py | 48 ++++++++++------ tests/test_structure.py | 106 +++++++++++++++++------------------- tests/test_supercell.py | 11 ++-- 7 files changed, 148 insertions(+), 118 deletions(-) diff --git a/tests/test_loadstructure.py b/tests/test_loadstructure.py index 92bd4c7f..4f099c7d 100644 --- a/tests/test_loadstructure.py +++ b/tests/test_loadstructure.py @@ -5,17 +5,21 @@ import unittest +import pytest + from diffpy.structure import PDFFitStructure, Structure, loadStructure from diffpy.structure.structureerrors import StructureFormatError -from diffpy.structure.tests.testutils import datafile ############################################################################## class TestLoadStructure(unittest.TestCase): + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile def test_xcfg(self): """check loading of atomeye xcfg format""" - f = datafile("BubbleRaftShort.xcfg") + f = self.datafile("BubbleRaftShort.xcfg") stru = loadStructure(f) self.assertTrue(type(stru) is Structure) self.assertRaises(StructureFormatError, loadStructure, f, "xyz") @@ -23,14 +27,14 @@ def test_xcfg(self): def test_discus(self): """check loading of discus file format""" - f = datafile("Ni-discus.stru") + f = self.datafile("Ni-discus.stru") stru = loadStructure(f) self.assertTrue(type(stru) is PDFFitStructure) return def test_cif(self): """check loading of CIF file format""" - f = datafile("PbTe.cif") + f = self.datafile("PbTe.cif") stru = loadStructure(f) self.assertTrue(isinstance(stru, Structure)) self.assertFalse(isinstance(stru, PDFFitStructure)) @@ -38,20 +42,20 @@ def test_cif(self): def test_badfile(self): """check loading of CIF file format""" - f = datafile("Ni-bad.stru") + f = self.datafile("Ni-bad.stru") self.assertRaises(StructureFormatError, loadStructure, f) return def test_goodkwarg(self): """check loading of CIF file and passing of parser keyword argument.""" - f = datafile("graphite.cif") + f = self.datafile("graphite.cif") stru = loadStructure(f, eps=1e-10) self.assertEqual(8, len(stru)) return def test_badkwarg(self): """check loading of xyz file format with invalid keyword argument""" - f = datafile("bucky.xyz") + f = self.datafile("bucky.xyz") self.assertRaises(TypeError, loadStructure, f, eps=1e-10) return diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index edd611f6..62bb25db 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -19,12 +19,12 @@ import unittest import numpy +import pytest from diffpy.structure import Structure from diffpy.structure.parsers import getParser from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float from diffpy.structure.structureerrors import StructureFormatError -from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- @@ -65,14 +65,16 @@ def test_getSymOp(self): class TestP_cif(unittest.TestCase): - - pbteciffile = datafile("PbTe.cif") - badciffile = datafile("LiCl-bad.cif") - graphiteciffile = datafile("graphite.cif") - cdsebulkpdffitfile = datafile("CdSe_bulk.stru") - teiciffile = datafile("TeI.cif") - refciffile = datafile("Ni_ref.cif") - places = 6 + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + self.pbteciffile = datafile("PbTe.cif") + self.badciffile = datafile("LiCl-bad.cif") + self.graphiteciffile = datafile("graphite.cif") + self.cdsebulkpdffitfile = datafile("CdSe_bulk.stru") + self.teiciffile = datafile("TeI.cif") + self.refciffile = datafile("Ni_ref.cif") + self.places = 6 def setUp(self): self.ptest = P_cif() @@ -240,7 +242,7 @@ def test_eps(self): def test_unknown_occupancy(self): "test CIF file with unknown occupancy data" - stru = self.ptest.parseFile(datafile("TeI-unkocc.cif")) + stru = self.ptest.parseFile(self.datafile("TeI-unkocc.cif")) self.assertTrue(numpy.array_equal(16 * [1], stru.occupancy)) return @@ -268,7 +270,7 @@ def test_unknown_spacegroup_number(self): def test_nosites_cif(self): """Test reading of CIF file with no valid sites.""" ptest = self.ptest - stru = ptest.parseFile(datafile("nosites.cif")) + stru = ptest.parseFile(self.datafile("nosites.cif")) self.assertEqual(0, len(stru)) self.assertEqual(10.413, stru.lattice.a) self.assertEqual(10.413, stru.lattice.b) @@ -278,14 +280,14 @@ def test_nosites_cif(self): def test_badspacegroup_cif(self): """Test reading of CIF file with unrecognized space group.""" ptest = self.ptest - filename = datafile("badspacegroup.cif") + filename = self.datafile("badspacegroup.cif") self.assertRaises(StructureFormatError, ptest.parseFile, filename) return def test_custom_spacegroup_cif(self): """Test parsing of nonstandard symops-defined space group.""" pfile = self.pfile - filename = datafile("customsg.cif") + filename = self.datafile("customsg.cif") pfile.parseFile(filename) sg = pfile.spacegroup self.assertEqual("CIF data", sg.short_name) @@ -363,7 +365,7 @@ def test_unknown_aniso(self): def test_curly_brace(self): "verify loading of a CIF file with unquoted curly brace" ptest = self.ptest - stru = ptest.parseFile(datafile("curlybrackets.cif")) + stru = ptest.parseFile(self.datafile("curlybrackets.cif")) self.assertEqual(20, len(stru)) return diff --git a/tests/test_p_discus.py b/tests/test_p_discus.py index 43c44ea5..8959718e 100644 --- a/tests/test_p_discus.py +++ b/tests/test_p_discus.py @@ -19,9 +19,10 @@ import re import unittest +import pytest + from diffpy.structure import Structure from diffpy.structure.parsers import StructureFormatError -from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- @@ -29,6 +30,10 @@ class TestP_discus(unittest.TestCase): """test Parser for PDFFit file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "discus" @@ -37,7 +42,7 @@ def setUp(self): def test_read_discus_Ni(self): """check reading of Ni structure in discus format""" stru = self.stru - stru.read(datafile("Ni-discus.stru"), self.format) + stru.read(self.datafile("Ni-discus.stru"), self.format) f_title = "structure Ni FCC" self.assertEqual(f_title, stru.title) self.assertEqual("Fm-3m", stru.pdffit["spcgr"]) @@ -75,7 +80,7 @@ def test_except_other_formats(self): "hexagon-raw.xyz", ] for ft in badfiles: - ff = datafile(ft) + ff = self.datafile(ft) self.assertRaises(StructureFormatError, self.stru.read, ff, format=self.format) return @@ -83,7 +88,7 @@ def test_ignored_lines(self): """check skipping of ignored lines in the header""" r1 = "ignored record 1\n" r2 = "ignored record 2\n" - with open(datafile("Ni-discus.stru")) as fp: + with open(self.datafile("Ni-discus.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(2, r1) ni_lines.insert(4, r2) @@ -98,7 +103,7 @@ def test_ignored_lines(self): def test_spdiameter_parsing(self): """check parsing of spdiameter record from a file.""" stru = self.stru - stru.read(datafile("Ni-discus.stru"), self.format) + stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) snoshape = stru.writeStr(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) @@ -109,7 +114,7 @@ def test_spdiameter_parsing(self): stru13 = Structure() stru13.readStr(s13) self.assertEqual(13, stru13.pdffit["spdiameter"]) - with open(datafile("Ni.stru")) as fp: + with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) @@ -119,7 +124,7 @@ def test_spdiameter_parsing(self): def test_stepcut_parsing(self): """check parsing of stepcut record from a file.""" stru = self.stru - stru.read(datafile("Ni-discus.stru"), self.format) + stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) snoshape = stru.writeStr(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) @@ -130,7 +135,7 @@ def test_stepcut_parsing(self): stru13 = Structure() stru13.readStr(s13) self.assertEqual(13, stru13.pdffit["stepcut"]) - with open(datafile("Ni.stru")) as fp: + with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) diff --git a/tests/test_p_pdffit.py b/tests/test_p_pdffit.py index 586ca413..f993cb4b 100644 --- a/tests/test_p_pdffit.py +++ b/tests/test_p_pdffit.py @@ -20,10 +20,10 @@ import unittest import numpy +import pytest from diffpy.structure import Structure from diffpy.structure.structureerrors import StructureFormatError -from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- @@ -31,6 +31,10 @@ class TestP_pdffit(unittest.TestCase): """test Parser for PDFFit file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "pdffit" @@ -39,7 +43,7 @@ def setUp(self): def test_read_pdffit_ZnSb(self): """check reading of ZnSb pdffit structure file""" stru = self.stru - stru.read(datafile("ZnSb_RT_Q28X_VM_20_fxiso.rstr"), self.format) + stru.read(self.datafile("ZnSb_RT_Q28X_VM_20_fxiso.rstr"), self.format) f_title = "Cell structure file of Zn4Sb3 #167 interstitial" self.assertEqual(stru.title, f_title) self.assertAlmostEqual(stru.pdffit["scale"], 0.826145) @@ -84,7 +88,7 @@ def test_read_pdffit_ZnSb(self): def test_read_pdffit_Ni(self): """check reading of Ni pdffit structure file""" stru = self.stru - stru.read(datafile("Ni.stru"), self.format) + stru.read(self.datafile("Ni.stru"), self.format) f_title = "structure Ni FCC" self.assertEqual(stru.title, f_title) self.assertEqual(stru.pdffit["spcgr"], "Fm-3m") @@ -117,7 +121,7 @@ def test_read_pdffit_Ni(self): def test_read_pdffit_Ni_prim123(self): """check reading of Ni_prim supercell 1x2x3""" stru = self.stru - stru.read(datafile("Ni_prim123.stru"), self.format) + stru.read(self.datafile("Ni_prim123.stru"), self.format) s_lat = [ stru.lattice.a, stru.lattice.b, @@ -148,15 +152,15 @@ def test_read_pdffit_Ni_prim123(self): def test_read_pdffit_bad(self): """check exceptions when reading invalid pdffit file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, datafile("Ni-bad.stru"), self.format) - self.assertRaises(StructureFormatError, stru.read, datafile("bucky.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("Ni-bad.stru"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky.xyz"), self.format) return def test_writeStr_pdffit(self): """check writing of normal xyz file""" stru = self.stru - stru.read(datafile("Ni.stru"), self.format) - with open(datafile("Ni.stru")) as fp: + stru.read(self.datafile("Ni.stru"), self.format) + with open(self.datafile("Ni.stru")) as fp: f_s = fp.read() f_s = re.sub("[ \t]+", " ", f_s) f_s = re.sub("[ \t]+\n", "\n", f_s) @@ -167,7 +171,7 @@ def test_writeStr_pdffit(self): def test_huge_occupancy(self): """check structure with huge occupancy can be read.""" - self.stru.read(datafile("Ni.stru"), self.format) + self.stru.read(self.datafile("Ni.stru"), self.format) self.stru[0].occupancy = 16e16 s_s = self.stru.writeStr(self.format) stru1 = Structure() @@ -179,7 +183,7 @@ def test_ignored_lines(self): """check skipping of ignored lines in the header""" r1 = "ignored record 1" r2 = "ignored record 2" - with open(datafile("Ni.stru")) as fp: + with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(2, r1 + "\n") ni_lines.insert(4, r2 + "\n") @@ -194,7 +198,7 @@ def test_ignored_lines(self): def test_spdiameter_parsing(self): """check parsing of spdiameter record from a file.""" stru = self.stru - stru.read(datafile("Ni.stru"), self.format) + stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) snoshape = stru.writeStr(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) @@ -205,7 +209,7 @@ def test_spdiameter_parsing(self): stru13 = Structure() stru13.readStr(s13) self.assertEqual(13, stru13.pdffit["spdiameter"]) - with open(datafile("Ni.stru")) as fp: + with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) @@ -215,7 +219,7 @@ def test_spdiameter_parsing(self): def test_stepcut_parsing(self): """check parsing of stepcut record from a file.""" stru = self.stru - stru.read(datafile("Ni.stru"), self.format) + stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) snoshape = stru.writeStr(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) @@ -226,7 +230,7 @@ def test_stepcut_parsing(self): stru13 = Structure() stru13.readStr(s13) self.assertEqual(13, stru13.pdffit["stepcut"]) - with open(datafile("Ni.stru")) as fp: + with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 91f0e085..a3f7f3c1 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -22,10 +22,10 @@ import unittest import numpy +import pytest from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.structureerrors import StructureFormatError -from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- @@ -33,6 +33,10 @@ class TestP_xyz(unittest.TestCase): """test Parser for xyz file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "xyz" @@ -52,7 +56,7 @@ def mktmpfile(self): def test_read_xyz(self): """check reading of normal xyz file""" stru = self.stru - stru.read(datafile("bucky.xyz"), self.format) + stru.read(self.datafile("bucky.xyz"), self.format) s_els = [a.element for a in stru] self.assertEqual(stru.title, "bucky-ball") self.assertEqual(s_els, 60 * ["C"]) @@ -61,10 +65,10 @@ def test_read_xyz(self): def test_read_xyz_bad(self): """check exceptions when reading invalid xyz file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, datafile("bucky-bad1.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, datafile("bucky-bad2.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, datafile("bucky-plain.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw.xy"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad1.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad2.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-plain.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw.xy"), self.format) return def test_writeStr_xyz(self): @@ -103,6 +107,10 @@ def test_write_xyz(self): class TestP_rawxyz(unittest.TestCase): """test Parser for rawxyz file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "rawxyz" @@ -111,7 +119,7 @@ def setUp(self): def test_read_plainxyz(self): """check reading of a plain xyz file""" stru = self.stru - stru.read(datafile("bucky-plain.xyz"), self.format) + stru.read(self.datafile("bucky-plain.xyz"), self.format) s_els = [a.element for a in stru] self.assertEqual(stru.title, "bucky-plain") self.assertEqual(s_els, 60 * ["C"]) @@ -120,17 +128,17 @@ def test_read_plainxyz(self): def test_read_plainxyz_bad(self): """check exceptions when reading invalid plain xyz file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, datafile("bucky-plain-bad.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-plain-bad.xyz"), self.format) return def test_read_rawxyz(self): """check reading of raw xyz file""" stru = self.stru - stru.read(datafile("bucky-raw.xyz"), self.format) + stru.read(self.datafile("bucky-raw.xyz"), self.format) s_els = [a.element for a in stru] self.assertEqual(stru.title, "bucky-raw") self.assertEqual(s_els, 60 * [""]) - stru.read(datafile("hexagon-raw.xyz"), self.format) + stru.read(self.datafile("hexagon-raw.xyz"), self.format) zs = [a.xyz[-1] for a in stru] self.assertEqual(zs, 6 * [0.0]) return @@ -138,8 +146,8 @@ def test_read_rawxyz(self): def test_read_rawxyz_bad(self): """check exceptions when reading unsupported xy file""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw-bad.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, datafile("hexagon-raw.xy"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw-bad.xyz"), self.format) + self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw.xy"), self.format) return def test_writeStr_rawxyz(self): @@ -168,6 +176,10 @@ def test_writeStr_rawxyz(self): class TestP_pdb(unittest.TestCase): """test Parser for PDB file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "pdb" @@ -176,7 +188,7 @@ def setUp(self): def test_read_pdb_arginine(self): """check reading of arginine PDB file""" stru = self.stru - stru.read(datafile("arginine.pdb"), self.format) + stru.read(self.datafile("arginine.pdb"), self.format) f_els = [ "N", "C", @@ -224,7 +236,7 @@ def test_read_pdb_arginine(self): def test_rwStr_pdb_CdSe(self): """check conversion to PDB file format""" stru = self.stru - stru.read(datafile("CdSe_bulk.stru"), "pdffit") + stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) # all lines should be 80 characters long linelens = [len(line) for line in s.split("\n") if line != ""] @@ -265,6 +277,10 @@ def test_rwStr_pdb_CdSe(self): class TestP_xcfg(unittest.TestCase): """test Parser for XCFG file format""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def setUp(self): self.stru = Structure() self.format = "xcfg" @@ -273,7 +289,7 @@ def setUp(self): def test_read_xcfg(self): """check reading of BubbleRaft XCFG file""" stru = self.stru - stru.read(datafile("BubbleRaftShort.xcfg"), self.format) + stru.read(self.datafile("BubbleRaftShort.xcfg"), self.format) f_els = 500 * ["Ar"] s_els = [a.element for a in stru] self.assertEqual(s_els, f_els) @@ -293,7 +309,7 @@ def test_read_xcfg(self): def test_rwStr_xcfg_CdSe(self): """check conversion to XCFG file format""" stru = self.stru - stru.read(datafile("CdSe_bulk.stru"), "pdffit") + stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) stru = Structure() stru.readStr(s, self.format) diff --git a/tests/test_structure.py b/tests/test_structure.py index 37f89a59..e9016e3f 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -22,14 +22,9 @@ import unittest import numpy +import pytest from diffpy.structure import Atom, Lattice, Structure -from diffpy.structure.tests.testutils import datafile - -# useful variables -cdsefile = datafile("CdSe_bulk.stru") -teifile = datafile("TeI.cif") -pbtefile = datafile("PbTe.cif") # ---------------------------------------------------------------------------- @@ -37,16 +32,24 @@ class TestStructure(unittest.TestCase): """test methods of Structure class""" + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.cdsefile = datafile("CdSe_bulk.stru") + self.teifile = datafile("TeI.cif") + self.pbtefile = datafile("PbTe.cif") + _loaded_structures = {} def setUp(self): self.stru = Structure([Atom("C", [0, 0, 0]), Atom("C", [1, 1, 1])], lattice=Lattice(1, 1, 1, 90, 90, 120)) + # useful variables + if not self._loaded_structures: self._loaded_structures.update( [ - ("cdse", Structure(filename=cdsefile)), - ("tei", Structure(filename=teifile)), - ("pbte", Structure(filename=pbtefile)), + ("cdse", Structure(filename=self.cdsefile)), + ("tei", Structure(filename=self.teifile)), + ("pbte", Structure(filename=self.pbtefile)), ] ) self.__dict__.update(self._loaded_structures) @@ -56,9 +59,9 @@ def setUp(self): def test___init__(self): """check Structure.__init__()""" atoms = [Atom("C", [0, 0, 0]), Atom("C", [0.5, 0.5, 0.5])] - self.assertRaises(ValueError, Structure, atoms, filename=teifile) - self.assertRaises(ValueError, Structure, lattice=Lattice(), filename=teifile) - self.assertRaises(ValueError, Structure, title="test", filename=teifile) + self.assertRaises(ValueError, Structure, atoms, filename=self.teifile) + self.assertRaises(ValueError, Structure, lattice=Lattice(), filename=self.teifile) + self.assertRaises(ValueError, Structure, title="test", filename=self.teifile) stru1 = Structure(title="my title") self.assertEqual("my title", stru1.title) stru2a = Structure(atoms) @@ -95,7 +98,7 @@ def __copy__(self): def test___copy__(self): """check Structure.__copy__()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) cdse_str = cdse.writeStr("pdffit") cdse2 = copy.copy(cdse) self.assertEqual(cdse_str, cdse2.writeStr("pdffit")) @@ -104,20 +107,17 @@ def test___copy__(self): self.assertFalse(sameatoms) return - # def test___str__(self): - # """check Structure.__str__() - # """ - # return - # - # def test_addNewAtom(self): - # """check Structure.addNewAtom() - # """ - # return - # - # def test_getLastAtom(self): - # """check Structure.getLastAtom() - # """ - # return + def test___str__(self): + """check Structure.__str__()""" + return + + def test_addNewAtom(self): + """check Structure.addNewAtom()""" + return + + def test_getLastAtom(self): + """check Structure.getLastAtom()""" + return def test_assignUniqueLabels(self): """check Structure.assignUniqueLabels()""" @@ -141,7 +141,7 @@ def test_distance(self): def test_angle(self): """check Structure.angle()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) cdse.assignUniqueLabels() self.assertEqual(109, round(cdse.angle(0, 2, 1))) self.assertEqual(109, round(cdse.angle("Cd1", "Se1", "Cd2"))) @@ -157,25 +157,21 @@ def test_placeInLattice(self): a1 = stru[1] self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) - # def test_read(self): - # """check Structure.read() - # """ - # return - # - # def test_readStr(self): - # """check Structure.readStr() - # """ - # return - # - # def test_write(self): - # """check Structure.write() - # """ - # return - # - # def test_writeStr(self): - # """check Structure.writeStr() - # """ - # return + def test_read(self): + """check Structure.read()""" + return + + def test_readStr(self): + """check Structure.readStr()""" + return + + def test_write(self): + """check Structure.write()""" + return + + def test_writeStr(self): + """check Structure.writeStr()""" + return def test_aslist(self): """check Structure.tolist()""" @@ -215,7 +211,7 @@ def test_insert(self): def test_extend(self): """check Structure.extend()""" stru = self.stru - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) lst = stru.tolist() stru.extend(cdse) self.assertEqual(6, len(stru)) @@ -289,7 +285,7 @@ def test___setitem__slice(self): def test___add__(self): """check Structure.__add__()""" stru = self.stru - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) total = stru + cdse self.assertEqual(6, len(total)) ta0 = total[0] @@ -307,7 +303,7 @@ def test___iadd__(self): stru = self.stru lat0 = stru.lattice lst = stru.tolist() - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) stru += cdse self.assertEqual(6, len(stru)) self.assertEqual(lst, stru[:2].tolist()) @@ -321,7 +317,7 @@ def test___iadd__(self): def test___sub__(self): """check Structure.__sub__()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) cadmiums = cdse - cdse[2:] self.assertEqual(2, len(cadmiums)) self.assertEqual("Cd", cadmiums[0].element) @@ -334,7 +330,7 @@ def test___sub__(self): def test___isub__(self): """check Structure.__isub__()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) lat = cdse.lattice lst = cdse.tolist() cdse -= cdse[2:] @@ -348,7 +344,7 @@ def test___isub__(self): def test___mul__(self): """check Structure.__mul__()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) self.assertEqual(12, len(set(3 * cdse))) self.assertEqual(12, len(set(cdse * 3))) cdsex3 = 3 * cdse @@ -361,7 +357,7 @@ def test___mul__(self): def test___imul__(self): """check Structure.__imul__()""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) lat = cdse.lattice els = cdse.element xyz = cdse.xyz @@ -466,7 +462,7 @@ def test_z(self): def test_label(self): """check Structure.label""" - cdse = Structure(filename=cdsefile) + cdse = Structure(filename=self.cdsefile) self.assertEqual(4 * [""], cdse.label.tolist()) cdse.assignUniqueLabels() self.assertEqual("Cd1 Cd2 Se1 Se2".split(), cdse.label.tolist()) diff --git a/tests/test_supercell.py b/tests/test_supercell.py index 2ca5d72e..0e840dfa 100644 --- a/tests/test_supercell.py +++ b/tests/test_supercell.py @@ -16,17 +16,20 @@ """Unit tests for supercell.py """ - import unittest +import pytest + from diffpy.structure import Structure from diffpy.structure.expansion import supercell -from diffpy.structure.tests.testutils import datafile # ---------------------------------------------------------------------------- class TestSuperCell(unittest.TestCase): + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile stru_cdse = None stru_ni = None @@ -34,10 +37,10 @@ class TestSuperCell(unittest.TestCase): def setUp(self): # load test structures once if TestSuperCell.stru_cdse is None: - cdsefile = datafile("CdSe_bulk.stru") + cdsefile = self.datafile("CdSe_bulk.stru") TestSuperCell.stru_cdse = Structure(filename=cdsefile) if TestSuperCell.stru_ni is None: - nifile = datafile("Ni.stru") + nifile = self.datafile("Ni.stru") TestSuperCell.stru_ni = Structure(filename=nifile) # bring them to the instance self.stru_cdse = TestSuperCell.stru_cdse From 05e106c3a83632f4ee7ce667657d5e2ab6fad98d Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 15:58:34 -0400 Subject: [PATCH 066/226] Add commented tests back --- tests/test_structure.py | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index e9016e3f..9c1a6308 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -107,17 +107,17 @@ def test___copy__(self): self.assertFalse(sameatoms) return - def test___str__(self): - """check Structure.__str__()""" - return + # def test___str__(self): + # """check Structure.__str__()""" + # return - def test_addNewAtom(self): - """check Structure.addNewAtom()""" - return + # def test_addNewAtom(self): + # """check Structure.addNewAtom()""" + # return - def test_getLastAtom(self): - """check Structure.getLastAtom()""" - return + # def test_getLastAtom(self): + # """check Structure.getLastAtom()""" + # return def test_assignUniqueLabels(self): """check Structure.assignUniqueLabels()""" @@ -157,21 +157,21 @@ def test_placeInLattice(self): a1 = stru[1] self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) - def test_read(self): - """check Structure.read()""" - return + # def test_read(self): + # """check Structure.read()""" + # return - def test_readStr(self): - """check Structure.readStr()""" - return + # def test_readStr(self): + # """check Structure.readStr()""" + # return - def test_write(self): - """check Structure.write()""" - return + # def test_write(self): + # """check Structure.write()""" + # return - def test_writeStr(self): - """check Structure.writeStr()""" - return + # def test_writeStr(self): + # """check Structure.writeStr()""" + # return def test_aslist(self): """check Structure.tolist()""" From c80ecc55c15b187e4821f2f42e4fda6eb8005633 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 9 Sep 2024 16:08:59 -0400 Subject: [PATCH 067/226] Create folder.rst --- news/folder.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/folder.rst diff --git a/news/folder.rst b/news/folder.rst new file mode 100644 index 00000000..63f83284 --- /dev/null +++ b/news/folder.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* tests folder at the root of the repo + +**Security:** + +* From 2f8aace4eba92918cd6e39d4499501e62080dd13 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Sep 2024 23:06:23 -0400 Subject: [PATCH 068/226] Delete tests/__init__.py --- tests/__init__.py | 77 ----------------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 98485bde..00000000 --- a/tests/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 Trustees of the Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Unit tests for diffpy.structure. -""" - -import unittest - - -def testsuite(pattern=""): - """Create a unit tests suite for diffpy.structure package. - - Parameters - ---------- - pattern : str, optional - Regular expression pattern for selecting test cases. - Select all tests when empty. Ignore the pattern when - any of unit test modules fails to import. - - Returns - ------- - suite : `unittest.TestSuite` - The TestSuite object containing the matching tests. - """ - import re - from importlib import resources - from itertools import chain - from os.path import dirname - - loader = unittest.defaultTestLoader - thisdir = str(resources.files(__name__)) - depth = __name__.count(".") + 1 - topdir = thisdir - for i in range(depth): - topdir = dirname(topdir) - suite_all = loader.discover(thisdir, top_level_dir=topdir) - # always filter the suite by pattern to test-cover the selection code. - suite = unittest.TestSuite() - rx = re.compile(pattern) - tsuites = list(chain.from_iterable(suite_all)) - tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover - return suite_all - tcases = chain.from_iterable(tsuites) - for tc in tcases: - tcwords = tc.id().split(".") - shortname = ".".join(tcwords[-3:]) - if rx.search(shortname): - suite.addTest(tc) - # verify all tests are found for an empty pattern. - assert pattern or suite_all.countTestCases() == suite.countTestCases() - return suite - - -def test(): - """Execute all unit tests for the diffpy.structure package. - - Returns - ------- - result : `unittest.TestResult` - """ - suite = testsuite() - runner = unittest.TextTestRunner() - result = runner.run(suite) - return result From e4cf9f38197585a081f3277b50ac843148a607cb Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Fri, 13 Sep 2024 08:33:28 -0400 Subject: [PATCH 069/226] Fix contest not to use __init__.py content --- tests/conftest.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ff8aad16..5471acc1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ import json -from importlib import resources from pathlib import Path import pytest @@ -20,15 +19,11 @@ def user_filesystem(tmp_path): yield tmp_path -def get_datafile(filename): - return str(resources.files(__package__).joinpath("testdata/" + filename)) - - @pytest.fixture def datafile(): """Fixture to dynamically load any test file.""" def _load(filename): - return get_datafile(filename) + return "tests/testdata/" + filename return _load From 8cfba3883b171ed661f0d79ca04b2dc91402407a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Fri, 13 Sep 2024 20:09:52 -0400 Subject: [PATCH 070/226] Leave exclude tag but empty --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 66fb7f89..e50524b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,7 @@ dirty_template = "{tag}" [tool.setuptools.packages.find] where = ["src"] # list of folders that contain the packages (["."] by default) include = ["*"] # package names should match these glob patterns (["*"] by default) +exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) [tool.setuptools.dynamic] From 756be826dc38e5f4b3ca4b7dc992c34aa0cdbde9 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 21 Sep 2024 20:23:36 -0400 Subject: [PATCH 071/226] Remove warnings --- pyproject.toml | 2 +- requirements/run.txt | 2 +- src/diffpy/structure/atom.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e50524b1..206884bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=62.0", "setuptools-git-versioning<2"] +requires = ["setuptools>=62.0", "setuptools-git-versioning>=2.0"] build-backend = "setuptools.build_meta" [project] diff --git a/requirements/run.txt b/requirements/run.txt index 70f81389..5413a934 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -1,2 +1,2 @@ -numpy < 2.0.0 # Need to fix deprecations before 2.0.0 compat +numpy pycifrw diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index 9693b812..b2af9626 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -536,7 +536,7 @@ def __setitem__(self, idx, value): self._atom.xyz[:] = self._atom.lattice.fractional(self) return - def __array_wrap__(self, out_arr, context=None): + def __array_wrap__(self, out_arr, context=None, return_scalar=False): """Ensure math operations on this type yield standard numpy array.""" return out_arr.view(numpy.ndarray) From 65963333017577c8525dd0e662640b524eb7ed63 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 21 Sep 2024 20:49:51 -0400 Subject: [PATCH 072/226] Fix lenght to 5 characterse --- src/diffpy/structure/structure.py | 10 ++++++---- src/diffpy/structure/utils.py | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 5bebf4eb..fcd1489e 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -711,8 +711,9 @@ def _get_composition(self): element = _linkAtomAttribute( "element", """Character array of `Atom` types. Assignment updates - the element attribute of the respective `Atoms`.""", - toarray=numpy.char.array, + the element attribute of the respective `Atoms`. + Set the maximum length of the element string to 5 characters.""", + toarray=lambda items: numpy.char.array(items, itemsize=5) ) xyz = _linkAtomAttribute( @@ -742,8 +743,9 @@ def _get_composition(self): label = _linkAtomAttribute( "label", """Character array of `Atom` names. Assignment updates - the label attribute of all `Atoms`.""", - toarray=numpy.char.array, + the label attribute of all `Atoms`. + Set the maximum length of the label string to 5 characters.""", + toarray=lambda items: numpy.char.array(items, itemsize=5) ) occupancy = _linkAtomAttribute( diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index e5fa3ce3..0feeb5d1 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -92,7 +92,7 @@ def _linkAtomAttribute(attrname, doc, toarray=numpy.array): from operator import setitem _all = slice(None) - + def fget(self): va = toarray([getattr(a, attrname) for a in self]) return va From a67e6ac08af2114ba9fbbb6ddee9889945bca82b Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 21 Sep 2024 20:53:42 -0400 Subject: [PATCH 073/226] Add return_scalar none to array_wrap --- src/diffpy/structure/atom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index b2af9626..e531780b 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -536,7 +536,7 @@ def __setitem__(self, idx, value): self._atom.xyz[:] = self._atom.lattice.fractional(self) return - def __array_wrap__(self, out_arr, context=None, return_scalar=False): + def __array_wrap__(self, out_arr, context=None, return_scalar=None): """Ensure math operations on this type yield standard numpy array.""" return out_arr.view(numpy.ndarray) From dd620e89e08b68ff49c6ca4255824af5abd06ac2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 22 Sep 2024 00:55:19 +0000 Subject: [PATCH 074/226] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/structure/structure.py | 4 ++-- src/diffpy/structure/utils.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index fcd1489e..f0cb515c 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -713,7 +713,7 @@ def _get_composition(self): """Character array of `Atom` types. Assignment updates the element attribute of the respective `Atoms`. Set the maximum length of the element string to 5 characters.""", - toarray=lambda items: numpy.char.array(items, itemsize=5) + toarray=lambda items: numpy.char.array(items, itemsize=5), ) xyz = _linkAtomAttribute( @@ -745,7 +745,7 @@ def _get_composition(self): """Character array of `Atom` names. Assignment updates the label attribute of all `Atoms`. Set the maximum length of the label string to 5 characters.""", - toarray=lambda items: numpy.char.array(items, itemsize=5) + toarray=lambda items: numpy.char.array(items, itemsize=5), ) occupancy = _linkAtomAttribute( diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 0feeb5d1..e5fa3ce3 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -92,7 +92,7 @@ def _linkAtomAttribute(attrname, doc, toarray=numpy.array): from operator import setitem _all = slice(None) - + def fget(self): va = toarray([getattr(a, attrname) for a in self]) return va From 01d07b239c05f8cc3601187ac1ec8c21efb0537a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 08:35:44 -0400 Subject: [PATCH 075/226] Add news for supporting numpy >2.0 --- news/numpy2 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/numpy2 diff --git a/news/numpy2 b/news/numpy2 new file mode 100644 index 00000000..af1631fa --- /dev/null +++ b/news/numpy2 @@ -0,0 +1,23 @@ +**Added:** + +* support for numpy >=2.0 + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* element/label itemsize to 5 in _linkAtomAttribute to support numpy >=2.0 + +**Security:** + +* From 32a4a2ef4d3dcc6fd817cc63d5ee64b6ea7e607a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 08:46:10 -0400 Subject: [PATCH 076/226] Rename numpy2 to numpy2.rst --- news/{numpy2 => numpy2.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename news/{numpy2 => numpy2.rst} (100%) diff --git a/news/numpy2 b/news/numpy2.rst similarity index 100% rename from news/numpy2 rename to news/numpy2.rst From 6391c7c95ebd5bb3ffc114ba5c6345fa8771af88 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 09:25:44 -0400 Subject: [PATCH 077/226] Add unit test for version check --- tests/test_version.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/test_version.py diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 00000000..ecc61bea --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,10 @@ +"""Unit tests for __version__.py +""" + +import diffpy.structure + + +def test_package_version(): + """Ensure the package version is defined and not set to the initial placeholder.""" + assert hasattr(diffpy.structure, '__version__'), "The package version is not defined." + assert diffpy.structure.__version__ != "0.0.0" From 4e212e4f9975785c2a7247b71efde3dcc44eb9e7 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 09:27:09 -0400 Subject: [PATCH 078/226] Add unit test for version --- news/version-test.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/version-test.rst diff --git a/news/version-test.rst b/news/version-test.rst new file mode 100644 index 00000000..05c39477 --- /dev/null +++ b/news/version-test.rst @@ -0,0 +1,23 @@ +**Added:** + +* Unit test for version.py + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 2df4a06417885a662a579971cb87eb6984f2bcfc Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 09:28:36 -0400 Subject: [PATCH 079/226] Remove failed msg for version attribute --- tests/test_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_version.py b/tests/test_version.py index ecc61bea..b57eda25 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -6,5 +6,5 @@ def test_package_version(): """Ensure the package version is defined and not set to the initial placeholder.""" - assert hasattr(diffpy.structure, '__version__'), "The package version is not defined." + assert hasattr(diffpy.structure, '__version__') assert diffpy.structure.__version__ != "0.0.0" From 3473749a75c86e7fc57a82132f528772ae3546c8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:33:44 +0000 Subject: [PATCH 080/226] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_version.py b/tests/test_version.py index b57eda25..e62433e1 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -6,5 +6,5 @@ def test_package_version(): """Ensure the package version is defined and not set to the initial placeholder.""" - assert hasattr(diffpy.structure, '__version__') + assert hasattr(diffpy.structure, "__version__") assert diffpy.structure.__version__ != "0.0.0" From 4573f45b3c1d665de09b871af79b65bdcee4ad85 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 16:57:49 -0400 Subject: [PATCH 081/226] Modify MANIFEST.in to test files in sdist --- MANIFEST.in | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 3bcdfb4f..f1a78eec 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,14 +1,12 @@ -include AUTHORS.rst -include LICENSE -include README.rst -include requirements.txt - -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] - -recursive-include docs *.rst conf.py Makefile make.bat - -include diffpy.structure/version.py - -# If including data files in the package, add them like: -# include path/to/data_file +graft src +graft tests +graft requirements + +include AUTHORS.rst LICENSE*.rst README.rst + +# Exclude all bytecode files and __pycache__ directories +global-exclude *.py[cod] # Exclude all .pyc, .pyo, and .pyd files. +global-exclude .DS_Store # Exclude Mac filesystem artifacts. +global-exclude __pycache__ # Exclude Python cache directories. +global-exclude .git* # Exclude git files and directories. +global-exclude .idea # Exclude PyCharm project settings. From 01bb3032c78e79e8fecc601dbd8f7b350b79a3a0 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:22:06 -0400 Subject: [PATCH 082/226] Replace github workflows --- .github/workflows/check-news-item.yml | 12 +++++ .github/workflows/codecov.yml | 53 ------------------- .github/workflows/docs.yml | 48 ----------------- .github/workflows/main.yml | 42 --------------- .../matrix-and-codecov-on-merge-to-main.yml | 21 ++++++++ .github/workflows/publish-docs-on-release.yml | 14 +++++ .github/workflows/tests-on-pr.yml | 16 ++++++ 7 files changed, 63 insertions(+), 143 deletions(-) create mode 100644 .github/workflows/check-news-item.yml delete mode 100644 .github/workflows/codecov.yml delete mode 100644 .github/workflows/docs.yml delete mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/matrix-and-codecov-on-merge-to-main.yml create mode 100644 .github/workflows/publish-docs-on-release.yml create mode 100644 .github/workflows/tests-on-pr.yml diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml new file mode 100644 index 00000000..1301ca85 --- /dev/null +++ b/.github/workflows/check-news-item.yml @@ -0,0 +1,12 @@ +name: Check for News + +on: + pull_request_target: + branches: + - main + +jobs: + build: + uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + with: + project: diffpy.structure diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml deleted file mode 100644 index fd96a710..00000000 --- a/.github/workflows/codecov.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Gather coverage report and upload to codecov - -on: - push: - branches: - - main - release: - types: - - prereleased - - published - workflow_dispatch: - -defaults: - run: - shell: bash -l {0} - -jobs: - coverage: - runs-on: ubuntu-latest - steps: - - name: Check out diffpy.structure - 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 - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.structure and requirements - run: | - conda install --file requirements/run.txt - conda install --file requirements/test.txt - python -m pip install -r requirements/pip.txt - python -m pip install . --no-deps - - - name: Validate diffpy.structure - run: | - coverage run -m pytest -vv -s - coverage report -m - codecov - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index df2b392f..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Build and Deploy Documentation - -on: - release: - types: - - published - workflow_dispatch: - -defaults: - run: - shell: bash -l {0} - -jobs: - docs: - runs-on: ubuntu-latest - steps: - - name: Check out diffpy.structure - uses: actions/checkout@v4 - - - name: Initialize miniconda - uses: conda-incubator/setup-miniconda@v3 - with: - activate-environment: build - auto-update-conda: true - environment-file: environment.yml - auto-activate-base: false - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.structure and build requirements - run: | - conda install --file requirements/build.txt - conda install --file requirements/run.txt - conda install --file requirements/docs.txt - python -m pip install -r requirements/pip.txt - python -m pip install . --no-deps - - - name: build documents - run: make -C doc html - - - name: Deploy - uses: peaceiris/actions-gh-pages@v4 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./doc/build/html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 33ece6cf..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Test - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - -defaults: - run: - shell: bash -l {0} - -jobs: - validate: - runs-on: ubuntu-latest - steps: - - name: Check out diffpy.structure - 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 - - - name: Conda config - run: >- - conda config --set always_yes yes - --set changeps1 no - - - name: Install diffpy.structure and requirements - run: | - conda install --file requirements/run.txt - conda install --file requirements/test.txt - python -m pip install -r requirements/pip.txt - python -m pip install . --no-deps - - - name: Validate diffpy.structure - run: python -m pytest diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml new file mode 100644 index 00000000..c1905e0d --- /dev/null +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: + - main + release: + types: + - prereleased + - published + workflow_dispatch: null + +jobs: + coverage: + uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.structure + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml new file mode 100644 index 00000000..1c5981db --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,14 @@ +name: Build and Deploy Docs + +on: + release: + types: + - published + workflow_dispatch: + +jobs: + docs: + uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.structure + c_extension: false diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml new file mode 100644 index 00000000..614b16f2 --- /dev/null +++ b/.github/workflows/tests-on-pr.yml @@ -0,0 +1,16 @@ +name: Tests on PR + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + validate: + uses: Billingegroup/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + with: + project: diffpy.structure + c_extension: false + headless: false From 88414c00c4b6d611e13bfacdc2c40ee76f78dcd6 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:25:34 -0400 Subject: [PATCH 083/226] Add requirements, add pytest-cov --- requirements/build.txt | 2 -- requirements/run.txt | 4 ++-- requirements/test.txt | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/requirements/build.txt b/requirements/build.txt index f72d870d..e69de29b 100644 --- a/requirements/build.txt +++ b/requirements/build.txt @@ -1,2 +0,0 @@ -python -setuptools diff --git a/requirements/run.txt b/requirements/run.txt index 5413a934..0fdcecb6 100644 --- a/requirements/run.txt +++ b/requirements/run.txt @@ -1,2 +1,2 @@ -numpy -pycifrw +numpy +pycifrw diff --git a/requirements/test.txt b/requirements/test.txt index 6f9ccf84..a7277865 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -2,4 +2,5 @@ flake8 pytest codecov coverage +pytest-cov pytest-env From 373dc722a43a2861afc5cdcbe328390e43e889e1 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:26:16 -0400 Subject: [PATCH 084/226] Delete gitattributes and add pre-commit config --- .gitattributes | 1 - .pre-commit-config.yaml | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index de811ba3..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -diffpy.structure/_version.py export-subst diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4588061..3070e199 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,10 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - exclude: '\.(rst|txt)$' + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + - id: check-added-large-files - repo: https://github.com/psf/black rev: 24.4.2 hooks: From 31f61f530e6360f2454760495bec7a0db1bf787c Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:27:37 -0400 Subject: [PATCH 085/226] Remove devutils --- devutils/makesdist | 60 ---------- devutils/sgtbx_extra_groups.py | 210 --------------------------------- 2 files changed, 270 deletions(-) delete mode 100755 devutils/makesdist delete mode 100644 devutils/sgtbx_extra_groups.py diff --git a/devutils/makesdist b/devutils/makesdist deleted file mode 100755 index dccfaa99..00000000 --- a/devutils/makesdist +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python - -"""Create source distribution tar.gz archive, where each file belongs -to a root user and modification time is set to the git commit time. -""" - -import glob -import gzip -import os -import subprocess -import sys -import tarfile - -from setup import FALLBACK_VERSION, versiondata - -BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -sys.path.insert(0, BASEDIR) - -timestamp = versiondata.getint("DEFAULT", "timestamp") - -vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" -emsg = "Invalid FALLBACK_VERSION. Expected %r got %r." -assert vfb == FALLBACK_VERSION, emsg % (vfb, FALLBACK_VERSION) - - -def inform(s): - sys.stdout.write(s) - sys.stdout.flush() - return - - -inform('Run "setup.py sdist --formats=tar" ') -cmd_sdist = [sys.executable] + "setup.py sdist --formats=tar".split() -ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, "w")) -if ec: - sys.exit(ec) -inform("[done]\n") - -tarname = max(glob.glob(BASEDIR + "/dist/*.tar"), key=os.path.getmtime) - -tfin = tarfile.open(tarname) -fpout = gzip.GzipFile(tarname + ".gz", "w", mtime=0) -tfout = tarfile.open(fileobj=fpout, mode="w") - - -def fixtarinfo(tinfo): - tinfo.uid = tinfo.gid = 0 - tinfo.uname = tinfo.gname = "root" - tinfo.mtime = timestamp - tinfo.mode &= ~0o022 - return tinfo - - -inform("Filter %s --> %s.gz " % (2 * (os.path.basename(tarname),))) -for ti in tfin: - tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) - -tfin.close() -os.remove(tarname) -inform("[done]\n") diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py deleted file mode 100644 index 4cab28c2..00000000 --- a/devutils/sgtbx_extra_groups.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python - -"""Quick and extremely dirty script for generating code for SpaceGroup that -are defined in cctbx, but not in mmLib. It was used to generate module -sgtbxspacegroups. - -This is a utility script that should not be included with code distribution. - -Not to be included with code distributions. -""" - - -import math -import re - -import numpy -from cctbx import sgtbx - -from diffpy.structure.spacegroups import IsSpaceGroupIdentifier, SpaceGroup, SymOp, mmLibSpaceGroupList - - -def tupleToSGArray(tpl): - if not _rtarrays: - import diffpy.structure.SpaceGroups as sgmod - - for n in dir(sgmod): - if not n.startswith("Rot_") and not n.startswith("Tr_"): - continue - a = getattr(sgmod, n) - t = tuple(a.flatten()) - _rtarrays[t] = a - if len(tpl) == 3: - tpl = tuple([(x - math.floor(x)) for x in tpl]) - if tpl not in _rtarrays: - _rtarrays[tpl] = numpy.array(tpl, dtype=float) - return _rtarrays[tpl] - - -_rtarrays = {} - - -def mmSpaceGroupFromSymbol(symbol): - """Construct SpaceGroup instance from a string symbol using sgtbx data.""" - sginfo = sgtbx.space_group_info(symbol) - symop_list = [] - symop_list = getSymOpList(sginfo.group()) - sgtype = sginfo.type() - uhm = sgtype.lookup_symbol() - sgsmbls = sgtbx.space_group_symbols(uhm) - kw = {} - kw["number"] = sgtype.number() - kw["num_sym_equiv"] = len(symop_list) - kw["num_primitive_sym_equiv"] = countUniqueRotations(symop_list) - kw["short_name"] = sgsmbls.hermann_mauguin().replace(" ", "") - pgt = sgsmbls.point_group_type() - pgn = "PG" + re.sub(r"-(\d)", "\\1bar", pgt) - kw["point_group_name"] = pgn - kw["crystal_system"] = sgsmbls.crystal_system().upper() - kw["pdb_name"] = sgsmbls.hermann_mauguin() - kw["symop_list"] = symop_list - mmsg = SpaceGroup(**kw) - return mmsg - - -def adjustMMSpaceGroupNumber(mmsg): - sg0 = [x for x in mmLibSpaceGroupList if x.number == mmsg.number] - if sg0 and cmpSpaceGroups(sg0[0], mmsg): - return - while mmsg.number in sgnumbers: - mmsg.number += 1000 - sgnumbers.append(mmsg.number) - - -def getSymOpList(grp): - symop_list = [] - for op in grp: - r_sgtbx = op.r().as_double() - t_sgtbx = op.t().as_double() - R = tupleToSGArray(r_sgtbx) - t = tupleToSGArray(t_sgtbx) - symop_list.append(SymOp(R, t)) - return symop_list - - -def countUniqueRotations(symop_list): - unique_rotations = set() - for op in symop_list: - tpl = tuple(op.R.flatten()) - unique_rotations.add(tpl) - return len(unique_rotations) - - -def cmpSpaceGroups(sg0, sg1): - if sg0 is sg1: - return True - s0 = hashMMSpaceGroup(sg0) - s1 = hashMMSpaceGroup(sg1) - return s0 == s1 - - -def findEquivalentMMSpaceGroup(grp): - if not _equivmmsg: - for sgn in mmLibSpaceGroupList: - ssgn = hashMMSpaceGroup(sgn) - _equivmmsg.setdefault(ssgn, sgn) - ssg = hashSgtbxGroup(grp) - return _equivmmsg.get(ssg) - - -_equivmmsg = {} - - -def findEquivalentSgtbxSpaceGroup(sgmm): - if not _equivsgtbx: - for smbls in sgtbx.space_group_symbol_iterator(): - uhm = smbls.universal_hermann_mauguin() - grp = sgtbx.space_group_info(uhm).group() - hgrp = hashSgtbxGroup(grp) - _equivsgtbx.setdefault(hgrp, grp) - hgmm = hashMMSpaceGroup(sgmm) - return _equivsgtbx.get(hgmm) - - -_equivsgtbx = {} - - -def hashMMSpaceGroup(sg): - lines = [str(sg.number % 1000)] + sorted(map(str, sg.iter_symops())) - s = "\n".join(lines) - return s - - -def hashSgtbxGroup(grp): - n = grp.type().number() - lines = [str(n)] + sorted(map(str, getSymOpList(grp))) - s = "\n".join(lines) - return s - - -sgnumbers = [sg.number for sg in mmLibSpaceGroupList] - -_SGsrc = """\ -sg%(number)i = SpaceGroup( - number = %(number)i, - num_sym_equiv = %(num_sym_equiv)i, - num_primitive_sym_equiv = %(num_sym_equiv)i, - short_name = %(short_name)r, - point_group_name = %(point_group_name)r, - crystal_system = %(crystal_system)r, - pdb_name = %(pdb_name)r, - symop_list = [ - @SYMOPS@ - ] -) -""" - - -def SGCode(mmsg): - src0 = _SGsrc % mmsg.__dict__ - src1 = src0.replace("@SYMOPS@", SymOpsCode(mmsg)) - return src1 - - -def SymOpsCode(mmsg): - lst = ["%8s%s," % ("", SymOpCode(op)) for op in mmsg.iter_symops()] - src = "\n".join(lst).strip() - return src - - -def SymOpCode(op): - if not _rtnames: - import diffpy.structure.SpaceGroups as sgmod - - for n in dir(sgmod): - if not n.startswith("Rot_") and not n.startswith("Tr_"): - continue - a = getattr(sgmod, n) - at = tuple(a.flatten()) - _rtnames[at] = "sgmod." + n - nR = _rtnames[tuple(op.R.flatten())] - nt = _rtnames[tuple(op.t)] - src = "SymOp(%s, %s)" % (nR, nt) - return src - - -_rtnames = {} - - -def main(): - duplicates = set() - for smbls in sgtbx.space_group_symbol_iterator(): - uhm = smbls.universal_hermann_mauguin() - grp = sgtbx.space_group_info(uhm).group() - if findEquivalentMMSpaceGroup(grp): - continue - shn = smbls.hermann_mauguin().replace(" ", "") - if IsSpaceGroupIdentifier(shn): - continue - sg = mmSpaceGroupFromSymbol(uhm) - hsg = hashMMSpaceGroup(sg) - if hsg in duplicates: - continue - adjustMMSpaceGroupNumber(sg) - duplicates.add(hsg) - print(SGCode(sg)) - return - - -if __name__ == "__main__": - main() From 848b25e5727c180cb5b3dd892d87764f3774ad33 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:29:41 -0400 Subject: [PATCH 086/226] Add devutils script --- devutils/sgtbx_extra_groups.py | 210 +++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 devutils/sgtbx_extra_groups.py diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py new file mode 100644 index 00000000..4cab28c2 --- /dev/null +++ b/devutils/sgtbx_extra_groups.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +"""Quick and extremely dirty script for generating code for SpaceGroup that +are defined in cctbx, but not in mmLib. It was used to generate module +sgtbxspacegroups. + +This is a utility script that should not be included with code distribution. + +Not to be included with code distributions. +""" + + +import math +import re + +import numpy +from cctbx import sgtbx + +from diffpy.structure.spacegroups import IsSpaceGroupIdentifier, SpaceGroup, SymOp, mmLibSpaceGroupList + + +def tupleToSGArray(tpl): + if not _rtarrays: + import diffpy.structure.SpaceGroups as sgmod + + for n in dir(sgmod): + if not n.startswith("Rot_") and not n.startswith("Tr_"): + continue + a = getattr(sgmod, n) + t = tuple(a.flatten()) + _rtarrays[t] = a + if len(tpl) == 3: + tpl = tuple([(x - math.floor(x)) for x in tpl]) + if tpl not in _rtarrays: + _rtarrays[tpl] = numpy.array(tpl, dtype=float) + return _rtarrays[tpl] + + +_rtarrays = {} + + +def mmSpaceGroupFromSymbol(symbol): + """Construct SpaceGroup instance from a string symbol using sgtbx data.""" + sginfo = sgtbx.space_group_info(symbol) + symop_list = [] + symop_list = getSymOpList(sginfo.group()) + sgtype = sginfo.type() + uhm = sgtype.lookup_symbol() + sgsmbls = sgtbx.space_group_symbols(uhm) + kw = {} + kw["number"] = sgtype.number() + kw["num_sym_equiv"] = len(symop_list) + kw["num_primitive_sym_equiv"] = countUniqueRotations(symop_list) + kw["short_name"] = sgsmbls.hermann_mauguin().replace(" ", "") + pgt = sgsmbls.point_group_type() + pgn = "PG" + re.sub(r"-(\d)", "\\1bar", pgt) + kw["point_group_name"] = pgn + kw["crystal_system"] = sgsmbls.crystal_system().upper() + kw["pdb_name"] = sgsmbls.hermann_mauguin() + kw["symop_list"] = symop_list + mmsg = SpaceGroup(**kw) + return mmsg + + +def adjustMMSpaceGroupNumber(mmsg): + sg0 = [x for x in mmLibSpaceGroupList if x.number == mmsg.number] + if sg0 and cmpSpaceGroups(sg0[0], mmsg): + return + while mmsg.number in sgnumbers: + mmsg.number += 1000 + sgnumbers.append(mmsg.number) + + +def getSymOpList(grp): + symop_list = [] + for op in grp: + r_sgtbx = op.r().as_double() + t_sgtbx = op.t().as_double() + R = tupleToSGArray(r_sgtbx) + t = tupleToSGArray(t_sgtbx) + symop_list.append(SymOp(R, t)) + return symop_list + + +def countUniqueRotations(symop_list): + unique_rotations = set() + for op in symop_list: + tpl = tuple(op.R.flatten()) + unique_rotations.add(tpl) + return len(unique_rotations) + + +def cmpSpaceGroups(sg0, sg1): + if sg0 is sg1: + return True + s0 = hashMMSpaceGroup(sg0) + s1 = hashMMSpaceGroup(sg1) + return s0 == s1 + + +def findEquivalentMMSpaceGroup(grp): + if not _equivmmsg: + for sgn in mmLibSpaceGroupList: + ssgn = hashMMSpaceGroup(sgn) + _equivmmsg.setdefault(ssgn, sgn) + ssg = hashSgtbxGroup(grp) + return _equivmmsg.get(ssg) + + +_equivmmsg = {} + + +def findEquivalentSgtbxSpaceGroup(sgmm): + if not _equivsgtbx: + for smbls in sgtbx.space_group_symbol_iterator(): + uhm = smbls.universal_hermann_mauguin() + grp = sgtbx.space_group_info(uhm).group() + hgrp = hashSgtbxGroup(grp) + _equivsgtbx.setdefault(hgrp, grp) + hgmm = hashMMSpaceGroup(sgmm) + return _equivsgtbx.get(hgmm) + + +_equivsgtbx = {} + + +def hashMMSpaceGroup(sg): + lines = [str(sg.number % 1000)] + sorted(map(str, sg.iter_symops())) + s = "\n".join(lines) + return s + + +def hashSgtbxGroup(grp): + n = grp.type().number() + lines = [str(n)] + sorted(map(str, getSymOpList(grp))) + s = "\n".join(lines) + return s + + +sgnumbers = [sg.number for sg in mmLibSpaceGroupList] + +_SGsrc = """\ +sg%(number)i = SpaceGroup( + number = %(number)i, + num_sym_equiv = %(num_sym_equiv)i, + num_primitive_sym_equiv = %(num_sym_equiv)i, + short_name = %(short_name)r, + point_group_name = %(point_group_name)r, + crystal_system = %(crystal_system)r, + pdb_name = %(pdb_name)r, + symop_list = [ + @SYMOPS@ + ] +) +""" + + +def SGCode(mmsg): + src0 = _SGsrc % mmsg.__dict__ + src1 = src0.replace("@SYMOPS@", SymOpsCode(mmsg)) + return src1 + + +def SymOpsCode(mmsg): + lst = ["%8s%s," % ("", SymOpCode(op)) for op in mmsg.iter_symops()] + src = "\n".join(lst).strip() + return src + + +def SymOpCode(op): + if not _rtnames: + import diffpy.structure.SpaceGroups as sgmod + + for n in dir(sgmod): + if not n.startswith("Rot_") and not n.startswith("Tr_"): + continue + a = getattr(sgmod, n) + at = tuple(a.flatten()) + _rtnames[at] = "sgmod." + n + nR = _rtnames[tuple(op.R.flatten())] + nt = _rtnames[tuple(op.t)] + src = "SymOp(%s, %s)" % (nR, nt) + return src + + +_rtnames = {} + + +def main(): + duplicates = set() + for smbls in sgtbx.space_group_symbol_iterator(): + uhm = smbls.universal_hermann_mauguin() + grp = sgtbx.space_group_info(uhm).group() + if findEquivalentMMSpaceGroup(grp): + continue + shn = smbls.hermann_mauguin().replace(" ", "") + if IsSpaceGroupIdentifier(shn): + continue + sg = mmSpaceGroupFromSymbol(uhm) + hsg = hashMMSpaceGroup(sg) + if hsg in duplicates: + continue + adjustMMSpaceGroupNumber(sg) + duplicates.add(hsg) + print(SGCode(sg)) + return + + +if __name__ == "__main__": + main() From 84182c446614b1735757d2f9b97474fbd0375d3d Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:31:13 -0400 Subject: [PATCH 087/226] Resolve authors --- AUTHORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index 9f6a419f..1abf16be 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,6 +1,7 @@ Authors ======= +Billinge Group and community contributors, Pavol Juhas, Christopher L. Farrow, Xiaohao Yang, From f3029fb1b42df9edb46b23a6f9204cd376de0085 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:31:47 -0400 Subject: [PATCH 088/226] Add updated doc --- .../api/diffpy.structure.example_package.rst | 31 +++++ doc/source/api/diffpy.structure.rst | 106 ++---------------- doc/source/conf.py | 14 --- doc/source/index.rst | 43 +------ 4 files changed, 43 insertions(+), 151 deletions(-) create mode 100644 doc/source/api/diffpy.structure.example_package.rst diff --git a/doc/source/api/diffpy.structure.example_package.rst b/doc/source/api/diffpy.structure.example_package.rst new file mode 100644 index 00000000..3595000a --- /dev/null +++ b/doc/source/api/diffpy.structure.example_package.rst @@ -0,0 +1,31 @@ +.. _example_package documentation: + +|title| +======= + +.. |title| replace:: diffpy.structure.example_package package + +.. automodule:: diffpy.structure.example_package + :members: + :undoc-members: + :show-inheritance: + +|foo| +----- + +.. |foo| replace:: diffpy.structure.example_package.foo module + +.. automodule:: diffpy.structure.example_package.foo + :members: + :undoc-members: + :show-inheritance: + +|bar| +----- + +.. |bar| replace:: diffpy.structure.example_package.bar module + +.. automodule:: diffpy.structure.example_package.foo + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index 95ff1285..cdcc80ea 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -1,7 +1,9 @@ :tocdepth: -1 -diffpy.structure package -======================== +|title| +======= + +.. |title| replace:: diffpy.structure package .. automodule:: diffpy.structure :members: @@ -12,107 +14,17 @@ Subpackages ----------- .. toctree:: - :titlesonly: - - diffpy.structure.parsers - diffpy.structure.expansion - diffpy.structure.apps + diffpy.structure.example_package Submodules ---------- -diffpy.structure.spacegroups module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.spacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure._legacy_importer module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure._legacy_importer - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structureerrors module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.structureerrors - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.spacegroupmod module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.spacegroupmod - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.utils module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.utils - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.lattice module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.lattice - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.structure module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.structure - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.mmlibspacegroups module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.mmlibspacegroups - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.symmetryutilities module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.symmetryutilities - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.atom module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.atom - :members: - :undoc-members: - :show-inheritance: - -diffpy.structure.pdffitstructure module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.structure.pdffitstructure - :members: - :undoc-members: - :show-inheritance: +|module| +-------- -diffpy.structure.sgtbxspacegroups module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. |module| replace:: diffpy.structure.example_submodule module -.. automodule:: diffpy.structure.sgtbxspacegroups +.. automodule:: diffpy.structure.example_submodule :members: :undoc-members: :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py index d3af3e37..f7b1c770 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -18,8 +18,6 @@ from importlib.metadata import version from pathlib import Path -autodoc_mock_imports = ["importlib.metadata"] - # 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. @@ -48,8 +46,6 @@ "m2r", ] -autodoc_member_order = "groupwise" - # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -120,12 +116,6 @@ # Display all warnings for missing links. nitpicky = True -nitpick_ignore = [ - ("py:class", "array_like"), - ("py:class", "Parser"), - ("py:class", "CifFile"), -] - # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -297,7 +287,3 @@ # Example configuration for intersphinx: refer to the Python standard library. # intersphinx_mapping = {'http://docs.python.org/': None} -intersphinx_mapping = { - "python": ("https://docs.python.org/3", None), - "numpy": ("https://numpy.org/doc/stable/", None), -} diff --git a/doc/source/index.rst b/doc/source/index.rst index 4fabbaa1..54ec3695 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,57 +4,21 @@ .. |title| replace:: diffpy.structure documentation -diffpy.structure - Crystal structure container and parsers for structure formats. +diffpy.structure - Crystal structure container and parsers for structure formats.. | Software version |release|. | Last updated |today|. -The diffpy.structure package provides objects for storing atomic -coordinates, displacement parameters and other crystal structure data. -diffpy.structure supports import and export of structure data in several -structure formats such as CIF, PDB, xyz. It provides conversion -between fractional and absolute Cartesian coordinates, functions for -symmetry expansion from asymmetric unit and generation of symmetry -constraints for atom positions and displacement parameters. diffpy.structure -includes definitions of all space groups in over 500 symmetry settings. - ======= Authors ======= -diffpy.structure is developed by members of the Billinge Group at -Columbia University and at Brookhaven National Laboratory including -Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. +diffpy.structure is developed by Billinge Group +and its community contributors. For a detailed list of contributors see https://github.com/diffpy/diffpy.structure/graphs/contributors. -Acknowledgments -=============== - -Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* -originate from the pymmlib project, http://pymmlib.sourceforge.net. -Less common settings of space groups were generating using the -Computational Crystallography Toolbox, -http://cctbx.sourceforge.net. - - -.. index:: citation, reference - -Reference -========= - -If you use this program for a scientific research that leads -to publication, we ask that you acknowledge use of the program -by citing the following paper in your publication: - - P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, - `Complex modeling: a strategy and software program for combining - multiple information sources to solve ill posed structure and - nanostructure inverse problems - `__, - *Acta Crystallogr. A* **71**, 562-568 (2015). - ============ Installation ============ @@ -65,7 +29,6 @@ file included with the distribution. ================= Table of contents ================= - .. toctree:: :titlesonly: From de0ab3787eb328c5acf4dd65ffc29bcb5973a404 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:34:22 -0400 Subject: [PATCH 089/226] Remove legacy import --- src/diffpy/Structure.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/diffpy/Structure.py diff --git a/src/diffpy/Structure.py b/src/diffpy/Structure.py deleted file mode 100644 index 1f65df4b..00000000 --- a/src/diffpy/Structure.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure Complex Modeling Initiative -# (c) 2017 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. -# -############################################################################## - -"""Support import of old camel-case module names with `DeprecationWarning`. - -The imported camel-case modules are aliases for the current module -instances. Their `__name__` attributes are thus all in lower-case. - -Warning -------- -This module is deprecated and will be removed in the future. -""" - - -import sys - -# install legacy import hooks -import diffpy.structure._legacy_importer - -# replace this module with the new one -sys.modules["diffpy.Structure"] = diffpy.structure - -# End of file From 0500e49af3a6addda73ad837abd5e3c225b1b2f8 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:38:30 -0400 Subject: [PATCH 090/226] Add license --- LICENSE.rst | 2 +- LICENSE_DANSE.rst | 4 +- LICENSE_pymmlib.rst | 2 +- doc/source/license.rst | 169 +++++++++++++++++++++++++++++++++-------- 4 files changed, 143 insertions(+), 34 deletions(-) diff --git a/LICENSE.rst b/LICENSE.rst index f1fe010e..2e8d4ba9 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -15,7 +15,7 @@ Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory -Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. All rights reserved. The "DiffPy-CMI" is distributed subject to the following license conditions: diff --git a/LICENSE_DANSE.rst b/LICENSE_DANSE.rst index c05648e1..d56af619 100644 --- a/LICENSE_DANSE.rst +++ b/LICENSE_DANSE.rst @@ -9,13 +9,13 @@ Copyright 2006-2007, Board of Trustees of Michigan State University, Copyright 2008-2012, The Trustees of Columbia University in the City of New York. (Copyright holder indicated in each source file). -Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. All rights reserved. For more information please visit the project web-page: http://www.diffpy.org/ - + or email Prof. Simon Billinge at sb2896@columbia.edu Redistribution and use in source and binary forms, with or without diff --git a/LICENSE_pymmlib.rst b/LICENSE_pymmlib.rst index e0b82c94..ef484f5a 100644 --- a/LICENSE_pymmlib.rst +++ b/LICENSE_pymmlib.rst @@ -1,5 +1,5 @@ .. code-block:: text - + The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. diff --git a/doc/source/license.rst b/doc/source/license.rst index cfab61c2..39176b12 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -7,33 +7,142 @@ License OPEN SOURCE LICENSE AGREEMENT ============================= -BSD 3-Clause License - -Copyright (c) 2024, The Trustees of Columbia University in -the City of New York. -All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (c) 1989, 1991 Free Software Foundation, Inc. + +Copyright (c) 2006, The Regents of the University of California through Lawrence Berkeley National Laboratory + +Copyright (c) 2006-2007, Board of Trustees of Michigan State University + +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York + +Copyright (c) 2009-2011, University of Tennessee + +Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") + +Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory + +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +All rights reserved. + +The "DiffPy-CMI" is distributed subject to the following license conditions: + +.. code-block:: text + + SOFTWARE LICENSE AGREEMENT + + Software: DiffPy-CMI + + + (1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either + source code, or binary form and accompanying documentation). + + Part of the software was derived from the DANSE, ObjCryst++ (with permission), + PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of + which the original Copyrights are contained in each individual file. + + Each licensee is addressed as "you" or "Licensee." + + + (2) The copyright holders shown above and their third-party Licensors hereby + grant licensee a royalty-free nonexclusive license, subject to the limitations + stated herein and U.S. Government license rights. + + + (3) You may modify and make a copy or copies of the software for use within + your organization, if you meet the following conditions: + + (a) Copies in source code must include the copyright notice and this + software license agreement. + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy. + + + (4) You may modify a copy or copies of the Software or any portion of it, thus + forming a work based on the Software, and distribute copies of such work + outside your organization, if you meet all of the following conditions: + + (a) Copies in source code must include the copyright notice and this + Software License Agreement; + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy; + + (c) Modified copies and works based on the Software must carry prominent + notices stating that you changed specified portions of the Software. + + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + + (5) Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: + The Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer software + to reproduce, prepare derivative works, and perform publicly and display + publicly. + + + (6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND + THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL + LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE + PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION + UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + + (7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING + BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, + WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING + NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS + BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + +END OF LICENSE From dc12979efd51e6765b4f0df4dfb809e2255d848e Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:40:23 -0400 Subject: [PATCH 091/226] Resolve README --- README.rst | 22 +++++----------------- doc/source/license.rst | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/README.rst b/README.rst index 5dd3a227..5ae201ad 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,8 @@ .. |Black| image:: https://img.shields.io/badge/code_style-black-black :target: https://github.com/psf/black -.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml/badge.svg - :target: https://github.com/diffpy/diffpy.structure/actions/workflows/main.yml +.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov-on-merge-to-main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov-on-merge-to-main.yml .. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/main/graph/badge.svg :target: https://codecov.io/gh/diffpy/diffpy.structure @@ -47,6 +47,7 @@ of symmetry constraints for atom positions and displacement parameters. diffpy.structure includes definitions of all space groups in over 500 symmetry settings. + For more information about the diffpy.structure library, please consult our `online documentation `_. Citation @@ -86,11 +87,7 @@ Then, to fully install ``diffpy.structure`` in our active environment, run :: Another option is to use ``pip`` to download and install the latest release from `Python Package Index `_. -To install using ``pip`` into your ``diffpy.structure_env`` environment, we will also have to install dependencies :: - - pip install -r https://raw.githubusercontent.com/diffpy/diffpy.structure/main/requirements/run.txt - -and then install the package :: +To install using ``pip`` into your ``diffpy.structure_env`` environment, type :: pip install diffpy.structure @@ -105,7 +102,7 @@ Support and Contribute `Diffpy user group `_ is the discussion forum for general questions and discussions about the use of diffpy.structure. Please join the diffpy.structure users community by joining the Google group. The diffpy.structure 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 `_. You can also post it to the `Diffpy user group `_. Feel free to fork the project and contribute. To install diffpy.structure in a development mode, with its sources being directly used by Python @@ -130,15 +127,6 @@ Improvements and fixes are always appreciated. Before contribuing, please read our `Code of Conduct `_. -Acknowledgement ---------------- - -Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* -originate from the `pymmlib project `_. - -Less common settings of space groups were generating using the -`Computational Crystallography Toolbox `_. - Contact ------- diff --git a/doc/source/license.rst b/doc/source/license.rst index 39176b12..33a363ae 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -22,7 +22,7 @@ Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory -Copyright (c) 2024, The Trustees of Columbia University in the City of New York. +Copyright (c) 2024, The Trustees of Columbia University in the City of New York. All rights reserved. The "DiffPy-CMI" is distributed subject to the following license conditions: From 89e8b4686caebce54a87c738b6f22c77f4f98a31 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:41:59 -0400 Subject: [PATCH 092/226] Use existing index.rst --- doc/source/index.rst | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/doc/source/index.rst b/doc/source/index.rst index 54ec3695..4fabbaa1 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -4,21 +4,57 @@ .. |title| replace:: diffpy.structure documentation -diffpy.structure - Crystal structure container and parsers for structure formats.. +diffpy.structure - Crystal structure container and parsers for structure formats. | Software version |release|. | Last updated |today|. +The diffpy.structure package provides objects for storing atomic +coordinates, displacement parameters and other crystal structure data. +diffpy.structure supports import and export of structure data in several +structure formats such as CIF, PDB, xyz. It provides conversion +between fractional and absolute Cartesian coordinates, functions for +symmetry expansion from asymmetric unit and generation of symmetry +constraints for atom positions and displacement parameters. diffpy.structure +includes definitions of all space groups in over 500 symmetry settings. + ======= Authors ======= -diffpy.structure is developed by Billinge Group -and its community contributors. +diffpy.structure is developed by members of the Billinge Group at +Columbia University and at Brookhaven National Laboratory including +Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.structure/graphs/contributors. +Acknowledgments +=============== + +Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* +originate from the pymmlib project, http://pymmlib.sourceforge.net. +Less common settings of space groups were generating using the +Computational Crystallography Toolbox, +http://cctbx.sourceforge.net. + + +.. index:: citation, reference + +Reference +========= + +If you use this program for a scientific research that leads +to publication, we ask that you acknowledge use of the program +by citing the following paper in your publication: + + P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, + `Complex modeling: a strategy and software program for combining + multiple information sources to solve ill posed structure and + nanostructure inverse problems + `__, + *Acta Crystallogr. A* **71**, 562-568 (2015). + ============ Installation ============ @@ -29,6 +65,7 @@ file included with the distribution. ================= Table of contents ================= + .. toctree:: :titlesonly: From 9a93d8ebf9ca4071aade442d64c6bf3597505a49 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:42:59 -0400 Subject: [PATCH 093/226] Add sgroup acknowledgements in readme --- README.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.rst b/README.rst index 5ae201ad..076bc7e3 100644 --- a/README.rst +++ b/README.rst @@ -127,6 +127,15 @@ Improvements and fixes are always appreciated. Before contribuing, please read our `Code of Conduct `_. +Acknowledgement +--------------- + +Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* +originate from the `pymmlib project `_. + +Less common settings of space groups were generating using the +`Computational Crystallography Toolbox `_. + Contact ------- From 2e992d9fa8505bef99561a8feba7adf429c7050c Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:48:19 -0400 Subject: [PATCH 094/226] Remove older import tests --- tests/test_oldimports.py | 77 ---------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 tests/test_oldimports.py diff --git a/tests/test_oldimports.py b/tests/test_oldimports.py deleted file mode 100644 index 9c6ff11d..00000000 --- a/tests/test_oldimports.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.structure Complex Modeling Initiative -# (c) 2017 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. -# -############################################################################## - -""" -Unit tests for imports of old camel-case names. -""" - - -import importlib -import sys -import unittest -import warnings - -import diffpy - -# ---------------------------------------------------------------------------- - - -class TestOldImports(unittest.TestCase): - - @classmethod - def setUpClass(cls): - "Uncache any already-imported old modules." - for modname in tuple(sys.modules): - if modname.startswith("diffpy.Structure"): - del sys.modules[modname] # pragma: no cover - return - - def test_00TopImport(self): - """check import of diffpy.Structure""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", category=DeprecationWarning) - import diffpy.Structure as m0 - self.assertIs(diffpy.structure, m0) - # second import should raise no warning - with warnings.catch_warnings(): - warnings.simplefilter("error") - import diffpy.Structure as m1 - self.assertIs(diffpy.structure, m1) - return - - def test_O1SubmoduleImport(self): - """check import of diffpy.Structure submodules.""" - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", category=DeprecationWarning) - import diffpy.Structure.SymmetryUtilities as symutil - - self.assertIs(DeprecationWarning, w[0].category) - self.assertIs(diffpy.structure.symmetryutilities, symutil) - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", category=DeprecationWarning) - import diffpy.Structure.Parsers.P_cif as pcif - - self.assertIs(DeprecationWarning, w[0].category) - self.assertIs(diffpy.structure.parsers.p_cif, pcif) - self.assertRaises(ImportError, importlib.import_module, "diffpy.Structure.SSpaceGroups") - return - - -# End of class TestOldImports - -# ---------------------------------------------------------------------------- - -if __name__ == "__main__": - unittest.main() From 4cccb7a18c6cb077e9cb9a441a16c2246675ca59 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:51:13 -0400 Subject: [PATCH 095/226] Add api generated docs --- doc/source/api/diffpy.structure.apps.rst | 1 + .../api/diffpy.structure.example_package.rst | 31 ----- doc/source/api/diffpy.structure.expansion.rst | 1 + doc/source/api/diffpy.structure.parsers.rst | 1 + doc/source/api/diffpy.structure.rst | 107 ++++++++++++++++-- 5 files changed, 101 insertions(+), 40 deletions(-) delete mode 100644 doc/source/api/diffpy.structure.example_package.rst diff --git a/doc/source/api/diffpy.structure.apps.rst b/doc/source/api/diffpy.structure.apps.rst index 8b91adf5..5ac351dd 100644 --- a/doc/source/api/diffpy.structure.apps.rst +++ b/doc/source/api/diffpy.structure.apps.rst @@ -26,3 +26,4 @@ diffpy.structure.apps.anyeye module :members: :undoc-members: :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.example_package.rst b/doc/source/api/diffpy.structure.example_package.rst deleted file mode 100644 index 3595000a..00000000 --- a/doc/source/api/diffpy.structure.example_package.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. _example_package documentation: - -|title| -======= - -.. |title| replace:: diffpy.structure.example_package package - -.. automodule:: diffpy.structure.example_package - :members: - :undoc-members: - :show-inheritance: - -|foo| ------ - -.. |foo| replace:: diffpy.structure.example_package.foo module - -.. automodule:: diffpy.structure.example_package.foo - :members: - :undoc-members: - :show-inheritance: - -|bar| ------ - -.. |bar| replace:: diffpy.structure.example_package.bar module - -.. automodule:: diffpy.structure.example_package.foo - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/api/diffpy.structure.expansion.rst b/doc/source/api/diffpy.structure.expansion.rst index 34529fcd..afce983c 100644 --- a/doc/source/api/diffpy.structure.expansion.rst +++ b/doc/source/api/diffpy.structure.expansion.rst @@ -34,3 +34,4 @@ diffpy.structure.expansion.supercell_mod module :members: :undoc-members: :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.parsers.rst b/doc/source/api/diffpy.structure.parsers.rst index 74a27bcb..54a88f2e 100644 --- a/doc/source/api/diffpy.structure.parsers.rst +++ b/doc/source/api/diffpy.structure.parsers.rst @@ -90,3 +90,4 @@ diffpy.structure.parsers.p_xyz module :members: :undoc-members: :show-inheritance: + diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index cdcc80ea..eb13f679 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -1,9 +1,7 @@ :tocdepth: -1 -|title| -======= - -.. |title| replace:: diffpy.structure package +diffpy.structure package +======================== .. automodule:: diffpy.structure :members: @@ -14,17 +12,108 @@ Subpackages ----------- .. toctree:: - diffpy.structure.example_package + :titlesonly: + + diffpy.structure.parsers + diffpy.structure.expansion + diffpy.structure.apps Submodules ---------- -|module| --------- +diffpy.structure.spacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.spacegroups + :members: + :undoc-members: + :show-inheritance: -.. |module| replace:: diffpy.structure.example_submodule module +diffpy.structure._legacy_importer module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.structure.example_submodule +.. automodule:: diffpy.structure._legacy_importer :members: :undoc-members: :show-inheritance: + +diffpy.structure.structureerrors module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.structureerrors + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.spacegroupmod module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.spacegroupmod + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.utils module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.utils + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.lattice module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.lattice + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.structure module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.structure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.mmlibspacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.mmlibspacegroups + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.symmetryutilities module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.symmetryutilities + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.atom module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.atom + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.pdffitstructure module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.pdffitstructure + :members: + :undoc-members: + :show-inheritance: + +diffpy.structure.sgtbxspacegroups module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.sgtbxspacegroups + :members: + :undoc-members: + :show-inheritance: + From d3d5456af8a6a3b256f2837af3562aa41fbc86de Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:53:16 +0000 Subject: [PATCH 096/226] [pre-commit.ci] auto fixes from pre-commit hooks --- doc/source/api/diffpy.structure.apps.rst | 1 - doc/source/api/diffpy.structure.expansion.rst | 1 - doc/source/api/diffpy.structure.parsers.rst | 1 - doc/source/api/diffpy.structure.rst | 1 - 4 files changed, 4 deletions(-) diff --git a/doc/source/api/diffpy.structure.apps.rst b/doc/source/api/diffpy.structure.apps.rst index 5ac351dd..8b91adf5 100644 --- a/doc/source/api/diffpy.structure.apps.rst +++ b/doc/source/api/diffpy.structure.apps.rst @@ -26,4 +26,3 @@ diffpy.structure.apps.anyeye module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.expansion.rst b/doc/source/api/diffpy.structure.expansion.rst index afce983c..34529fcd 100644 --- a/doc/source/api/diffpy.structure.expansion.rst +++ b/doc/source/api/diffpy.structure.expansion.rst @@ -34,4 +34,3 @@ diffpy.structure.expansion.supercell_mod module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.parsers.rst b/doc/source/api/diffpy.structure.parsers.rst index 54a88f2e..74a27bcb 100644 --- a/doc/source/api/diffpy.structure.parsers.rst +++ b/doc/source/api/diffpy.structure.parsers.rst @@ -90,4 +90,3 @@ diffpy.structure.parsers.p_xyz module :members: :undoc-members: :show-inheritance: - diff --git a/doc/source/api/diffpy.structure.rst b/doc/source/api/diffpy.structure.rst index eb13f679..95ff1285 100644 --- a/doc/source/api/diffpy.structure.rst +++ b/doc/source/api/diffpy.structure.rst @@ -116,4 +116,3 @@ diffpy.structure.sgtbxspacegroups module :members: :undoc-members: :show-inheritance: - From 866aa7de0508e3af26ae8193667e49587f695763 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Mon, 23 Sep 2024 19:56:28 -0400 Subject: [PATCH 097/226] Add news item of recut.rst --- news/recut.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/recut.rst diff --git a/news/recut.rst b/news/recut.rst new file mode 100644 index 00000000..973fc92b --- /dev/null +++ b/news/recut.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Recookiecut package to the group standard + +**Security:** + +* From b67fbb76f6801df52d4a979c214133f7eb4faac0 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Wed, 25 Sep 2024 21:45:30 -0400 Subject: [PATCH 098/226] Remove null in matrix and codecov.yml --- .github/workflows/matrix-and-codecov-on-merge-to-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml index c1905e0d..743193f7 100644 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -8,7 +8,7 @@ on: types: - prereleased - published - workflow_dispatch: null + workflow_dispatch: jobs: coverage: From 3fdc6d0f37a94bee228f171cd2043da85d64e12d Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 3 Oct 2024 13:02:09 -0400 Subject: [PATCH 099/226] Add pip packages under pip.txt --- news/pip.rst | 23 +++++++++++++++++++++++ pyproject.toml | 2 +- requirements/{run.txt => conda.txt} | 0 requirements/pip.txt | 2 ++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 news/pip.rst rename requirements/{run.txt => conda.txt} (100%) diff --git a/news/pip.rst b/news/pip.rst new file mode 100644 index 00000000..d10e3b6d --- /dev/null +++ b/news/pip.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Add pip dependencies under pip.txt and conda dependencies under conda.txt + +**Security:** + +* diff --git a/pyproject.toml b/pyproject.toml index 206884bf..147c3705 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) [tool.setuptools.dynamic] -dependencies = {file = ["requirements/run.txt"]} +dependencies = {file = ["requirements/pip.txt"]} [tool.black] line-length = 115 diff --git a/requirements/run.txt b/requirements/conda.txt similarity index 100% rename from requirements/run.txt rename to requirements/conda.txt diff --git a/requirements/pip.txt b/requirements/pip.txt index e69de29b..0fdcecb6 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -0,0 +1,2 @@ +numpy +pycifrw From 5e2ff1e179d956f7571b6d5730e81845f27a355c Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Fri, 4 Oct 2024 18:08:25 +0000 Subject: [PATCH 100/226] Update CHANGELOG.rst --- CHANGELOG.rst | 17 +++++++++++++++++ news/folder.rst | 23 ----------------------- news/numpy2.rst | 23 ----------------------- news/pip.rst | 23 ----------------------- news/recut.rst | 23 ----------------------- news/version-test.rst | 23 ----------------------- 6 files changed, 17 insertions(+), 115 deletions(-) delete mode 100644 news/folder.rst delete mode 100644 news/numpy2.rst delete mode 100644 news/pip.rst delete mode 100644 news/recut.rst delete mode 100644 news/version-test.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0fde0ea2..be9a82a7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,23 @@ Release Notes .. current developments +3.2.2 +===== + +**Added:** + +* Unit test for version.py +* support for numpy >=2.0 + +**Fixed:** + +* tests folder at the root of the repo +* Add pip dependencies under pip.txt and conda dependencies under conda.txt +* element/label itemsize to 5 in _linkAtomAttribute to support numpy >=2.0 +* Recookiecut package to the group standard + + + 3.2.1 ===== diff --git a/news/folder.rst b/news/folder.rst deleted file mode 100644 index 63f83284..00000000 --- a/news/folder.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* tests folder at the root of the repo - -**Security:** - -* diff --git a/news/numpy2.rst b/news/numpy2.rst deleted file mode 100644 index af1631fa..00000000 --- a/news/numpy2.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* support for numpy >=2.0 - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* element/label itemsize to 5 in _linkAtomAttribute to support numpy >=2.0 - -**Security:** - -* diff --git a/news/pip.rst b/news/pip.rst deleted file mode 100644 index d10e3b6d..00000000 --- a/news/pip.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Add pip dependencies under pip.txt and conda dependencies under conda.txt - -**Security:** - -* diff --git a/news/recut.rst b/news/recut.rst deleted file mode 100644 index 973fc92b..00000000 --- a/news/recut.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Recookiecut package to the group standard - -**Security:** - -* diff --git a/news/version-test.rst b/news/version-test.rst deleted file mode 100644 index 05c39477..00000000 --- a/news/version-test.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Unit test for version.py - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* From 541dde4355da052fce81f586d9c29a43ba570906 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Tue, 22 Oct 2024 23:57:46 -0400 Subject: [PATCH 101/226] recut to align with the new release process --- .github/ISSUE_TEMPLATE/bug_feature.md | 16 ++++++++++++ .github/ISSUE_TEMPLATE/release_checklist.md | 22 ++++++++++++++++ .../workflows/build-wheel-release-upload.yml | 16 ++++++++++++ README.rst | 15 ++++++++--- news/recut.rst | 25 +++++++++++++++++++ src/diffpy/__init__.py | 1 + 6 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_feature.md create mode 100644 .github/ISSUE_TEMPLATE/release_checklist.md create mode 100644 .github/workflows/build-wheel-release-upload.yml create mode 100644 news/recut.rst diff --git a/.github/ISSUE_TEMPLATE/bug_feature.md b/.github/ISSUE_TEMPLATE/bug_feature.md new file mode 100644 index 00000000..b3454deb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_feature.md @@ -0,0 +1,16 @@ +--- +name: Bug Report or Feature Request +about: Report a bug or suggest a new feature! +title: "" +labels: "" +assignees: "" +--- + +### Problem + + + +### Proposed solution diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md new file mode 100644 index 00000000..a87a44a8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -0,0 +1,22 @@ +--- +name: Release +about: Checklist and communication channel for PyPI and GitHub release +title: "Ready for PyPI/GitHub release" +labels: "release" +assignees: "" +--- + +### Release checklist for GitHub contributors + +- [ ] 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 on the website (e.g., diffpy.org) are updated and + tested +- [ ] Successfully run any tutorial examples or do functional testing in some other way. +- [ ] Grammar and writing quality have been checked (no typos). + +Please mention @sbillinge when you are ready for release. Include any additional comments necessary, such as +version information and details about the pre-release. diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml new file mode 100644 index 00000000..9eb24167 --- /dev/null +++ b/.github/workflows/build-wheel-release-upload.yml @@ -0,0 +1,16 @@ +name: Release (GitHub/PyPI) + +on: + workflow_dispatch: + push: + tags: + - '*' # 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 + with: + project: diffpy.structure + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/README.rst b/README.rst index 076bc7e3..9ac19161 100644 --- a/README.rst +++ b/README.rst @@ -78,14 +78,16 @@ To add "conda-forge" to the conda channels, run the following in a terminal. :: We want to install our packages in a suitable conda environment. The following creates and activates a new environment named ``diffpy.structure_env`` :: - conda create -n diffpy.structure_env python=3 + conda create -n diffpy.structure_env diffpy.structure conda activate diffpy.structure_env -Then, to fully install ``diffpy.structure`` in our active environment, run :: +To confirm that the installation was successful, type :: - conda install diffpy.structure + python -c "import diffpy.structure; print(diffpy.structure.__version__)" -Another option is to use ``pip`` to download and install the latest release from +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 `Python Package Index `_. To install using ``pip`` into your ``diffpy.structure_env`` environment, type :: @@ -97,6 +99,11 @@ and run the following :: pip install . +Getting Started +--------------- + +You may consult our `online documentation `_ for tutorials and API references. + Support and Contribute ---------------------- diff --git a/news/recut.rst b/news/recut.rst new file mode 100644 index 00000000..153d1bb0 --- /dev/null +++ b/news/recut.rst @@ -0,0 +1,25 @@ +**Added:** + +* Use GitHub Actions to build, release, upload to PyPI +* Added issue template for PyPI/GitHub release +* Include GitHub Issues templates for bug report and feature request + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Add getting started section and re-arrange install success check instructions + +**Security:** + +* diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index ee55ab5f..3e7952ae 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -21,3 +21,4 @@ __path__ = extend_path(__path__, __name__) # End of file + From 4aa57b34d45c38e7f2f93fa739a3dbfdfb94c353 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 04:01:42 +0000 Subject: [PATCH 102/226] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 3e7952ae..ee55ab5f 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -21,4 +21,3 @@ __path__ = extend_path(__path__, __name__) # End of file - From c1bfa76abcd854581ad0582671c86ca8176d4041 Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 24 Oct 2024 15:27:35 -0400 Subject: [PATCH 103/226] add app sripts, fix python version, small updates anyeye --- pyproject.toml | 5 ++++- src/diffpy/structure/apps/anyeye.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 147c3705..16875161 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Crystal structure container and parsers for structure formats." keywords = ['diffpy', 'crystal structure data storage CIF PDB'] readme = "README.rst" -requires-python = ">=3.10" +requires-python = ">=3.10, < 3.13" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -36,6 +36,9 @@ classifiers = [ Homepage = "https://github.com/diffpy/diffpy.structure/" Issues = "https://github.com/diffpy/diffpy.structure/issues/" +[project.scripts] +transtru = "diffpy.structure.apps.transtru:main" + [tool.setuptools-git-versioning] enabled = true template = "{tag}" diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index fbf549ca..b7904d8e 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -265,7 +265,7 @@ def main(): spawnargs = (pd["viewer"], pd["viewer"], pd["tmpfile"], env) # load strufile in atomeye if pd["watch"]: - signal.signal(signal.SIGCLD, signalHandler) + signal.signal(signal.SIGCHLD, signalHandler) os.spawnlpe(os.P_NOWAIT, *spawnargs) watchStructureFile(pd) else: From 959e5be971c228e8c39cfa698f155d3221c411ef Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 24 Oct 2024 15:32:47 -0400 Subject: [PATCH 104/226] add news --- news/toml.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 news/toml.rst diff --git a/news/toml.rst b/news/toml.rst new file mode 100644 index 00000000..600d0d47 --- /dev/null +++ b/news/toml.rst @@ -0,0 +1,24 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Added termial script for transtru app in pyproject.toml +* Changed requires-python to align with classifiers + +**Security:** + +* From 6fa73b649fb73b267e7cede848064432d5ec81eb Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 24 Oct 2024 15:33:35 -0400 Subject: [PATCH 105/226] change <3.13 to <=3.12 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 16875161..b64a1346 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Crystal structure container and parsers for structure formats." keywords = ['diffpy', 'crystal structure data storage CIF PDB'] readme = "README.rst" -requires-python = ">=3.10, < 3.13" +requires-python = ">=3.10, <=3.12" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', From 6b4a018e24cfbcf17a8a46dbfbf4c68e8b248d2f Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 24 Oct 2024 15:39:12 -0400 Subject: [PATCH 106/226] change <=3.12 back to <3.13 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b64a1346..6076df58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Crystal structure container and parsers for structure formats." keywords = ['diffpy', 'crystal structure data storage CIF PDB'] readme = "README.rst" -requires-python = ">=3.10, <=3.12" +requires-python = ">=3.10, <3.13" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', From b0a034406f9ee43f47f10467689c7def9e143de6 Mon Sep 17 00:00:00 2001 From: sbillinge Date: Thu, 24 Oct 2024 21:13:20 +0000 Subject: [PATCH 107/226] update changelog --- CHANGELOG.rst | 16 ++++++++++++++++ news/recut.rst | 25 ------------------------- news/toml.rst | 24 ------------------------ 3 files changed, 16 insertions(+), 49 deletions(-) delete mode 100644 news/recut.rst delete mode 100644 news/toml.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index be9a82a7..2c9a55f7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,22 @@ Release Notes .. current developments +3.2.3 +===== + +**Added:** + +* Use GitHub Actions to build, release, upload to PyPI +* Added issue template for PyPI/GitHub release +* Include GitHub Issues templates for bug report and feature request + +**Fixed:** + +* Add getting started section and re-arrange install success check instructions +* Added termial script for transtru app in pyproject.toml +* Changed requires-python to align with classifiers + + 3.2.2 ===== diff --git a/news/recut.rst b/news/recut.rst deleted file mode 100644 index 153d1bb0..00000000 --- a/news/recut.rst +++ /dev/null @@ -1,25 +0,0 @@ -**Added:** - -* Use GitHub Actions to build, release, upload to PyPI -* Added issue template for PyPI/GitHub release -* Include GitHub Issues templates for bug report and feature request - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Add getting started section and re-arrange install success check instructions - -**Security:** - -* diff --git a/news/toml.rst b/news/toml.rst deleted file mode 100644 index 600d0d47..00000000 --- a/news/toml.rst +++ /dev/null @@ -1,24 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Added termial script for transtru app in pyproject.toml -* Changed requires-python to align with classifiers - -**Security:** - -* From aac7cf39e22701dbb149c3b1faa5c1917bcbc2dd Mon Sep 17 00:00:00 2001 From: Tieqiong Zhang Date: Thu, 24 Oct 2024 22:39:59 -0400 Subject: [PATCH 108/226] Support Python 3.13, drop 3.10 --- news/3.13.rst | 23 +++++++++++++++++++++++ pyproject.toml | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 news/3.13.rst diff --git a/news/3.13.rst b/news/3.13.rst new file mode 100644 index 00000000..afb325da --- /dev/null +++ b/news/3.13.rst @@ -0,0 +1,23 @@ +**Added:** + +* Support for Python 3.13 + +**Changed:** + +* + +**Deprecated:** + +* Support for Python 3.10 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/pyproject.toml b/pyproject.toml index 6076df58..dd1150c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ maintainers = [ description = "Crystal structure container and parsers for structure formats." keywords = ['diffpy', 'crystal structure data storage CIF PDB'] readme = "README.rst" -requires-python = ">=3.10, <3.13" +requires-python = ">=3.11, <3.14" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -25,9 +25,9 @@ classifiers = [ 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', 'Operating System :: Unix', - 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Scientific/Engineering :: Physics', 'Topic :: Scientific/Engineering :: Chemistry', ] From 4b7ba36ea879bd492630efa1b8a86f0dcd1e0f99 Mon Sep 17 00:00:00 2001 From: sbillinge Date: Sat, 26 Oct 2024 20:32:44 +0000 Subject: [PATCH 109/226] update changelog --- CHANGELOG.rst | 12 ++++++++++++ news/3.13.rst | 23 ----------------------- 2 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 news/3.13.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2c9a55f7..2bf42c49 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,18 @@ Release Notes .. current developments +3.3.0 +===== + +**Added:** + +* Support for Python 3.13 + +**Deprecated:** + +* Support for Python 3.10 + + 3.2.3 ===== diff --git a/news/3.13.rst b/news/3.13.rst deleted file mode 100644 index afb325da..00000000 --- a/news/3.13.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Support for Python 3.13 - -**Changed:** - -* - -**Deprecated:** - -* Support for Python 3.10 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* From 3eb963d9d9c4ead06177266e05d46605c1702188 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 7 Nov 2024 21:39:43 -0500 Subject: [PATCH 110/226] Add news, codecov, codespell --- .codecov.yml | 42 +++++-------------- .codespell/ignore_lines.txt | 2 + .codespell/ignore_words.txt | 11 +++++ .coveragerc | 13 ------ .github/ISSUE_TEMPLATE/release_checklist.md | 14 +++++-- .../workflows/build-wheel-release-upload.yml | 2 +- .github/workflows/publish-docs-on-release.yml | 14 ------- .github/workflows/tests-on-pr.yml | 2 + news/codecov.rst | 24 +++++++++++ 9 files changed, 61 insertions(+), 63 deletions(-) create mode 100644 .codespell/ignore_lines.txt create mode 100644 .codespell/ignore_words.txt delete mode 100644 .coveragerc delete mode 100644 .github/workflows/publish-docs-on-release.yml create mode 100644 news/codecov.rst diff --git a/.codecov.yml b/.codecov.yml index 04dd6510..5a94096e 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,34 +1,14 @@ -# codecov can find this file anywhere in the repo, so we don't need to clutter -# the root folder. -#comment: false - -codecov: - notify: - require_ci_to_pass: no - coverage: status: - patch: + project: # more options at https://docs.codecov.com/docs/commit-status default: - target: '70' - if_no_uploads: error - if_not_found: success - if_ci_failed: failure - project: - default: false - library: - target: auto - if_no_uploads: error - if_not_found: success - if_ci_failed: error - paths: '!*/tests/.*' - - tests: - target: 97.9% - paths: '*/tests/.*' - if_not_found: success - -flags: - tests: - paths: - - tests/ + target: auto # use the coverage from the base commit, fail if coverage is lower + threshold: 0% # allow the coverage to drop by + +comment: + layout: " diff, flags, files" + behavior: default + require_changes: false + require_base: false # [true :: must have a base report to post] + require_head: false # [true :: must have a head report to post] + hide_project_coverage: false # [true :: only show coverage on the git diff aka patch coverage] diff --git a/.codespell/ignore_lines.txt b/.codespell/ignore_lines.txt new file mode 100644 index 00000000..07fa7c8c --- /dev/null +++ b/.codespell/ignore_lines.txt @@ -0,0 +1,2 @@ +;; Please include filenames and explanations for each ignored line. +;; See https://docs.openverse.org/meta/codespell.html for docs. diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt new file mode 100644 index 00000000..9757d7c0 --- /dev/null +++ b/.codespell/ignore_words.txt @@ -0,0 +1,11 @@ +;; Please include explanations for each ignored word (lowercase). +;; See https://docs.openverse.org/meta/codespell.html for docs. + +;; abbreviation for "materials" often used in a journal title +mater + +;; alternative use of socioeconomic +socio-economic + +;; Frobenius norm used in np.linalg.norm +fro diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 34ea3e4c..00000000 --- a/.coveragerc +++ /dev/null @@ -1,13 +0,0 @@ -[run] -source = - diffpy.structure -[report] -omit = - */python?.?/* - */site-packages/nose/* - # ignore _version.py and versioneer.py - .*version.* - *_version.py - -exclude_lines = - if __name__ == '__main__': diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index a87a44a8..b96c782d 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -13,10 +13,16 @@ assignees: "" - [ ] 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 on the website (e.g., diffpy.org) are updated and - tested -- [ ] Successfully run any tutorial examples or do functional testing in some other way. +- [ ] Installation instructions in the README, documentation and on the website (e.g., diffpy.org) updated. +- [ ] Successfully run any tutorial examples or do functional testing with the latest Python version - [ ] Grammar and writing quality have been checked (no typos). Please mention @sbillinge when you are ready for release. Include any additional comments necessary, such as -version information and details about the pre-release. +version information and details about the pre-release here: + +### Post-release checklist + +Before closing this issue, please complete the following: + +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index 9eb24167..c89ca95c 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) +name: Release (GitHub/PyPI) and Deploy Docs on: workflow_dispatch: diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml deleted file mode 100644 index 1c5981db..00000000 --- a/.github/workflows/publish-docs-on-release.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Build and Deploy Docs - -on: - release: - types: - - published - workflow_dispatch: - -jobs: - docs: - uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 - with: - project: diffpy.structure - c_extension: false diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index 614b16f2..1dd2ee1b 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -14,3 +14,5 @@ jobs: project: diffpy.structure c_extension: false headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/news/codecov.rst b/news/codecov.rst new file mode 100644 index 00000000..1c91077e --- /dev/null +++ b/news/codecov.rst @@ -0,0 +1,24 @@ +**Added:** + +* Spelling check via Codespell in pre-commit +* Coverage report in each PR + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From bb873328e40427d43eac9d8b4c2f2b72572390db Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 9 Nov 2024 16:10:59 -0500 Subject: [PATCH 111/226] Add conda-forge release checklist to GitHub Issue template --- .github/ISSUE_TEMPLATE/release_checklist.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index b96c782d..0f560278 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -6,23 +6,30 @@ labels: "release" assignees: "" --- -### Release checklist for GitHub contributors +### PyPI/GitHub release checklist: - [ ] 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 on the website (e.g., diffpy.org) updated. -- [ ] Successfully run any tutorial examples or do functional testing with the latest Python version -- [ ] Grammar and writing quality have been checked (no typos). +- [ ] Installation instructions in the README, documentation and on the website (e.g., diffpy.org) are updated. +- [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. +- [ ] Grammar and writing quality are checked (no typos). -Please mention @sbillinge when you are ready for release. Include any additional comments necessary, such as +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: +### conda-forge release checklist: + + + +- [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. +- [ ] All relevant issues in the feedstock are addressed in the release PR. + ### Post-release checklist -Before closing this issue, please complete the following: + -- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. - [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. From a3a6d267792b06ea71b167df8c40aa2ffead4de4 Mon Sep 17 00:00:00 2001 From: Tingwen Zhang Date: Sun, 1 Jun 2025 15:34:17 -0400 Subject: [PATCH 112/226] chored: fixed all static files --- CODE_OF_CONDUCT.rst => CODE-OF-CONDUCT.rst | 0 LICENSE_DANSE.rst => LICENSE-DANSE.rst | 0 LICENSE_pymmlib.rst => LICENSE-pymmlib.rst | 0 doc/source/{mod_atom.rst => mod-atom.rst} | 0 doc/source/{mod_lattice.rst => mod-lattice.rst} | 0 doc/source/{mod_spacegroup.rst => mod-spacegroup.rst} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename CODE_OF_CONDUCT.rst => CODE-OF-CONDUCT.rst (100%) rename LICENSE_DANSE.rst => LICENSE-DANSE.rst (100%) rename LICENSE_pymmlib.rst => LICENSE-pymmlib.rst (100%) rename doc/source/{mod_atom.rst => mod-atom.rst} (100%) rename doc/source/{mod_lattice.rst => mod-lattice.rst} (100%) rename doc/source/{mod_spacegroup.rst => mod-spacegroup.rst} (100%) diff --git a/CODE_OF_CONDUCT.rst b/CODE-OF-CONDUCT.rst similarity index 100% rename from CODE_OF_CONDUCT.rst rename to CODE-OF-CONDUCT.rst diff --git a/LICENSE_DANSE.rst b/LICENSE-DANSE.rst similarity index 100% rename from LICENSE_DANSE.rst rename to LICENSE-DANSE.rst diff --git a/LICENSE_pymmlib.rst b/LICENSE-pymmlib.rst similarity index 100% rename from LICENSE_pymmlib.rst rename to LICENSE-pymmlib.rst diff --git a/doc/source/mod_atom.rst b/doc/source/mod-atom.rst similarity index 100% rename from doc/source/mod_atom.rst rename to doc/source/mod-atom.rst diff --git a/doc/source/mod_lattice.rst b/doc/source/mod-lattice.rst similarity index 100% rename from doc/source/mod_lattice.rst rename to doc/source/mod-lattice.rst diff --git a/doc/source/mod_spacegroup.rst b/doc/source/mod-spacegroup.rst similarity index 100% rename from doc/source/mod_spacegroup.rst rename to doc/source/mod-spacegroup.rst From cd7ddd384b6ae863429e4efc4e92e17045166c45 Mon Sep 17 00:00:00 2001 From: Tingwen Zhang Date: Sun, 1 Jun 2025 15:38:23 -0400 Subject: [PATCH 113/226] chored: updated the link in README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 9ac19161..cf7020c2 100644 --- a/README.rst +++ b/README.rst @@ -132,7 +132,7 @@ trying to commit again. Improvements and fixes are always appreciated. -Before contribuing, please read our `Code of Conduct `_. +Before contribuing, please read our `Code of Conduct `_. Acknowledgement --------------- From 2351e86f0d4057f39a0f25f3a5baedfe2754638e Mon Sep 17 00:00:00 2001 From: Kai Wagoner-Oshima Date: Sat, 7 Jun 2025 01:31:35 -0400 Subject: [PATCH 114/226] skpkg: apply black to all files in the project directory --- src/diffpy/structure/apps/__init__.py | 3 +-- src/diffpy/structure/expansion/supercell_mod.py | 3 +-- src/diffpy/structure/mmlibspacegroups.py | 3 +-- src/diffpy/structure/parsers/p_discus.py | 3 +-- src/diffpy/structure/parsers/p_pdffit.py | 3 +-- src/diffpy/structure/parsers/p_xyz.py | 6 +++--- src/diffpy/structure/parsers/structureparser.py | 3 +-- src/diffpy/structure/pdffitstructure.py | 3 +-- src/diffpy/structure/spacegroupmod.py | 3 +-- src/diffpy/structure/structure.py | 3 +-- src/diffpy/structure/structureerrors.py | 3 +-- src/diffpy/structure/utils.py | 3 +-- tests/test_lattice.py | 3 +-- tests/test_loadstructure.py | 3 +-- tests/test_p_cif.py | 3 +-- tests/test_p_discus.py | 3 +-- tests/test_p_pdffit.py | 3 +-- tests/test_parsers.py | 3 +-- tests/test_spacegroups.py | 3 +-- tests/test_structure.py | 3 +-- tests/test_supercell.py | 3 +-- tests/test_symmetryutilities.py | 3 +-- tests/test_version.py | 3 +-- 23 files changed, 25 insertions(+), 47 deletions(-) diff --git a/src/diffpy/structure/apps/__init__.py b/src/diffpy/structure/apps/__init__.py index 6f0249a8..15ad4702 100644 --- a/src/diffpy/structure/apps/__init__.py +++ b/src/diffpy/structure/apps/__init__.py @@ -13,5 +13,4 @@ # ############################################################################## -"""Script applications that use the `diffpy.structure` package. -""" +"""Script applications that use the `diffpy.structure` package.""" diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index b5760a3b..dee99d95 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -13,8 +13,7 @@ # ############################################################################## -"""This module contains functions for simple `Structure` manipulation. -""" +"""This module contains functions for simple `Structure` manipulation.""" import numpy diff --git a/src/diffpy/structure/mmlibspacegroups.py b/src/diffpy/structure/mmlibspacegroups.py index faa5ce2d..1acd2662 100644 --- a/src/diffpy/structure/mmlibspacegroups.py +++ b/src/diffpy/structure/mmlibspacegroups.py @@ -3,8 +3,7 @@ # This code is part of the PyMMLib distribution and governed by # its license.Please see the LICENSE_pymmlib file that should have been # included as part of this package. -"""Space groups defined as a part of the pymmlib. -""" +"""Space groups defined as a part of the pymmlib.""" from diffpy.structure.spacegroupmod import ( Rot_mX_mXY_mZ, diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 3ee7e5fd..c7185cd8 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Parser for DISCUS structure format -""" +"""Parser for DISCUS structure format""" import sys from functools import reduce diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 692c417f..7fb7a56e 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Parser for PDFfit structure format -""" +"""Parser for PDFfit structure format""" import sys from functools import reduce diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index cd540a90..9d19e0c6 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -15,9 +15,9 @@ """Parser for XYZ file format, where - * First line gives number of atoms. - * Second line has optional title. - * Remaining lines contain element, `x, y, z`. +* First line gives number of atoms. +* Second line has optional title. +* Remaining lines contain element, `x, y, z`. """ import sys diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index 2b748664..7a3ee3a3 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Definition of StructureParser, a base class for specific parsers. -""" +"""Definition of StructureParser, a base class for specific parsers.""" class StructureParser(object): diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index cc3b66d1..414b10b9 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Definition of PDFFitStructure class derived from Structure -""" +"""Definition of PDFFitStructure class derived from Structure""" from diffpy.structure.structure import Structure diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index c31b7cae..42fab5cf 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -3,8 +3,7 @@ # This code is part of the PyMMLib distribution and governed by # its license. Please see the LICENSE_pymmlib file that should have been # included as part of this package. -"""Symmetry operations as functions on vectors or arrays. -""" +"""Symmetry operations as functions on vectors or arrays.""" import numpy diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index f0cb515c..aee9ed75 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -13,8 +13,7 @@ # ############################################################################## -"""This module defines class `Structure`. -""" +"""This module defines class `Structure`.""" import codecs import copy as copymod diff --git a/src/diffpy/structure/structureerrors.py b/src/diffpy/structure/structureerrors.py index c930b9b7..89679369 100644 --- a/src/diffpy/structure/structureerrors.py +++ b/src/diffpy/structure/structureerrors.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Exceptions used in Structure package. -""" +"""Exceptions used in Structure package.""" class StructureFormatError(Exception): diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index e5fa3ce3..4fcee682 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Small shared functions. -""" +"""Small shared functions.""" from collections.abc import Iterable as _Iterable diff --git a/tests/test_lattice.py b/tests/test_lattice.py index a2b22d38..c562d202 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for Lattice class. -""" +"""Unit tests for Lattice class.""" import unittest diff --git a/tests/test_loadstructure.py b/tests/test_loadstructure.py index 4f099c7d..ad197420 100644 --- a/tests/test_loadstructure.py +++ b/tests/test_loadstructure.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -"""Unit tests for the loadStructure factory. -""" +"""Unit tests for the loadStructure factory.""" import unittest diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index 62bb25db..d21b2597 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for diffpy.structure.parsers.p_cif module -""" +"""Unit tests for diffpy.structure.parsers.p_cif module""" import unittest diff --git a/tests/test_p_discus.py b/tests/test_p_discus.py index 8959718e..83f4494e 100644 --- a/tests/test_p_discus.py +++ b/tests/test_p_discus.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for diffpy.structure.parsers.p_discus module -""" +"""Unit tests for diffpy.structure.parsers.p_discus module""" import re import unittest diff --git a/tests/test_p_pdffit.py b/tests/test_p_pdffit.py index f993cb4b..b33b6549 100644 --- a/tests/test_p_pdffit.py +++ b/tests/test_p_pdffit.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for diffpy.structure.parsers.p_pdffit module -""" +"""Unit tests for diffpy.structure.parsers.p_pdffit module""" import re import unittest diff --git a/tests/test_parsers.py b/tests/test_parsers.py index a3f7f3c1..55c5244d 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for structure.parsers module. -""" +"""Unit tests for structure.parsers module.""" import os import re diff --git a/tests/test_spacegroups.py b/tests/test_spacegroups.py index c9980e17..996a73d4 100644 --- a/tests/test_spacegroups.py +++ b/tests/test_spacegroups.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for diffpy.structure.spacegroups -""" +"""Unit tests for diffpy.structure.spacegroups""" import unittest diff --git a/tests/test_structure.py b/tests/test_structure.py index 9c1a6308..d79f5ed3 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for Structure class. -""" +"""Unit tests for Structure class.""" import copy diff --git a/tests/test_supercell.py b/tests/test_supercell.py index 0e840dfa..68aa8092 100644 --- a/tests/test_supercell.py +++ b/tests/test_supercell.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for supercell.py -""" +"""Unit tests for supercell.py""" import unittest diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index c4de983b..377f7554 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Unit tests for SymmetryUtilities.py -""" +"""Unit tests for SymmetryUtilities.py""" import re import sys diff --git a/tests/test_version.py b/tests/test_version.py index e62433e1..de45655e 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -1,5 +1,4 @@ -"""Unit tests for __version__.py -""" +"""Unit tests for __version__.py""" import diffpy.structure From 5788f4f55392db1756d3ada7849c321761562625 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 12:54:07 -0400 Subject: [PATCH 115/226] skpkg: linter config files; pyproject.toml --- .flake8 | 2 ++ .isort.cfg | 1 + pyproject.toml | 22 ++++++++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.flake8 b/.flake8 index 2d2cb168..04d2d0b0 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,5 @@ +# As of now, flake8 does not natively support configuration via pyproject.toml +# https://github.com/microsoft/vscode-flake8/issues/135 [flake8] exclude = .git, diff --git a/.isort.cfg b/.isort.cfg index e0926f42..7ce0fb1f 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,4 +1,5 @@ [settings] +# Keep import statement below line_length character limit line_length = 115 multi_line_output = 3 include_trailing_comma = True diff --git a/pyproject.toml b/pyproject.toml index dd1150c9..46176534 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,13 +6,13 @@ build-backend = "setuptools.build_meta" name = "diffpy.structure" dynamic=['version', 'dependencies'] authors = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] maintainers = [ - { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, + { name="Simon Billinge", email="sb2896@columbia.edu" }, ] description = "Crystal structure container and parsers for structure formats." -keywords = ['diffpy', 'crystal structure data storage CIF PDB'] +keywords = ['diffpy', 'crystal structure data storage', 'CIF', 'PDB'] readme = "README.rst" requires-python = ">=3.11, <3.14" classifiers = [ @@ -32,13 +32,13 @@ classifiers = [ 'Topic :: Scientific/Engineering :: Chemistry', ] +[project.scripts] +transtru = "diffpy.structure.apps.transtru:main" + [project.urls] Homepage = "https://github.com/diffpy/diffpy.structure/" Issues = "https://github.com/diffpy/diffpy.structure/issues/" -[project.scripts] -transtru = "diffpy.structure.apps.transtru:main" - [tool.setuptools-git-versioning] enabled = true template = "{tag}" @@ -54,6 +54,16 @@ namespaces = false # to disable scanning PEP 420 namespaces (true by default) [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} +[tool.codespell] +exclude-file = ".codespell/ignore_lines.txt" +ignore-words = ".codespell/ignore_words.txt" +skip = "*.cif,*.dat" + +[tool.docformatter] +recursive = true +wrap-summaries = 72 +wrap-descriptions = 72 + [tool.black] line-length = 115 include = '\.pyi?$' From 8f15f932838b81e7ba17b41d8fa071140589f37a Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 13:00:13 -0400 Subject: [PATCH 116/226] skpkg: init and version files --- src/diffpy/__init__.py | 11 +---------- src/diffpy/structure/version.py | 7 +++---- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index ee55ab5f..7ecfc294 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,7 +1,7 @@ #!/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. @@ -12,12 +12,3 @@ # See LICENSE.rst for license information. # ############################################################################## - -"""Blank namespace package for module diffpy.""" - - -from pkgutil import extend_path - -__path__ = extend_path(__path__, __name__) - -# End of file diff --git a/src/diffpy/structure/version.py b/src/diffpy/structure/version.py index be7f6a2d..605c9101 100644 --- a/src/diffpy/structure/version.py +++ b/src/diffpy/structure/version.py @@ -1,18 +1,17 @@ #!/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. +# File coded by: Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. -# https://github.com/diffpy/diffpy.structure/graphs/contributors +# https://github.com/diffpy/diffpy.structure/graphs/contributors # noqa: E501 # # See LICENSE.rst for license information. # ############################################################################## - """Definition of __version__.""" # We do not use the other three variables, but can be added back if needed. From 19d7d4c9d43701986f7dd77abde2848723a7cc03 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 13:06:16 -0400 Subject: [PATCH 117/226] skpkg: structure/__init__.py --- src/diffpy/structure/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index f8106490..e736f8bf 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -1,10 +1,10 @@ #!/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. +# File coded by: Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.structure/graphs/contributors From fb7d421705685b2872ceae494a0423bb759107c7 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 13:10:31 -0400 Subject: [PATCH 118/226] skpkg: tests/test_version.py --- tests/test_version.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_version.py b/tests/test_version.py index de45655e..5d55a864 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -1,9 +1,10 @@ -"""Unit tests for __version__.py""" +"""Unit tests for __version__.py.""" -import diffpy.structure +import diffpy.structure # noqa def test_package_version(): - """Ensure the package version is defined and not set to the initial placeholder.""" + """Ensure the package version is defined and not set to the initial + placeholder.""" assert hasattr(diffpy.structure, "__version__") assert diffpy.structure.__version__ != "0.0.0" From 1acf3f484d7988834c6db4fa21e3b8eef4b99bac Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 13:16:04 -0400 Subject: [PATCH 119/226] skpkg: docformatter --- src/diffpy/structure/__init__.py | 4 +- src/diffpy/structure/_legacy_importer.py | 6 +- src/diffpy/structure/apps/__init__.py | 1 - src/diffpy/structure/apps/anyeye.py | 9 +-- src/diffpy/structure/apps/transtru.py | 4 +- src/diffpy/structure/atom.py | 18 +++-- src/diffpy/structure/expansion/__init__.py | 1 - .../structure/expansion/makeellipsoid.py | 4 +- src/diffpy/structure/expansion/shapeutils.py | 1 - .../structure/expansion/supercell_mod.py | 7 +- src/diffpy/structure/lattice.py | 7 +- src/diffpy/structure/parsers/__init__.py | 1 - src/diffpy/structure/parsers/p_auto.py | 14 ++-- src/diffpy/structure/parsers/p_cif.py | 20 +++-- src/diffpy/structure/parsers/p_discus.py | 7 +- src/diffpy/structure/parsers/p_pdb.py | 6 +- src/diffpy/structure/parsers/p_pdffit.py | 3 +- src/diffpy/structure/parsers/p_rawxyz.py | 5 +- src/diffpy/structure/parsers/p_xcfg.py | 7 +- src/diffpy/structure/parsers/p_xyz.py | 3 +- .../structure/parsers/parser_index_mod.py | 1 - .../structure/parsers/structureparser.py | 1 - src/diffpy/structure/pdffitstructure.py | 3 +- src/diffpy/structure/sgtbxspacegroups.py | 6 +- src/diffpy/structure/spacegroupmod.py | 6 +- src/diffpy/structure/spacegroups.py | 8 +- src/diffpy/structure/structure.py | 38 +++++---- src/diffpy/structure/structureerrors.py | 1 - src/diffpy/structure/symmetryutilities.py | 50 +++++++----- src/diffpy/structure/utils.py | 4 +- tests/test_atom.py | 9 +-- tests/test_lattice.py | 23 +++--- tests/test_loadstructure.py | 14 ++-- tests/test_p_cif.py | 18 ++--- tests/test_p_discus.py | 15 ++-- tests/test_p_pdffit.py | 23 +++--- tests/test_parsers.py | 35 ++++---- tests/test_spacegroups.py | 3 +- tests/test_structure.py | 80 +++++++++---------- tests/test_supercell.py | 9 +-- tests/test_symmetryutilities.py | 38 ++++----- 41 files changed, 258 insertions(+), 255 deletions(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index e736f8bf..e66c0879 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -12,9 +12,7 @@ # See LICENSE.rst for license information. # ############################################################################## - -""" -Crystal structure container and parsers for structure formats. +"""Crystal structure container and parsers for structure formats. Classes related to the structure of materials: * Atom diff --git a/src/diffpy/structure/_legacy_importer.py b/src/diffpy/structure/_legacy_importer.py index e37a907f..56123c60 100644 --- a/src/diffpy/structure/_legacy_importer.py +++ b/src/diffpy/structure/_legacy_importer.py @@ -12,9 +12,8 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Support import of old camel-case module names with DeprecationWarning. +"""Support import of old camel-case module names with +DeprecationWarning. The imported camel-case modules are aliases for the current module instances. Their `__name__` attributes are thus all in lower-case. @@ -61,6 +60,7 @@ def find_spec(self, fullname, path=None, target=None): class MapRenamedStructureModule(importlib.abc.Loader): """Loader for old camel-case module names. + Import the current module and alias it under the old name. """ diff --git a/src/diffpy/structure/apps/__init__.py b/src/diffpy/structure/apps/__init__.py index 15ad4702..98aa2feb 100644 --- a/src/diffpy/structure/apps/__init__.py +++ b/src/diffpy/structure/apps/__init__.py @@ -12,5 +12,4 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Script applications that use the `diffpy.structure` package.""" diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index b7904d8e..39122fee 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -Anyeye view structure file in atomeye. +"""Anyeye view structure file in atomeye. Usage: ``anyeye [options] strufile`` @@ -65,7 +63,8 @@ def usage(style=None): - """Show usage info, for ``style=="brief"`` show only first 2 lines.""" + """Show usage info, for ``style=="brief"`` show only first 2 + lines.""" import os.path myname = os.path.basename(sys.argv[0]) @@ -175,7 +174,7 @@ def cleanUp(pd): def parseFormula(formula): - """Parse chemical formula and return a list of elements""" + """Parse chemical formula and return a list of elements.""" # remove all blanks formula = re.sub(r"\s", "", formula) if not re.match("^[A-Z]", formula): diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 86c682db..4c8af03a 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Translate structure file to different format. Usage: ``transtru INFMT..OUTFMT strufile`` @@ -44,7 +43,8 @@ def usage(style=None): - """Show usage info, for ``style=="brief"`` show only first 2 lines.""" + """Show usage info, for ``style=="brief"`` show only first 2 + lines.""" import os.path myname = os.path.basename(sys.argv[0]) diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index e531780b..beac9e7b 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -12,10 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -""" -Provide class Atom for managing properties of an atom in structure model. -""" +"""Provide class Atom for managing properties of an atom in structure +model.""" import numpy @@ -176,7 +174,8 @@ def msdLat(self, vl): return msd def msdCart(self, vc): - """Calculate mean square displacement along the Cartesian vector. + """Calculate mean square displacement along the Cartesian + vector. Parameters ---------- @@ -252,7 +251,8 @@ def __copy__(self, target=None): @property def xyz_cartn(self): - """numpy.ndarray: Atom position in absolute Cartesian coordinates. + """numpy.ndarray: Atom position in absolute Cartesian + coordinates. This is computed from fractional coordinates `xyz` and the current `lattice` setup. Assignment to *xyz_cartn* or @@ -301,7 +301,8 @@ def anisotropy(self, value): @property def U(self): - """numpy.ndarray : The 3x3 matrix of anisotropic atomic displacements. + """numpy.ndarray : The 3x3 matrix of anisotropic atomic + displacements. For isotropic displacements (when `anisotropy` is ``False``) assignment to *U* uses only the first ``Unew[0, 0]`` element @@ -537,7 +538,8 @@ def __setitem__(self, idx, value): return def __array_wrap__(self, out_arr, context=None, return_scalar=None): - """Ensure math operations on this type yield standard numpy array.""" + """Ensure math operations on this type yield standard numpy + array.""" return out_arr.view(numpy.ndarray) diff --git a/src/diffpy/structure/expansion/__init__.py b/src/diffpy/structure/expansion/__init__.py index faa60ca3..8e6d02c1 100644 --- a/src/diffpy/structure/expansion/__init__.py +++ b/src/diffpy/structure/expansion/__init__.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Methods and classes for manipulating `Structure` instances. Package content: diff --git a/src/diffpy/structure/expansion/makeellipsoid.py b/src/diffpy/structure/expansion/makeellipsoid.py index 009be577..547096c2 100644 --- a/src/diffpy/structure/expansion/makeellipsoid.py +++ b/src/diffpy/structure/expansion/makeellipsoid.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Make a spheroid nanoparticle from a template structure.""" from math import ceil @@ -42,8 +41,7 @@ def makeSphere(S, radius): def makeEllipsoid(S, a, b=None, c=None): - """ - Cut a `Structure` out of another one. + """Cut a `Structure` out of another one. Parameters ---------- diff --git a/src/diffpy/structure/expansion/shapeutils.py b/src/diffpy/structure/expansion/shapeutils.py index 0e99df05..12ba80d6 100644 --- a/src/diffpy/structure/expansion/shapeutils.py +++ b/src/diffpy/structure/expansion/shapeutils.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Utilities for making shapes.""" diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index dee99d95..44d55408 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -12,8 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""This module contains functions for simple `Structure` manipulation.""" +"""This module contains functions for simple `Structure` +manipulation.""" import numpy @@ -21,8 +21,7 @@ def supercell(S, mno): - """ - Perform supercell expansion for a `Structure`. + """Perform supercell expansion for a `Structure`. New `lattice` parameters are multiplied and fractional coordinates divided by corresponding multiplier. New `Atoms` are grouped with diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index fb51de04..5a623208 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -12,9 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Class Lattice stores properties and provides simple operations in lattice -coordinate system. +"""Class Lattice stores properties and provides simple operations in +lattice coordinate system. Attributes ---------- @@ -442,6 +441,7 @@ def setLatBase(self, base): def abcABG(self): """Return the cell parameters in the standard setting. + Returns ------- tuple : @@ -452,6 +452,7 @@ def abcABG(self): def reciprocal(self): """Return the reciprocal lattice of the current lattice. + Returns ------- Lattice diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 0d549b80..cb9bd4f8 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Conversion plugins for various structure formats. The recognized structure formats are defined by subclassing `StructureParser`, diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 745eb5a9..ab688987 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Parser for automatic file format detection. This Parser does not provide the the `toLines()` method. @@ -54,6 +53,7 @@ def __init__(self, **kw): # parseLines helpers def _getOrderedFormats(self): """Build a list of relevance ordered structure formats. + This only works when `self.filename` has a known extension. """ from diffpy.structure.parsers import inputFormats @@ -77,7 +77,8 @@ def _getOrderedFormats(self): return ofmts def parseLines(self, lines): - """Detect format and create `Structure` instance from a list of lines. + """Detect format and create `Structure` instance from a list of + lines. Set format attribute to the detected file format. @@ -119,7 +120,8 @@ def parse(self, s): return self._wrapParseMethod("parse", s) def parseFile(self, filename): - """Detect format and create Structure instance from an existing file. + """Detect format and create Structure instance from an existing + file. Set format attribute to the detected file format. @@ -144,9 +146,9 @@ def parseFile(self, filename): return self._wrapParseMethod("parseFile", filename) def _wrapParseMethod(self, method, *args, **kwargs): - """A helper evaluator method that try the specified parse method with - each registered structure parser and return the first successful - resul. + """A helper evaluator method that try the specified parse method + with each registered structure parser and return the first + successful resul. Structure parsers that match structure file extension are tried first. diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 6fba3b44..cb2f3fa1 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Parser for basic CIF file format. Attributes @@ -267,7 +266,8 @@ def _tr_atom_site_aniso_B_23(a, value): _tr_atom_site_aniso_B_23 = staticmethod(_tr_atom_site_aniso_B_23) def _get_atom_setters(cifloop): - """Static method for finding translators of CifLoop items to data in `Atom` instance. + """Static method for finding translators of CifLoop items to + data in `Atom` instance. Parameters ---------- @@ -416,8 +416,8 @@ def _parseCifDataSource(self, datasource): return self.stru def _parseCifBlock(self, blockname): - """Translate CIF file block, skip blocks without `_atom_site_label`. - Updates data members `stru`, `eau`. + """Translate CIF file block, skip blocks without + `_atom_site_label`. Updates data members `stru`, `eau`. Parameters ---------- @@ -505,7 +505,8 @@ def _parse_atom_site_label(self, block): return def _parse_atom_site_aniso_label(self, block): - """Obtain value of anisotropic thermal displacements from a `CifBlock`. + """Obtain value of anisotropic thermal displacements from a + `CifBlock`. This method updates `U` members of `Atom` instances in `self.stru`. The `labelindex` dictionary has to be defined beforehand. @@ -599,7 +600,8 @@ def _parse_space_group_symop_operation_xyz(self, block): return def _expandAsymmetricUnit(self, block): - """Perform symmetry expansion of `self.stru` using `self.spacegroup`. + """Perform symmetry expansion of `self.stru` using + `self.spacegroup`. This method updates data in `stru` and `eau`. @@ -763,7 +765,8 @@ def toLines(self, stru): def leading_float(s, d=0.0): - """Extract the first float from a string and ignore trailing characters. + """Extract the first float from a string and ignore trailing + characters. Useful for extracting values from "value(std)" syntax. @@ -863,7 +866,8 @@ def getParser(eps=None): @contextmanager def _suppressCifParserOutput(): - """Context manager which suppresses diagnostic messages from CIF parser.""" + """Context manager which suppresses diagnostic messages from CIF + parser.""" from CifFile import yapps3_compiled_rt print_error = yapps3_compiled_rt.print_error diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index c7185cd8..8c59af54 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Parser for DISCUS structure format""" +"""Parser for DISCUS structure format.""" import sys from functools import reduce @@ -24,8 +23,8 @@ class P_discus(StructureParser): - """Parser for DISCUS structure format. The parser chokes - on molecule and generator records. + """Parser for DISCUS structure format. The parser chokes on molecule + and generator records. Attributes ---------- diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 6d0f95aa..a7d2d936 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Basic parser for PDB structure format. Note @@ -281,9 +280,8 @@ def cryst1Lines(self, stru): return lines def atomLines(self, stru, idx): - """Build `ATOM` records and possibly `SIGATM`, `ANISOU` or `SIGUIJ` records - for `structure` stru `atom` number aidx. - """ + """Build `ATOM` records and possibly `SIGATM`, `ANISOU` or + `SIGUIJ` records for `structure` stru `atom` number aidx.""" lines = [] a = stru[idx] ad = a.__dict__ diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 7fb7a56e..f0c50bd4 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Parser for PDFfit structure format""" +"""Parser for PDFfit structure format.""" import sys from functools import reduce diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index 65e9588e..24ad293b 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -12,11 +12,10 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Parser for raw XYZ file format. -Raw XYZ is a 3 or 4 column text file with cartesian coordinates -of atoms and an optional first column for atom types. +Raw XYZ is a 3 or 4 column text file with cartesian coordinates of atoms +and an optional first column for atom types. """ import sys diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 372e7ba8..3a29dee3 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Parser for extended CFG format used by atomeye. Attributes @@ -287,7 +286,8 @@ def parseLines(self, lines): return stru def toLines(self, stru): - """Convert Structure stru to a list of lines in XCFG atomeye format. + """Convert Structure stru to a list of lines in XCFG atomeye + format. Parameters ---------- @@ -424,7 +424,8 @@ def getParser(): def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): - """Assing auxiliary properties for `Atom` object when reading CFG format. + """Assing auxiliary properties for `Atom` object when reading CFG + format. Parameters ---------- diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index 9d19e0c6..5c08f99b 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Parser for XYZ file format, where +"""Parser for XYZ file format, where. * First line gives number of atoms. * Second line has optional title. diff --git a/src/diffpy/structure/parsers/parser_index_mod.py b/src/diffpy/structure/parsers/parser_index_mod.py index 5bb6ba98..5f8c3ec7 100644 --- a/src/diffpy/structure/parsers/parser_index_mod.py +++ b/src/diffpy/structure/parsers/parser_index_mod.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Index of recognized structure formats, their IO capabilities and associated modules where they are defined. diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index 7a3ee3a3..f785b52e 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Definition of StructureParser, a base class for specific parsers.""" diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index 414b10b9..73115db6 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Definition of PDFFitStructure class derived from Structure""" +"""Definition of PDFFitStructure class derived from Structure.""" from diffpy.structure.structure import Structure diff --git a/src/diffpy/structure/sgtbxspacegroups.py b/src/diffpy/structure/sgtbxspacegroups.py index 0ba28fc2..30aacfcf 100644 --- a/src/diffpy/structure/sgtbxspacegroups.py +++ b/src/diffpy/structure/sgtbxspacegroups.py @@ -12,9 +12,9 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Extra space group representations generated using `sgtbx` module from `cctbx`. -Import of this module extends the `SpaceGroupList` in the `SpaceGroups` module. +"""Extra space group representations generated using `sgtbx` module from +`cctbx`. Import of this module extends the `SpaceGroupList` in the +`SpaceGroups` module. Attributes ---------- diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 42fab5cf..9c35eae7 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -143,7 +143,8 @@ def __str__(self): return x def __call__(self, vec): - """Return symmetry-related position for the specified coordinates. + """Return symmetry-related position for the specified + coordinates. Parameters ---------- @@ -301,7 +302,8 @@ def check_group_name(self, name): return False def iter_equivalent_positions(self, vec): - """Generate symmetry equivalent positions for the specified position. + """Generate symmetry equivalent positions for the specified + position. The initial position must be in fractional coordinates and so are the symmetry equivalent positions yielded by iteration. diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index 414d56e5..a5d33372 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Space group classes and definitions from mmLib and sgtbx. Attributes @@ -693,7 +692,8 @@ def GetSpaceGroup(sgid): def IsSpaceGroupIdentifier(sgid): - """Check if identifier can be used as an argument to `GetSpaceGroup`. + """Check if identifier can be used as an argument to + `GetSpaceGroup`. Returns ------- @@ -768,6 +768,7 @@ def _hashSymOpList(symops): def _buildSGLookupTable(): """Rebuild space group lookup table from the `SpaceGroupList` data. + This routine updates the global `_sg_lookup_table` dictionary. """ _sg_lookup_table.clear() @@ -809,7 +810,8 @@ def _buildSGLookupTable(): def _getSGHashLookupTable(): - """Return lookup table of symop hashes to standard `SpaceGroup` objects.""" + """Return lookup table of symop hashes to standard `SpaceGroup` + objects.""" if _sg_hash_lookup_table: return _sg_hash_lookup_table for sg in SpaceGroupList: diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index aee9ed75..5038bce2 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """This module defines class `Structure`.""" import codecs @@ -28,7 +27,8 @@ class Structure(list): - """Define group of atoms in a specified lattice. Structure --> group of atoms. + """Define group of atoms in a specified lattice. Structure --> group + of atoms. `Structure` class is inherited from Python `list`. It contains a list of `Atom` instances. `Structure` overloads `setitem` and `setslice` @@ -183,7 +183,8 @@ def assignUniqueLabels(self): return def distance(self, aid0, aid1): - """Calculate distance between 2 `Atoms`, no periodic boundary conditions. + """Calculate distance between 2 `Atoms`, no periodic boundary + conditions. Parameters ---------- @@ -207,8 +208,7 @@ def distance(self, aid0, aid1): return self.lattice.dist(a0.xyz, a1.xyz) def angle(self, aid0, aid1, aid2): - """ - The bond angle at the second of three `Atoms` in degrees. + """The bond angle at the second of three `Atoms` in degrees. Parameters ---------- @@ -235,7 +235,7 @@ def angle(self, aid0, aid1, aid2): return self.lattice.angle(u10, u12) def placeInLattice(self, new_lattice): - """place structure into `new_lattice` coordinate system. + """Place structure into `new_lattice` coordinate system. Sets `lattice` to `new_lattice` and recalculate fractional coordinates of all `Atoms` so their absolute positions remain the same. @@ -352,7 +352,8 @@ def write(self, filename, format): return def writeStr(self, format): - """return string representation of the structure in specified format. + """Return string representation of the structure in specified + format. Note ---- @@ -367,14 +368,16 @@ def writeStr(self, format): return s def tolist(self): - """Return `Atoms` in this `Structure` as a standard Python list.""" + """Return `Atoms` in this `Structure` as a standard Python + list.""" rv = [a for a in self] return rv # Overloaded list Methods and Operators ---------------------------------- def append(self, a, copy=True): - """Append `Atom` to a structure and update its `lattice` attribute. + """Append `Atom` to a structure and update its `lattice` + attribute. Parameters ---------- @@ -571,7 +574,8 @@ def _fixlat(a): return def __add__(self, other): - """Return new `Structure` object with appended `Atoms` from other. + """Return new `Structure` object with appended `Atoms` from + other. Parameters ---------- @@ -604,7 +608,8 @@ def __iadd__(self, other): return self def __sub__(self, other): - """Return new `Structure` that has `Atoms` from the other removed. + """Return new `Structure` that has `Atoms` from the other + removed. Parameters ---------- @@ -639,8 +644,8 @@ def __isub__(self, other): return self def __mul__(self, n): - """Return new `Structure` with n-times concatenated `Atoms` from self. - `Atoms` and `lattice` in the new structure are all copies. + """Return new `Structure` with n-times concatenated `Atoms` from + self. `Atoms` and `lattice` in the new structure are all copies. Parameters ---------- @@ -660,8 +665,8 @@ def __mul__(self, n): __rmul__ = __mul__ def __imul__(self, n): - """Concatenate this `Structure` to n-times more `Atoms`. - For positive multiple the current `Atom` objects remain at the + """Concatenate this `Structure` to n-times more `Atoms`. For + positive multiple the current `Atom` objects remain at the beginning of this `Structure`. Parameters @@ -858,7 +863,8 @@ def _get_composition(self): # Private Methods -------------------------------------------------------- def __emptySharedStructure(self): - """Return empty `Structure` with standard attributes same as in self.""" + """Return empty `Structure` with standard attributes same as in + self.""" rv = Structure() rv.__dict__.update([(k, getattr(self, k)) for k in rv.__dict__]) return rv diff --git a/src/diffpy/structure/structureerrors.py b/src/diffpy/structure/structureerrors.py index 89679369..f9a2aaec 100644 --- a/src/diffpy/structure/structureerrors.py +++ b/src/diffpy/structure/structureerrors.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Exceptions used in Structure package.""" diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index b58e7c88..ea7a40d0 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -12,9 +12,8 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Symmetry utility functions such as expansion of asymmetric unit, -and generation of positional constraints. +"""Symmetry utility functions such as expansion of asymmetric unit, and +generation of positional constraints. Attributes ---------- @@ -132,8 +131,8 @@ def isconstantFormula(s): class _Position2Tuple(object): - """Create callable object that converts fractional coordinates to - a tuple of integers with given precision. For presision close to zero + """Create callable object that converts fractional coordinates to a + tuple of integers with given precision. For presision close to zero it will return a tuples of double. Note @@ -417,7 +416,8 @@ class GeneratorSite(object): ], dtype=float, ) - """numpy.ndarray: 6x3x3 array of independent components of U matrices.""" + """numpy.ndarray: 6x3x3 array of independent components of U + matrices.""" idx2Usymbol = {0: "U11", 1: "U12", 2: "U13", 3: "U12", 4: "U22", 5: "U23", 6: "U13", 7: "U23", 8: "U33"} """dict: Mapping of index to standard U symbol.""" @@ -467,7 +467,8 @@ def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3, 3)), sgoffset=[0, 0, 0], return def signedRatStr(self, x): - """Convert floating point number to signed rational representation. + """Convert floating point number to signed rational + representation. Possible fractional are multiples of 1/3, 1/6, 1/7, 1/9, if these are not close, return `%+g` format. @@ -495,6 +496,7 @@ def signedRatStr(self, x): def _findNullSpace(self): """Calculate `self.null_space` from `self.invariants`. + Try to represent `self.null_space` using small integers. """ R0 = self.invariants[0].R @@ -525,7 +527,8 @@ def _findNullSpace(self): return def _findPosParameters(self): - """Find pparameters and their values for expressing `self.xyz`.""" + """Find pparameters and their values for expressing + `self.xyz`.""" usedsymbol = {} # parameter values depend on offset of self.xyz txyz = self.xyz @@ -542,8 +545,7 @@ def _findPosParameters(self): def _findUSpace(self): """Find independent U components with respect to invariant - rotations. - """ + rotations.""" n = len(self.invariants) R6zall = numpy.tile(-numpy.identity(6, dtype=float), (n, 1)) R6zall_iter = numpy.split(R6zall, n, axis=0) @@ -568,7 +570,8 @@ def _findUSpace(self): return def _findUParameters(self): - """Find Uparameters and their values for expressing `self.Uij`.""" + """Find Uparameters and their values for expressing + `self.Uij`.""" # permute indices as 00 11 22 01 02 12 10 20 21 diagorder = numpy.array((0, 4, 8, 1, 2, 5, 3, 6, 7)) Uijflat = self.Uij.flatten() @@ -583,7 +586,8 @@ def _findUParameters(self): return def _findeqUij(self): - """Adjust `self.Uij` and `self.eqUij` to be consistent with spacegroup.""" + """Adjust `self.Uij` and `self.eqUij` to be consistent with + spacegroup.""" self.Uij = numpy.zeros((3, 3), dtype=float) for i in range(len(self.Uparameters)): Usp = self.Uspace[i] @@ -598,7 +602,8 @@ def _findeqUij(self): return def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): - """Formula of equivalent position with respect to generator site. + """Formula of equivalent position with respect to generator + site. Parameters ---------- @@ -646,7 +651,8 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): return dict(zip(("x", "y", "z"), xyzformula)) def UFormula(self, pos, Usymbols=stdUsymbols): - """List of atom displacement formulas with custom parameter symbols. + """List of atom displacement formulas with custom parameter + symbols. Parameters ---------- @@ -902,7 +908,8 @@ def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=Non return def _findConstraints(self): - """Find constraints for positions and anisotropic displacements `Uij`.""" + """Find constraints for positions and anisotropic displacements + `Uij`.""" numpos = len(self.positions) # canonical xyzsymbols and Usymbols xyzsymbols = [smbl + str(i) for i in range(numpos) for smbl in "xyz"] @@ -994,7 +1001,8 @@ def translatesymbol(matchobj): return rv def positionFormulasPruned(self, xyzsymbols=None): - """List of position formula dictionaries with constant items removed. + """List of position formula dictionaries with constant items + removed. See also -------- @@ -1014,7 +1022,8 @@ def positionFormulasPruned(self, xyzsymbols=None): return rv def UparSymbols(self): - """Return list of standard atom displacement parameter symbols.""" + """Return list of standard atom displacement parameter + symbols.""" return [n for n, v in self.Upars] def UparValues(self): @@ -1022,7 +1031,8 @@ def UparValues(self): return [v for n, v in self.Upars] def UFormulas(self, Usymbols=None): - """List of atom displacement formulas with custom parameter symbols. + """List of atom displacement formulas with custom parameter + symbols. Parameters ---------- @@ -1059,8 +1069,8 @@ def translatesymbol(matchobj): return rv def UFormulasPruned(self, Usymbols=None): - """List of atom displacement formula dictionaries with constant items - removed. + """List of atom displacement formula dictionaries with constant + items removed. See Also -------- diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index 4fcee682..facab843 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Small shared functions.""" from collections.abc import Iterable as _Iterable @@ -37,7 +36,8 @@ def isfloat(s): def atomBareSymbol(smbl): - """Remove atom type string stripped of isotope and ion charge symbols. + """Remove atom type string stripped of isotope and ion charge + symbols. This function removes any blank, isotope numbers (0-9), leading hyphens (-), and ion charge symbols (1-9)(+-) from the given atom type string, returning only the bare element symbol. diff --git a/tests/test_atom.py b/tests/test_atom.py index 67009e80..6c7dd32d 100644 --- a/tests/test_atom.py +++ b/tests/test_atom.py @@ -12,10 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -""" -Unit tests for the Atom class. -""" +"""Unit tests for the Atom class.""" import unittest @@ -31,7 +28,7 @@ class TestAtom(unittest.TestCase): def test___init__(self): - """check Atom.__init__()""" + """Check Atom.__init__()""" a = Atom() self.assertEqual("", a.element) self.assertTrue((a.xyz == 0).all()) @@ -78,7 +75,7 @@ def test___init__(self): # return def test_xyz_cartn(self): - """check Atom.xyz_cartn property""" + """Check Atom.xyz_cartn property.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) a0 = Atom("C", [0, 0, 0], lattice=hexagonal) a1 = Atom("C", [1, 1, 1], lattice=hexagonal) diff --git a/tests/test_lattice.py b/tests/test_lattice.py index c562d202..e98ec95c 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Unit tests for Lattice class.""" import unittest @@ -26,7 +25,7 @@ class TestLattice(unittest.TestCase): - """test methods of Lattice class""" + """Test methods of Lattice class.""" def setUp(self): self.lattice = Lattice() @@ -52,7 +51,7 @@ def test___init__(self): return def test_setLatPar(self): - """check calculation of standard unit cell vectors""" + """Check calculation of standard unit cell vectors.""" from math import cos, radians, sqrt from numpy import dot @@ -74,7 +73,7 @@ def cosd(x): return def test_latpar_properties(self): - """check assignment to a, b, c, alpha, beta, gamma.""" + """Check assignment to a, b, c, alpha, beta, gamma.""" lat = self.lattice lat.a = 2 lat.b = 4 @@ -135,7 +134,7 @@ def test_readonly_properties(self): return def test_setLatBase(self): - """check calculation of unit cell rotation""" + """Check calculation of unit cell rotation.""" base = numpy.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) self.lattice.setLatBase(base) self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places) @@ -160,7 +159,7 @@ def test_setLatBase(self): return def test_reciprocal(self): - """check calculation of reciprocal lattice.""" + """Check calculation of reciprocal lattice.""" r1 = self.lattice.reciprocal() self.assertEqual((1, 1, 1, 90, 90, 90), r1.abcABG()) L2 = Lattice(2, 4, 8, 90, 90, 90) @@ -171,7 +170,7 @@ def test_reciprocal(self): return def test_dot(self): - """check dot product of lattice vectors.""" + """Check dot product of lattice vectors.""" L = self.lattice L.setLatPar(gamma=120) self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places) @@ -183,7 +182,7 @@ def test_dot(self): return def test_norm(self): - """check norm of a lattice vector.""" + """Check norm of a lattice vector.""" self.assertEqual(1, self.lattice.norm([1, 0, 0])) u = numpy.array([[3, 4, 0], [1, 1, 1]]) self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u))) @@ -192,7 +191,7 @@ def test_norm(self): return def test_rnorm(self): - """check norm of a reciprocal vector.""" + """Check norm of a reciprocal vector.""" L = self.lattice L.setLatPar(1, 1.5, 2.3, 80, 95, 115) r = L.reciprocal() @@ -203,7 +202,7 @@ def test_rnorm(self): return def test_dist(self): - """check dist function for distance between lattice points.""" + """Check dist function for distance between lattice points.""" L = self.lattice L.setLatPar(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] @@ -219,7 +218,7 @@ def test_dist(self): return def test_angle(self): - """check angle calculation between lattice vectors.""" + """Check angle calculation between lattice vectors.""" from math import acos, degrees L = self.lattice @@ -239,7 +238,7 @@ def test_angle(self): return def test_repr(self): - """check string representation of this lattice""" + """Check string representation of this lattice.""" r = repr(self.lattice) self.assertEqual(r, "Lattice()") self.lattice.setLatPar(1, 2, 3, 10, 20, 30) diff --git a/tests/test_loadstructure.py b/tests/test_loadstructure.py index ad197420..8bd1ec21 100644 --- a/tests/test_loadstructure.py +++ b/tests/test_loadstructure.py @@ -17,7 +17,7 @@ def prepare_fixture(self, datafile): self.datafile = datafile def test_xcfg(self): - """check loading of atomeye xcfg format""" + """Check loading of atomeye xcfg format.""" f = self.datafile("BubbleRaftShort.xcfg") stru = loadStructure(f) self.assertTrue(type(stru) is Structure) @@ -25,14 +25,14 @@ def test_xcfg(self): return def test_discus(self): - """check loading of discus file format""" + """Check loading of discus file format.""" f = self.datafile("Ni-discus.stru") stru = loadStructure(f) self.assertTrue(type(stru) is PDFFitStructure) return def test_cif(self): - """check loading of CIF file format""" + """Check loading of CIF file format.""" f = self.datafile("PbTe.cif") stru = loadStructure(f) self.assertTrue(isinstance(stru, Structure)) @@ -40,20 +40,22 @@ def test_cif(self): return def test_badfile(self): - """check loading of CIF file format""" + """Check loading of CIF file format.""" f = self.datafile("Ni-bad.stru") self.assertRaises(StructureFormatError, loadStructure, f) return def test_goodkwarg(self): - """check loading of CIF file and passing of parser keyword argument.""" + """Check loading of CIF file and passing of parser keyword + argument.""" f = self.datafile("graphite.cif") stru = loadStructure(f, eps=1e-10) self.assertEqual(8, len(stru)) return def test_badkwarg(self): - """check loading of xyz file format with invalid keyword argument""" + """Check loading of xyz file format with invalid keyword + argument.""" f = self.datafile("bucky.xyz") self.assertRaises(TypeError, loadStructure, f, eps=1e-10) return diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index d21b2597..5676120b 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Unit tests for diffpy.structure.parsers.p_cif module""" +"""Unit tests for diffpy.structure.parsers.p_cif module.""" import unittest @@ -37,14 +36,14 @@ def tearDown(self): return def test_leading_float(self): - """check leading_float()""" + """Check leading_float()""" self.assertEqual(0.37, leading_float("0.37(3)")) self.assertEqual(0.37, leading_float("0.37ab\ncd")) self.assertRaises(ValueError, leading_float, "q1") return def test_getSymOp(self): - """check getSymOp()""" + """Check getSymOp()""" from diffpy.structure.spacegroups import Rot_X_mY_Z, SymOp, Tr_0_12_12 op = getSymOp("x,1/2-y,1/2+z") @@ -84,7 +83,7 @@ def tearDown(self): return def test_parse(self): - """check P_cif.parse()""" + """Check P_cif.parse()""" with open(self.pbteciffile) as fp1: sgood = fp1.read() with open(self.badciffile) as fp2: @@ -100,7 +99,7 @@ def test_parse(self): return def test_parseLines(self): - """check P_cif.parseLines()""" + """Check P_cif.parseLines()""" with open(self.pbteciffile) as fp1: goodlines = fp1.readlines() with open(self.badciffile) as fp2: @@ -116,7 +115,7 @@ def test_parseLines(self): return def test_parseFile(self): - """check P_cif.parseFile()""" + """Check P_cif.parseFile()""" # pbteciffile stru = self.pfile.parseFile(self.pbteciffile) self.assertEqual(8, len(stru)) @@ -199,7 +198,7 @@ def test_parseFile(self): # return def test_write_and_read(self): - """high-level check of P_cif.tostring()""" + """High-level check of P_cif.tostring()""" # high-level check stru_check = Structure() stru_check.read(self.cdsebulkpdffitfile) @@ -369,7 +368,8 @@ def test_curly_brace(self): return def test_getParser(self): - """Test passing of eps keyword argument by getParser function.""" + """Test passing of eps keyword argument by getParser + function.""" pcif = getParser("cif", eps=1e-6) grph = pcif.parseFile(self.graphiteciffile) self.assertEqual(8, len(grph)) diff --git a/tests/test_p_discus.py b/tests/test_p_discus.py index 83f4494e..71f0d695 100644 --- a/tests/test_p_discus.py +++ b/tests/test_p_discus.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Unit tests for diffpy.structure.parsers.p_discus module""" +"""Unit tests for diffpy.structure.parsers.p_discus module.""" import re import unittest @@ -27,7 +26,7 @@ class TestP_discus(unittest.TestCase): - """test Parser for PDFFit file format""" + """Test Parser for PDFFit file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -39,7 +38,7 @@ def setUp(self): self.places = 8 def test_read_discus_Ni(self): - """check reading of Ni structure in discus format""" + """Check reading of Ni structure in discus format.""" stru = self.stru stru.read(self.datafile("Ni-discus.stru"), self.format) f_title = "structure Ni FCC" @@ -60,7 +59,7 @@ def test_read_discus_Ni(self): return def test_except_other_formats(self): - """check exceptions when reading files in other formats""" + """Check exceptions when reading files in other formats.""" badfiles = [ "LiCl-bad.cif", "PbTe.cif", @@ -84,7 +83,7 @@ def test_except_other_formats(self): return def test_ignored_lines(self): - """check skipping of ignored lines in the header""" + """Check skipping of ignored lines in the header.""" r1 = "ignored record 1\n" r2 = "ignored record 2\n" with open(self.datafile("Ni-discus.stru")) as fp: @@ -100,7 +99,7 @@ def test_ignored_lines(self): return def test_spdiameter_parsing(self): - """check parsing of spdiameter record from a file.""" + """Check parsing of spdiameter record from a file.""" stru = self.stru stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) @@ -121,7 +120,7 @@ def test_spdiameter_parsing(self): return def test_stepcut_parsing(self): - """check parsing of stepcut record from a file.""" + """Check parsing of stepcut record from a file.""" stru = self.stru stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) diff --git a/tests/test_p_pdffit.py b/tests/test_p_pdffit.py index b33b6549..316f8ba2 100644 --- a/tests/test_p_pdffit.py +++ b/tests/test_p_pdffit.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Unit tests for diffpy.structure.parsers.p_pdffit module""" +"""Unit tests for diffpy.structure.parsers.p_pdffit module.""" import re import unittest @@ -28,7 +27,7 @@ class TestP_pdffit(unittest.TestCase): - """test Parser for PDFFit file format""" + """Test Parser for PDFFit file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -40,7 +39,7 @@ def setUp(self): self.places = 8 def test_read_pdffit_ZnSb(self): - """check reading of ZnSb pdffit structure file""" + """Check reading of ZnSb pdffit structure file.""" stru = self.stru stru.read(self.datafile("ZnSb_RT_Q28X_VM_20_fxiso.rstr"), self.format) f_title = "Cell structure file of Zn4Sb3 #167 interstitial" @@ -85,7 +84,7 @@ def test_read_pdffit_ZnSb(self): self.assertAlmostEqual(s_sigo, f_sigo) def test_read_pdffit_Ni(self): - """check reading of Ni pdffit structure file""" + """Check reading of Ni pdffit structure file.""" stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) f_title = "structure Ni FCC" @@ -118,7 +117,7 @@ def test_read_pdffit_Ni(self): self.assertAlmostEqual(s_o, f_o) def test_read_pdffit_Ni_prim123(self): - """check reading of Ni_prim supercell 1x2x3""" + """Check reading of Ni_prim supercell 1x2x3.""" stru = self.stru stru.read(self.datafile("Ni_prim123.stru"), self.format) s_lat = [ @@ -149,14 +148,14 @@ def test_read_pdffit_Ni_prim123(self): return def test_read_pdffit_bad(self): - """check exceptions when reading invalid pdffit file""" + """Check exceptions when reading invalid pdffit file.""" stru = self.stru self.assertRaises(StructureFormatError, stru.read, self.datafile("Ni-bad.stru"), self.format) self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky.xyz"), self.format) return def test_writeStr_pdffit(self): - """check writing of normal xyz file""" + """Check writing of normal xyz file.""" stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) with open(self.datafile("Ni.stru")) as fp: @@ -169,7 +168,7 @@ def test_writeStr_pdffit(self): return def test_huge_occupancy(self): - """check structure with huge occupancy can be read.""" + """Check structure with huge occupancy can be read.""" self.stru.read(self.datafile("Ni.stru"), self.format) self.stru[0].occupancy = 16e16 s_s = self.stru.writeStr(self.format) @@ -179,7 +178,7 @@ def test_huge_occupancy(self): return def test_ignored_lines(self): - """check skipping of ignored lines in the header""" + """Check skipping of ignored lines in the header.""" r1 = "ignored record 1" r2 = "ignored record 2" with open(self.datafile("Ni.stru")) as fp: @@ -195,7 +194,7 @@ def test_ignored_lines(self): return def test_spdiameter_parsing(self): - """check parsing of spdiameter record from a file.""" + """Check parsing of spdiameter record from a file.""" stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) @@ -216,7 +215,7 @@ def test_spdiameter_parsing(self): return def test_stepcut_parsing(self): - """check parsing of stepcut record from a file.""" + """Check parsing of stepcut record from a file.""" stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 55c5244d..552154f0 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Unit tests for structure.parsers module.""" import os @@ -30,7 +29,7 @@ class TestP_xyz(unittest.TestCase): - """test Parser for xyz file format""" + """Test Parser for xyz file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -53,7 +52,7 @@ def mktmpfile(self): return self.tmpnames[-1] def test_read_xyz(self): - """check reading of normal xyz file""" + """Check reading of normal xyz file.""" stru = self.stru stru.read(self.datafile("bucky.xyz"), self.format) s_els = [a.element for a in stru] @@ -62,7 +61,7 @@ def test_read_xyz(self): return def test_read_xyz_bad(self): - """check exceptions when reading invalid xyz file""" + """Check exceptions when reading invalid xyz file.""" stru = self.stru self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad1.xyz"), self.format) self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad2.xyz"), self.format) @@ -71,7 +70,7 @@ def test_read_xyz_bad(self): return def test_writeStr_xyz(self): - """check string representation of normal xyz file""" + """Check string representation of normal xyz file.""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) @@ -83,7 +82,7 @@ def test_writeStr_xyz(self): return def test_write_xyz(self): - """check writing of normal xyz file""" + """Check writing of normal xyz file.""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) @@ -104,7 +103,7 @@ def test_write_xyz(self): class TestP_rawxyz(unittest.TestCase): - """test Parser for rawxyz file format""" + """Test Parser for rawxyz file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -116,7 +115,7 @@ def setUp(self): return def test_read_plainxyz(self): - """check reading of a plain xyz file""" + """Check reading of a plain xyz file.""" stru = self.stru stru.read(self.datafile("bucky-plain.xyz"), self.format) s_els = [a.element for a in stru] @@ -125,13 +124,13 @@ def test_read_plainxyz(self): return def test_read_plainxyz_bad(self): - """check exceptions when reading invalid plain xyz file""" + """Check exceptions when reading invalid plain xyz file.""" stru = self.stru self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-plain-bad.xyz"), self.format) return def test_read_rawxyz(self): - """check reading of raw xyz file""" + """Check reading of raw xyz file.""" stru = self.stru stru.read(self.datafile("bucky-raw.xyz"), self.format) s_els = [a.element for a in stru] @@ -143,14 +142,14 @@ def test_read_rawxyz(self): return def test_read_rawxyz_bad(self): - """check exceptions when reading unsupported xy file""" + """Check exceptions when reading unsupported xy file.""" stru = self.stru self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw-bad.xyz"), self.format) self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw.xy"), self.format) return def test_writeStr_rawxyz(self): - """check writing of normal xyz file""" + """Check writing of normal xyz file.""" stru = self.stru stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) @@ -173,7 +172,7 @@ def test_writeStr_rawxyz(self): class TestP_pdb(unittest.TestCase): - """test Parser for PDB file format""" + """Test Parser for PDB file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -185,7 +184,7 @@ def setUp(self): self.places = 3 def test_read_pdb_arginine(self): - """check reading of arginine PDB file""" + """Check reading of arginine PDB file.""" stru = self.stru stru.read(self.datafile("arginine.pdb"), self.format) f_els = [ @@ -233,7 +232,7 @@ def test_read_pdb_arginine(self): self.assertTrue(numpy.allclose(a0.xyz, [0.735, 2.219, 1.389])) def test_rwStr_pdb_CdSe(self): - """check conversion to PDB file format""" + """Check conversion to PDB file format.""" stru = self.stru stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) @@ -274,7 +273,7 @@ def test_rwStr_pdb_CdSe(self): class TestP_xcfg(unittest.TestCase): - """test Parser for XCFG file format""" + """Test Parser for XCFG file format.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -286,7 +285,7 @@ def setUp(self): self.places = 6 def test_read_xcfg(self): - """check reading of BubbleRaft XCFG file""" + """Check reading of BubbleRaft XCFG file.""" stru = self.stru stru.read(self.datafile("BubbleRaftShort.xcfg"), self.format) f_els = 500 * ["Ar"] @@ -306,7 +305,7 @@ def test_read_xcfg(self): return def test_rwStr_xcfg_CdSe(self): - """check conversion to XCFG file format""" + """Check conversion to XCFG file format.""" stru = self.stru stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") s = stru.writeStr(self.format) diff --git a/tests/test_spacegroups.py b/tests/test_spacegroups.py index 996a73d4..bfd71382 100644 --- a/tests/test_spacegroups.py +++ b/tests/test_spacegroups.py @@ -12,8 +12,7 @@ # See LICENSE.txt for license information. # ############################################################################## - -"""Unit tests for diffpy.structure.spacegroups""" +"""Unit tests for diffpy.structure.spacegroups.""" import unittest diff --git a/tests/test_structure.py b/tests/test_structure.py index d79f5ed3..65e851c1 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Unit tests for Structure class.""" @@ -29,7 +28,7 @@ class TestStructure(unittest.TestCase): - """test methods of Structure class""" + """Test methods of Structure class.""" @pytest.fixture(autouse=True) def prepare_fixture(self, datafile): @@ -56,7 +55,7 @@ def setUp(self): return def test___init__(self): - """check Structure.__init__()""" + """Check Structure.__init__()""" atoms = [Atom("C", [0, 0, 0]), Atom("C", [0.5, 0.5, 0.5])] self.assertRaises(ValueError, Structure, atoms, filename=self.teifile) self.assertRaises(ValueError, Structure, lattice=Lattice(), filename=self.teifile) @@ -72,7 +71,7 @@ def test___init__(self): return def test_copy(self): - """check Structure.copy()""" + """Check Structure.copy()""" class MyDerivedStructure(Structure): def __copy__(self): @@ -96,7 +95,7 @@ def __copy__(self): return def test___copy__(self): - """check Structure.__copy__()""" + """Check Structure.__copy__()""" cdse = Structure(filename=self.cdsefile) cdse_str = cdse.writeStr("pdffit") cdse2 = copy.copy(cdse) @@ -119,7 +118,7 @@ def test___copy__(self): # return def test_assignUniqueLabels(self): - """check Structure.assignUniqueLabels()""" + """Check Structure.assignUniqueLabels()""" self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assignUniqueLabels() self.assertEqual("C1", self.stru[0].label) @@ -127,7 +126,7 @@ def test_assignUniqueLabels(self): return def test_distance(self): - """check Structure.distance()""" + """Check Structure.distance()""" from math import sqrt self.stru.assignUniqueLabels() @@ -139,7 +138,7 @@ def test_distance(self): return def test_angle(self): - """check Structure.angle()""" + """Check Structure.angle()""" cdse = Structure(filename=self.cdsefile) cdse.assignUniqueLabels() self.assertEqual(109, round(cdse.angle(0, 2, 1))) @@ -147,7 +146,8 @@ def test_angle(self): return def test_placeInLattice(self): - """check Structure.placeInLattice() -- conversion of coordinates""" + """Check Structure.placeInLattice() -- conversion of + coordinates.""" stru = self.stru new_lattice = Lattice(0.5, 0.5, 0.5, 90, 90, 60) stru.placeInLattice(new_lattice) @@ -173,14 +173,14 @@ def test_placeInLattice(self): # return def test_aslist(self): - """check Structure.tolist()""" + """Check Structure.tolist()""" lst = self.stru.tolist() self.assertEqual(tuple(lst), tuple(self.stru)) self.assertEqual(list, type(lst)) return def test_append(self): - """check Structure.append()""" + """Check Structure.append()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru.append(a) @@ -194,7 +194,7 @@ def test_append(self): return def test_insert(self): - """check Structure.insert()""" + """Check Structure.insert()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru.insert(1, a) @@ -208,7 +208,7 @@ def test_insert(self): return def test_extend(self): - """check Structure.extend()""" + """Check Structure.extend()""" stru = self.stru cdse = Structure(filename=self.cdsefile) lst = stru.tolist() @@ -220,7 +220,7 @@ def test_extend(self): return def test___getitem__(self): - """check Structure.__getitem__()""" + """Check Structure.__getitem__()""" stru = self.stru self.assertTrue(stru[0] is stru.tolist()[0]) intidx = list(range(len(stru)))[::-1] @@ -247,14 +247,14 @@ def test___getitem__(self): return def test___getitem__slice(self): - """check Structure.__getitem__() with a slice argument""" + """Check Structure.__getitem__() with a slice argument.""" stru = self.stru self.assertEqual([stru[0]], stru[:1].tolist()) self.assertEqual([stru[1], stru[0]], stru[::-1].tolist()) return def test___setitem__(self): - """check Structure.__setitem__()""" + """Check Structure.__setitem__()""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru[1] = a @@ -268,7 +268,7 @@ def test___setitem__(self): return def test___setitem__slice(self): - """check Structure.__setitem__() with a slice argument""" + """Check Structure.__setitem__() with a slice argument.""" a = Atom("Si", (0.1, 0.2, 0.3)) lat = self.stru.lattice self.stru[:] = [a] @@ -282,7 +282,7 @@ def test___setitem__slice(self): return def test___add__(self): - """check Structure.__add__()""" + """Check Structure.__add__()""" stru = self.stru cdse = Structure(filename=self.cdsefile) total = stru + cdse @@ -298,7 +298,7 @@ def test___add__(self): return def test___iadd__(self): - """check Structure.__iadd__()""" + """Check Structure.__iadd__()""" stru = self.stru lat0 = stru.lattice lst = stru.tolist() @@ -315,7 +315,7 @@ def test___iadd__(self): return def test___sub__(self): - """check Structure.__sub__()""" + """Check Structure.__sub__()""" cdse = Structure(filename=self.cdsefile) cadmiums = cdse - cdse[2:] self.assertEqual(2, len(cadmiums)) @@ -328,7 +328,7 @@ def test___sub__(self): return def test___isub__(self): - """check Structure.__isub__()""" + """Check Structure.__isub__()""" cdse = Structure(filename=self.cdsefile) lat = cdse.lattice lst = cdse.tolist() @@ -342,7 +342,7 @@ def test___isub__(self): return def test___mul__(self): - """check Structure.__mul__()""" + """Check Structure.__mul__()""" cdse = Structure(filename=self.cdsefile) self.assertEqual(12, len(set(3 * cdse))) self.assertEqual(12, len(set(cdse * 3))) @@ -355,7 +355,7 @@ def test___mul__(self): return def test___imul__(self): - """check Structure.__imul__()""" + """Check Structure.__imul__()""" cdse = Structure(filename=self.cdsefile) lat = cdse.lattice els = cdse.element @@ -373,7 +373,7 @@ def test___imul__(self): return def test__get_lattice(self): - """check Structure._get_lattice()""" + """Check Structure._get_lattice()""" lat = Lattice() stru = Structure() self.assertEqual((1, 1, 1, 90, 90, 90), stru.lattice.abcABG()) @@ -382,14 +382,14 @@ def test__get_lattice(self): return def test__set_lattice(self): - """check Structure._set_lattice()""" + """Check Structure._set_lattice()""" lat = Lattice() self.stru.lattice = lat self.assertEqual(2 * [lat], [a.lattice for a in self.stru]) return def test_composition(self): - """check Structure.composition property""" + """Check Structure.composition property.""" stru = self.stru self.assertEqual({"C": 2}, stru.composition) stru *= 2 @@ -399,7 +399,7 @@ def test_composition(self): return def test_element(self): - """check Structure.element""" + """Check Structure.element.""" stru = self.stru cdse = self.cdse self.assertEqual("Cd Cd Se Se".split(), cdse.element.tolist()) @@ -409,7 +409,7 @@ def test_element(self): return def test_xyz(self): - """check Structure.xyz""" + """Check Structure.xyz.""" stru = self.stru self.assertEqual((2, 3), stru.xyz.shape) self.assertTrue(numpy.array_equal([1, 1, 1], stru.xyz[1])) @@ -427,7 +427,7 @@ def test_xyz(self): return def test_x(self): - """check Structure.x""" + """Check Structure.x.""" cdse = self.cdse self.assertEqual((4,), cdse.x.shape) self.assertAlmostEqual(0.6666, cdse.x[3], 5) @@ -438,7 +438,7 @@ def test_x(self): return def test_y(self): - """check Structure.y""" + """Check Structure.y.""" cdse = self.cdse self.assertEqual((4,), cdse.y.shape) self.assertAlmostEqual(0.3333, cdse.y[3], 5) @@ -449,7 +449,7 @@ def test_y(self): return def test_z(self): - """check Structure.z""" + """Check Structure.z.""" cdse = self.cdse self.assertEqual((4,), cdse.z.shape) self.assertAlmostEqual(0.87667, cdse.z[3], 5) @@ -460,7 +460,7 @@ def test_z(self): return def test_label(self): - """check Structure.label""" + """Check Structure.label.""" cdse = Structure(filename=self.cdsefile) self.assertEqual(4 * [""], cdse.label.tolist()) cdse.assignUniqueLabels() @@ -470,7 +470,7 @@ def test_label(self): return def test_occupancy(self): - """check Structure.occupancy""" + """Check Structure.occupancy.""" cdse = self.cdse self.assertTrue(numpy.array_equal(numpy.ones(4), cdse.occupancy)) self.stru.occupancy *= 0.5 @@ -480,7 +480,7 @@ def test_occupancy(self): return def test_xyz_cartn(self): - """check Structure.xyz_cartn""" + """Check Structure.xyz_cartn.""" pbte = copy.copy(self.pbte) self.assertEqual((8, 3), pbte.xyz_cartn.shape) self.assertTrue(numpy.allclose(6.461 / 2.0 * numpy.ones(3), pbte.xyz_cartn[0])) @@ -490,7 +490,7 @@ def test_xyz_cartn(self): return def test_anisotropy(self): - """check Structure.anisotropy""" + """Check Structure.anisotropy.""" self.assertEqual((2,), self.stru.anisotropy.shape) self.assertFalse(numpy.any(self.stru.anisotropy)) tei = copy.copy(self.tei) @@ -507,7 +507,7 @@ def test_anisotropy(self): return def test_U(self): - """check Structure.U""" + """Check Structure.U.""" stru = self.stru self.assertEqual((2, 3, 3), stru.U.shape) self.assertFalse(numpy.any(stru.anisotropy)) @@ -529,7 +529,7 @@ def test_U(self): return def test_Uisoequiv(self): - """check Structure.Uisoequiv""" + """Check Structure.Uisoequiv.""" tei = copy.copy(self.tei) self.assertEqual((16,), tei.Uisoequiv.shape) self.assertAlmostEqual(0.019227, tei.Uisoequiv[0], 6) @@ -542,7 +542,7 @@ def test_Uisoequiv(self): return def test_Uij(self): - """check Structure.Uij""" + """Check Structure.Uij.""" stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] @@ -557,7 +557,7 @@ def test_Uij(self): return def test_Bisoequiv(self): - """check Structure.Bisoequiv""" + """Check Structure.Bisoequiv.""" utob = 8 * numpy.pi**2 tei = copy.copy(self.tei) self.assertEqual((16,), tei.Bisoequiv.shape) @@ -571,7 +571,7 @@ def test_Bisoequiv(self): return def test_Bij(self): - """check Structure.Bij""" + """Check Structure.Bij.""" stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] diff --git a/tests/test_supercell.py b/tests/test_supercell.py index 68aa8092..d20434ca 100644 --- a/tests/test_supercell.py +++ b/tests/test_supercell.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Unit tests for supercell.py""" +"""Unit tests for supercell.py.""" import unittest @@ -50,14 +49,14 @@ def tearDown(self): return def test_exceptions(self): - """check argument checking of supercell.""" + """Check argument checking of supercell.""" self.assertRaises(ValueError, supercell, self.stru_ni, (0, 1, 1)) self.assertRaises(ValueError, supercell, self.stru_ni, (0, 1)) self.assertRaises(TypeError, supercell, list(self.stru_ni), (1, 1, 1)) return def test_ni_supercell(self): - """check supercell expansion for Ni.""" + """Check supercell expansion for Ni.""" ni_123 = supercell(self.stru_ni, (1, 2, 3)) self.assertEqual(6 * len(self.stru_ni), len(ni_123)) a, b, c = self.stru_ni.lattice.abcABG()[:3] @@ -73,7 +72,7 @@ def test_ni_supercell(self): return def test_cdse_supercell(self): - """check supercell expansion for CdSe.""" + """Check supercell expansion for CdSe.""" cdse_222 = supercell(self.stru_cdse, (2, 2, 2)) # new atoms should be grouped together elems = sum([8 * [a.element] for a in self.stru_cdse], []) diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 377f7554..5e733906 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -12,8 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Unit tests for SymmetryUtilities.py""" +"""Unit tests for SymmetryUtilities.py.""" import re import sys @@ -45,7 +44,7 @@ def tearDown(self): return def test_isSpaceGroupLatPar(self): - """check isSpaceGroupLatPar()""" + """Check isSpaceGroupLatPar()""" triclinic = GetSpaceGroup("P1") monoclinic = GetSpaceGroup("P2") orthorhombic = GetSpaceGroup("P222") @@ -69,13 +68,13 @@ def test_isSpaceGroupLatPar(self): return def test_sgtbx_spacegroup_aliases(self): - """check GetSpaceGroup for non-standard aliases from sgtbx.""" + """Check GetSpaceGroup for non-standard aliases from sgtbx.""" self.assertIs(GetSpaceGroup("Fm3m"), GetSpaceGroup(225)) self.assertIs(GetSpaceGroup("Ia3d"), GetSpaceGroup("I a -3 d")) return def test_expandPosition(self): - """check expandPosition()""" + """Check expandPosition()""" # ok again Ni example fcc = GetSpaceGroup(225) pos, pops, pmult = expandPosition(fcc, [0, 0, 0]) @@ -86,14 +85,14 @@ def test_expandPosition(self): return def test_pruneFormulaDictionary(self): - """check pruneFormulaDictionary()""" + """Check pruneFormulaDictionary()""" fmdict = {"x": "3*y-0.17", "y": "0", "z": "0.13"} pruned = pruneFormulaDictionary(fmdict) self.assertEqual({"x": "3*y-0.17"}, pruned) return def test_isconstantFormula(self): - """check isconstantFormula()""" + """Check isconstantFormula()""" self.assertFalse(isconstantFormula("x-y+z")) self.assertTrue(isconstantFormula("6.023e23")) self.assertTrue(isconstantFormula("22/7")) @@ -119,14 +118,14 @@ def tearDown(self): return def test___init__(self): - """check _Position2Tuple.__init__()""" + """Check _Position2Tuple.__init__()""" self.assertNotEqual(0.0, self.pos2tuple.eps) self.pos2tuple = _Position2Tuple(1.0 / sys.maxsize / 2) self.assertEqual(0.0, self.pos2tuple.eps) return def test___call__(self): - """check _Position2Tuple.__call__()""" + """Check _Position2Tuple.__call__()""" pos2tuple = self.pos2tuple positions = numpy.zeros((100, 3), dtype=float) positions[:, 0] = numpy.arange(100) / 100.0 * pos2tuple.eps + 0.1 @@ -202,7 +201,7 @@ def tearDown(self): return def test___init__(self): - """check GeneratorSite.__init__()""" + """Check GeneratorSite.__init__()""" # check multiplicities self.assertEqual(2, self.g117c.multiplicity) self.assertEqual(4, self.g117h.multiplicity) @@ -230,7 +229,7 @@ def test_signedRatStr(self): return def test_positionFormula(self): - """check GeneratorSite.positionFormula()""" + """Check GeneratorSite.positionFormula()""" # 117c self.assertEqual([], self.g117c.pparameters) self.assertEqual([("x", self.x)], self.g117h.pparameters) @@ -265,7 +264,7 @@ def test_positionFormula_sg209(self): return def test_UFormula(self): - """check GeneratorSite.UFormula()""" + """Check GeneratorSite.UFormula()""" # Ref: Willis and Pryor, Thermal Vibrations in Crystallography, # Cambridge University Press 1975, p. 104-110 smbl = ("A", "B", "C", "D", "E", "F") @@ -315,7 +314,8 @@ def test_UFormula(self): return def test_UFormula_g186c_eqxyz(self): - """Check rotated U formulas at the symmetry positions of c-site in 186.""" + """Check rotated U formulas at the symmetry positions of c-site + in 186.""" sg186 = GetSpaceGroup(186) crules = [ {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "-E"}, @@ -354,7 +354,7 @@ def test_UFormula_self_reference(self): return def test__findUParameters(self): - """check GeneratorSite._findUParameters()""" + """Check GeneratorSite._findUParameters()""" # by default all Uparameters equal zero, this would fail for NaNs for gen in TestGeneratorSite.generators.values(): for usym, uval in gen.Uparameters: @@ -371,7 +371,7 @@ def test__findUParameters(self): return def test_eqIndex(self): - """check GeneratorSite.eqIndex()""" + """Check GeneratorSite.eqIndex()""" self.assertEqual(13, self.g227oc.eqIndex(self.g227oc.eqxyz[13])) return @@ -390,7 +390,7 @@ def tearDown(self): return def test___init__(self): - """check SymmetryConstraints.__init__()""" + """Check SymmetryConstraints.__init__()""" sg225 = GetSpaceGroup(225) # initialize from nested lists and arrays from ExpandAsymmetricUnit eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) @@ -430,7 +430,7 @@ def test_corepos(self): return def test_Uisotropy(self): - """check isotropy value for ADP-s at specified sites.""" + """Check isotropy value for ADP-s at specified sites.""" sg225 = GetSpaceGroup(225) corepos = [[0, 0, 0], [0.1, 0.13, 0.17]] eau = ExpandAsymmetricUnit(sg225, corepos) @@ -465,7 +465,7 @@ def test_Uisotropy(self): # return # def test_UparSymbols(self): - """check SymmetryConstraints.UparSymbols()""" + """Check SymmetryConstraints.UparSymbols()""" sg1 = GetSpaceGroup(1) sg225 = GetSpaceGroup(225) pos = [[0, 0, 0]] @@ -477,7 +477,7 @@ def test_UparSymbols(self): return def test_UparValues(self): - """check SymmetryConstraints.UparValues()""" + """Check SymmetryConstraints.UparValues()""" places = 12 sg1 = GetSpaceGroup(1) sg225 = GetSpaceGroup(225) From 4b7b89cc8522aee82b7a89541f23726b6040d046 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 13:49:18 -0400 Subject: [PATCH 120/226] skpkg: new files --- .../pull_request_template.md | 15 ++ .github/workflows/publish-docs-on-release.yml | 12 ++ .pre-commit-config.yaml | 38 +++-- .readthedocs.yaml | 13 ++ CODE_OF_CONDUCT.rst | 133 ++++++++++++++++++ doc/source/img/.placeholder | 0 doc/source/snippets/.placeholder | 0 environment.yml | 6 - requirements/docs.txt | 1 + 9 files changed, 203 insertions(+), 15 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md create mode 100644 .github/workflows/publish-docs-on-release.yml create mode 100644 .readthedocs.yaml create mode 100644 CODE_OF_CONDUCT.rst create mode 100644 doc/source/img/.placeholder create mode 100644 doc/source/snippets/.placeholder delete mode 100644 environment.yml diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 00000000..1099d862 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,15 @@ +### What problem does this PR address? + + + +### What should the reviewer(s) do? + + + + diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml new file mode 100644 index 00000000..461e8ac3 --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,12 @@ +name: Deploy Documentation on Release + +on: + workflow_dispatch: + +jobs: + docs: + uses: scikit-package/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.structure + c_extension: false + headless: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3070e199..0e4a84d1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,14 @@ default_language_version: - python: python3 + python: python3 ci: - autofix_commit_msg: | - [pre-commit.ci] auto fixes from pre-commit hooks - autofix_prs: true - autoupdate_branch: 'pre-commit-autoupdate' - autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' - autoupdate_schedule: monthly - skip: [no-commit-to-branch] - submodules: false + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit hooks + autofix_prs: true + autoupdate_branch: "pre-commit-autoupdate" + autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate" + autoupdate_schedule: monthly + skip: [no-commit-to-branch] + submodules: false repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 @@ -44,3 +44,23 @@ repos: name: Prevent Commit to Main Branch args: ["--branch", "main"] stages: [pre-commit] + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli + # prettier - multi formatter for .json, .yml, and .md files + - repo: https://github.com/pre-commit/mirrors-prettier + rev: f12edd9c7be1c20cfa42420fd0e6df71e42b51ea # frozen: v4.0.0-alpha.8 + hooks: + - id: prettier + additional_dependencies: + - "prettier@^3.2.4" + # docformatter - PEP 257 compliant docstring formatter + - repo: https://github.com/s-weigand/docformatter + rev: 5757c5190d95e5449f102ace83df92e7d3b06c6c + hooks: + - id: docformatter + additional_dependencies: [tomli] + args: [--in-place, --config, ./pyproject.toml] diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..47f7a017 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: "ubuntu-22.04" + tools: + python: "latest" + +python: + install: + - requirements: requirements/docs.txt + +sphinx: + configuration: doc/source/conf.py diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..e8199ca5 --- /dev/null +++ b/CODE_OF_CONDUCT.rst @@ -0,0 +1,133 @@ +===================================== + Contributor Covenant Code of Conduct +===================================== + +Our Pledge +---------- + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socioeconomic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +Our Standards +------------- + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Enforcement Responsibilities +---------------------------- + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +Scope +----- + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +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. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +Enforcement Guidelines +---------------------- + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +1. Correction +**************** + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +2. Warning +************* + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +3. Temporary Ban +****************** + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +4. Permanent Ban +****************** + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +Attribution +----------- + +This Code of Conduct is adapted from the `Contributor Covenant `_. + +Community Impact Guidelines were inspired by `Mozilla's code of conduct enforcement ladder `_. + +For answers to common questions about this code of conduct, see the `FAQ `_. `Translations are available `_ diff --git a/doc/source/img/.placeholder b/doc/source/img/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/doc/source/snippets/.placeholder b/doc/source/snippets/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/environment.yml b/environment.yml deleted file mode 100644 index c7cd23cd..00000000 --- a/environment.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: diffpy.structure -channels: - - conda-forge -dependencies: - - python=3 - - pip diff --git a/requirements/docs.txt b/requirements/docs.txt index ab17b1c8..5f34c6ed 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,4 +1,5 @@ sphinx sphinx_rtd_theme +sphinx-copybutton doctr m2r From 9d7972e275592c1f9122cd5a4dbe64b1a2887100 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 14:08:17 -0400 Subject: [PATCH 121/226] skpkg: docs --- doc/source/conf.py | 45 ++++++++++++++++++++++++++++++++++++------ doc/source/index.rst | 3 +++ doc/source/license.rst | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index f7b1c770..6e3d83bc 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# diffpy.structure documentation build configuration file, created by +# diffpy.structure documentation build configuration file, created by # noqa: E501 # sphinx-quickstart on Thu Jan 30 15:49:41 2014. # # This file is execfile()d with the current directory set to its @@ -18,15 +18,21 @@ from importlib.metadata import version from pathlib import Path +# Attempt to import the version dynamically from GitHub tag. +try: + fullversion = version("diffpy.structure") +except Exception: + fullversion = "No version found. The correct version will appear in the released version." # noqa: E501 + # 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. # noqa: E501 # 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 = "Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members" # -- General configuration ------------------------------------------------ @@ -43,6 +49,7 @@ "sphinx.ext.viewcode", "sphinx.ext.intersphinx", "sphinx_rtd_theme", + "sphinx_copybutton", "m2r", ] @@ -68,7 +75,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,6 +94,11 @@ # 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"] @@ -123,6 +134,14 @@ # html_theme = "sphinx_rtd_theme" +html_context = { + "display_github": True, + "github_user": "diffpy", + "github_repo": "diffpy.structure", + "github_version": "main", + "conf_py_path": "/doc/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. @@ -221,7 +240,13 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ("index", "diffpy.structure.tex", "diffpy.structure Documentation", ab_authors, "manual"), + ( + "index", + "diffpy.structure.tex", + "diffpy.structure Documentation", + ab_authors, + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -249,7 +274,15 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("index", "diffpy.structure", "diffpy.structure Documentation", ab_authors, 1)] +man_pages = [ + ( + "index", + "diffpy.structure", + "diffpy.structure Documentation", + ab_authors, + 1, + ) +] # If true, show URL addresses after external links. # man_show_urls = False diff --git a/doc/source/index.rst b/doc/source/index.rst index 4fabbaa1..46e3b737 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -29,6 +29,7 @@ Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.structure/graphs/contributors. +=============== Acknowledgments =============== @@ -38,9 +39,11 @@ Less common settings of space groups were generating using the Computational Crystallography Toolbox, http://cctbx.sourceforge.net. +``diffpy.structure`` is built and maintained with `scikit-package `_. .. index:: citation, reference +========= Reference ========= diff --git a/doc/source/license.rst b/doc/source/license.rst index 33a363ae..00315fc7 100644 --- a/doc/source/license.rst +++ b/doc/source/license.rst @@ -22,7 +22,7 @@ Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory -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. The "DiffPy-CMI" is distributed subject to the following license conditions: From 04f6aa571ba85309df6d8df948ca54c6e57bc2de Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 14:30:04 -0400 Subject: [PATCH 122/226] skpkg: codespell src/ --- .codespell/ignore_words.txt | 19 ++++++++++++++++--- src/diffpy/structure/expansion/shapeutils.py | 2 +- src/diffpy/structure/parsers/p_auto.py | 2 +- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_xcfg.py | 2 +- src/diffpy/structure/spacegroupmod.py | 2 +- src/diffpy/structure/structure.py | 4 ++-- src/diffpy/structure/symmetryutilities.py | 2 +- 8 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt index 9757d7c0..e2ee211b 100644 --- a/.codespell/ignore_words.txt +++ b/.codespell/ignore_words.txt @@ -4,8 +4,21 @@ ;; abbreviation for "materials" often used in a journal title mater -;; alternative use of socioeconomic -socio-economic - ;; Frobenius norm used in np.linalg.norm fro + +;; "discus" is the name of a software package +discus +DISCUS + +;; chemical elements +Te +Nd + +;; /src/diffpy/structure/parsers/p_pdb.py:100 +;; pdb identifier +CONECT + +;; /src/diffpy/structure/parsers/p_xcfg.py:452 +;; used in a function +BU diff --git a/src/diffpy/structure/expansion/shapeutils.py b/src/diffpy/structure/expansion/shapeutils.py index 12ba80d6..16f6c4c3 100644 --- a/src/diffpy/structure/expansion/shapeutils.py +++ b/src/diffpy/structure/expansion/shapeutils.py @@ -32,7 +32,7 @@ def findCenter(S): """ best = -1 bestd = len(S) - center = [0.5, 0.5, 0.5] # the cannonical center + center = [0.5, 0.5, 0.5] # the canonical center for i in range(len(S)): d = S.lattice.dist(S[i].xyz, center) diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index ab688987..ae0ae05a 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -148,7 +148,7 @@ def parseFile(self, filename): def _wrapParseMethod(self, method, *args, **kwargs): """A helper evaluator method that try the specified parse method with each registered structure parser and return the first - successful resul. + successful result. Structure parsers that match structure file extension are tried first. diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 8c59af54..e8220ca7 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -272,7 +272,7 @@ def _parse_unknown_record(self, words): Raises ------ StructureFormatError - Unkown record. + Unknown record. """ self.ignored_lines.append(self.line) return diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 3a29dee3..ea432a6b 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -424,7 +424,7 @@ def getParser(): def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): - """Assing auxiliary properties for `Atom` object when reading CFG + """Assign auxiliary properties for `Atom` object when reading CFG format. Parameters diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index 9c35eae7..b14d3023 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -7,7 +7,7 @@ import numpy -# 64 unique rotation matricies +# 64 unique rotation matrices Rot_Z_mY_X = numpy.array([[0.0, 0.0, 1.0], [0.0, -1.0, 0.0], [1.0, 0.0, 0.0]], float) Rot_Y_mX_mZ = numpy.array([[0.0, 1.0, 0.0], [-1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) Rot_XmY_X_mZ = numpy.array([[1.0, -1.0, 0.0], [1.0, 0.0, 0.0], [0.0, 0.0, -1.0]], float) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 5038bce2..1193b929 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -453,7 +453,7 @@ def __getitem__(self, idx): Parameters ---------- - idx : int ot str ot Iterable + idx : int or str or Iterable `Atom` identifier. When integer use standard list lookup. For iterables use numpy lookup, this supports integer or boolean flag arrays. For string or string-containing iterables @@ -566,7 +566,7 @@ def _fixlat(a): keep = set(super(Structure, self).__getitem__(idx)) v1 = (a if a in keep else Atom(a) for a in value) vfinal = filter(_fixlat, v1) - # handle scalar assingment + # handle scalar assignment else: vfinal = Atom(value) if copy else value vfinal.lattice = self.lattice diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index ea7a40d0..94a08421 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -147,7 +147,7 @@ class _Position2Tuple(object): Attributes ---------- eps : float - Cutoff for equivalent coordinates. When two coordiantes map to the + Cutoff for equivalent coordinates. When two coordinates map to the same tuple, they are closer than `eps`. """ From c787b24e9ee24832a147cf45181f7974e1b26f29 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 14:39:48 -0400 Subject: [PATCH 123/226] skpkg: .github/ --- .codecov.yml | 8 ++--- .github/ISSUE_TEMPLATE/release_checklist.md | 31 +++++++++++++------ .../workflows/build-wheel-release-upload.yml | 6 ++-- .github/workflows/check-news-item.yml | 6 ++-- .../matrix-and-codecov-on-merge-to-main.yml | 4 +-- .github/workflows/tests-on-pr.yml | 7 ++--- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 5a94096e..4af5eb24 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,14 +1,14 @@ coverage: status: - project: # more options at https://docs.codecov.com/docs/commit-status + project: # more options at https://docs.codecov.com/docs/commit-status default: target: auto # use the coverage from the base commit, fail if coverage is lower - threshold: 0% # allow the coverage to drop by + threshold: 0% # allow the coverage to drop by comment: layout: " diff, flags, files" behavior: default require_changes: false - require_base: false # [true :: must have a base report to post] - require_head: false # [true :: must have a head report to post] + require_base: false # [true :: must have a base report to post] + require_head: false # [true :: must have a head report to post] hide_project_coverage: false # [true :: only show coverage on the git diff aka patch coverage] diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index 0f560278..6107962c 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -6,30 +6,41 @@ labels: "release" assignees: "" --- -### PyPI/GitHub release checklist: +### PyPI/GitHub rc-release preparation checklist: - [ ] 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 on the website (e.g., diffpy.org) are updated. + 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 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. -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: -### conda-forge release checklist: +### 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:///`. +- [ ] Successfully run all tests, tutorial examples or do functional testing. +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. -- [ ] All relevant issues in the feedstock are addressed in the release PR. +- [ ] 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 -- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. -- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml index c89ca95c..caeb09c4 100644 --- a/.github/workflows/build-wheel-release-upload.yml +++ b/.github/workflows/build-wheel-release-upload.yml @@ -4,13 +4,15 @@ on: workflow_dispatch: push: tags: - - '*' # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml + - "*" # 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 + uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 with: project: diffpy.structure + c_extension: false + 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 1301ca85..e5853983 100644 --- a/.github/workflows/check-news-item.yml +++ b/.github/workflows/check-news-item.yml @@ -3,10 +3,10 @@ name: Check for News on: pull_request_target: branches: - - main + - main jobs: - build: - uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + check-news-item: + uses: scikit-package/release-scripts/.github/workflows/_check-news-item.yml@v0 with: project: diffpy.structure diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml index 743193f7..235c9f71 100644 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -11,8 +11,8 @@ on: workflow_dispatch: jobs: - coverage: - uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + matrix-coverage: + uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 with: project: diffpy.structure c_extension: false diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml index 1dd2ee1b..1ac611fb 100644 --- a/.github/workflows/tests-on-pr.yml +++ b/.github/workflows/tests-on-pr.yml @@ -1,15 +1,12 @@ name: Tests on PR on: - push: - branches: - - main pull_request: workflow_dispatch: jobs: - validate: - uses: Billingegroup/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + tests-on-pr: + uses: scikit-package/release-scripts/.github/workflows/_tests-on-pr.yml@v0 with: project: diffpy.structure c_extension: false From 4db5ce9bbfe126ef2f65bf0759cf04501a62a346 Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 14:48:42 -0400 Subject: [PATCH 124/226] skpkg: readme --- .gitignore | 8 +------- CHANGELOG.rst | 4 ++-- LICENSE.rst | 2 +- README.rst | 8 +++++--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index a25212ea..099e2948 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ __pycache__/ .Python env/ build/ +_build/ develop-eggs/ dist/ downloads/ @@ -90,10 +91,3 @@ target/ # Ipython Notebook .ipynb_checkpoints - -# version information -setup.cfg -/src/diffpy/*/version.cfg - -# Rever -rever/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2bf42c49..1be318f0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,5 +1,5 @@ ============= -Release Notes +Release notes ============= .. current developments @@ -28,7 +28,7 @@ Release Notes **Fixed:** * Add getting started section and re-arrange install success check instructions -* Added termial script for transtru app in pyproject.toml +* Added terminal script for transtru app in pyproject.toml * Changed requires-python to align with classifiers diff --git a/LICENSE.rst b/LICENSE.rst index 2e8d4ba9..1f91b0ba 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -15,7 +15,7 @@ Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory -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. The "DiffPy-CMI" is distributed subject to the following license conditions: diff --git a/README.rst b/README.rst index cf7020c2..694315b7 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ :target: https://diffpy.github.io/diffpy.structure :height: 100px -|PyPi| |Forge| |PythonVersion| |PR| +|PyPI| |Forge| |PythonVersion| |PR| |CI| |Codecov| |Black| |Tracking| @@ -26,7 +26,7 @@ .. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff -.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.structure +.. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.structure :target: https://pypi.org/project/diffpy.structure/ .. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.structure @@ -132,7 +132,7 @@ trying to commit again. Improvements and fixes are always appreciated. -Before contribuing, please read our `Code of Conduct `_. +Before contributing, please read our `Code of Conduct `_. Acknowledgement --------------- @@ -143,6 +143,8 @@ originate from the `pymmlib project `_. Less common settings of space groups were generating using the `Computational Crystallography Toolbox `_. +``diffpy.structure`` is built and maintained with `scikit-package `_. + Contact ------- From b19f51ac36839bdd968df5e83cee901d296e2f7f Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 14:50:52 -0400 Subject: [PATCH 125/226] skpkg: devutils docformatter --- devutils/sgtbx_extra_groups.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py index 4cab28c2..1c718fa8 100644 --- a/devutils/sgtbx_extra_groups.py +++ b/devutils/sgtbx_extra_groups.py @@ -1,10 +1,11 @@ #!/usr/bin/env python -"""Quick and extremely dirty script for generating code for SpaceGroup that -are defined in cctbx, but not in mmLib. It was used to generate module -sgtbxspacegroups. +"""Quick and extremely dirty script for generating code for SpaceGroup +that are defined in cctbx, but not in mmLib. It was used to generate +module sgtbxspacegroups. -This is a utility script that should not be included with code distribution. +This is a utility script that should not be included with code +distribution. Not to be included with code distributions. """ @@ -40,7 +41,8 @@ def tupleToSGArray(tpl): def mmSpaceGroupFromSymbol(symbol): - """Construct SpaceGroup instance from a string symbol using sgtbx data.""" + """Construct SpaceGroup instance from a string symbol using sgtbx + data.""" sginfo = sgtbx.space_group_info(symbol) symop_list = [] symop_list = getSymOpList(sginfo.group()) From c3a578a6251c64ca61a2f9f54458c181b30e1d9b Mon Sep 17 00:00:00 2001 From: Ting Date: Thu, 19 Jun 2025 15:06:02 -0400 Subject: [PATCH 126/226] skpkg: fixed CODE-OF-CONDUCT.rst --- CODE-OF-CONDUCT.rst | 2 +- CODE_OF_CONDUCT.rst | 133 -------------------------------------------- 2 files changed, 1 insertion(+), 134 deletions(-) delete mode 100644 CODE_OF_CONDUCT.rst diff --git a/CODE-OF-CONDUCT.rst b/CODE-OF-CONDUCT.rst index ff9c3561..e8199ca5 100644 --- a/CODE-OF-CONDUCT.rst +++ b/CODE-OF-CONDUCT.rst @@ -8,7 +8,7 @@ Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socio-economic status, +identity and expression, level of experience, education, socioeconomic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst deleted file mode 100644 index e8199ca5..00000000 --- a/CODE_OF_CONDUCT.rst +++ /dev/null @@ -1,133 +0,0 @@ -===================================== - Contributor Covenant Code of Conduct -===================================== - -Our Pledge ----------- - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone, regardless of age, body -size, visible or invisible disability, ethnicity, sex characteristics, gender -identity and expression, level of experience, education, socioeconomic status, -nationality, personal appearance, race, caste, color, religion, or sexual -identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, -diverse, inclusive, and healthy community. - -Our Standards -------------- - -Examples of behavior that contributes to a positive environment for our -community include: - -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall - community - -Examples of unacceptable behavior include: - -* The use of sexualized language or imagery, and sexual attention or advances of - any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, - without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -Enforcement Responsibilities ----------------------------- - -Community leaders are responsible for clarifying and enforcing our standards of -acceptable behavior and will take appropriate and fair corrective action in -response to any behavior that they deem inappropriate, threatening, offensive, -or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject -comments, commits, code, wiki edits, issues, and other contributions that are -not aligned to this Code of Conduct, and will communicate reasons for moderation -decisions when appropriate. - -Scope ------ - -This Code of Conduct applies within all community spaces, and also applies when -an individual is officially representing the community in public spaces. -Examples of representing our community include using an official email address, -posting via an official social media account, or acting as an appointed -representative at an online or offline event. - -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. - -All community leaders are obligated to respect the privacy and security of the -reporter of any incident. - -Enforcement Guidelines ----------------------- - -Community leaders will follow these Community Impact Guidelines in determining -the consequences for any action they deem in violation of this Code of Conduct: - -1. Correction -**************** - -**Community Impact**: Use of inappropriate language or other behavior deemed -unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing -clarity around the nature of the violation and an explanation of why the -behavior was inappropriate. A public apology may be requested. - -2. Warning -************* - -**Community Impact**: A violation through a single incident or series of -actions. - -**Consequence**: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction with -those enforcing the Code of Conduct, for a specified period of time. This -includes avoiding interactions in community spaces as well as external channels -like social media. Violating these terms may lead to a temporary or permanent -ban. - -3. Temporary Ban -****************** - -**Community Impact**: A serious violation of community standards, including -sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No public or -private interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, is allowed during this period. -Violating these terms may lead to a permanent ban. - -4. Permanent Ban -****************** - -**Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the -community. - -Attribution ------------ - -This Code of Conduct is adapted from the `Contributor Covenant `_. - -Community Impact Guidelines were inspired by `Mozilla's code of conduct enforcement ladder `_. - -For answers to common questions about this code of conduct, see the `FAQ `_. `Translations are available `_ From 293dcd66327436d21919a01d6a46b8a7088b2b23 Mon Sep 17 00:00:00 2001 From: Yuchen Ethan Xiao Date: Tue, 22 Jul 2025 16:46:40 -0400 Subject: [PATCH 127/226] style: use `docs` and `requirements/tests.txt` according to the new group standard --- .flake8 | 2 +- .github/ISSUE_TEMPLATE/release_checklist.md | 2 +- .readthedocs.yaml | 2 +- {doc => docs}/Makefile | 0 {doc => docs}/make.bat | 0 {doc => docs}/manual/Makefile | 0 {doc => docs}/manual/requirements.txt | 0 {doc => docs}/source/_static/.placeholder | 0 {doc => docs}/source/api/diffpy.structure.apps.rst | 0 {doc => docs}/source/api/diffpy.structure.expansion.rst | 0 {doc => docs}/source/api/diffpy.structure.parsers.rst | 0 {doc => docs}/source/api/diffpy.structure.rst | 0 {doc => docs}/source/conf.py | 4 ++-- {doc => docs}/source/diffpy.structure.apps.rst | 0 {doc => docs}/source/diffpy.structure.expansion.rst | 0 {doc => docs}/source/diffpy.structure.parsers.rst | 0 {doc => docs}/source/img/.placeholder | 0 {doc => docs}/source/index.rst | 0 {doc => docs}/source/license.rst | 0 {doc => docs}/source/mod-atom.rst | 0 {doc => docs}/source/mod-lattice.rst | 0 {doc => docs}/source/mod-spacegroup.rst | 0 {doc => docs}/source/release.rst | 0 {doc => docs}/source/snippets/.placeholder | 0 requirements/{test.txt => tests.txt} | 0 25 files changed, 5 insertions(+), 5 deletions(-) rename {doc => docs}/Makefile (100%) rename {doc => docs}/make.bat (100%) rename {doc => docs}/manual/Makefile (100%) rename {doc => docs}/manual/requirements.txt (100%) rename {doc => docs}/source/_static/.placeholder (100%) rename {doc => docs}/source/api/diffpy.structure.apps.rst (100%) rename {doc => docs}/source/api/diffpy.structure.expansion.rst (100%) rename {doc => docs}/source/api/diffpy.structure.parsers.rst (100%) rename {doc => docs}/source/api/diffpy.structure.rst (100%) rename {doc => docs}/source/conf.py (99%) rename {doc => docs}/source/diffpy.structure.apps.rst (100%) rename {doc => docs}/source/diffpy.structure.expansion.rst (100%) rename {doc => docs}/source/diffpy.structure.parsers.rst (100%) rename {doc => docs}/source/img/.placeholder (100%) rename {doc => docs}/source/index.rst (100%) rename {doc => docs}/source/license.rst (100%) rename {doc => docs}/source/mod-atom.rst (100%) rename {doc => docs}/source/mod-lattice.rst (100%) rename {doc => docs}/source/mod-spacegroup.rst (100%) rename {doc => docs}/source/release.rst (100%) rename {doc => docs}/source/snippets/.placeholder (100%) rename requirements/{test.txt => tests.txt} (100%) diff --git a/.flake8 b/.flake8 index 04d2d0b0..a5105116 100644 --- a/.flake8 +++ b/.flake8 @@ -6,7 +6,7 @@ exclude = __pycache__, build, dist, - doc/source/conf.py + docs/source/conf.py max-line-length = 115 # 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 6107962c..56bcd015 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -34,7 +34,7 @@ Please let the maintainer know that all checks are done and the package is ready - [ ] 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. +- [ ] 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. diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 47f7a017..aaa88895 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,4 +10,4 @@ python: - requirements: requirements/docs.txt sphinx: - configuration: doc/source/conf.py + configuration: docs/source/conf.py diff --git a/doc/Makefile b/docs/Makefile similarity index 100% rename from doc/Makefile rename to docs/Makefile diff --git a/doc/make.bat b/docs/make.bat similarity index 100% rename from doc/make.bat rename to docs/make.bat diff --git a/doc/manual/Makefile b/docs/manual/Makefile similarity index 100% rename from doc/manual/Makefile rename to docs/manual/Makefile diff --git a/doc/manual/requirements.txt b/docs/manual/requirements.txt similarity index 100% rename from doc/manual/requirements.txt rename to docs/manual/requirements.txt 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.structure.apps.rst b/docs/source/api/diffpy.structure.apps.rst similarity index 100% rename from doc/source/api/diffpy.structure.apps.rst rename to docs/source/api/diffpy.structure.apps.rst diff --git a/doc/source/api/diffpy.structure.expansion.rst b/docs/source/api/diffpy.structure.expansion.rst similarity index 100% rename from doc/source/api/diffpy.structure.expansion.rst rename to docs/source/api/diffpy.structure.expansion.rst diff --git a/doc/source/api/diffpy.structure.parsers.rst b/docs/source/api/diffpy.structure.parsers.rst similarity index 100% rename from doc/source/api/diffpy.structure.parsers.rst rename to docs/source/api/diffpy.structure.parsers.rst diff --git a/doc/source/api/diffpy.structure.rst b/docs/source/api/diffpy.structure.rst similarity index 100% rename from doc/source/api/diffpy.structure.rst rename to docs/source/api/diffpy.structure.rst diff --git a/doc/source/conf.py b/docs/source/conf.py similarity index 99% rename from doc/source/conf.py rename to docs/source/conf.py index 6e3d83bc..15ccfef6 100644 --- a/doc/source/conf.py +++ b/docs/source/conf.py @@ -139,7 +139,7 @@ "github_user": "diffpy", "github_repo": "diffpy.structure", "github_version": "main", - "conf_py_path": "/doc/source/", + "conf_py_path": "/docs/source/", } # Theme options are theme-specific and customize the look and feel of a theme @@ -222,7 +222,7 @@ # Output file base name for HTML help builder. basename = "diffpy.structure".replace(" ", "").replace(".", "") -htmlhelp_basename = basename + "doc" +htmlhelp_basename = basename + "docs" # -- Options for LaTeX output --------------------------------------------- diff --git a/doc/source/diffpy.structure.apps.rst b/docs/source/diffpy.structure.apps.rst similarity index 100% rename from doc/source/diffpy.structure.apps.rst rename to docs/source/diffpy.structure.apps.rst diff --git a/doc/source/diffpy.structure.expansion.rst b/docs/source/diffpy.structure.expansion.rst similarity index 100% rename from doc/source/diffpy.structure.expansion.rst rename to docs/source/diffpy.structure.expansion.rst diff --git a/doc/source/diffpy.structure.parsers.rst b/docs/source/diffpy.structure.parsers.rst similarity index 100% rename from doc/source/diffpy.structure.parsers.rst rename to docs/source/diffpy.structure.parsers.rst diff --git a/doc/source/img/.placeholder b/docs/source/img/.placeholder similarity index 100% rename from doc/source/img/.placeholder rename to docs/source/img/.placeholder diff --git a/doc/source/index.rst b/docs/source/index.rst similarity index 100% rename from doc/source/index.rst rename to docs/source/index.rst diff --git a/doc/source/license.rst b/docs/source/license.rst similarity index 100% rename from doc/source/license.rst rename to docs/source/license.rst diff --git a/doc/source/mod-atom.rst b/docs/source/mod-atom.rst similarity index 100% rename from doc/source/mod-atom.rst rename to docs/source/mod-atom.rst diff --git a/doc/source/mod-lattice.rst b/docs/source/mod-lattice.rst similarity index 100% rename from doc/source/mod-lattice.rst rename to docs/source/mod-lattice.rst diff --git a/doc/source/mod-spacegroup.rst b/docs/source/mod-spacegroup.rst similarity index 100% rename from doc/source/mod-spacegroup.rst rename to docs/source/mod-spacegroup.rst diff --git a/doc/source/release.rst b/docs/source/release.rst similarity index 100% rename from doc/source/release.rst rename to docs/source/release.rst diff --git a/doc/source/snippets/.placeholder b/docs/source/snippets/.placeholder similarity index 100% rename from doc/source/snippets/.placeholder rename to docs/source/snippets/.placeholder diff --git a/requirements/test.txt b/requirements/tests.txt similarity index 100% rename from requirements/test.txt rename to requirements/tests.txt From a13bd26298d4aeb9dc4373ae3ad2f84ca207d38f Mon Sep 17 00:00:00 2001 From: Yuchen Ethan Xiao Date: Tue, 22 Jul 2025 16:52:46 -0400 Subject: [PATCH 128/226] chore: add news --- news/new-group-standard.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/new-group-standard.rst diff --git a/news/new-group-standard.rst b/news/new-group-standard.rst new file mode 100644 index 00000000..e1107145 --- /dev/null +++ b/news/new-group-standard.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* Use the names CODE-OF-CONDUCT.rst, docs and requirements/tests.txt according to the new group standard. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 5c747a3dd4047486ceb338e169f1260b3a5a1b8c Mon Sep 17 00:00:00 2001 From: Yuchen Ethan Xiao Date: Wed, 23 Jul 2025 19:01:42 -0400 Subject: [PATCH 129/226] fix: catch `YappsSyntaxError` as `StructureFormatErrro` --- news/catch-YapsSyntaxError.rst | 23 +++++++++++++++++++++++ src/diffpy/structure/parsers/p_cif.py | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 news/catch-YapsSyntaxError.rst diff --git a/news/catch-YapsSyntaxError.rst b/news/catch-YapsSyntaxError.rst new file mode 100644 index 00000000..7e35ae76 --- /dev/null +++ b/news/catch-YapsSyntaxError.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Let ``diffpy.structure`` pass the tests with ``pycifrw`` installed from ``PyPI``. + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index cb2f3fa1..c1d32fff 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -36,6 +36,7 @@ from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from CifFile.yapps3_compiled_rt import YappsSyntaxError # ---------------------------------------------------------------------------- @@ -408,7 +409,7 @@ def _parseCifDataSource(self, datasource): # stop after reading the first structure if self.stru is not None: break - except (StarError, ValueError, IndexError) as err: + except (YappsSyntaxError, StarError, ValueError, IndexError) as err: exc_type, exc_value, exc_traceback = sys.exc_info() emsg = str(err).strip() e = StructureFormatError(emsg) From b910f8767bdbeb83c2fbcfe0ae48d363437621eb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 23 Jul 2025 23:17:18 +0000 Subject: [PATCH 130/226] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/structure/parsers/p_cif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index c1d32fff..3d0611ab 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -32,11 +32,11 @@ from contextlib import contextmanager import numpy +from CifFile.yapps3_compiled_rt import YappsSyntaxError from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError -from CifFile.yapps3_compiled_rt import YappsSyntaxError # ---------------------------------------------------------------------------- From 2316eaa8bfc4eeaa0e5fc9a3f4a12b80ddccfb5e Mon Sep 17 00:00:00 2001 From: sbillinge <4254545+sbillinge@users.noreply.github.com> Date: Fri, 25 Jul 2025 01:01:32 +0000 Subject: [PATCH 131/226] update changelog --- CHANGELOG.rst | 17 +++++++++++++++++ news/catch-YapsSyntaxError.rst | 23 ----------------------- news/codecov.rst | 24 ------------------------ news/new-group-standard.rst | 23 ----------------------- 4 files changed, 17 insertions(+), 70 deletions(-) delete mode 100644 news/catch-YapsSyntaxError.rst delete mode 100644 news/codecov.rst delete mode 100644 news/new-group-standard.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1be318f0..66a1a4b8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,23 @@ Release notes .. current developments +3.3.1 +===== + +**Added:** + +* Spelling check via Codespell in pre-commit +* Coverage report in each PR + +**Changed:** + +* Use the names CODE-OF-CONDUCT.rst, docs and requirements/tests.txt according to the new group standard. + +**Fixed:** + +* Let ``diffpy.structure`` pass the tests with ``pycifrw`` installed from ``PyPI``. + + 3.3.0 ===== diff --git a/news/catch-YapsSyntaxError.rst b/news/catch-YapsSyntaxError.rst deleted file mode 100644 index 7e35ae76..00000000 --- a/news/catch-YapsSyntaxError.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Let ``diffpy.structure`` pass the tests with ``pycifrw`` installed from ``PyPI``. - -**Security:** - -* diff --git a/news/codecov.rst b/news/codecov.rst deleted file mode 100644 index 1c91077e..00000000 --- a/news/codecov.rst +++ /dev/null @@ -1,24 +0,0 @@ -**Added:** - -* Spelling check via Codespell in pre-commit -* Coverage report in each PR - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/new-group-standard.rst b/news/new-group-standard.rst deleted file mode 100644 index e1107145..00000000 --- a/news/new-group-standard.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* Use the names CODE-OF-CONDUCT.rst, docs and requirements/tests.txt according to the new group standard. - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* From 0a5d4414f597abb45a81919ca1439154d4ea27ee Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 21 Nov 2025 16:56:10 -0500 Subject: [PATCH 132/226] add deprecator --- src/diffpy/structure/__init__.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index e66c0879..4b531e89 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -33,8 +33,10 @@ * SymmetryError """ -# Interface definitions ------------------------------------------------------ +import sys + +import diffpy.structure as _structure from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice from diffpy.structure.parsers import getParser @@ -45,6 +47,28 @@ # package version from diffpy.structure.version import __version__ +# Deprecations ------------------------------------------------------- +# Only use the backport for module shims + + +# @deprecated +# custom deprecator for diffpy.Structure module +class DeprecatedStructureModule: + """Proxy for backward compatibility of diffpy.Structure.""" + + def __getattr__(self, name): + import warnings + + warnings.warn( + "Module 'diffpy.Structure' is deprecated. Use 'diffpy.structure' instead.", + DeprecationWarning, + stacklevel=2, + ) + return getattr(_structure, name) + + +sys.modules["diffpy.Structure"] = DeprecatedStructureModule() + # top level routines From 275990058abfc1d914e0c40d11014da662ffb272 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 21 Nov 2025 16:56:53 -0500 Subject: [PATCH 133/226] news --- news/dep-warning1.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/dep-warning1.rst diff --git a/news/dep-warning1.rst b/news/dep-warning1.rst new file mode 100644 index 00000000..bd4b2fbd --- /dev/null +++ b/news/dep-warning1.rst @@ -0,0 +1,23 @@ +**Added:** + +* Add deprecation warning for ``diffpy.Structure`` import. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 73a6b13a856d8140eb6cee315674fb3a09b2ac53 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 21 Nov 2025 16:58:46 -0500 Subject: [PATCH 134/226] rm comment --- src/diffpy/structure/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 4b531e89..3ab52b61 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -48,7 +48,6 @@ from diffpy.structure.version import __version__ # Deprecations ------------------------------------------------------- -# Only use the backport for module shims # @deprecated From 5841feb7e4502638bd85e7be1ca3bc40b8b05859 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 24 Nov 2025 09:56:08 -0500 Subject: [PATCH 135/226] update wording --- src/diffpy/structure/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 3ab52b61..263ef216 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -59,7 +59,8 @@ def __getattr__(self, name): import warnings warnings.warn( - "Module 'diffpy.Structure' is deprecated. Use 'diffpy.structure' instead.", + "Module 'diffpy.Structure' is deprecated and will be removed in version 3.8. " + "Use 'diffpy.structure' instead.", DeprecationWarning, stacklevel=2, ) From 3c462a7b2414ebe2abe0022811d04bb62b87559d Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Tue, 25 Nov 2025 15:29:41 -0500 Subject: [PATCH 136/226] Update deprecation warning for diffpy.Structure module --- src/diffpy/structure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 263ef216..62778b45 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -59,7 +59,7 @@ def __getattr__(self, name): import warnings warnings.warn( - "Module 'diffpy.Structure' is deprecated and will be removed in version 3.8. " + "Module 'diffpy.Structure' is deprecated and will be removed in version 4.0. " "Use 'diffpy.structure' instead.", DeprecationWarning, stacklevel=2, From 4fc651ba0bb3ba1d644e2a0e643f9aa979043d6c Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 17 Feb 2026 13:56:05 -0500 Subject: [PATCH 137/226] skpkg: redo skpkg with latest version for minimal manual fix --- .github/ISSUE_TEMPLATE/release_checklist.md | 5 +- .../build-and-publish-docs-on-dispatch.yml | 18 +++ .../workflows/build-wheel-release-upload.yml | 4 +- .github/workflows/matrix-and-codecov.yml | 21 +++ CODE-OF-CONDUCT.rst | 2 +- README.rst | 30 +++- cookiecutter.json | 20 +++ docs/source/api/diffpy.structure.rst | 6 +- docs/source/conf.py | 6 +- docs/source/index.rst | 41 +++--- pyproject.toml | 14 +- requirements/docs.txt | 2 +- src/diffpy/__init__.py | 2 +- src/diffpy/structure/__init__.py | 2 +- src/diffpy/structure/_legacy_importer.py | 6 +- src/diffpy/structure/apps/anyeye.py | 9 +- src/diffpy/structure/apps/transtru.py | 5 +- src/diffpy/structure/atom.py | 32 ++++- src/diffpy/structure/lattice.py | 115 ++++++++++++--- src/diffpy/structure/mmlibspacegroups.py | 24 +++- src/diffpy/structure/parsers/p_auto.py | 5 +- src/diffpy/structure/parsers/p_cif.py | 9 +- src/diffpy/structure/parsers/p_discus.py | 19 ++- src/diffpy/structure/parsers/p_pdb.py | 35 ++++- src/diffpy/structure/parsers/p_pdffit.py | 16 ++- src/diffpy/structure/parsers/p_xcfg.py | 7 +- src/diffpy/structure/spacegroupmod.py | 21 ++- src/diffpy/structure/structure.py | 11 +- src/diffpy/structure/structure_app.py | 33 +++++ src/diffpy/structure/symmetryutilities.py | 35 ++++- src/diffpy/structure/version.py | 13 +- tests/test_lattice.py | 19 ++- tests/test_p_pdffit.py | 14 +- tests/test_parsers.py | 49 ++++++- tests/test_spacegroups.py | 15 +- tests/test_structure.py | 5 +- tests/test_symmetryutilities.py | 135 ++++++++++++++++-- 37 files changed, 663 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/build-and-publish-docs-on-dispatch.yml create mode 100644 .github/workflows/matrix-and-codecov.yml create mode 100644 cookiecutter.json create mode 100644 src/diffpy/structure/structure_app.py diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index 56bcd015..56c5fca3 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -11,12 +11,13 @@ 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. +- [ ] 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 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: 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 00000000..ff9a22b7 --- /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.structure + 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 caeb09c4..794bf94c 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,7 +7,7 @@ on: - "*" # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml jobs: - release: + build-release: uses: scikit-package/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 with: project: diffpy.structure diff --git a/.github/workflows/matrix-and-codecov.yml b/.github/workflows/matrix-and-codecov.yml new file mode 100644 index 00000000..aa3ea76f --- /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.structure + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/CODE-OF-CONDUCT.rst b/CODE-OF-CONDUCT.rst index e8199ca5..25fafe27 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/README.rst b/README.rst index 694315b7..c1059381 100644 --- a/README.rst +++ b/README.rst @@ -25,6 +25,7 @@ :target: https://anaconda.org/conda-forge/diffpy.structure .. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + :target: https://github.com/diffpy/diffpy.structure/pulls .. |PyPI| image:: https://img.shields.io/pypi/v/diffpy.structure :target: https://pypi.org/project/diffpy.structure/ @@ -99,6 +100,19 @@ and run the following :: pip install . +This package also provides command-line utilities. To check the software has been installed correctly, type :: + + diffpy.structure --version + +You can also type the following command to verify the installation. :: + + python -c "import diffpy.structure; print(diffpy.structure.__version__)" + + +To view the basic usage and available commands, type :: + + diffpy.structure -h + Getting Started --------------- @@ -134,8 +148,15 @@ Improvements and fixes are always appreciated. Before contributing, please read our `Code of Conduct `_. -Acknowledgement ---------------- +Contact +------- + +For more information on diffpy.structure please visit the project `web-page `_ or email the maintainer``Simon Billinge(sbillinge@ucsb.edu)``. + +Acknowledgements +---------------- + +``diffpy.structure`` is built and maintained with `scikit-package `_. Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* originate from the `pymmlib project `_. @@ -144,8 +165,3 @@ Less common settings of space groups were generating using the `Computational Crystallography Toolbox `_. ``diffpy.structure`` is built and maintained with `scikit-package `_. - -Contact -------- - -For more information on diffpy.structure please visit the project `web-page `_ or email Prof. Simon Billinge at sb2896@columbia.edu. diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 00000000..5b4de11a --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,20 @@ +{ + "author_names": "Simon Billinge, Sangjoon Bob Lee", + "author_emails": "sbillinge@ucsb.edu, sl5400@columbia.edu", + "maintainer_names": "Simon Billinge, Sangjoon Bob Lee", + "maintainer_emails": "sbillinge@ucsb.edu, sl5400@columbia.edu", + "maintainer_github_usernames": "sbillinge, bobleesj", + "contributors": "Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members", + "license_holders": "The Trustees of Columbia University in the City of New York", + "project_name": "diffpy.structure", + "github_username_or_orgname": "diffpy", + "github_repo_name": "diffpy.structure", + "conda_pypi_package_dist_name": "diffpy.structure", + "package_dir_name": "diffpy.structure", + "project_short_description": "Crystal structure container and parsers for structure formats.", + "project_keywords": "diffpy, crystal structure data storage, CIF, PDB", + "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/docs/source/api/diffpy.structure.rst b/docs/source/api/diffpy.structure.rst index 95ff1285..d6ffb2ad 100644 --- a/docs/source/api/diffpy.structure.rst +++ b/docs/source/api/diffpy.structure.rst @@ -1,7 +1,9 @@ :tocdepth: -1 -diffpy.structure package -======================== +|title| +======= + +.. |title| replace:: diffpy.structure package .. automodule:: diffpy.structure :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index 15ccfef6..960f8fbb 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -32,7 +32,7 @@ sys.path.insert(0, str(Path("../../src").resolve())) # abbreviations -ab_authors = "Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members" +ab_authors = "Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members" # -- General configuration ------------------------------------------------ @@ -50,7 +50,7 @@ "sphinx.ext.intersphinx", "sphinx_rtd_theme", "sphinx_copybutton", - "m2r", + "m2r2", ] # Add any paths that contain templates here, relative to this directory. @@ -222,7 +222,7 @@ # Output file base name for HTML help builder. basename = "diffpy.structure".replace(" ", "").replace(".", "") -htmlhelp_basename = basename + "docs" +htmlhelp_basename = basename + "doc" # -- Options for LaTeX output --------------------------------------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 46e3b737..591a32a2 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,11 +4,15 @@ .. |title| replace:: diffpy.structure documentation -diffpy.structure - Crystal structure container and parsers for structure formats. +``diffpy.structure`` - Crystal structure container and parsers for structure formats. -| Software version |release|. +| Software version |release| | Last updated |today|. +=============== +Getting started +=============== + The diffpy.structure package provides objects for storing atomic coordinates, displacement parameters and other crystal structure data. diffpy.structure supports import and export of structure data in several @@ -22,16 +26,19 @@ includes definitions of all space groups in over 500 symmetry settings. Authors ======= -diffpy.structure is developed by members of the Billinge Group at -Columbia University and at Brookhaven National Laboratory including -Pavol Juhás, Christopher L. Farrow, Xiaohao Yang, Simon J.L. Billinge. - -For a detailed list of contributors see +``diffpy.structure`` is developed by Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. This project is maintained by Simon Billinge. For a detailed list of contributors see https://github.com/diffpy/diffpy.structure/graphs/contributors. -=============== -Acknowledgments -=============== +============ +Installation +============ + +See the `README `_ +file included with the distribution. + +================ +Acknowledgements +================ Space group codes in *spacegroupmod.py* and *mmlibspacegroups.py* originate from the pymmlib project, http://pymmlib.sourceforge.net. @@ -58,23 +65,15 @@ by citing the following paper in your publication: `__, *Acta Crystallogr. A* **71**, 562-568 (2015). -============ -Installation -============ - -See the `README `_ -file included with the distribution. - ================= Table of contents ================= - .. toctree:: - :titlesonly: + :maxdepth: 2 - license - release Package API + release + license ======= Indices diff --git a/pyproject.toml b/pyproject.toml index 46176534..40645c0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,15 +6,15 @@ build-backend = "setuptools.build_meta" name = "diffpy.structure" dynamic=['version', 'dependencies'] authors = [ - { name="Simon Billinge", email="sb2896@columbia.edu" }, + {name='Simon Billinge', email='sbillinge@ucsb.edu'}, ] maintainers = [ - { name="Simon Billinge", email="sb2896@columbia.edu" }, + {name='Simon Billinge', email='sbillinge@ucsb.edu'}, ] description = "Crystal structure container and parsers for structure formats." keywords = ['diffpy', 'crystal structure data storage', 'CIF', 'PDB'] readme = "README.rst" -requires-python = ">=3.11, <3.14" +requires-python = ">=3.12, <3.15" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', @@ -25,16 +25,13 @@ 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', ] -[project.scripts] -transtru = "diffpy.structure.apps.transtru:main" - [project.urls] Homepage = "https://github.com/diffpy/diffpy.structure/" Issues = "https://github.com/diffpy/diffpy.structure/issues/" @@ -51,6 +48,9 @@ include = ["*"] # package names should match these glob patterns (["*"] by defa exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[project.scripts] +diffpy-structure = "diffpy.structure.app:main" + [tool.setuptools.dynamic] dependencies = {file = ["requirements/pip.txt"]} diff --git a/requirements/docs.txt b/requirements/docs.txt index 5f34c6ed..1de813f9 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -2,4 +2,4 @@ sphinx sphinx_rtd_theme sphinx-copybutton doctr -m2r +m2r2 diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 7ecfc294..1cd13da0 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024-2025 The Trustees of Columbia University in the City of New York. +# (c) 2024-2026 The Trustees of Columbia University in the City of New York. # All rights reserved. # # File coded by: Billinge Group members and community contributors. diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 62778b45..58d7e3a8 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024-2025 The Trustees of Columbia University in the City of New York. +# (c) 2024-2026 The Trustees of Columbia University in the City of New York. # All rights reserved. # # File coded by: Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. diff --git a/src/diffpy/structure/_legacy_importer.py b/src/diffpy/structure/_legacy_importer.py index 56123c60..672d0835 100644 --- a/src/diffpy/structure/_legacy_importer.py +++ b/src/diffpy/structure/_legacy_importer.py @@ -80,7 +80,11 @@ def exec_module(self, module): # ---------------------------------------------------------------------------- # show deprecation warning for diffpy.Structure -warn(WMSG.format("diffpy.Structure", "diffpy.structure"), DeprecationWarning, stacklevel=2) +warn( + WMSG.format("diffpy.Structure", "diffpy.structure"), + DeprecationWarning, + stacklevel=2, +) # install meta path finder for diffpy.Structure submodules sys.meta_path.append(FindRenamedStructureModule()) diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index 39122fee..b75c5bdb 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -138,7 +138,10 @@ def convertStructureFile(pd): if pd["formula"]: formula = pd["formula"] if len(formula) != len(stru): - emsg = "Formula has %i atoms while structure %i" % (len(formula), len(stru)) + emsg = "Formula has %i atoms while structure %i" % ( + len(formula), + len(stru), + ) raise RuntimeError(emsg) for a, el in zip(stru, formula): a.element = el @@ -217,7 +220,9 @@ def main(): pd["watch"] = False try: opts, args = getopt.getopt( - sys.argv[1:], "f:whV", ["formula=", "watch", "viewer=", "formats=", "help", "version"] + sys.argv[1:], + "f:whV", + ["formula=", "watch", "viewer=", "formats=", "help", "version"], ) except getopt.GetoptError as errmsg: print(errmsg, file=sys.stderr) diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 4c8af03a..963ebcf5 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -99,7 +99,10 @@ def main(): print("'%s' is not valid output format" % outfmt, file=sys.stderr) sys.exit(2) except ValueError: - print("invalid format specification '%s' does not contain .." % args[0], file=sys.stderr) + print( + "invalid format specification '%s' does not contain .." % args[0], + file=sys.stderr, + ) sys.exit(2) # ready to do some real work try: diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index beac9e7b..6571a815 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -201,7 +201,13 @@ def msdCart(self, vc): def __repr__(self): """String representation of this Atom.""" xyz = self.xyz - s = "%-4s %8.6f %8.6f %8.6f %6.4f" % (self.element, xyz[0], xyz[1], xyz[2], self.occupancy) + s = "%-4s %8.6f %8.6f %8.6f %6.4f" % ( + self.element, + xyz[0], + xyz[1], + xyz[2], + self.occupancy, + ) return s def __copy__(self, target=None): @@ -355,13 +361,19 @@ def _set_Uij(self, i, j, value): """ U11 = property( - lambda self: self._get_Uij(0, 0), lambda self, value: self._set_Uij(0, 0, value), doc=_doc_uii.format(0) + lambda self: self._get_Uij(0, 0), + lambda self, value: self._set_Uij(0, 0, value), + doc=_doc_uii.format(0), ) U22 = property( - lambda self: self._get_Uij(1, 1), lambda self, value: self._set_Uij(1, 1, value), doc=_doc_uii.format(1) + lambda self: self._get_Uij(1, 1), + lambda self, value: self._set_Uij(1, 1, value), + doc=_doc_uii.format(1), ) U33 = property( - lambda self: self._get_Uij(2, 2), lambda self, value: self._set_Uij(2, 2, value), doc=_doc_uii.format(2) + lambda self: self._get_Uij(2, 2), + lambda self, value: self._set_Uij(2, 2, value), + doc=_doc_uii.format(2), ) _doc_uij = """ @@ -372,13 +384,19 @@ def _set_Uij(self, i, j, value): """ U12 = property( - lambda self: self._get_Uij(0, 1), lambda self, value: self._set_Uij(0, 1, value), doc=_doc_uij.format(0, 1) + lambda self: self._get_Uij(0, 1), + lambda self, value: self._set_Uij(0, 1, value), + doc=_doc_uij.format(0, 1), ) U13 = property( - lambda self: self._get_Uij(0, 2), lambda self, value: self._set_Uij(0, 2, value), doc=_doc_uij.format(0, 2) + lambda self: self._get_Uij(0, 2), + lambda self, value: self._set_Uij(0, 2, value), + doc=_doc_uij.format(0, 2), ) U23 = property( - lambda self: self._get_Uij(1, 2), lambda self, value: self._set_Uij(1, 2, value), doc=_doc_uij.format(1, 2) + lambda self: self._get_Uij(1, 2), + lambda self, value: self._set_Uij(1, 2, value), + doc=_doc_uij.format(1, 2), ) # clean local variables diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 5a623208..73885e4f 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -31,7 +31,16 @@ # Helper Functions ----------------------------------------------------------- # exact values of cosd -_EXACT_COSD = {0.0: +1.0, 60.0: +0.5, 90.0: 0.0, 120.0: -0.5, 180.0: -1.0, 240.0: -0.5, 270.0: 0.0, 300.0: +0.5} +_EXACT_COSD = { + 0.0: +1.0, + 60.0: +0.5, + 90.0: 0.0, + 120.0: -0.5, + 180.0: -1.0, + 240.0: -0.5, + 270.0: 0.0, + 300.0: +0.5, +} def cosd(x): @@ -158,15 +167,21 @@ class Lattice(object): # properties ------------------------------------------------------------- a = property( - lambda self: self._a, lambda self, value: self.setLatPar(a=value), doc="The unit cell length *a*." + lambda self: self._a, + lambda self, value: self.setLatPar(a=value), + doc="The unit cell length *a*.", ) b = property( - lambda self: self._b, lambda self, value: self.setLatPar(b=value), doc="The unit cell length *b*." + lambda self: self._b, + lambda self, value: self.setLatPar(b=value), + doc="The unit cell length *b*.", ) c = property( - lambda self: self._c, lambda self, value: self.setLatPar(c=value), doc="The unit cell length *c*." + lambda self: self._c, + lambda self, value: self.setLatPar(c=value), + doc="The unit cell length *c*.", ) alpha = property( @@ -200,19 +215,40 @@ def unitvolume(self): rv = math.sqrt(1.0 + 2.0 * ca * cb * cg - ca * ca - cb * cb - cg * cg) return rv - volume = property(lambda self: self.a * self.b * self.c * self.unitvolume, doc="The unit cell volume.") + volume = property( + lambda self: self.a * self.b * self.c * self.unitvolume, + doc="The unit cell volume.", + ) - ar = property(lambda self: self._ar, doc="The cell length *a* of the reciprocal lattice.") + ar = property( + lambda self: self._ar, + doc="The cell length *a* of the reciprocal lattice.", + ) - br = property(lambda self: self._br, doc="The cell length *b* of the reciprocal lattice.") + br = property( + lambda self: self._br, + doc="The cell length *b* of the reciprocal lattice.", + ) - cr = property(lambda self: self._cr, doc="The cell length *c* of the reciprocal lattice.") + cr = property( + lambda self: self._cr, + doc="The cell length *c* of the reciprocal lattice.", + ) - alphar = property(lambda self: self._alphar, doc="The reciprocal cell angle *alpha* in degrees.") + alphar = property( + lambda self: self._alphar, + doc="The reciprocal cell angle *alpha* in degrees.", + ) - betar = property(lambda self: self._betar, doc="The reciprocal cell angle *beta* in degrees") + betar = property( + lambda self: self._betar, + doc="The reciprocal cell angle *beta* in degrees", + ) - gammar = property(lambda self: self._gammar, doc="The reciprocal cell angle *gamma* in degrees") + gammar = property( + lambda self: self._gammar, + doc="The reciprocal cell angle *gamma* in degrees", + ) ca = property(lambda self: self._ca, doc="The cosine of the cell angle *alpha*.") @@ -226,11 +262,20 @@ def unitvolume(self): sg = property(lambda self: self._sg, doc="The sine of the cell angle *gamma*.") - car = property(lambda self: self._car, doc="The cosine of the reciprocal angle *alpha*.") + car = property( + lambda self: self._car, + doc="The cosine of the reciprocal angle *alpha*.", + ) - cbr = property(lambda self: self._cbr, doc="The cosine of the reciprocal angle *beta*.") + cbr = property( + lambda self: self._cbr, + doc="The cosine of the reciprocal angle *beta*.", + ) - cgr = property(lambda self: self._cgr, doc="The cosine of the reciprocal angle *gamma*.") + cgr = property( + lambda self: self._cgr, + doc="The cosine of the reciprocal angle *gamma*.", + ) sar = property(lambda self: self._sar, doc="The sine of the reciprocal angle *alpha*.") @@ -240,7 +285,17 @@ def unitvolume(self): # done with properties --------------------------------------------------- - def __init__(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, baserot=None, base=None): + def __init__( + self, + a=None, + b=None, + c=None, + alpha=None, + beta=None, + gamma=None, + baserot=None, + base=None, + ): # build a set of provided argument names for later use. apairs = ( ("a", a), @@ -287,7 +342,16 @@ def __init__(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, ba self.setLatPar(a, b, c, alpha, beta, gamma, baserot=baserot) return - def setLatPar(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, baserot=None): + def setLatPar( + self, + a=None, + b=None, + c=None, + alpha=None, + beta=None, + gamma=None, + baserot=None, + ): """Set one or more lattice parameters. This updates all attributes that depend on the lattice parameters. @@ -361,7 +425,11 @@ def setLatPar(self, a=None, b=None, c=None, alpha=None, beta=None, gamma=None, b ) # standard Cartesian coordinates of lattice vectors self.stdbase = numpy.array( - [[1.0 / ar, -cgr / sgr / ar, cb * self.a], [0.0, self.b * sa, self.b * ca], [0.0, 0.0, self.c]], + [ + [1.0 / ar, -cgr / sgr / ar, cb * self.a], + [0.0, self.b * sa, self.b * ca], + [0.0, 0.0, self.c], + ], dtype=float, ) # Cartesian coordinates of lattice vectors @@ -423,7 +491,12 @@ def setLatBase(self, base): self._gammar = math.degrees(math.acos(cgr)) # standard orientation of lattice vectors self.stdbase = numpy.array( - [[1.0 / ar, -cgr / sgr / ar, cb * a], [0.0, b * sa, b * ca], [0.0, 0.0, c]], dtype=float + [ + [1.0 / ar, -cgr / sgr / ar, cb * a], + [0.0, b * sa, b * ca], + [0.0, 0.0, c], + ], + dtype=float, ) # calculate unit cell rotation matrix, base = stdbase @ baserot self.baserot = numpy.dot(numalg.inv(self.stdbase), self.base) @@ -434,7 +507,11 @@ def setLatBase(self, base): self.isotropicunit = _isotropicunit(self.recnormbase) # update metrics tensor self.metrics = numpy.array( - [[a * a, a * b * cg, a * c * cb], [b * a * cg, b * b, b * c * ca], [c * a * cb, c * b * ca, c * c]], + [ + [a * a, a * b * cg, a * c * cb], + [b * a * cg, b * b, b * c * ca], + [c * a * cb, c * b * ca, c * c], + ], dtype=float, ) return diff --git a/src/diffpy/structure/mmlibspacegroups.py b/src/diffpy/structure/mmlibspacegroups.py index 1acd2662..c3507f92 100644 --- a/src/diffpy/structure/mmlibspacegroups.py +++ b/src/diffpy/structure/mmlibspacegroups.py @@ -3269,7 +3269,11 @@ point_group_name="PG3", crystal_system="TRIGONAL", pdb_name="P 3", - symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_0), SymOp(Rot_mXY_mX_Z, Tr_0_0_0)], + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_0), + SymOp(Rot_mXY_mX_Z, Tr_0_0_0), + ], ) sg144 = SpaceGroup( @@ -3280,7 +3284,11 @@ point_group_name="PG3", crystal_system="TRIGONAL", pdb_name="P 31", - symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_13), SymOp(Rot_mXY_mX_Z, Tr_0_0_23)], + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_13), + SymOp(Rot_mXY_mX_Z, Tr_0_0_23), + ], ) sg145 = SpaceGroup( @@ -3291,7 +3299,11 @@ point_group_name="PG3", crystal_system="TRIGONAL", pdb_name="P 32", - symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_mY_XmY_Z, Tr_0_0_23), SymOp(Rot_mXY_mX_Z, Tr_0_0_13)], + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_mY_XmY_Z, Tr_0_0_23), + SymOp(Rot_mXY_mX_Z, Tr_0_0_13), + ], ) sg146 = SpaceGroup( @@ -3323,7 +3335,11 @@ point_group_name="PG3", crystal_system="TRIGONAL", pdb_name="R 3", - symop_list=[SymOp(Rot_X_Y_Z, Tr_0_0_0), SymOp(Rot_Z_X_Y, Tr_0_0_0), SymOp(Rot_Y_Z_X, Tr_0_0_0)], + symop_list=[ + SymOp(Rot_X_Y_Z, Tr_0_0_0), + SymOp(Rot_Z_X_Y, Tr_0_0_0), + SymOp(Rot_Y_Z_X, Tr_0_0_0), + ], ) sg147 = SpaceGroup( diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index ae0ae05a..27b0d1ad 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -190,7 +190,10 @@ def _wrapParseMethod(self, method, *args, **kwargs): pass if stru is None: emsg = "\n".join( - ["Unknown or invalid structure format.", "Errors per each tested structure format:"] + [ + "Unknown or invalid structure format.", + "Errors per each tested structure format:", + ] + parsers_emsgs ) raise StructureFormatError(emsg) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 3d0611ab..814074f2 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -554,7 +554,10 @@ def _parse_space_group_symop_operation_xyz(self, block): from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, IsSpaceGroupIdentifier, SpaceGroup self.asymmetric_unit = list(self.stru) - sym_synonyms = ("_space_group_symop_operation_xyz", "_symmetry_equiv_pos_as_xyz") + sym_synonyms = ( + "_space_group_symop_operation_xyz", + "_symmetry_equiv_pos_as_xyz", + ) sym_loop_name = [n for n in sym_synonyms if n in block] # recover explicit list of symmetry operations symop_list = [] @@ -592,7 +595,9 @@ def _parse_space_group_symop_operation_xyz(self, block): block.get("_space_group_crystal_system") or block.get("_symmetry_cell_setting") or "TRICLINIC" ).upper() self.spacegroup = SpaceGroup( - short_name=new_short_name, crystal_system=new_crystal_system, symop_list=symop_list + short_name=new_short_name, + crystal_system=new_crystal_system, + symop_list=symop_list, ) if self.spacegroup is None: emsg = "CIF file has unknown space group identifier {!r}." diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index e8220ca7..a87f99d3 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -115,7 +115,10 @@ def parseLines(self, lines): exp_natoms = reduce(lambda x, y: x * y, self.stru.pdffit["ncell"]) # only check if ncell record exists if self.ncell_read and exp_natoms != len(self.stru): - emsg = "Expected %d atoms, read %d." % (exp_natoms, len(self.stru)) + emsg = "Expected %d atoms, read %d." % ( + exp_natoms, + len(self.stru), + ) raise StructureFormatError(emsg) # take care of superlattice if self.stru.pdffit["ncell"][:3] != [1, 1, 1]: @@ -168,7 +171,14 @@ def toLines(self, stru): lines.append("atoms") for a in self.stru: lines.append( - "%-4s %17.8f %17.8f %17.8f %12.4f" % (a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.Bisoequiv) + "%-4s %17.8f %17.8f %17.8f %12.4f" + % ( + a.element.upper(), + a.xyz[0], + a.xyz[1], + a.xyz[2], + a.Bisoequiv, + ) ) return lines @@ -290,7 +300,10 @@ def _parse_not_implemented(self, words): NotImplementedError If the record is not implemented. """ - emsg = "%d: reading of DISCUS record %r is not implemented." % (self.nl, words[0]) + emsg = "%d: reading of DISCUS record %r is not implemented." % ( + self.nl, + words[0], + ) raise NotImplementedError(emsg) diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index a7d2d936..73ea41c1 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -323,7 +323,19 @@ def atomLines(self, stru, idx): isotropic = numpy.all(a.U == a.U[0, 0] * numpy.identity(3)) if not isotropic: mid = " %7i%7i%7i%7i%7i%7i " % tuple( - numpy.around(1e4 * numpy.array([a.U[0, 0], a.U[1, 1], a.U[2, 2], a.U[0, 1], a.U[0, 2], a.U[1, 2]])) + numpy.around( + 1e4 + * numpy.array( + [ + a.U[0, 0], + a.U[1, 1], + a.U[2, 2], + a.U[0, 1], + a.U[0, 2], + a.U[1, 2], + ] + ) + ) ) line = "ANISOU" + atomline[6:27] + mid + atomline[72:80] lines.append(line) @@ -348,7 +360,17 @@ def atomLines(self, stru, idx): if not numpy.all(sigU == sigU[0, 0] * numpy.identity(3)): mid = " %7i%7i%7i%7i%7i%7i " % tuple( numpy.around( - 1e4 * numpy.array([sigU[0, 0], sigU[1, 1], sigU[2, 2], sigU[0, 1], sigU[0, 2], sigU[1, 2]]) + 1e4 + * numpy.array( + [ + sigU[0, 0], + sigU[1, 1], + sigU[2, 2], + sigU[0, 1], + sigU[0, 2], + sigU[1, 2], + ] + ) ) ) line = "SIGUIJ" + atomline[6:27] + mid + atomline[72:80] @@ -381,7 +403,14 @@ def toLines(self, stru): + "%(resSeq)4i" # 23-26 + "%(iCode)c" # 27 + "%(blank)53s" # 28-80 - ) % {"serial": len(stru) + 1, "resName": "", "chainID": " ", "resSeq": 1, "iCode": " ", "blank": " "} + ) % { + "serial": len(stru) + 1, + "resName": "", + "chainID": " ", + "resSeq": 1, + "iCode": " ", + "blank": " ", + } lines.append(line) lines.append("%-80s" % "END") return lines diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index f0c50bd4..ae95d6f5 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -208,7 +208,12 @@ def toLines(self, stru): lines.append("scale %9.6f" % stru_pdffit["scale"]) lines.append( "sharp %9.6f, %9.6f, %9.6f, %9.6f" - % (stru_pdffit["delta2"], stru_pdffit["delta1"], stru_pdffit["sratio"], stru_pdffit["rcut"]) + % ( + stru_pdffit["delta2"], + stru_pdffit["delta1"], + stru_pdffit["sratio"], + stru_pdffit["rcut"], + ) ) lines.append("spcgr " + stru_pdffit["spcgr"]) if stru_pdffit.get("spdiameter", 0.0) > 0.0: @@ -228,7 +233,14 @@ def toLines(self, stru): for a in stru: ad = a.__dict__ lines.append( - "%-4s %17.8f %17.8f %17.8f %12.4f" % (a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.occupancy) + "%-4s %17.8f %17.8f %17.8f %12.4f" + % ( + a.element.upper(), + a.xyz[0], + a.xyz[1], + a.xyz[2], + a.occupancy, + ) ) sigmas = numpy.concatenate((ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)])) lines.append(" %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas)) diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index ea432a6b..4f24c420 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -271,7 +271,12 @@ def parseLines(self, lines): xyz = [xcfg_A * xi for xi in fields[:3]] stru.addNewAtom(p_element, xyz=xyz) a = stru[-1] - _assign_auxiliaries(a, fields, auxiliaries=p_auxiliary, no_velocity=xcfg_NO_VELOCITY) + _assign_auxiliaries( + a, + fields, + auxiliaries=p_auxiliary, + no_velocity=xcfg_NO_VELOCITY, + ) else: emsg = "%d: invalid record" % p_nl raise StructureFormatError(emsg) diff --git a/src/diffpy/structure/spacegroupmod.py b/src/diffpy/structure/spacegroupmod.py index b14d3023..2403d32f 100644 --- a/src/diffpy/structure/spacegroupmod.py +++ b/src/diffpy/structure/spacegroupmod.py @@ -137,9 +137,24 @@ def __init__(self, R, t): def __str__(self): """Printable representation of this SymOp object.""" - x = "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[0, 0], self.R[0, 1], self.R[0, 2], self.t[0]) - x += "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[1, 0], self.R[1, 1], self.R[1, 2], self.t[1]) - x += "[%6.3f %6.3f %6.3f %6.3f]\n" % (self.R[2, 0], self.R[2, 1], self.R[2, 2], self.t[2]) + x = "[%6.3f %6.3f %6.3f %6.3f]\n" % ( + self.R[0, 0], + self.R[0, 1], + self.R[0, 2], + self.t[0], + ) + x += "[%6.3f %6.3f %6.3f %6.3f]\n" % ( + self.R[1, 0], + self.R[1, 1], + self.R[1, 2], + self.t[1], + ) + x += "[%6.3f %6.3f %6.3f %6.3f]\n" % ( + self.R[2, 0], + self.R[2, 1], + self.R[2, 2], + self.t[2], + ) return x def __call__(self, vec): diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 1193b929..012c1677 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -698,7 +698,11 @@ def _set_lattice(self, value): self._lattice = value return - lattice = property(_get_lattice, _set_lattice, doc="Coordinate system for this `Structure`.") + lattice = property( + _get_lattice, + _set_lattice, + doc="Coordinate system for this `Structure`.", + ) # composition @@ -708,7 +712,10 @@ def _get_composition(self): rv[a.element] = rv.get(a.element, 0.0) + a.occupancy return rv - composition = property(_get_composition, doc="Dictionary of chemical symbols and their total occupancies.") + composition = property( + _get_composition, + doc="Dictionary of chemical symbols and their total occupancies.", + ) # linked atom attributes diff --git a/src/diffpy/structure/structure_app.py b/src/diffpy/structure/structure_app.py new file mode 100644 index 00000000..56623a58 --- /dev/null +++ b/src/diffpy/structure/structure_app.py @@ -0,0 +1,33 @@ +import argparse + +from diffpy.structure.version import __version__ # noqa + + +def main(): + parser = argparse.ArgumentParser( + prog="diffpy.structure", + description=( + "Crystal structure container and parsers for structure formats.\n\n" + "For more information, visit: " + "https://github.com/diffpy/diffpy.structure/" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + + parser.add_argument( + "--version", + action="store_true", + help="Show the program's version number and exit", + ) + + args = parser.parse_args() + + if args.version: + print(f"diffpy.structure {__version__}") + else: + # Default behavior when no arguments are given + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 94a08421..d2556661 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -419,10 +419,27 @@ class GeneratorSite(object): """numpy.ndarray: 6x3x3 array of independent components of U matrices.""" - idx2Usymbol = {0: "U11", 1: "U12", 2: "U13", 3: "U12", 4: "U22", 5: "U23", 6: "U13", 7: "U23", 8: "U33"} + idx2Usymbol = { + 0: "U11", + 1: "U12", + 2: "U13", + 3: "U12", + 4: "U22", + 5: "U23", + 6: "U13", + 7: "U23", + 8: "U33", + } """dict: Mapping of index to standard U symbol.""" - def __init__(self, spacegroup, xyz, Uij=numpy.zeros((3, 3)), sgoffset=[0, 0, 0], eps=None): + def __init__( + self, + spacegroup, + xyz, + Uij=numpy.zeros((3, 3)), + sgoffset=[0, 0, 0], + eps=None, + ): if eps is None: eps = epsilon # just declare the members @@ -549,7 +566,14 @@ def _findUSpace(self): n = len(self.invariants) R6zall = numpy.tile(-numpy.identity(6, dtype=float), (n, 1)) R6zall_iter = numpy.split(R6zall, n, axis=0) - i6kl = ((0, (0, 0)), (1, (1, 1)), (2, (2, 2)), (3, (0, 1)), (4, (0, 2)), (5, (1, 2))) + i6kl = ( + (0, (0, 0)), + (1, (1, 1)), + (2, (2, 2)), + (3, (0, 1)), + (4, (0, 2)), + (5, (1, 2)), + ) for op, R6z in zip(self.invariants, R6zall_iter): R = op.R for j, Ucj in enumerate(self.Ucomponents): @@ -640,7 +664,10 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): for i in range(3): if abs(nvec[i]) < epsilon: continue - xyzformula[i] += "%s*%s " % (self.signedRatStr(nvec[i]), name2sym[vname]) + xyzformula[i] += "%s*%s " % ( + self.signedRatStr(nvec[i]), + name2sym[vname], + ) # add constant offset teqpos to all formulas for i in range(3): if xyzformula[i] and abs(teqpos[i]) < epsilon: diff --git a/src/diffpy/structure/version.py b/src/diffpy/structure/version.py index 605c9101..05a8d8ea 100644 --- a/src/diffpy/structure/version.py +++ b/src/diffpy/structure/version.py @@ -1,10 +1,10 @@ #!/usr/bin/env python ############################################################################## # -# (c) 2024-2025 The Trustees of Columbia University in the City of New York. +# (c) 2026 The Trustees of Columbia University in the City of New York. # All rights reserved. # -# File coded by: Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. +# File coded by: Chris Farrow, Pavol Juhas, Simon Billinge, Billinge Group members. # # See GitHub contributions for a more detailed list of contributors. # https://github.com/diffpy/diffpy.structure/graphs/contributors # noqa: E501 @@ -18,8 +18,9 @@ # __all__ = ["__date__", "__git_commit__", "__timestamp__", "__version__"] # obtain version information -from importlib.metadata import version +from importlib.metadata import PackageNotFoundError, version -__version__ = version("diffpy.structure") - -# End of file +try: + __version__ = version("diffpy.structure") +except PackageNotFoundError: + __version__ = "unknown" diff --git a/tests/test_lattice.py b/tests/test_lattice.py index e98ec95c..d9efff6f 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -35,7 +35,12 @@ def setUp(self): def test___init__(self): """Check Lattice.__init__ processing of arguments.""" self.assertRaises(ValueError, Lattice, self.lattice, c=4) - self.assertRaises(ValueError, Lattice, base=self.lattice.base, baserot=self.lattice.baserot) + self.assertRaises( + ValueError, + Lattice, + base=self.lattice.base, + baserot=self.lattice.baserot, + ) self.assertRaises(ValueError, Lattice, 1, 2, 3) self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90) L0 = self.lattice @@ -154,8 +159,16 @@ def test_setLatBase(self): self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) # try base checking - self.assertRaises(LatticeError, self.lattice.setLatBase, [[1, 0, 0], [1, 0, 0], [0, 0, 1]]) - self.assertRaises(LatticeError, self.lattice.setLatBase, [[1, 0, 0], [0, 0, 1], [0, 1, 0]]) + self.assertRaises( + LatticeError, + self.lattice.setLatBase, + [[1, 0, 0], [1, 0, 0], [0, 0, 1]], + ) + self.assertRaises( + LatticeError, + self.lattice.setLatBase, + [[1, 0, 0], [0, 0, 1], [0, 1, 0]], + ) return def test_reciprocal(self): diff --git a/tests/test_p_pdffit.py b/tests/test_p_pdffit.py index 316f8ba2..989dd541 100644 --- a/tests/test_p_pdffit.py +++ b/tests/test_p_pdffit.py @@ -150,8 +150,18 @@ def test_read_pdffit_Ni_prim123(self): def test_read_pdffit_bad(self): """Check exceptions when reading invalid pdffit file.""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, self.datafile("Ni-bad.stru"), self.format) - self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky.xyz"), self.format) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("Ni-bad.stru"), + self.format, + ) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("bucky.xyz"), + self.format, + ) return def test_writeStr_pdffit(self): diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 552154f0..7723a2aa 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -63,10 +63,30 @@ def test_read_xyz(self): def test_read_xyz_bad(self): """Check exceptions when reading invalid xyz file.""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad1.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-bad2.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-plain.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw.xy"), self.format) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("bucky-bad1.xyz"), + self.format, + ) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("bucky-bad2.xyz"), + self.format, + ) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("bucky-plain.xyz"), + self.format, + ) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("hexagon-raw.xy"), + self.format, + ) return def test_writeStr_xyz(self): @@ -126,7 +146,12 @@ def test_read_plainxyz(self): def test_read_plainxyz_bad(self): """Check exceptions when reading invalid plain xyz file.""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, self.datafile("bucky-plain-bad.xyz"), self.format) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("bucky-plain-bad.xyz"), + self.format, + ) return def test_read_rawxyz(self): @@ -144,8 +169,18 @@ def test_read_rawxyz(self): def test_read_rawxyz_bad(self): """Check exceptions when reading unsupported xy file.""" stru = self.stru - self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw-bad.xyz"), self.format) - self.assertRaises(StructureFormatError, stru.read, self.datafile("hexagon-raw.xy"), self.format) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("hexagon-raw-bad.xyz"), + self.format, + ) + self.assertRaises( + StructureFormatError, + stru.read, + self.datafile("hexagon-raw.xy"), + self.format, + ) return def test_writeStr_rawxyz(self): diff --git a/tests/test_spacegroups.py b/tests/test_spacegroups.py index bfd71382..7eb3f97d 100644 --- a/tests/test_spacegroups.py +++ b/tests/test_spacegroups.py @@ -94,23 +94,28 @@ def test__hashSymOpList(self): def test_spacegroup_representation(self): """Verify SpaceGroup.__repr__().""" self.assertEqual( - repr(GetSpaceGroup(1)), "SpaceGroup #1 (P1, Triclinic). Symmetry matrices: 1, point sym. matr.: 1" + repr(GetSpaceGroup(1)), + "SpaceGroup #1 (P1, Triclinic). Symmetry matrices: 1, point sym. matr.: 1", ) self.assertEqual( - repr(GetSpaceGroup(3)), "SpaceGroup #3 (P2, Monoclinic). Symmetry matrices: 2, point sym. matr.: 2" + repr(GetSpaceGroup(3)), + "SpaceGroup #3 (P2, Monoclinic). Symmetry matrices: 2, point sym. matr.: 2", ) self.assertEqual( repr(GetSpaceGroup(16)), ("SpaceGroup #16 (P222, Orthorhombic). Symmetry matrices: 4, point sym. " "matr.: 4"), ) self.assertEqual( - repr(GetSpaceGroup(75)), "SpaceGroup #75 (P4, Tetragonal). Symmetry matrices: 4, point sym. matr.: 4" + repr(GetSpaceGroup(75)), + "SpaceGroup #75 (P4, Tetragonal). Symmetry matrices: 4, point sym. matr.: 4", ) self.assertEqual( - repr(GetSpaceGroup(143)), "SpaceGroup #143 (P3, Trigonal). Symmetry matrices: 3, point sym. matr.: 3" + repr(GetSpaceGroup(143)), + "SpaceGroup #143 (P3, Trigonal). Symmetry matrices: 3, point sym. matr.: 3", ) self.assertEqual( - repr(GetSpaceGroup(168)), "SpaceGroup #168 (P6, Hexagonal). Symmetry matrices: 6, point sym. matr.: 6" + repr(GetSpaceGroup(168)), + "SpaceGroup #168 (P6, Hexagonal). Symmetry matrices: 6, point sym. matr.: 6", ) self.assertEqual( repr(GetSpaceGroup(229)), diff --git a/tests/test_structure.py b/tests/test_structure.py index 65e851c1..65d028c4 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -39,7 +39,10 @@ def prepare_fixture(self, datafile): _loaded_structures = {} def setUp(self): - self.stru = Structure([Atom("C", [0, 0, 0]), Atom("C", [1, 1, 1])], lattice=Lattice(1, 1, 1, 90, 90, 120)) + self.stru = Structure( + [Atom("C", [0, 0, 0]), Atom("C", [1, 1, 1])], + lattice=Lattice(1, 1, 1, 90, 90, 120), + ) # useful variables if not self._loaded_structures: diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 5e733906..5002a293 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -268,14 +268,70 @@ def test_UFormula(self): # Ref: Willis and Pryor, Thermal Vibrations in Crystallography, # Cambridge University Press 1975, p. 104-110 smbl = ("A", "B", "C", "D", "E", "F") - norule = {"U11": "A", "U22": "B", "U33": "C", "U12": "D", "U13": "E", "U23": "F"} - rule05 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "0", "U23": "0"} - rule06 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "E"} - rule07 = {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "-E"} - rule15 = {"U11": "A", "U22": "B", "U33": "C", "U12": "0.5*B", "U13": "0.5*F", "U23": "F"} - rule16 = {"U11": "A", "U22": "A", "U33": "C", "U12": "0.5*A", "U13": "0", "U23": "0"} - rule17 = {"U11": "A", "U22": "A", "U33": "A", "U12": "0", "U13": "0", "U23": "0"} - rule18 = {"U11": "A", "U22": "A", "U33": "A", "U12": "D", "U13": "D", "U23": "D"} + norule = { + "U11": "A", + "U22": "B", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "F", + } + rule05 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "0", + "U23": "0", + } + rule06 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "E", + } + rule07 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "-E", + } + rule15 = { + "U11": "A", + "U22": "B", + "U33": "C", + "U12": "0.5*B", + "U13": "0.5*F", + "U23": "F", + } + rule16 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + "U13": "0", + "U23": "0", + } + rule17 = { + "U11": "A", + "U22": "A", + "U33": "A", + "U12": "0", + "U13": "0", + "U23": "0", + } + rule18 = { + "U11": "A", + "U22": "A", + "U33": "A", + "U12": "D", + "U13": "D", + "U23": "D", + } ufm = self.g117c.UFormula(self.g117c.xyz, smbl) self.assertEqual(rule05, ufm) ufm = self.g117h.UFormula(self.g117h.xyz, smbl) @@ -318,12 +374,54 @@ def test_UFormula_g186c_eqxyz(self): in 186.""" sg186 = GetSpaceGroup(186) crules = [ - {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "E", "U23": "-E"}, - {"U11": "A", "U22": "2*A-2*D", "U33": "C", "U12": "A-D", "U13": "E", "U23": "2*E"}, - {"U11": "2*A-2*D", "U22": "A", "U33": "C", "U12": "A-D", "U13": "-2*E", "U23": "-E"}, - {"U11": "A", "U22": "A", "U33": "C", "U12": "D", "U13": "-E", "U23": "E"}, - {"U11": "A", "U22": "2*A-2*D", "U33": "C", "U12": "A-D", "U13": "-E", "U23": "-2*E"}, - {"U11": "2*A-2*D", "U22": "A", "U33": "C", "U12": "A-D", "U13": "2*E", "U23": "E"}, + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "-E", + }, + { + "U11": "A", + "U22": "2*A-2*D", + "U33": "C", + "U12": "A-D", + "U13": "E", + "U23": "2*E", + }, + { + "U11": "2*A-2*D", + "U22": "A", + "U33": "C", + "U12": "A-D", + "U13": "-2*E", + "U23": "-E", + }, + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "-E", + "U23": "E", + }, + { + "U11": "A", + "U22": "2*A-2*D", + "U33": "C", + "U12": "A-D", + "U13": "-E", + "U23": "-2*E", + }, + { + "U11": "2*A-2*D", + "U22": "A", + "U33": "C", + "U12": "A-D", + "U13": "2*E", + "U23": "E", + }, ] self.assertEqual(6, len(self.g186c.eqxyz)) gc = self.g186c @@ -340,7 +438,14 @@ def test_UFormula_g186c_eqxyz(self): self.assertEqual(2.0, upd["U330"]) self.assertEqual(1.0, upd["U120"]) self.assertEqual(0.0, upd["U130"]) - uisod = {"U11": 2.0, "U22": 2.0, "U33": 2.0, "U12": 1.0, "U13": 0.0, "U23": 0.0} + uisod = { + "U11": 2.0, + "U22": 2.0, + "U33": 2.0, + "U12": 1.0, + "U13": 0.0, + "U23": 0.0, + } for ufms in symcon.UFormulas(): for n, fm in ufms.items(): self.assertEqual(uisod[n], eval(fm, upd)) From 64d4e59fa43444c18e4b1f7ee2dc4293d7481d84 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 17 Feb 2026 13:58:12 -0500 Subject: [PATCH 138/226] fix: add news item --- news/skpkg-update.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/skpkg-update.rst diff --git a/news/skpkg-update.rst b/news/skpkg-update.rst new file mode 100644 index 00000000..a037a121 --- /dev/null +++ b/news/skpkg-update.rst @@ -0,0 +1,23 @@ +**Added:** + +* Support for Python 3.14 + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* Support for Python 3.11 + +**Fixed:** + +* + +**Security:** + +* From 50380f50fee6ff633b043e180745a3f51d0b426a Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 17 Feb 2026 14:53:11 -0500 Subject: [PATCH 139/226] fix: fix deprecation warning --- news/fix-deprecation.rst | 23 +++++++++++++++++++++++ src/diffpy/structure/structure.py | 3 +-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 news/fix-deprecation.rst diff --git a/news/fix-deprecation.rst b/news/fix-deprecation.rst new file mode 100644 index 00000000..5be83709 --- /dev/null +++ b/news/fix-deprecation.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Fix deprecation for open file for Python 3.14 + +**Security:** + +* diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 012c1677..3c7b725f 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -14,7 +14,6 @@ ############################################################################## """This module defines class `Structure`.""" -import codecs import copy as copymod import numpy @@ -347,7 +346,7 @@ def write(self, filename, format): p = getParser(format) p.filename = filename s = p.tostring(self) - with codecs.open(filename, "w", encoding="UTF-8") as fp: + with open(filename, "w", encoding="utf-8", newline="") as fp: fp.write(s) return From 9ed7fc60db364ce5eca97767551d92fdec264907 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 13:47:06 -0500 Subject: [PATCH 140/226] build: deprecate addNewItem --- news/deprecate-addNewItem.rst | 23 +++++++++++++++++++++++ requirements/conda.txt | 1 + requirements/pip.txt | 1 + src/diffpy/structure/parsers/p_cif.py | 2 +- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 2 +- src/diffpy/structure/parsers/p_pdffit.py | 2 +- src/diffpy/structure/parsers/p_rawxyz.py | 2 +- src/diffpy/structure/parsers/p_xcfg.py | 2 +- src/diffpy/structure/parsers/p_xyz.py | 2 +- src/diffpy/structure/structure.py | 22 ++++++++++++++++++++++ 11 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 news/deprecate-addNewItem.rst diff --git a/news/deprecate-addNewItem.rst b/news/deprecate-addNewItem.rst new file mode 100644 index 00000000..7aeb4b68 --- /dev/null +++ b/news/deprecate-addNewItem.rst @@ -0,0 +1,23 @@ +**Added:** + +* No News Added: deprecate CamelCase function for addNewItem + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/requirements/conda.txt b/requirements/conda.txt index 0fdcecb6..4c4ff50e 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,2 +1,3 @@ numpy pycifrw +diffpy.utils diff --git a/requirements/pip.txt b/requirements/pip.txt index 0fdcecb6..4c4ff50e 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,2 +1,3 @@ numpy pycifrw +diffpy.utils diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 814074f2..b542e69e 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -497,7 +497,7 @@ def _parse_atom_site_label(self, block): if curlabel == "?": continue self.labelindex[curlabel] = len(self.stru) - self.stru.addNewAtom() + self.stru.add_new_atom() a = self.stru.getLastAtom() for fset, val in zip(prop_setters, values): fset(a, val) diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index a87f99d3..665c096f 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -264,7 +264,7 @@ def _parse_atom(self, words): element = words[0][0:1].upper() + words[0][1:].lower() xyz = [float(w) for w in words[1:4]] Biso = float(words[4]) - self.stru.addNewAtom(element, xyz) + self.stru.add_new_atom(element, xyz) a = self.stru.getLastAtom() a.Bisoequiv = Biso return diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 73ea41c1..9f2ecc47 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -197,7 +197,7 @@ def parseLines(self, lines): # get element from the first 2 characters of name element = line[12:14].strip() element = element[0].upper() + element[1:].lower() - stru.addNewAtom(element, occupancy=occupancy, label=name) + stru.add_new_atom(element, occupancy=occupancy, label=name) last_atom = stru.getLastAtom() last_atom.xyz_cartn = rc last_atom.Uisoequiv = uiso diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index ae95d6f5..84b55fce 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -132,7 +132,7 @@ def parseLines(self, lines): element = wl1[0][0].upper() + wl1[0][1:].lower() xyz = [float(w) for w in wl1[1:4]] occ = float(wl1[4]) - stru.addNewAtom(element, xyz=xyz, occupancy=occ) + stru.add_new_atom(element, xyz=xyz, occupancy=occ) a = stru.getLastAtom() p_nl += 1 wl2 = next(ilines).split() diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index 24ad293b..ab28ec41 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -103,7 +103,7 @@ def parseLines(self, lines): xyz = [float(f) for f in fields[x_idx : x_idx + 3]] if len(xyz) == 2: xyz.append(0.0) - stru.addNewAtom(element, xyz=xyz) + stru.add_new_atom(element, xyz=xyz) except ValueError: emsg = "%d: invalid number" % p_nl exc_type, exc_value, exc_traceback = sys.exc_info() diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 4f24c420..08c108a9 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -269,7 +269,7 @@ def parseLines(self, lines): elif len(words) == xcfg_entry_count and p_element is not None: fields = [float(w) for w in words] xyz = [xcfg_A * xi for xi in fields[:3]] - stru.addNewAtom(p_element, xyz=xyz) + stru.add_new_atom(p_element, xyz=xyz) a = stru[-1] _assign_auxiliaries( a, diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index 5c08f99b..a91c431f 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -109,7 +109,7 @@ def parseLines(self, lines): element = fields[0] element = element[0].upper() + element[1:].lower() xyz = [float(f) for f in fields[1:4]] - stru.addNewAtom(element, xyz=xyz) + stru.add_new_atom(element, xyz=xyz) except ValueError: exc_type, exc_value, exc_traceback = sys.exc_info() emsg = "%d: invalid number format" % p_nl diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 3c7b725f..930b5149 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -21,9 +21,19 @@ from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice from diffpy.structure.utils import _linkAtomAttribute, atomBareSymbol, isiterable +from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- +base = "diffpy.structure.Structure" +removal_version = "4.0.0" +addNewAtom_deprecation_msg = build_deprecation_message( + base, + "addNewAtom", + "add_new_atom", + removal_version, +) + class Structure(list): """Define group of atoms in a specified lattice. Structure --> group @@ -145,7 +155,19 @@ def __str__(self): s_atoms = "\n".join([str(a) for a in self]) return s_lattice + "\n" + s_atoms + @deprecated(addNewAtom_deprecation_msg) def addNewAtom(self, *args, **kwargs): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.add_new_atom instead. + """ + kwargs["lattice"] = self.lattice + a = Atom(*args, **kwargs) + self.append(a, copy=False) + return + + def add_new_atom(self, *args, **kwargs): """Add new `Atom` instance to the end of this `Structure`. Parameters From 6e990822ff4f8fa73f09f8ec469c58cceedbf4d3 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 16:13:46 -0500 Subject: [PATCH 141/226] build: change body of deprecated function --- src/diffpy/structure/structure.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 930b5149..865e1862 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -162,9 +162,7 @@ def addNewAtom(self, *args, **kwargs): Please use diffpy.structure.Structure.add_new_atom instead. """ - kwargs["lattice"] = self.lattice - a = Atom(*args, **kwargs) - self.append(a, copy=False) + self.add_new_atom(*args, **kwargs) return def add_new_atom(self, *args, **kwargs): From 95138f709ee3d79f56d5f14cc0b0f9af20cd175d Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 16:52:24 -0500 Subject: [PATCH 142/226] build: add test cases for addNewAtom to test it & show deprecation message. --- tests/test_structure.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_structure.py b/tests/test_structure.py index 65d028c4..d772c5d1 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -120,6 +120,38 @@ def test___copy__(self): # """check Structure.getLastAtom()""" # return + def test_add_new_atom(self): + s_lat = Lattice() + other_lat = Lattice() + expected = Structure(lattice=s_lat) + + length = len(expected) + expected.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) + actual = length + 1 + assert len(expected) == actual + + object = expected[-1] + if hasattr(object, "element"): + assert object.element == "C" + if hasattr(object, "xyz"): + assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + + def test_addNewAtom(self): + s_lat = Lattice() + other_lat = Lattice() + expected = Structure(lattice=s_lat) + + length = len(expected) + expected.addNewAtom(atype="C", xyz=[0.1, 0.2, 0.3]) + actual = length + 1 + assert len(expected) == actual + + object = expected[-1] + if hasattr(object, "element"): + assert object.element == "C" + if hasattr(object, "xyz"): + assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + def test_assignUniqueLabels(self): """Check Structure.assignUniqueLabels()""" self.assertEqual("", "".join([a.label for a in self.stru])) From 3f285b6ef555f504ae487972a54361e67bdcfe96 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 17:00:11 -0500 Subject: [PATCH 143/226] fix: refine test code to avoid if logic --- tests/test_structure.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index d772c5d1..28a3fb25 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -122,7 +122,6 @@ def test___copy__(self): def test_add_new_atom(self): s_lat = Lattice() - other_lat = Lattice() expected = Structure(lattice=s_lat) length = len(expected) @@ -131,26 +130,20 @@ def test_add_new_atom(self): assert len(expected) == actual object = expected[-1] - if hasattr(object, "element"): - assert object.element == "C" - if hasattr(object, "xyz"): - assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + assert object.element == "C" + assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) def test_addNewAtom(self): s_lat = Lattice() - other_lat = Lattice() expected = Structure(lattice=s_lat) length = len(expected) expected.addNewAtom(atype="C", xyz=[0.1, 0.2, 0.3]) actual = length + 1 assert len(expected) == actual - object = expected[-1] - if hasattr(object, "element"): - assert object.element == "C" - if hasattr(object, "xyz"): - assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + assert object.element == "C" + assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) def test_assignUniqueLabels(self): """Check Structure.assignUniqueLabels()""" From 1fc8a341d8a052197a207ef65f66c72d63c15eef Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 17:34:25 -0500 Subject: [PATCH 144/226] test: add docstring and comments to the test. --- tests/test_structure.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 28a3fb25..5cc880d7 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -121,29 +121,39 @@ def test___copy__(self): # return def test_add_new_atom(self): + """Check Structure.add_new_item()""" + # Case: We initialize a Structure object, after calling + # add_new_item method, we check whether length of Structure + # object is added by 1. Moreover, we check added Atom's attributes + # are properly loaded into Structure object. s_lat = Lattice() - expected = Structure(lattice=s_lat) + structure = Structure(lattice=s_lat) - length = len(expected) - expected.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) + length = len(structure) + structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) + expected = len(structure) # length of structure should add by 1 actual = length + 1 - assert len(expected) == actual - - object = expected[-1] - assert object.element == "C" - assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + assert expected == actual + atom_object = structure[-1] + assert atom_object.element == "C" + assert numpy.allclose(atom_object.xyz, [0.1, 0.2, 0.3]) def test_addNewAtom(self): + """Duplicate test for the deprecated addNewAtom method. + + Remove this test in version 4.0.0 + """ s_lat = Lattice() - expected = Structure(lattice=s_lat) + structure = Structure(lattice=s_lat) - length = len(expected) - expected.addNewAtom(atype="C", xyz=[0.1, 0.2, 0.3]) + length = len(structure) + structure.addNewAtom(atype="C", xyz=[0.1, 0.2, 0.3]) + expected = len(structure) actual = length + 1 - assert len(expected) == actual - object = expected[-1] - assert object.element == "C" - assert numpy.allclose(object.xyz, [0.1, 0.2, 0.3]) + assert expected == actual + atom_object = structure[-1] + assert atom_object.element == "C" + assert numpy.allclose(atom_object.xyz, [0.1, 0.2, 0.3]) def test_assignUniqueLabels(self): """Check Structure.assignUniqueLabels()""" From 8b5c62d5789d04cc1d87da9b7d8bffbdef46dd42 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 18:36:37 -0500 Subject: [PATCH 145/226] build: deprecate assignUniqueLabels --- news/deprecate-assignUniqueLabels.rst | 23 +++++++++++++++++++++++ src/diffpy/structure/structure.py | 20 +++++++++++++++++++- tests/test_structure.py | 20 +++++++++++++++----- 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 news/deprecate-assignUniqueLabels.rst diff --git a/news/deprecate-assignUniqueLabels.rst b/news/deprecate-assignUniqueLabels.rst new file mode 100644 index 00000000..669337a6 --- /dev/null +++ b/news/deprecate-assignUniqueLabels.rst @@ -0,0 +1,23 @@ +**Added:** + +* No News Added: deprecate assignUniqueLabels method + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 3c7b725f..e0ea8e07 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -21,9 +21,18 @@ from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice from diffpy.structure.utils import _linkAtomAttribute, atomBareSymbol, isiterable +from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- +base = "diffpy.structure.Structure" +removal_version = "4.0.0" +assignUniqueLabels_deprecation_msg = build_deprecation_message( + base, + "assignUniqueLabels", + "assign_unique_labels", + removal_version, +) class Structure(list): """Define group of atoms in a specified lattice. Structure --> group @@ -163,7 +172,7 @@ def getLastAtom(self): last_atom = self[-1] return last_atom - def assignUniqueLabels(self): + def assign_unique_labels(self): """Set a unique label string for each `Atom` in this structure. The label strings are formatted as "%(baresymbol)s%(index)i", @@ -181,6 +190,15 @@ def assignUniqueLabels(self): islabeled.add(a) return + @deprecated(assignUniqueLabels_deprecation_msg) + def assignUniqueLabels(self): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.assign_unique_labels instead. + """ + return self.assign_unique_labels() + def distance(self, aid0, aid1): """Calculate distance between 2 `Atoms`, no periodic boundary conditions. diff --git a/tests/test_structure.py b/tests/test_structure.py index 65d028c4..6e102a83 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -121,18 +121,28 @@ def test___copy__(self): # return def test_assignUniqueLabels(self): - """Check Structure.assignUniqueLabels()""" + """Duplicate test with the deprecated assignUniqueLabels method. + + Remove this test in version 4.0.0""" self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assignUniqueLabels() self.assertEqual("C1", self.stru[0].label) self.assertEqual("C2", self.stru[1].label) return + def test_assign_unique_labels(self): + """Check Structure.assignUniqueLabels()""" + self.assertEqual("", "".join([a.label for a in self.stru])) + self.stru.assign_unique_labels() + self.assertEqual("C1", self.stru[0].label) + self.assertEqual("C2", self.stru[1].label) + return + def test_distance(self): """Check Structure.distance()""" from math import sqrt - self.stru.assignUniqueLabels() + self.stru.assign_unique_labels() self.assertRaises(IndexError, self.stru.distance, 333, "C1") self.assertRaises(IndexError, self.stru.distance, "C", "C1") self.assertAlmostEqual(sqrt(2.0), self.stru.distance(0, 1), self.places) @@ -143,7 +153,7 @@ def test_distance(self): def test_angle(self): """Check Structure.angle()""" cdse = Structure(filename=self.cdsefile) - cdse.assignUniqueLabels() + cdse.assign_unique_labels() self.assertEqual(109, round(cdse.angle(0, 2, 1))) self.assertEqual(109, round(cdse.angle("Cd1", "Se1", "Cd2"))) return @@ -236,7 +246,7 @@ def test___getitem__(self): cdse013.pop(2) self.assertEqual(cdse013, cdse[:2, 3].tolist()) self.assertRaises(IndexError, cdse.__getitem__, "Cd1") - cdse.assignUniqueLabels() + cdse.assign_unique_labels() self.assertTrue(cdse[0] is cdse["Cd1"]) cdse[0].label = "Hohenzollern" self.assertRaises(IndexError, cdse.__getitem__, "Cd1") @@ -466,7 +476,7 @@ def test_label(self): """Check Structure.label.""" cdse = Structure(filename=self.cdsefile) self.assertEqual(4 * [""], cdse.label.tolist()) - cdse.assignUniqueLabels() + cdse.assign_unique_labels() self.assertEqual("Cd1 Cd2 Se1 Se2".split(), cdse.label.tolist()) cdse.label = cdse.label.lower() self.assertEqual("cd1 cd2 se1 se2".split(), cdse.label.tolist()) From b692fb614cbc2936c3249729cdb943e558c5e2d8 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 18:38:19 -0500 Subject: [PATCH 146/226] build: add requirement for diffpy.utils --- requirements/conda.txt | 1 + requirements/pip.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements/conda.txt b/requirements/conda.txt index 0fdcecb6..825c92f2 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,2 +1,3 @@ numpy pycifrw +diffpy.utils \ No newline at end of file diff --git a/requirements/pip.txt b/requirements/pip.txt index 0fdcecb6..825c92f2 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,2 +1,3 @@ numpy pycifrw +diffpy.utils \ No newline at end of file From e9c39fec7e084142aea51e60181eed4930885287 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 23:39:52 +0000 Subject: [PATCH 147/226] [pre-commit.ci] auto fixes from pre-commit hooks --- requirements/conda.txt | 2 +- requirements/pip.txt | 2 +- src/diffpy/structure/structure.py | 4 +++- tests/test_structure.py | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index 825c92f2..4c4ff50e 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,3 +1,3 @@ numpy pycifrw -diffpy.utils \ No newline at end of file +diffpy.utils diff --git a/requirements/pip.txt b/requirements/pip.txt index 825c92f2..4c4ff50e 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,3 +1,3 @@ numpy pycifrw -diffpy.utils \ No newline at end of file +diffpy.utils diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index e0ea8e07..ccba4044 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -34,6 +34,7 @@ removal_version, ) + class Structure(list): """Define group of atoms in a specified lattice. Structure --> group of atoms. @@ -195,7 +196,8 @@ def assignUniqueLabels(self): """This function has been deprecated and will be removed in version 4.0.0. - Please use diffpy.structure.Structure.assign_unique_labels instead. + Please use diffpy.structure.Structure.assign_unique_labels + instead. """ return self.assign_unique_labels() diff --git a/tests/test_structure.py b/tests/test_structure.py index 6e102a83..82d1fe5a 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -123,7 +123,8 @@ def test___copy__(self): def test_assignUniqueLabels(self): """Duplicate test with the deprecated assignUniqueLabels method. - Remove this test in version 4.0.0""" + Remove this test in version 4.0.0 + """ self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assignUniqueLabels() self.assertEqual("C1", self.stru[0].label) From 2a1f30eb0f5b77ca32fd3ac66e63565f21f7a9b1 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 20:21:13 -0500 Subject: [PATCH 148/226] fix: change news item and test docstring. --- news/deprecate-assignUniqueLabels.rst | 4 ++-- tests/test_structure.py | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/news/deprecate-assignUniqueLabels.rst b/news/deprecate-assignUniqueLabels.rst index 669337a6..cf07ff63 100644 --- a/news/deprecate-assignUniqueLabels.rst +++ b/news/deprecate-assignUniqueLabels.rst @@ -1,6 +1,6 @@ **Added:** -* No News Added: deprecate assignUniqueLabels method +* Added `diffpy.structure.Structure.assign_unique_labels` in replace of `assignUniqueLabels` **Changed:** @@ -8,7 +8,7 @@ **Deprecated:** -* +* Deprecated `diffpy.structure.Structure.assignUniqueLabels` for removal in 4.0.0 **Removed:** diff --git a/tests/test_structure.py b/tests/test_structure.py index 82d1fe5a..818cc265 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -121,10 +121,7 @@ def test___copy__(self): # return def test_assignUniqueLabels(self): - """Duplicate test with the deprecated assignUniqueLabels method. - - Remove this test in version 4.0.0 - """ + """Check Structure.assignUniqueLabels()""" self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assignUniqueLabels() self.assertEqual("C1", self.stru[0].label) @@ -132,7 +129,7 @@ def test_assignUniqueLabels(self): return def test_assign_unique_labels(self): - """Check Structure.assignUniqueLabels()""" + """Check Structure.assign_unique_labels()""" self.assertEqual("", "".join([a.label for a in self.stru])) self.stru.assign_unique_labels() self.assertEqual("C1", self.stru[0].label) From cb7aec062df2ae420ea77d84aa92b28b1f850504 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 21:35:32 -0500 Subject: [PATCH 149/226] fix: add more test cases and refine behavior of add_new_atom --- news/deprecate-addNewItem.rst | 4 ++-- src/diffpy/structure/structure.py | 15 +++++++++------ tests/test_structure.py | 30 ++++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/news/deprecate-addNewItem.rst b/news/deprecate-addNewItem.rst index 7aeb4b68..922d41c9 100644 --- a/news/deprecate-addNewItem.rst +++ b/news/deprecate-addNewItem.rst @@ -1,6 +1,6 @@ **Added:** -* No News Added: deprecate CamelCase function for addNewItem +* Added `diffpy.structure.Structure.add_new_atom` in replace of `addNewAtom` **Changed:** @@ -8,7 +8,7 @@ **Deprecated:** -* +* Deprecated `diffpy.structure.Structure.addNewAtom` method for removal in version 4.0.0 **Removed:** diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 865e1862..9719fe03 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -168,14 +168,17 @@ def addNewAtom(self, *args, **kwargs): def add_new_atom(self, *args, **kwargs): """Add new `Atom` instance to the end of this `Structure`. - Parameters - ---------- - *args, **kwargs : - See `Atom` class constructor. + Raises + ------ + ValueError + If an atom with the same element/type and coordinates already exists. """ kwargs["lattice"] = self.lattice - a = Atom(*args, **kwargs) - self.append(a, copy=False) + atom = Atom(*args, **kwargs) + for existing in self: + if existing.element == atom.element and numpy.allclose(existing.xyz, atom.xyz): + raise ValueError(f"Duplicate atom {atom.element} already exists at {atom.xyz!r}") + self.append(atom, copy=False) return def getLastAtom(self): diff --git a/tests/test_structure.py b/tests/test_structure.py index 5cc880d7..9cac4b92 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -122,22 +122,40 @@ def test___copy__(self): def test_add_new_atom(self): """Check Structure.add_new_item()""" - # Case: We initialize a Structure object, after calling - # add_new_item method, we check whether length of Structure - # object is added by 1. Moreover, we check added Atom's attributes - # are properly loaded into Structure object. + # Case 1: valid atom added to an empty structure. + # Expect the atom list length to go from 0 to 1. + # Expect the atom attributes are successfully loaded. s_lat = Lattice() structure = Structure(lattice=s_lat) - length = len(structure) structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) - expected = len(structure) # length of structure should add by 1 + expected = len(structure) actual = length + 1 assert expected == actual atom_object = structure[-1] assert atom_object.element == "C" assert numpy.allclose(atom_object.xyz, [0.1, 0.2, 0.3]) + # Case 2: valid atom added to existing atom list. + # Expect the atom list length to go from 1 to 2. + # Expect the atom attributes are successfully loaded. + length = len(structure) + structure.add_new_atom(atype="Ni", xyz=[0.8, 1.2, 0.9]) + expected = len(structure) + actual = length + 1 + assert expected == actual + atom_object = structure[-1] + assert atom_object.element == "Ni" + assert numpy.allclose(atom_object.xyz, [0.8, 1.2, 0.9]) + + # Case 3: duplicated atom added to the existing atom list. + # Expect the atom not to be added and gives an ValueError. + with pytest.raises(ValueError, match=r"Duplicate atom C already exists at array\(\[0\.1, 0\.2, 0\.3\]\)"): + structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) + actual = len(structure) + expected = 2 + assert expected == actual + def test_addNewAtom(self): """Duplicate test for the deprecated addNewAtom method. From 114f3d62a7a38cc7590067325d1669191ec1fe86 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 21:42:39 -0500 Subject: [PATCH 150/226] fix: add docstring for hyperparamter for add_new_atom --- src/diffpy/structure/structure.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 9719fe03..6caa33ac 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -168,6 +168,11 @@ def addNewAtom(self, *args, **kwargs): def add_new_atom(self, *args, **kwargs): """Add new `Atom` instance to the end of this `Structure`. + Parameters + ---------- + *args, **kwargs : + See `Atom` class constructor. + Raises ------ ValueError From 40e877366412867fa9c35c19a817813dfa0ee49a Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 21:46:01 -0500 Subject: [PATCH 151/226] fix: fix comment with syntax error --- tests/test_structure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 9cac4b92..0aae764b 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -149,7 +149,7 @@ def test_add_new_atom(self): assert numpy.allclose(atom_object.xyz, [0.8, 1.2, 0.9]) # Case 3: duplicated atom added to the existing atom list. - # Expect the atom not to be added and gives an ValueError. + # Expect the atom not to be added and gives a ValueError. with pytest.raises(ValueError, match=r"Duplicate atom C already exists at array\(\[0\.1, 0\.2, 0\.3\]\)"): structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) actual = len(structure) From 8f8253c3a356a160c13e0e02c69aef20c33c5f51 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 23:49:16 -0500 Subject: [PATCH 152/226] fix: change behavior to warning and use pytest parametrize to test it. --- src/diffpy/structure/structure.py | 10 +++- tests/test_structure.py | 84 ++++++++++++++++++------------- 2 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 6caa33ac..6b3a9cad 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -17,6 +17,7 @@ import copy as copymod import numpy +import warnings from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice @@ -175,14 +176,19 @@ def add_new_atom(self, *args, **kwargs): Raises ------ - ValueError + UserWarning If an atom with the same element/type and coordinates already exists. """ kwargs["lattice"] = self.lattice atom = Atom(*args, **kwargs) for existing in self: if existing.element == atom.element and numpy.allclose(existing.xyz, atom.xyz): - raise ValueError(f"Duplicate atom {atom.element} already exists at {atom.xyz!r}") + warnings.warn( + f"Duplicate atom {atom.element} already exists at {atom.xyz!r}", + category=UserWarning, + stacklevel=2, + ) + break self.append(atom, copy=False) return diff --git a/tests/test_structure.py b/tests/test_structure.py index 0aae764b..3f9b2864 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -120,41 +120,7 @@ def test___copy__(self): # """check Structure.getLastAtom()""" # return - def test_add_new_atom(self): - """Check Structure.add_new_item()""" - # Case 1: valid atom added to an empty structure. - # Expect the atom list length to go from 0 to 1. - # Expect the atom attributes are successfully loaded. - s_lat = Lattice() - structure = Structure(lattice=s_lat) - length = len(structure) - structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) - expected = len(structure) - actual = length + 1 - assert expected == actual - atom_object = structure[-1] - assert atom_object.element == "C" - assert numpy.allclose(atom_object.xyz, [0.1, 0.2, 0.3]) - # Case 2: valid atom added to existing atom list. - # Expect the atom list length to go from 1 to 2. - # Expect the atom attributes are successfully loaded. - length = len(structure) - structure.add_new_atom(atype="Ni", xyz=[0.8, 1.2, 0.9]) - expected = len(structure) - actual = length + 1 - assert expected == actual - atom_object = structure[-1] - assert atom_object.element == "Ni" - assert numpy.allclose(atom_object.xyz, [0.8, 1.2, 0.9]) - - # Case 3: duplicated atom added to the existing atom list. - # Expect the atom not to be added and gives a ValueError. - with pytest.raises(ValueError, match=r"Duplicate atom C already exists at array\(\[0\.1, 0\.2, 0\.3\]\)"): - structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) - actual = len(structure) - expected = 2 - assert expected == actual def test_addNewAtom(self): """Duplicate test for the deprecated addNewAtom method. @@ -655,6 +621,56 @@ def test_pickling(self): # End of class TestStructure # ---------------------------------------------------------------------------- +@pytest.mark.parametrize( + "existing, atype, xyz, expected_len, expected_element, expected_xyz", + [ + # Case 1: valid atom added to an empty structure. + # Expect the atom list length to go from 0 to 1. + # Expect the atom attributes are successfully loaded. + ( + None, + "C", + [0.1, 0.2, 0.3], + 1, + "C", + [0.1, 0.2, 0.3], + ), + # Case 2: valid atom added to existing atom list. + # Expect the atom list length to go from 1 to 2. + # Expect the atom attributes are successfully loaded. + ( + [Atom("C", [0, 0, 0])], + "Ni", + [0.8, 1.2, 0.9], + 2, + "Ni", + [0.8, 1.2, 0.9], + ), + ], +) +def test_add_new_atom(existing, atype, xyz, expected_len, expected_element, expected_xyz): + """Check Structure.add_new_item()""" + structure = Structure(existing, lattice=Lattice()) + structure.add_new_atom(atype=atype, xyz=xyz) + actual_length = len(structure) + assert expected_len == actual_length + atom_object = structure[-1] + assert atom_object.element == expected_element + assert numpy.allclose(atom_object.xyz, expected_xyz) + + +def test_add_new_atom_duplicate(): + # Case 3: duplicated atom added to the existing atom list. + # Expect the atom not to be added and gives a ValueError. + structure = Structure( + [Atom("C", [0.1, 0.2, 0.3]), Atom("Ni", [0.8, 1.2, 0.9])], + lattice=Lattice(), + ) + with pytest.warns(UserWarning): + structure.add_new_atom(atype="C", xyz=[0.1, 0.2, 0.3]) + assert len(structure) == 3 + assert structure[-1].element == "C" + assert numpy.allclose(structure[-1].xyz, [0.1, 0.2, 0.3]) if __name__ == "__main__": unittest.main() From 15ccba1545c6fe077389fcab68fd632182ab48d3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 04:49:45 +0000 Subject: [PATCH 153/226] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/structure/structure.py | 2 +- tests/test_structure.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 6b3a9cad..9e84bc83 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -15,9 +15,9 @@ """This module defines class `Structure`.""" import copy as copymod +import warnings import numpy -import warnings from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice diff --git a/tests/test_structure.py b/tests/test_structure.py index 3f9b2864..358c58dd 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -120,8 +120,6 @@ def test___copy__(self): # """check Structure.getLastAtom()""" # return - - def test_addNewAtom(self): """Duplicate test for the deprecated addNewAtom method. @@ -620,6 +618,7 @@ def test_pickling(self): # End of class TestStructure + # ---------------------------------------------------------------------------- @pytest.mark.parametrize( "existing, atype, xyz, expected_len, expected_element, expected_xyz", @@ -672,5 +671,6 @@ def test_add_new_atom_duplicate(): assert structure[-1].element == "C" assert numpy.allclose(structure[-1].xyz, [0.1, 0.2, 0.3]) + if __name__ == "__main__": unittest.main() From 52c99e64f965f9d608f6345b32e04397a96f0278 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 19 Feb 2026 23:53:16 -0500 Subject: [PATCH 154/226] fix: fix comment for UserWarning. --- tests/test_structure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 358c58dd..648f684b 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -660,7 +660,7 @@ def test_add_new_atom(existing, atype, xyz, expected_len, expected_element, expe def test_add_new_atom_duplicate(): # Case 3: duplicated atom added to the existing atom list. - # Expect the atom not to be added and gives a ValueError. + # Expect the atom to be added and gives a UserWarning. structure = Structure( [Atom("C", [0.1, 0.2, 0.3]), Atom("Ni", [0.8, 1.2, 0.9])], lattice=Lattice(), From 793f5b08666f1d32fc37b459a4aebb62c196f919 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 20 Feb 2026 00:14:29 -0500 Subject: [PATCH 155/226] build: deprecate getLastAtom and add a test --- news/deprecate-getLastAtom.rst | 23 +++++++++++++++++++++++ src/diffpy/structure/parsers/p_cif.py | 2 +- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 2 +- src/diffpy/structure/parsers/p_pdffit.py | 2 +- src/diffpy/structure/structure.py | 15 +++++++++++++++ tests/test_structure.py | 17 +++++++++++++++++ 7 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 news/deprecate-getLastAtom.rst diff --git a/news/deprecate-getLastAtom.rst b/news/deprecate-getLastAtom.rst new file mode 100644 index 00000000..9f2824ad --- /dev/null +++ b/news/deprecate-getLastAtom.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added `diffpy.structure.Structure.get_last_atom` in replace of `getLastAtom` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated `diffpy.structure.Structure.getLastAtom` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index b542e69e..e8029cde 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -498,7 +498,7 @@ def _parse_atom_site_label(self, block): continue self.labelindex[curlabel] = len(self.stru) self.stru.add_new_atom() - a = self.stru.getLastAtom() + a = self.stru.get_last_atom() for fset, val in zip(prop_setters, values): fset(a, val) if does_adp_type: diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 665c096f..35b868e2 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -265,7 +265,7 @@ def _parse_atom(self, words): xyz = [float(w) for w in words[1:4]] Biso = float(words[4]) self.stru.add_new_atom(element, xyz) - a = self.stru.getLastAtom() + a = self.stru.get_last_atom() a.Bisoequiv = Biso return diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 9f2ecc47..8694dba1 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -198,7 +198,7 @@ def parseLines(self, lines): element = line[12:14].strip() element = element[0].upper() + element[1:].lower() stru.add_new_atom(element, occupancy=occupancy, label=name) - last_atom = stru.getLastAtom() + last_atom = stru.get_last_atom() last_atom.xyz_cartn = rc last_atom.Uisoequiv = uiso elif record == "SIGATM": diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 84b55fce..93646aca 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -133,7 +133,7 @@ def parseLines(self, lines): xyz = [float(w) for w in wl1[1:4]] occ = float(wl1[4]) stru.add_new_atom(element, xyz=xyz, occupancy=occ) - a = stru.getLastAtom() + a = stru.get_last_atom() p_nl += 1 wl2 = next(ilines).split() a.sigxyz = [float(w) for w in wl2[0:3]] diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 9e84bc83..784a11aa 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -34,6 +34,12 @@ "add_new_atom", removal_version, ) +getLastAtom_deprecation_msg = build_deprecation_message( + base, + "getLastAtom", + "get_last_atom", + removal_version, +) class Structure(list): @@ -192,7 +198,16 @@ def add_new_atom(self, *args, **kwargs): self.append(atom, copy=False) return + @deprecated(getLastAtom_deprecation_msg) def getLastAtom(self): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.get_last_atom instead. + """ + return self.get_last_atom() + + def get_last_atom(self): """Return Reference to the last `Atom` in this structure.""" last_atom = self[-1] return last_atom diff --git a/tests/test_structure.py b/tests/test_structure.py index 648f684b..6528365f 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -119,6 +119,23 @@ def test___copy__(self): # def test_getLastAtom(self): # """check Structure.getLastAtom()""" # return + def test_getLastAtom(self): + """Check Structure.getLastAtom()""" + s_lat = Lattice() + expected = Atom("C", [0, 0, 0]) + structure = Structure(atoms=[Atom("C", [0, 0, 0])], lattice=s_lat) + actual = structure.getLastAtom() + assert actual.element == expected.element + assert numpy.allclose(expected.xyz, actual.xyz) + + def test_get_last_atom(self): + """Check Structure.get_last_atom()""" + s_lat = Lattice() + expected = Atom("C", [0, 0, 0]) + structure = Structure(atoms=[Atom("C", [0, 0, 0])], lattice=s_lat) + actual = structure.get_last_atom() + assert actual.element == expected.element + assert numpy.allclose(expected.xyz, actual.xyz) def test_addNewAtom(self): """Duplicate test for the deprecated addNewAtom method. From e66ddbeb4fa332380a51ffa44ea287c37a037024 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 20 Feb 2026 11:21:31 -0500 Subject: [PATCH 156/226] chore: deprecate read/writeStr, placeInLattice method --- news/deprecate-structure-function.rst | 27 +++++++++++++ src/diffpy/structure/apps/transtru.py | 4 +- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdffit.py | 2 +- src/diffpy/structure/pdffitstructure.py | 2 +- src/diffpy/structure/structure.py | 51 ++++++++++++++++++++++-- tests/test_p_cif.py | 27 +++++++++++++ tests/test_p_discus.py | 20 +++++----- tests/test_p_pdffit.py | 26 ++++++------ tests/test_parsers.py | 14 +++---- tests/test_structure.py | 15 ++++++- 11 files changed, 150 insertions(+), 40 deletions(-) create mode 100644 news/deprecate-structure-function.rst diff --git a/news/deprecate-structure-function.rst b/news/deprecate-structure-function.rst new file mode 100644 index 00000000..73071f43 --- /dev/null +++ b/news/deprecate-structure-function.rst @@ -0,0 +1,27 @@ +**Added:** + +* Added ``place_in_lattice`` method to ``Structure`` +* Added ``read_structure`` method to ``Structure`` +* Added ``write_structure`` method to ``Structure`` + +**Changed:** + +* Changed private method ``__emptySharedStructure`` to ``__empty_shared_structure`` + +**Deprecated:** + +* Deprecated ``placeInLattice`` method of ``Structure`` for removal in version 4.0.0 +* Deprecated ``readStr`` method of ``Structure`` for removal in version 4.0.0 +* Deprecated ``writeStr`` method of ``Structure`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 963ebcf5..7155a86f 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -109,10 +109,10 @@ def main(): strufile = args[1] stru = Structure() if args[1] == "-": - stru.readStr(sys.stdin.read(), infmt) + stru.read_structure(sys.stdin.read(), infmt) else: stru.read(strufile, infmt) - sys.stdout.write(stru.writeStr(outfmt)) + sys.stdout.write(stru.write_structure(outfmt)) except IndexError: print("strufile not specified", file=sys.stderr) sys.exit(2) diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 35b868e2..7dba1e96 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -125,7 +125,7 @@ def parseLines(self, lines): latpars = list(self.stru.lattice.abcABG()) superlatpars = [latpars[i] * self.stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] superlattice = Lattice(*superlatpars) - self.stru.placeInLattice(superlattice) + self.stru.place_in_lattice(superlattice) self.stru.pdffit["ncell"] = [1, 1, 1, exp_natoms] except (ValueError, IndexError): exc_type, exc_value, exc_traceback = sys.exc_info() diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 93646aca..822a8e26 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -169,7 +169,7 @@ def parseLines(self, lines): if stru.pdffit["ncell"][:3] != [1, 1, 1]: superlatpars = [latpars[i] * stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] superlattice = Lattice(*superlatpars) - stru.placeInLattice(superlattice) + stru.place_in_lattice(superlattice) stru.pdffit["ncell"] = [1, 1, 1, p_natoms] except (ValueError, IndexError): emsg = "%d: file is not in PDFfit format" % p_nl diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index 73115db6..9cad2d2d 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -97,7 +97,7 @@ def readStr(self, s, format="auto"): StructureParser Instance of `StructureParser` used to load the data. """ - p = Structure.readStr(self, s, format) + p = Structure.read_structure(self, s, format) sg = getattr(p, "spacegroup", None) if sg: self.pdffit["spcgr"] = sg.short_name diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 784a11aa..6f0ecd00 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -40,6 +40,24 @@ "get_last_atom", removal_version, ) +placeInLattice_deprecation_msg = build_deprecation_message( + base, + "placeInLattice", + "place_in_lattice", + removal_version, +) +readStr_deprecation_msg = build_deprecation_message( + base, + "readStr", + "read_structure", + removal_version, +) +writeStr_deprecation_msg = build_deprecation_message( + base, + "writeStr", + "write_structure", + removal_version, +) class Structure(list): @@ -282,7 +300,16 @@ def angle(self, aid0, aid1, aid2): u12 = a2.xyz - a1.xyz return self.lattice.angle(u10, u12) + @deprecated(placeInLattice_deprecation_msg) def placeInLattice(self, new_lattice): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.place_in_lattice instead. + """ + return self.place_in_lattice(new_lattice) + + def place_in_lattice(self, new_lattice): """Place structure into `new_lattice` coordinate system. Sets `lattice` to `new_lattice` and recalculate fractional coordinates @@ -345,7 +372,16 @@ def read(self, filename, format="auto"): self.title = tailbase return p + @deprecated(readStr_deprecation_msg) def readStr(self, s, format="auto"): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.read_structure instead. + """ + return self.read_structure(s, format) + + def read_structure(self, s, format="auto"): """Read structure from a string. Parameters @@ -399,7 +435,16 @@ def write(self, filename, format): fp.write(s) return + @deprecated(writeStr_deprecation_msg) def writeStr(self, format): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Structure.write_structure instead. + """ + return self.write_structure(format) + + def write_structure(self, format): """Return string representation of the structure in specified format. @@ -537,7 +582,7 @@ def __getitem__(self, idx): >>> stru['Na3', 2, 'Cl2'] """ if isinstance(idx, slice): - rv = self.__emptySharedStructure() + rv = self.__empty_shared_structure() lst = super(Structure, self).__getitem__(idx) rv.extend(lst, copy=False) return rv @@ -556,7 +601,7 @@ def __getitem__(self, idx): idx1 = numpy.r_[idx] indices = numpy.arange(len(self))[idx1] rhs = [list.__getitem__(self, i) for i in indices] - rv = self.__emptySharedStructure() + rv = self.__empty_shared_structure() rv.extend(rhs, copy=False) return rv # here we need to resolve at least one string label @@ -917,7 +962,7 @@ def _get_composition(self): # Private Methods -------------------------------------------------------- - def __emptySharedStructure(self): + def __empty_shared_structure(self): """Return empty `Structure` with standard attributes same as in self.""" rv = Structure() diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index 5676120b..4558c397 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -224,6 +224,33 @@ def test_write_and_read(self): self.assertAlmostEqual(0.046164, a3.U[2, 2]) return + def test_write_structure_and_read_structure(self): + """High-level check of P_cif.tostring()""" + # high-level check + stru_check = Structure() + stru_check.read(self.cdsebulkpdffitfile) + s_s = stru_check.write_structure("cif") + stru = Structure() + stru.read_structure(s_s, "cif") + self.assertAlmostEqual(4.2352, stru.lattice.a, self.places) + self.assertAlmostEqual(4.2352, stru.lattice.b, self.places) + self.assertAlmostEqual(6.90603, stru.lattice.c, self.places) + self.assertEqual(4, len(stru)) + a0 = stru[0] + self.assertEqual("Cd", a0.element) + self.assertTrue(numpy.allclose([0.3334, 0.6667, 0.0], a0.xyz)) + self.assertTrue(a0.anisotropy) + self.assertAlmostEqual(0.01303, a0.U[0, 0]) + self.assertAlmostEqual(0.01303, a0.U[1, 1]) + self.assertAlmostEqual(0.01402, a0.U[2, 2]) + a3 = stru[3] + self.assertEqual("Se", a3.element) + self.assertTrue(numpy.allclose([0.6666, 0.333300, 0.87667], a3.xyz)) + self.assertAlmostEqual(0.015673, a3.U[0, 0]) + self.assertAlmostEqual(0.015673, a3.U[1, 1]) + self.assertAlmostEqual(0.046164, a3.U[2, 2]) + return + def test_eps(self): """Test the P_cif.eps coordinates resolution.""" pcif = P_cif() diff --git a/tests/test_p_discus.py b/tests/test_p_discus.py index 71f0d695..1bfd7595 100644 --- a/tests/test_p_discus.py +++ b/tests/test_p_discus.py @@ -91,11 +91,11 @@ def test_ignored_lines(self): ni_lines.insert(2, r1) ni_lines.insert(4, r2) s_s1 = "".join(ni_lines) - p = self.stru.readStr(s_s1, self.format) + p = self.stru.read_structure(s_s1, self.format) self.assertEqual([r1.rstrip(), r2.rstrip()], p.ignored_lines) ni_lines.append(r1) s_s2 = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, s_s2, self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, s_s2, self.format) return def test_spdiameter_parsing(self): @@ -103,20 +103,20 @@ def test_spdiameter_parsing(self): stru = self.stru stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) - snoshape = stru.writeStr(format=self.format) + snoshape = stru.write_structure(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero spdiameter stru.pdffit["spdiameter"] = 13 - s13 = stru.writeStr(format=self.format) + s13 = stru.write_structure(format=self.format) self.assertTrue(re.search("(?m)^shape +sphere, ", s13)) stru13 = Structure() - stru13.readStr(s13) + stru13.read_structure(s13) self.assertEqual(13, stru13.pdffit["spdiameter"]) with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, sbad, format=self.format) return def test_stepcut_parsing(self): @@ -124,20 +124,20 @@ def test_stepcut_parsing(self): stru = self.stru stru.read(self.datafile("Ni-discus.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) - snoshape = stru.writeStr(format=self.format) + snoshape = stru.write_structure(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero stepcut stru.pdffit["stepcut"] = 13 - s13 = stru.writeStr(format=self.format) + s13 = stru.write_structure(format=self.format) self.assertTrue(re.search("(?m)^shape +stepcut, ", s13)) stru13 = Structure() - stru13.readStr(s13) + stru13.read_structure(s13) self.assertEqual(13, stru13.pdffit["stepcut"]) with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, sbad, format=self.format) return diff --git a/tests/test_p_pdffit.py b/tests/test_p_pdffit.py index 989dd541..07bc6ca1 100644 --- a/tests/test_p_pdffit.py +++ b/tests/test_p_pdffit.py @@ -172,7 +172,7 @@ def test_writeStr_pdffit(self): f_s = fp.read() f_s = re.sub("[ \t]+", " ", f_s) f_s = re.sub("[ \t]+\n", "\n", f_s) - s_s = stru.writeStr(self.format) + s_s = stru.write_structure(self.format) s_s = re.sub("[ \t]+", " ", s_s) self.assertEqual(f_s, s_s) return @@ -181,9 +181,9 @@ def test_huge_occupancy(self): """Check structure with huge occupancy can be read.""" self.stru.read(self.datafile("Ni.stru"), self.format) self.stru[0].occupancy = 16e16 - s_s = self.stru.writeStr(self.format) + s_s = self.stru.write_structure(self.format) stru1 = Structure() - stru1.readStr(s_s, self.format) + stru1.read_structure(s_s, self.format) self.assertEqual(16e16, stru1[0].occupancy) return @@ -196,11 +196,11 @@ def test_ignored_lines(self): ni_lines.insert(2, r1 + "\n") ni_lines.insert(4, r2 + "\n") s_s1 = "".join(ni_lines) - p = self.stru.readStr(s_s1, self.format) + p = self.stru.read_structure(s_s1, self.format) self.assertEqual([r1, r2], p.ignored_lines) ni_lines.insert(-3, r1 + "\n") s_s2 = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, s_s2, self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, s_s2, self.format) return def test_spdiameter_parsing(self): @@ -208,20 +208,20 @@ def test_spdiameter_parsing(self): stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["spdiameter"]) - snoshape = stru.writeStr(format=self.format) + snoshape = stru.write_structure(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero spdiameter stru.pdffit["spdiameter"] = 13 - s13 = stru.writeStr(format=self.format) + s13 = stru.write_structure(format=self.format) self.assertTrue(re.search("(?m)^shape +sphere, ", s13)) stru13 = Structure() - stru13.readStr(s13) + stru13.read_structure(s13) self.assertEqual(13, stru13.pdffit["spdiameter"]) with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, sbad, format=self.format) return def test_stepcut_parsing(self): @@ -229,20 +229,20 @@ def test_stepcut_parsing(self): stru = self.stru stru.read(self.datafile("Ni.stru"), self.format) self.assertEqual(0, stru.pdffit["stepcut"]) - snoshape = stru.writeStr(format=self.format) + snoshape = stru.write_structure(format=self.format) self.assertTrue(not re.search("(?m)^shape", snoshape)) # produce a string with non-zero stepcut stru.pdffit["stepcut"] = 13 - s13 = stru.writeStr(format=self.format) + s13 = stru.write_structure(format=self.format) self.assertTrue(re.search("(?m)^shape +stepcut, ", s13)) stru13 = Structure() - stru13.readStr(s13) + stru13.read_structure(s13) self.assertEqual(13, stru13.pdffit["stepcut"]) with open(self.datafile("Ni.stru")) as fp: ni_lines = fp.readlines() ni_lines.insert(3, "shape invalid, 7\n") sbad = "".join(ni_lines) - self.assertRaises(StructureFormatError, self.stru.readStr, sbad, format=self.format) + self.assertRaises(StructureFormatError, self.stru.read_structure, sbad, format=self.format) return diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 7723a2aa..548fbb78 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -95,7 +95,7 @@ def test_writeStr_xyz(self): stru.title = "test of writeStr" stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) stru[:] = [Atom("H", [1.0, 1.0, 1.0]), Atom("Cl", [3.0, 2.0, 1.0])] - s1 = stru.writeStr(self.format) + s1 = stru.write_structure(self.format) s1 = re.sub("[ \t]+", " ", s1) s0 = "2\n%s\nH 1 2 3\nCl 3 4 3\n" % stru.title self.assertEqual(s1, s0) @@ -190,12 +190,12 @@ def test_writeStr_rawxyz(self): stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0) # plain version stru[:] = [Atom("H", [1.0, 1.0, 1.0])] - s1 = stru.writeStr(self.format) + s1 = stru.write_structure(self.format) s1 = re.sub("[ \t]+", " ", s1) s0 = "H 1 2 3\n" # brutal raw version stru[0].element = "" - s1 = stru.writeStr(self.format) + s1 = stru.write_structure(self.format) s0 = "1 2 3\n" self.assertEqual(s1, s0) return @@ -270,13 +270,13 @@ def test_rwStr_pdb_CdSe(self): """Check conversion to PDB file format.""" stru = self.stru stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") - s = stru.writeStr(self.format) + s = stru.write_structure(self.format) # all lines should be 80 characters long linelens = [len(line) for line in s.split("\n") if line != ""] self.assertEqual(linelens, len(linelens) * [80]) # now clean and re-read structure stru = Structure() - stru.readStr(s, self.format) + stru.read_structure(s, self.format) s_els = [a.element for a in stru] f_els = ["Cd", "Cd", "Se", "Se"] self.assertEqual(s_els, f_els) @@ -343,9 +343,9 @@ def test_rwStr_xcfg_CdSe(self): """Check conversion to XCFG file format.""" stru = self.stru stru.read(self.datafile("CdSe_bulk.stru"), "pdffit") - s = stru.writeStr(self.format) + s = stru.write_structure(self.format) stru = Structure() - stru.readStr(s, self.format) + stru.read_structure(s, self.format) s_els = [a.element for a in stru] f_els = ["Cd", "Cd", "Se", "Se"] self.assertEqual(s_els, f_els) diff --git a/tests/test_structure.py b/tests/test_structure.py index 6528365f..c5b17ce5 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -100,9 +100,9 @@ def __copy__(self): def test___copy__(self): """Check Structure.__copy__()""" cdse = Structure(filename=self.cdsefile) - cdse_str = cdse.writeStr("pdffit") + cdse_str = cdse.write_structure("pdffit") cdse2 = copy.copy(cdse) - self.assertEqual(cdse_str, cdse2.writeStr("pdffit")) + self.assertEqual(cdse_str, cdse2.write_structure("pdffit")) self.assertFalse(cdse.lattice is cdse2.lattice) sameatoms = set(cdse).intersection(cdse2) self.assertFalse(sameatoms) @@ -193,6 +193,17 @@ def test_placeInLattice(self): a1 = stru[1] self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) + def test_place_in_lattice(self): + """Check Structure.placeInLattice() -- conversion of + coordinates.""" + stru = self.stru + new_lattice = Lattice(0.5, 0.5, 0.5, 90, 90, 60) + stru.place_in_lattice(new_lattice) + a0 = stru[0] + self.assertTrue(numpy.allclose(a0.xyz, [0.0, 0.0, 0.0])) + a1 = stru[1] + self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) + # def test_read(self): # """check Structure.read()""" # return From 9c26c25651798241a14fb3e8742841a003ffc688 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 20 Feb 2026 16:17:10 -0500 Subject: [PATCH 157/226] chore: deprecate private function in utils --- news/deprecate-private-linkatom.rst | 23 +++++++++++++ src/diffpy/structure/structure.py | 50 ++++++++++++++--------------- src/diffpy/structure/utils.py | 2 +- 3 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 news/deprecate-private-linkatom.rst diff --git a/news/deprecate-private-linkatom.rst b/news/deprecate-private-linkatom.rst new file mode 100644 index 00000000..860f7b08 --- /dev/null +++ b/news/deprecate-private-linkatom.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added ``_link_atom_attribute`` method in ``diffpy.structure.utils`` + +**Changed:** + +* + +**Deprecated:** + +* Derecated ``_linkAtomAttribute`` method in ``diffpy.structure.utils`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 6f0ecd00..7ba7f8ab 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -21,7 +21,7 @@ from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice -from diffpy.structure.utils import _linkAtomAttribute, atomBareSymbol, isiterable +from diffpy.structure.utils import _link_atom_attribute, atomBareSymbol, isiterable from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- @@ -812,7 +812,7 @@ def _get_composition(self): # linked atom attributes - element = _linkAtomAttribute( + element = _link_atom_attribute( "element", """Character array of `Atom` types. Assignment updates the element attribute of the respective `Atoms`. @@ -820,31 +820,31 @@ def _get_composition(self): toarray=lambda items: numpy.char.array(items, itemsize=5), ) - xyz = _linkAtomAttribute( + xyz = _link_atom_attribute( "xyz", """Array of fractional coordinates of all `Atoms`. Assignment updates `xyz` attribute of all `Atoms`.""", ) - x = _linkAtomAttribute( + x = _link_atom_attribute( "x", """Array of all fractional coordinates `x`. Assignment updates `xyz` attribute of all `Atoms`.""", ) - y = _linkAtomAttribute( + y = _link_atom_attribute( "y", """Array of all fractional coordinates `y`. Assignment updates `xyz` attribute of all `Atoms`.""", ) - z = _linkAtomAttribute( + z = _link_atom_attribute( "z", """Array of all fractional coordinates `z`. Assignment updates `xyz` attribute of all `Atoms`.""", ) - label = _linkAtomAttribute( + label = _link_atom_attribute( "label", """Character array of `Atom` names. Assignment updates the label attribute of all `Atoms`. @@ -852,109 +852,109 @@ def _get_composition(self): toarray=lambda items: numpy.char.array(items, itemsize=5), ) - occupancy = _linkAtomAttribute( + occupancy = _link_atom_attribute( "occupancy", """Array of `Atom` occupancies. Assignment updates the occupancy attribute of all `Atoms`.""", ) - xyz_cartn = _linkAtomAttribute( + xyz_cartn = _link_atom_attribute( "xyz_cartn", """Array of absolute Cartesian coordinates of all `Atoms`. Assignment updates the `xyz` attribute of all `Atoms`.""", ) - anisotropy = _linkAtomAttribute( + anisotropy = _link_atom_attribute( "anisotropy", """Boolean array for anisotropic thermal displacement flags. Assignment updates the anisotropy attribute of all `Atoms`.""", ) - U = _linkAtomAttribute( + U = _link_atom_attribute( "U", """Array of anisotropic thermal displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - Uisoequiv = _linkAtomAttribute( + Uisoequiv = _link_atom_attribute( "Uisoequiv", """Array of isotropic thermal displacement or equivalent values. Assignment updates the U attribute of all `Atoms`.""", ) - U11 = _linkAtomAttribute( + U11 = _link_atom_attribute( "U11", """Array of `U11` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - U22 = _linkAtomAttribute( + U22 = _link_atom_attribute( "U22", """Array of `U22` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - U33 = _linkAtomAttribute( + U33 = _link_atom_attribute( "U33", """Array of `U33` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - U12 = _linkAtomAttribute( + U12 = _link_atom_attribute( "U12", """Array of `U12` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - U13 = _linkAtomAttribute( + U13 = _link_atom_attribute( "U13", """Array of `U13` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - U23 = _linkAtomAttribute( + U23 = _link_atom_attribute( "U23", """Array of `U23` elements of the anisotropic displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - Bisoequiv = _linkAtomAttribute( + Bisoequiv = _link_atom_attribute( "Bisoequiv", """Array of Debye-Waller isotropic thermal displacement or equivalent values. Assignment updates the U attribute of all `Atoms`.""", ) - B11 = _linkAtomAttribute( + B11 = _link_atom_attribute( "B11", """Array of `B11` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - B22 = _linkAtomAttribute( + B22 = _link_atom_attribute( "B22", """Array of `B22` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - B33 = _linkAtomAttribute( + B33 = _link_atom_attribute( "B33", """Array of `B33` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - B12 = _linkAtomAttribute( + B12 = _link_atom_attribute( "B12", """Array of `B12` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - B13 = _linkAtomAttribute( + B13 = _link_atom_attribute( "B13", """Array of `B13` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", ) - B23 = _linkAtomAttribute( + B23 = _link_atom_attribute( "B23", """Array of `B23` elements of the Debye-Waller displacement tensors. Assignment updates the U and anisotropy attributes of all `Atoms`.""", diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index facab843..db7b21d2 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -69,7 +69,7 @@ def atomBareSymbol(smbl): # Helpers for the Structure class -------------------------------------------- -def _linkAtomAttribute(attrname, doc, toarray=numpy.array): +def _link_atom_attribute(attrname, doc, toarray=numpy.array): """Create property wrapper that maps the specified atom attribute. The returned property object provides convenient access to atom From f9035310cf51f6beb654369d377b58c847fed041 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sun, 22 Feb 2026 15:55:58 -0500 Subject: [PATCH 158/226] chore: deprecate setLatPar and setLatBase method --- news/deprecate-lattice.rst | 25 +++++++ .../structure/expansion/supercell_mod.py | 2 +- src/diffpy/structure/lattice.py | 63 +++++++++++++--- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 4 +- src/diffpy/structure/parsers/p_xcfg.py | 2 +- tests/test_lattice.py | 75 ++++++++++++++++--- 7 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 news/deprecate-lattice.rst diff --git a/news/deprecate-lattice.rst b/news/deprecate-lattice.rst new file mode 100644 index 00000000..6b8c6740 --- /dev/null +++ b/news/deprecate-lattice.rst @@ -0,0 +1,25 @@ +**Added:** + +* Added ``set_lat_par`` method into ``Lattice`` class +* Added ``set_lar_base`` method into ``Lattice`` class + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``setLatPar`` method in ``Lattice`` class for removal in version 4.0.0 +* Deprecated ``setLatBase`` method in ``Lattice`` class for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index 44d55408..a8f6fcdc 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -82,7 +82,7 @@ def supercell(S, mno): newS.__setitem__(slice(None), newAtoms, copy=False) # take care of lattice parameters - newS.lattice.setLatPar(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) + newS.lattice.set_lat_par(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) return newS diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 73885e4f..78a18475 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -27,6 +27,22 @@ import numpy.linalg as numalg from diffpy.structure.structureerrors import LatticeError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.Lattice" +removal_version = "4.0.0" +setLatPar_deprecation_msg = build_deprecation_message( + base, + "setLatPar", + "set_lat_par", + removal_version, +) +setLatBase_deprecation_msg = build_deprecation_message( + base, + "setLatBase", + "set_lat_base", + removal_version, +) # Helper Functions ----------------------------------------------------------- @@ -168,37 +184,37 @@ class Lattice(object): a = property( lambda self: self._a, - lambda self, value: self.setLatPar(a=value), + lambda self, value: self.set_lat_par(a=value), doc="The unit cell length *a*.", ) b = property( lambda self: self._b, - lambda self, value: self.setLatPar(b=value), + lambda self, value: self.set_lat_par(b=value), doc="The unit cell length *b*.", ) c = property( lambda self: self._c, - lambda self, value: self.setLatPar(c=value), + lambda self, value: self.set_lat_par(c=value), doc="The unit cell length *c*.", ) alpha = property( lambda self: self._alpha, - lambda self, value: self.setLatPar(alpha=value), + lambda self, value: self.set_lat_par(alpha=value), doc="The cell angle *alpha* in degrees.", ) beta = property( lambda self: self._beta, - lambda self, value: self.setLatPar(beta=value), + lambda self, value: self.set_lat_par(beta=value), doc="The cell angle *beta* in degrees.", ) gamma = property( lambda self: self._gamma, - lambda self, value: self.setLatPar(gamma=value), + lambda self, value: self.set_lat_par(gamma=value), doc="The cell angle *gamma* in degrees.", ) @@ -323,12 +339,12 @@ def __init__( # work out argument variants # Lattice() if not argset: - self.setLatPar(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot) + self.set_lat_par(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot) # Lattice(base=abc) elif base is not None: if len(argset) > 1: raise ValueError("'base' must be the only argument.") - self.setLatBase(base) + self.set_lat_base(base) # Lattice(lat) elif isinstance(a, Lattice): if len(argset) > 1: @@ -339,10 +355,10 @@ def __init__( abcabg = ("a", "b", "c", "alpha", "beta", "gamma") if not argset.issuperset(abcabg): raise ValueError("Provide all 6 cell parameters.") - self.setLatPar(a, b, c, alpha, beta, gamma, baserot=baserot) + self.set_lat_par(a, b, c, alpha, beta, gamma, baserot=baserot) return - def setLatPar( + def set_lat_par( self, a=None, b=None, @@ -441,7 +457,34 @@ def setLatPar( self.isotropicunit = _isotropicunit(self.recnormbase) return + @deprecated(setLatPar_deprecation_msg) + def setLatPar( + self, + a=None, + b=None, + c=None, + alpha=None, + beta=None, + gamma=None, + baserot=None, + ): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Lattice.set_lat_par instead. + """ + return self.set_lat_par(a, b, c, alpha, beta, gamma, baserot) + + @deprecated(setLatBase_deprecation_msg) def setLatBase(self, base): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Lattice.set_lat_base instead. + """ + return self.set_lat_base(base) + + def set_lat_base(self, base): """Set new base vectors for this lattice. This updates the cell lengths and cell angles according to the diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 7dba1e96..d09f7ebe 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -201,7 +201,7 @@ def _parse_cell(self, words): words = self.line.replace(",", " ").split() latpars = [float(w) for w in words[1:7]] try: - self.stru.lattice.setLatPar(*latpars) + self.stru.lattice.set_lat_par(*latpars) except ZeroDivisionError: emsg = "%d: Invalid lattice parameters - zero cell volume" % self.nl raise StructureFormatError(emsg) diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 8694dba1..31199f76 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -157,7 +157,7 @@ def parseLines(self, lines): alpha = float(line[33:40]) beta = float(line[40:47]) gamma = float(line[47:54]) - stru.lattice.setLatPar(a, b, c, alpha, beta, gamma) + stru.lattice.set_lat_par(a, b, c, alpha, beta, gamma) scale = numpy.transpose(stru.lattice.recbase) elif record == "SCALE1": sc = numpy.zeros((3, 3), dtype=float) @@ -171,7 +171,7 @@ def parseLines(self, lines): scaleU[2] = float(line[45:55]) base = numpy.transpose(numpy.linalg.inv(sc)) abcABGcryst = numpy.array(stru.lattice.abcABG()) - stru.lattice.setLatBase(base) + stru.lattice.set_lat_base(base) abcABGscale = numpy.array(stru.lattice.abcABG()) reldiff = numpy.fabs(1.0 - abcABGscale / abcABGcryst) if not numpy.all(reldiff < 1.0e-4): diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 08c108a9..40cc7c82 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -253,7 +253,7 @@ def parseLines(self, lines): emsg = ("%d: auxiliary fields are " "not consistent with entry_count") % p_nl raise StructureFormatError(emsg) # define proper lattice - stru.lattice.setLatBase(xcfg_H0) + stru.lattice.set_lat_base(xcfg_H0) # here we are inside the data block p_element = None for line in ilines: diff --git a/tests/test_lattice.py b/tests/test_lattice.py index d9efff6f..98c4a28c 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -44,7 +44,7 @@ def test___init__(self): self.assertRaises(ValueError, Lattice, 1, 2, 3) self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90) L0 = self.lattice - L0.setLatBase(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]])) + L0.set_lat_base(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]])) L1 = Lattice(L0) self.assertTrue(numpy.array_equal(L0.base, L1.base)) L2 = Lattice(base=L0.base) @@ -77,6 +77,28 @@ def cosd(x): self.assertAlmostEqual(cosd(120.0), dot(base[0], base[1]) / (1 * 2), self.places) return + def test_set_lat_par(self): + """Check calculation of standard unit cell vectors.""" + from math import cos, radians, sqrt + + from numpy import dot + + def norm(x): + return sqrt(sum([xi**2 for xi in x])) + + def cosd(x): + return cos(radians(x)) + + self.lattice.set_lat_par(1.0, 2.0, 3.0, 80, 100, 120) + base = self.lattice.base + self.assertAlmostEqual(1.0, norm(base[0]), self.places) + self.assertAlmostEqual(2.0, norm(base[1]), self.places) + self.assertAlmostEqual(3.0, norm(base[2]), self.places) + self.assertAlmostEqual(cosd(80.0), dot(base[1], base[2]) / (2 * 3), self.places) + self.assertAlmostEqual(cosd(100.0), dot(base[0], base[2]) / (1 * 3), self.places) + self.assertAlmostEqual(cosd(120.0), dot(base[0], base[1]) / (1 * 2), self.places) + return + def test_latpar_properties(self): """Check assignment to a, b, c, alpha, beta, gamma.""" lat = self.lattice @@ -152,9 +174,9 @@ def test_setLatBase(self): self.assertAlmostEqual(detR0, 1.0, self.places) # try if rotation matrix works self.assertEqual(numpy.all(base == self.lattice.base), True) - self.lattice.setLatPar(alpha=44, beta=66, gamma=88) + self.lattice.set_lat_par(alpha=44, beta=66, gamma=88) self.assertNotEqual(numpy.all(base == self.lattice.base), True) - self.lattice.setLatPar(alpha=60, beta=60, gamma=60) + self.lattice.set_lat_par(alpha=60, beta=60, gamma=60) self.assertTrue(numpy.allclose(base[0], self.lattice.base[0])) self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) @@ -171,6 +193,39 @@ def test_setLatBase(self): ) return + def test_set_lat_base(self): + """Check calculation of unit cell rotation.""" + base = numpy.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) + self.lattice.set_lat_base(base) + self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places) + self.assertAlmostEqual(self.lattice.b, numpy.sqrt(2.0), self.places) + self.assertAlmostEqual(self.lattice.c, numpy.sqrt(2.0), self.places) + self.assertAlmostEqual(self.lattice.alpha, 60.0, self.places) + self.assertAlmostEqual(self.lattice.beta, 60.0, self.places) + self.assertAlmostEqual(self.lattice.gamma, 60.0, self.places) + detR0 = numalg.det(self.lattice.baserot) + self.assertAlmostEqual(detR0, 1.0, self.places) + # try if rotation matrix works + self.assertEqual(numpy.all(base == self.lattice.base), True) + self.lattice.set_lat_par(alpha=44, beta=66, gamma=88) + self.assertNotEqual(numpy.all(base == self.lattice.base), True) + self.lattice.set_lat_par(alpha=60, beta=60, gamma=60) + self.assertTrue(numpy.allclose(base[0], self.lattice.base[0])) + self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) + self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) + # try base checking + self.assertRaises( + LatticeError, + self.lattice.set_lat_base, + [[1, 0, 0], [1, 0, 0], [0, 0, 1]], + ) + self.assertRaises( + LatticeError, + self.lattice.set_lat_base, + [[1, 0, 0], [0, 0, 1], [0, 1, 0]], + ) + return + def test_reciprocal(self): """Check calculation of reciprocal lattice.""" r1 = self.lattice.reciprocal() @@ -185,7 +240,7 @@ def test_reciprocal(self): def test_dot(self): """Check dot product of lattice vectors.""" L = self.lattice - L.setLatPar(gamma=120) + L.set_lat_par(gamma=120) self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places) va5 = numpy.tile([1.0, 0.0, 0.0], (5, 1)) vb5 = numpy.tile([0.0, 1.0, 0.0], (5, 1)) @@ -199,14 +254,14 @@ def test_norm(self): self.assertEqual(1, self.lattice.norm([1, 0, 0])) u = numpy.array([[3, 4, 0], [1, 1, 1]]) self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u))) - self.lattice.setLatPar(gamma=120) + self.lattice.set_lat_par(gamma=120) self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places) return def test_rnorm(self): """Check norm of a reciprocal vector.""" L = self.lattice - L.setLatPar(1, 1.5, 2.3, 80, 95, 115) + L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) r = L.reciprocal() hkl = [0.5, 0.3, 0.2] self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl), self.places) @@ -217,7 +272,7 @@ def test_rnorm(self): def test_dist(self): """Check dist function for distance between lattice points.""" L = self.lattice - L.setLatPar(1, 1.5, 2.3, 80, 95, 115) + L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] v = [0.3, 0.7, 0.7] d0 = numalg.norm(L.cartesian(numpy.array(u) - v)) @@ -235,7 +290,7 @@ def test_angle(self): from math import acos, degrees L = self.lattice - L.setLatPar(1, 1.5, 2.3, 80, 95, 115) + L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] v = [0.3, 0.7, 0.7] uc = L.cartesian(u) @@ -254,12 +309,12 @@ def test_repr(self): """Check string representation of this lattice.""" r = repr(self.lattice) self.assertEqual(r, "Lattice()") - self.lattice.setLatPar(1, 2, 3, 10, 20, 30) + self.lattice.set_lat_par(1, 2, 3, 10, 20, 30) r = repr(self.lattice) r0 = "Lattice(a=1, b=2, c=3, alpha=10, beta=20, gamma=30)" self.assertEqual(r, r0) base = [[1.0, 1.0, 0.0], [0.0, 2.0, 2.0], [3.0, 0.0, 3.0]] - self.lattice.setLatBase(base) + self.lattice.set_lat_base(base) r = repr(self.lattice) self.assertEqual(r, "Lattice(base=%r)" % self.lattice.base) From cca23ffc753bf019e37a89771c0e00ffe555b1bc Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sun, 22 Feb 2026 19:50:11 -0500 Subject: [PATCH 159/226] chore: rename the lower-case function to make it clearer in meaning --- .../structure/expansion/supercell_mod.py | 2 +- src/diffpy/structure/lattice.py | 28 ++++++++-------- src/diffpy/structure/parsers/p_discus.py | 2 +- src/diffpy/structure/parsers/p_pdb.py | 4 +-- src/diffpy/structure/parsers/p_xcfg.py | 2 +- tests/test_lattice.py | 32 +++++++++---------- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/diffpy/structure/expansion/supercell_mod.py b/src/diffpy/structure/expansion/supercell_mod.py index a8f6fcdc..bcaceb70 100644 --- a/src/diffpy/structure/expansion/supercell_mod.py +++ b/src/diffpy/structure/expansion/supercell_mod.py @@ -82,7 +82,7 @@ def supercell(S, mno): newS.__setitem__(slice(None), newAtoms, copy=False) # take care of lattice parameters - newS.lattice.set_lat_par(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) + newS.lattice.set_latt_parms(a=mno[0] * S.lattice.a, b=mno[1] * S.lattice.b, c=mno[2] * S.lattice.c) return newS diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 78a18475..f75e061c 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -34,7 +34,7 @@ setLatPar_deprecation_msg = build_deprecation_message( base, "setLatPar", - "set_lat_par", + "set_lat_parms", removal_version, ) setLatBase_deprecation_msg = build_deprecation_message( @@ -184,37 +184,37 @@ class Lattice(object): a = property( lambda self: self._a, - lambda self, value: self.set_lat_par(a=value), + lambda self, value: self.set_latt_parms(a=value), doc="The unit cell length *a*.", ) b = property( lambda self: self._b, - lambda self, value: self.set_lat_par(b=value), + lambda self, value: self.set_latt_parms(b=value), doc="The unit cell length *b*.", ) c = property( lambda self: self._c, - lambda self, value: self.set_lat_par(c=value), + lambda self, value: self.set_latt_parms(c=value), doc="The unit cell length *c*.", ) alpha = property( lambda self: self._alpha, - lambda self, value: self.set_lat_par(alpha=value), + lambda self, value: self.set_latt_parms(alpha=value), doc="The cell angle *alpha* in degrees.", ) beta = property( lambda self: self._beta, - lambda self, value: self.set_lat_par(beta=value), + lambda self, value: self.set_latt_parms(beta=value), doc="The cell angle *beta* in degrees.", ) gamma = property( lambda self: self._gamma, - lambda self, value: self.set_lat_par(gamma=value), + lambda self, value: self.set_latt_parms(gamma=value), doc="The cell angle *gamma* in degrees.", ) @@ -339,12 +339,12 @@ def __init__( # work out argument variants # Lattice() if not argset: - self.set_lat_par(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot) + self.set_latt_parms(1.0, 1.0, 1.0, 90.0, 90.0, 90.0, baserot) # Lattice(base=abc) elif base is not None: if len(argset) > 1: raise ValueError("'base' must be the only argument.") - self.set_lat_base(base) + self.set_new_latt_base_vec(base) # Lattice(lat) elif isinstance(a, Lattice): if len(argset) > 1: @@ -355,10 +355,10 @@ def __init__( abcabg = ("a", "b", "c", "alpha", "beta", "gamma") if not argset.issuperset(abcabg): raise ValueError("Provide all 6 cell parameters.") - self.set_lat_par(a, b, c, alpha, beta, gamma, baserot=baserot) + self.set_latt_parms(a, b, c, alpha, beta, gamma, baserot=baserot) return - def set_lat_par( + def set_latt_parms( self, a=None, b=None, @@ -473,7 +473,7 @@ def setLatPar( Please use diffpy.structure.Lattice.set_lat_par instead. """ - return self.set_lat_par(a, b, c, alpha, beta, gamma, baserot) + return self.set_latt_parms(a, b, c, alpha, beta, gamma, baserot) @deprecated(setLatBase_deprecation_msg) def setLatBase(self, base): @@ -482,9 +482,9 @@ def setLatBase(self, base): Please use diffpy.structure.Lattice.set_lat_base instead. """ - return self.set_lat_base(base) + return self.set_new_latt_base_vec(base) - def set_lat_base(self, base): + def set_new_latt_base_vec(self, base): """Set new base vectors for this lattice. This updates the cell lengths and cell angles according to the diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index d09f7ebe..8039c7c5 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -201,7 +201,7 @@ def _parse_cell(self, words): words = self.line.replace(",", " ").split() latpars = [float(w) for w in words[1:7]] try: - self.stru.lattice.set_lat_par(*latpars) + self.stru.lattice.set_latt_parms(*latpars) except ZeroDivisionError: emsg = "%d: Invalid lattice parameters - zero cell volume" % self.nl raise StructureFormatError(emsg) diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 31199f76..7dc2f327 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -157,7 +157,7 @@ def parseLines(self, lines): alpha = float(line[33:40]) beta = float(line[40:47]) gamma = float(line[47:54]) - stru.lattice.set_lat_par(a, b, c, alpha, beta, gamma) + stru.lattice.set_latt_parms(a, b, c, alpha, beta, gamma) scale = numpy.transpose(stru.lattice.recbase) elif record == "SCALE1": sc = numpy.zeros((3, 3), dtype=float) @@ -171,7 +171,7 @@ def parseLines(self, lines): scaleU[2] = float(line[45:55]) base = numpy.transpose(numpy.linalg.inv(sc)) abcABGcryst = numpy.array(stru.lattice.abcABG()) - stru.lattice.set_lat_base(base) + stru.lattice.set_new_latt_base_vec(base) abcABGscale = numpy.array(stru.lattice.abcABG()) reldiff = numpy.fabs(1.0 - abcABGscale / abcABGcryst) if not numpy.all(reldiff < 1.0e-4): diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 40cc7c82..ee626293 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -253,7 +253,7 @@ def parseLines(self, lines): emsg = ("%d: auxiliary fields are " "not consistent with entry_count") % p_nl raise StructureFormatError(emsg) # define proper lattice - stru.lattice.set_lat_base(xcfg_H0) + stru.lattice.set_new_latt_base_vec(xcfg_H0) # here we are inside the data block p_element = None for line in ilines: diff --git a/tests/test_lattice.py b/tests/test_lattice.py index 98c4a28c..48415352 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -44,7 +44,7 @@ def test___init__(self): self.assertRaises(ValueError, Lattice, 1, 2, 3) self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90) L0 = self.lattice - L0.set_lat_base(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]])) + L0.set_new_latt_base_vec(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]])) L1 = Lattice(L0) self.assertTrue(numpy.array_equal(L0.base, L1.base)) L2 = Lattice(base=L0.base) @@ -89,7 +89,7 @@ def norm(x): def cosd(x): return cos(radians(x)) - self.lattice.set_lat_par(1.0, 2.0, 3.0, 80, 100, 120) + self.lattice.set_latt_parms(1.0, 2.0, 3.0, 80, 100, 120) base = self.lattice.base self.assertAlmostEqual(1.0, norm(base[0]), self.places) self.assertAlmostEqual(2.0, norm(base[1]), self.places) @@ -174,9 +174,9 @@ def test_setLatBase(self): self.assertAlmostEqual(detR0, 1.0, self.places) # try if rotation matrix works self.assertEqual(numpy.all(base == self.lattice.base), True) - self.lattice.set_lat_par(alpha=44, beta=66, gamma=88) + self.lattice.set_latt_parms(alpha=44, beta=66, gamma=88) self.assertNotEqual(numpy.all(base == self.lattice.base), True) - self.lattice.set_lat_par(alpha=60, beta=60, gamma=60) + self.lattice.set_latt_parms(alpha=60, beta=60, gamma=60) self.assertTrue(numpy.allclose(base[0], self.lattice.base[0])) self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) @@ -196,7 +196,7 @@ def test_setLatBase(self): def test_set_lat_base(self): """Check calculation of unit cell rotation.""" base = numpy.array([[1.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 1.0]]) - self.lattice.set_lat_base(base) + self.lattice.set_new_latt_base_vec(base) self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places) self.assertAlmostEqual(self.lattice.b, numpy.sqrt(2.0), self.places) self.assertAlmostEqual(self.lattice.c, numpy.sqrt(2.0), self.places) @@ -207,21 +207,21 @@ def test_set_lat_base(self): self.assertAlmostEqual(detR0, 1.0, self.places) # try if rotation matrix works self.assertEqual(numpy.all(base == self.lattice.base), True) - self.lattice.set_lat_par(alpha=44, beta=66, gamma=88) + self.lattice.set_latt_parms(alpha=44, beta=66, gamma=88) self.assertNotEqual(numpy.all(base == self.lattice.base), True) - self.lattice.set_lat_par(alpha=60, beta=60, gamma=60) + self.lattice.set_latt_parms(alpha=60, beta=60, gamma=60) self.assertTrue(numpy.allclose(base[0], self.lattice.base[0])) self.assertTrue(numpy.allclose(base[1], self.lattice.base[1])) self.assertTrue(numpy.allclose(base[2], self.lattice.base[2])) # try base checking self.assertRaises( LatticeError, - self.lattice.set_lat_base, + self.lattice.set_new_latt_base_vec, [[1, 0, 0], [1, 0, 0], [0, 0, 1]], ) self.assertRaises( LatticeError, - self.lattice.set_lat_base, + self.lattice.set_new_latt_base_vec, [[1, 0, 0], [0, 0, 1], [0, 1, 0]], ) return @@ -240,7 +240,7 @@ def test_reciprocal(self): def test_dot(self): """Check dot product of lattice vectors.""" L = self.lattice - L.set_lat_par(gamma=120) + L.set_latt_parms(gamma=120) self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places) va5 = numpy.tile([1.0, 0.0, 0.0], (5, 1)) vb5 = numpy.tile([0.0, 1.0, 0.0], (5, 1)) @@ -254,14 +254,14 @@ def test_norm(self): self.assertEqual(1, self.lattice.norm([1, 0, 0])) u = numpy.array([[3, 4, 0], [1, 1, 1]]) self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u))) - self.lattice.set_lat_par(gamma=120) + self.lattice.set_latt_parms(gamma=120) self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places) return def test_rnorm(self): """Check norm of a reciprocal vector.""" L = self.lattice - L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) + L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115) r = L.reciprocal() hkl = [0.5, 0.3, 0.2] self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl), self.places) @@ -272,7 +272,7 @@ def test_rnorm(self): def test_dist(self): """Check dist function for distance between lattice points.""" L = self.lattice - L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) + L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] v = [0.3, 0.7, 0.7] d0 = numalg.norm(L.cartesian(numpy.array(u) - v)) @@ -290,7 +290,7 @@ def test_angle(self): from math import acos, degrees L = self.lattice - L.set_lat_par(1, 1.5, 2.3, 80, 95, 115) + L.set_latt_parms(1, 1.5, 2.3, 80, 95, 115) u = [0.1, 0.3, 0.7] v = [0.3, 0.7, 0.7] uc = L.cartesian(u) @@ -309,12 +309,12 @@ def test_repr(self): """Check string representation of this lattice.""" r = repr(self.lattice) self.assertEqual(r, "Lattice()") - self.lattice.set_lat_par(1, 2, 3, 10, 20, 30) + self.lattice.set_latt_parms(1, 2, 3, 10, 20, 30) r = repr(self.lattice) r0 = "Lattice(a=1, b=2, c=3, alpha=10, beta=20, gamma=30)" self.assertEqual(r, r0) base = [[1.0, 1.0, 0.0], [0.0, 2.0, 2.0], [3.0, 0.0, 3.0]] - self.lattice.set_lat_base(base) + self.lattice.set_new_latt_base_vec(base) r = repr(self.lattice) self.assertEqual(r, "Lattice(base=%r)" % self.lattice.base) From 74683b6d8d8e84ba72f96511ec7d61b84da9e277 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sun, 22 Feb 2026 19:52:30 -0500 Subject: [PATCH 160/226] fix: rename new function name in deprecation message and in news --- news/deprecate-lattice.rst | 4 ++-- src/diffpy/structure/lattice.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/news/deprecate-lattice.rst b/news/deprecate-lattice.rst index 6b8c6740..d3ef5438 100644 --- a/news/deprecate-lattice.rst +++ b/news/deprecate-lattice.rst @@ -1,7 +1,7 @@ **Added:** -* Added ``set_lat_par`` method into ``Lattice`` class -* Added ``set_lar_base`` method into ``Lattice`` class +* Added ``set_latt_parms`` method into ``Lattice`` class +* Added ``set_new_latt_base_vec`` method into ``Lattice`` class **Changed:** diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index f75e061c..76fe41d1 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -34,13 +34,13 @@ setLatPar_deprecation_msg = build_deprecation_message( base, "setLatPar", - "set_lat_parms", + "set_latt_parms", removal_version, ) setLatBase_deprecation_msg = build_deprecation_message( base, "setLatBase", - "set_lat_base", + "set_new_latt_base_vec", removal_version, ) From d09a89c65fd2864b507c49be5b8f95b3e7d1092e Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Mon, 23 Feb 2026 15:37:44 -0500 Subject: [PATCH 161/226] chore: deprecate abcABG and readStr method --- news/deprecate-lattice-readstr-method.rst | 25 +++++++++++++++++++++++ src/diffpy/structure/lattice.py | 15 ++++++++++++++ src/diffpy/structure/pdffitstructure.py | 9 ++++++++ tests/test_lattice.py | 6 +++--- tests/test_p_discus.py | 2 +- tests/test_structure.py | 11 +++++++++- tests/test_supercell.py | 4 ++-- 7 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 news/deprecate-lattice-readstr-method.rst diff --git a/news/deprecate-lattice-readstr-method.rst b/news/deprecate-lattice-readstr-method.rst new file mode 100644 index 00000000..31ff9ff4 --- /dev/null +++ b/news/deprecate-lattice-readstr-method.rst @@ -0,0 +1,25 @@ +**Added:** + +* Added ``read_structure`` method into ``PDFFitStructure`` class +* Added ``cell_parms`` method into ``Lattice`` class + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``readStr`` method in ``PDFFitStructure`` class for removal in version 4.0.0 +* Deprecated ``abcABG`` method in ``Lattice`` class for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/lattice.py b/src/diffpy/structure/lattice.py index 76fe41d1..bdef059a 100644 --- a/src/diffpy/structure/lattice.py +++ b/src/diffpy/structure/lattice.py @@ -43,6 +43,12 @@ "set_new_latt_base_vec", removal_version, ) +abcABG_deprecation_msg = build_deprecation_message( + base, + "abcABG", + "cell_parms", + removal_version, +) # Helper Functions ----------------------------------------------------------- @@ -559,7 +565,16 @@ def set_new_latt_base_vec(self, base): ) return + @deprecated(abcABG_deprecation_msg) def abcABG(self): + """'diffpy.structure.Lattice.abcABG' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.Lattice.cell_parms' instead. + """ + return self.cell_parms() + + def cell_parms(self): """Return the cell parameters in the standard setting. Returns diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index 9cad2d2d..7a49d28e 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -79,6 +79,15 @@ def read(self, filename, format="auto"): return p def readStr(self, s, format="auto"): + """'diffpy.structure.PDFFitStructure.readStr' is deprecated and + will be removed in version 4.0.0. + + Please use 'diffpy.structure.PDFFitStructure.read_structure' + instead. + """ + return self.read_structure(s, format) + + def read_structure(self, s, format="auto"): """Same as `Structure.readStr`, but update `spcgr` value in `self.pdffit` when parser can get spacegroup. diff --git a/tests/test_lattice.py b/tests/test_lattice.py index 48415352..c1cc80c8 100644 --- a/tests/test_lattice.py +++ b/tests/test_lattice.py @@ -50,7 +50,7 @@ def test___init__(self): L2 = Lattice(base=L0.base) self.assertTrue(numpy.array_equal(L0.base, L2.base)) self.assertTrue(numpy.array_equal(L0.isotropicunit, L2.isotropicunit)) - L3 = Lattice(*L0.abcABG(), baserot=L0.baserot) + L3 = Lattice(*L0.cell_parms(), baserot=L0.baserot) self.assertTrue(numpy.allclose(L0.base, L3.base)) self.assertTrue(numpy.allclose(L0.isotropicunit, L3.isotropicunit)) return @@ -229,10 +229,10 @@ def test_set_lat_base(self): def test_reciprocal(self): """Check calculation of reciprocal lattice.""" r1 = self.lattice.reciprocal() - self.assertEqual((1, 1, 1, 90, 90, 90), r1.abcABG()) + self.assertEqual((1, 1, 1, 90, 90, 90), r1.cell_parms()) L2 = Lattice(2, 4, 8, 90, 90, 90) r2 = L2.reciprocal() - self.assertEqual((0.5, 0.25, 0.125, 90, 90, 90), r2.abcABG()) + self.assertEqual((0.5, 0.25, 0.125, 90, 90, 90), r2.cell_parms()) rr2 = r2.reciprocal() self.assertTrue(numpy.array_equal(L2.base, rr2.base)) return diff --git a/tests/test_p_discus.py b/tests/test_p_discus.py index 1bfd7595..852acdfa 100644 --- a/tests/test_p_discus.py +++ b/tests/test_p_discus.py @@ -46,7 +46,7 @@ def test_read_discus_Ni(self): self.assertEqual("Fm-3m", stru.pdffit["spcgr"]) # cell record abcABG = (3.52, 3.52, 3.52, 90.0, 90.0, 90.0) - self.assertEqual(abcABG, stru.lattice.abcABG()) + self.assertEqual(abcABG, stru.lattice.cell_parms()) # ncell self.assertEqual([1, 1, 1, 4], stru.pdffit["ncell"]) self.assertEqual(4, len(stru)) diff --git a/tests/test_structure.py b/tests/test_structure.py index c5b17ce5..50445157 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -420,7 +420,7 @@ def test___imul__(self): self.assertEqual(0, len(self.stru)) return - def test__get_lattice(self): + def test__get_lattice_dep(self): """Check Structure._get_lattice()""" lat = Lattice() stru = Structure() @@ -429,6 +429,15 @@ def test__get_lattice(self): self.assertTrue(lat is stru2.lattice) return + def test__get_lattice(self): + """Check Structure._get_lattice()""" + lat = Lattice() + stru = Structure() + self.assertEqual((1, 1, 1, 90, 90, 90), stru.lattice.cell_parms()) + stru2 = Structure(lattice=lat) + self.assertTrue(lat is stru2.lattice) + return + def test__set_lattice(self): """Check Structure._set_lattice()""" lat = Lattice() diff --git a/tests/test_supercell.py b/tests/test_supercell.py index d20434ca..1b476c46 100644 --- a/tests/test_supercell.py +++ b/tests/test_supercell.py @@ -59,8 +59,8 @@ def test_ni_supercell(self): """Check supercell expansion for Ni.""" ni_123 = supercell(self.stru_ni, (1, 2, 3)) self.assertEqual(6 * len(self.stru_ni), len(ni_123)) - a, b, c = self.stru_ni.lattice.abcABG()[:3] - a1, b2, c3 = ni_123.lattice.abcABG()[:3] + a, b, c = self.stru_ni.lattice.cell_parms()[:3] + a1, b2, c3 = ni_123.lattice.cell_parms()[:3] self.assertAlmostEqual(a, a1, 8) self.assertAlmostEqual(b * 2, b2, 8) self.assertAlmostEqual(c * 3, c3, 8) From 99575aaf9a3b5f8a6a2f840ddbdb59b9035cb0a0 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 12:47:48 -0500 Subject: [PATCH 162/226] chore: deprecate methods in --- news/deprecate-symmetryutilities-1.rst | 25 +++++++++++++++ src/diffpy/structure/pdffitstructure.py | 11 +++++++ src/diffpy/structure/symmetryutilities.py | 38 ++++++++++++++++++++++- tests/test_symmetryutilities.py | 35 +++++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 news/deprecate-symmetryutilities-1.rst diff --git a/news/deprecate-symmetryutilities-1.rst b/news/deprecate-symmetryutilities-1.rst new file mode 100644 index 00000000..a6ccd9bc --- /dev/null +++ b/news/deprecate-symmetryutilities-1.rst @@ -0,0 +1,25 @@ +**Added:** + +* Added ``is_space_group_lat_par`` method in ``symmetryutilities.py`` +* Added ``is_constant_formula`` method in ``symmetryutilities.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``isSpaceGroupLatPar`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``isconstantFormula`` method in ``symmetryutilities.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index 7a49d28e..23f40350 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -16,6 +16,16 @@ from diffpy.structure.structure import Structure +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.PDFFitStructure" +removal_version = "4.0.0" +readStr_deprecation_msg = build_deprecation_message( + base, + "isSpaceGroupLatPar", + "is_space_group_lat_par", + removal_version, +) # ---------------------------------------------------------------------------- @@ -78,6 +88,7 @@ def read(self, filename, format="auto"): self.pdffit["spcgr"] = sg.short_name return p + @deprecated(readStr_deprecation_msg) def readStr(self, s, format="auto"): """'diffpy.structure.PDFFitStructure.readStr' is deprecated and will be removed in version 4.0.0. diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index d2556661..edf81fdf 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -32,6 +32,22 @@ import numpy from diffpy.structure.structureerrors import SymmetryError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure" +removal_version = "4.0.0" +isSpaceGroupLatPar_deprecation_msg = build_deprecation_message( + base, + "isSpaceGroupLatPar", + "is_space_group_lat_par", + removal_version, +) +isconstantFormula_deprecation_msg = build_deprecation_message( + base, + "isconstantFormula", + "is_constant_formula", + removal_version, +) # Constants ------------------------------------------------------------------ @@ -42,7 +58,17 @@ # ---------------------------------------------------------------------------- +@deprecated(isSpaceGroupLatPar_deprecation_msg) def isSpaceGroupLatPar(spacegroup, a, b, c, alpha, beta, gamma): + """'diffpy.structure.isSpaceGroupLatPar' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.is_space_group_lat_par' instead. + """ + return is_space_group_lat_par(spacegroup, a, b, c, alpha, beta, gamma) + + +def is_space_group_lat_par(spacegroup, a, b, c, alpha, beta, gamma): """Check if space group allows passed lattice parameters. Parameters @@ -110,7 +136,17 @@ def check_cubic(): _rx_constant_formula = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)??(/[-+]?\d+)?$") +@deprecated(isconstantFormula_deprecation_msg) def isconstantFormula(s): + """'diffpy.structure.isconstantFormula' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.is_constant_formula' instead. + """ + return is_constant_formula(s) + + +def is_constant_formula(s): """Check if formula string is constant. Parameters @@ -837,7 +873,7 @@ def pruneFormulaDictionary(eqdict): """ pruned = {} for smb, eq in eqdict.items(): - if not isconstantFormula(eq): + if not is_constant_formula(eq): pruned[smb] = eq return pruned diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 5002a293..caad3a8d 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -27,6 +27,8 @@ SymmetryConstraints, _Position2Tuple, expandPosition, + is_constant_formula, + is_space_group_lat_par, isconstantFormula, isSpaceGroupLatPar, pruneFormulaDictionary, @@ -67,6 +69,30 @@ def test_isSpaceGroupLatPar(self): self.assertTrue(isSpaceGroupLatPar(cubic, 3, 3, 3, 90, 90, 90)) return + def test_is_space_group_lat_par(self): + """Check isSpaceGroupLatPar()""" + triclinic = GetSpaceGroup("P1") + monoclinic = GetSpaceGroup("P2") + orthorhombic = GetSpaceGroup("P222") + tetragonal = GetSpaceGroup("P4") + trigonal = GetSpaceGroup("P3") + hexagonal = GetSpaceGroup("P6") + cubic = GetSpaceGroup("P23") + self.assertTrue(is_space_group_lat_par(triclinic, 1, 2, 3, 40, 50, 60)) + self.assertFalse(is_space_group_lat_par(monoclinic, 1, 2, 3, 40, 50, 60)) + self.assertTrue(is_space_group_lat_par(monoclinic, 1, 2, 3, 90, 50, 90)) + self.assertFalse(is_space_group_lat_par(orthorhombic, 1, 2, 3, 90, 50, 90)) + self.assertTrue(is_space_group_lat_par(orthorhombic, 1, 2, 3, 90, 90, 90)) + self.assertFalse(is_space_group_lat_par(tetragonal, 1, 2, 3, 90, 90, 90)) + self.assertTrue(is_space_group_lat_par(tetragonal, 2, 2, 3, 90, 90, 90)) + self.assertFalse(is_space_group_lat_par(trigonal, 2, 2, 3, 90, 90, 90)) + self.assertTrue(is_space_group_lat_par(trigonal, 2, 2, 2, 80, 80, 80)) + self.assertFalse(is_space_group_lat_par(hexagonal, 2, 2, 2, 80, 80, 80)) + self.assertTrue(is_space_group_lat_par(hexagonal, 2, 2, 3, 90, 90, 120)) + self.assertFalse(is_space_group_lat_par(cubic, 2, 2, 3, 90, 90, 120)) + self.assertTrue(is_space_group_lat_par(cubic, 3, 3, 3, 90, 90, 90)) + return + def test_sgtbx_spacegroup_aliases(self): """Check GetSpaceGroup for non-standard aliases from sgtbx.""" self.assertIs(GetSpaceGroup("Fm3m"), GetSpaceGroup(225)) @@ -100,6 +126,15 @@ def test_isconstantFormula(self): self.assertTrue(isconstantFormula("+13/ 9")) return + def test_is_constant_formula(self): + """Check isconstantFormula()""" + self.assertFalse(is_constant_formula("x-y+z")) + self.assertTrue(is_constant_formula("6.023e23")) + self.assertTrue(is_constant_formula("22/7")) + self.assertTrue(is_constant_formula("- 22/7")) + self.assertTrue(is_constant_formula("+13/ 9")) + return + # End of class TestRoutines From 9a4195a134581b955159d6493b2ec0ef8c01a713 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 15:12:54 -0500 Subject: [PATCH 163/226] fix: fix deprecation message and rename the snakecase method to be consistent. --- news/deprecate-symmetryutilities-1.rst | 2 +- src/diffpy/structure/pdffitstructure.py | 4 ++-- src/diffpy/structure/symmetryutilities.py | 8 +++---- tests/test_symmetryutilities.py | 28 +++++++++++------------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/news/deprecate-symmetryutilities-1.rst b/news/deprecate-symmetryutilities-1.rst index a6ccd9bc..36cde7fa 100644 --- a/news/deprecate-symmetryutilities-1.rst +++ b/news/deprecate-symmetryutilities-1.rst @@ -1,6 +1,6 @@ **Added:** -* Added ``is_space_group_lat_par`` method in ``symmetryutilities.py`` +* Added ``is_space_group_latt_parms`` method in ``symmetryutilities.py`` * Added ``is_constant_formula`` method in ``symmetryutilities.py`` **Changed:** diff --git a/src/diffpy/structure/pdffitstructure.py b/src/diffpy/structure/pdffitstructure.py index 23f40350..2ee1f7ac 100644 --- a/src/diffpy/structure/pdffitstructure.py +++ b/src/diffpy/structure/pdffitstructure.py @@ -22,8 +22,8 @@ removal_version = "4.0.0" readStr_deprecation_msg = build_deprecation_message( base, - "isSpaceGroupLatPar", - "is_space_group_lat_par", + "readStr", + "read_structure", removal_version, ) diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index edf81fdf..57d6b433 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -39,7 +39,7 @@ isSpaceGroupLatPar_deprecation_msg = build_deprecation_message( base, "isSpaceGroupLatPar", - "is_space_group_lat_par", + "is_space_group_latt_parms", removal_version, ) isconstantFormula_deprecation_msg = build_deprecation_message( @@ -63,12 +63,12 @@ def isSpaceGroupLatPar(spacegroup, a, b, c, alpha, beta, gamma): """'diffpy.structure.isSpaceGroupLatPar' is deprecated and will be removed in version 4.0.0. - Please use 'diffpy.structure.is_space_group_lat_par' instead. + Please use 'diffpy.structure.is_space_group_latt_parms' instead. """ - return is_space_group_lat_par(spacegroup, a, b, c, alpha, beta, gamma) + return is_space_group_latt_parms(spacegroup, a, b, c, alpha, beta, gamma) -def is_space_group_lat_par(spacegroup, a, b, c, alpha, beta, gamma): +def is_space_group_latt_parms(spacegroup, a, b, c, alpha, beta, gamma): """Check if space group allows passed lattice parameters. Parameters diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index caad3a8d..fabe40ec 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -28,7 +28,7 @@ _Position2Tuple, expandPosition, is_constant_formula, - is_space_group_lat_par, + is_space_group_latt_parms, isconstantFormula, isSpaceGroupLatPar, pruneFormulaDictionary, @@ -78,19 +78,19 @@ def test_is_space_group_lat_par(self): trigonal = GetSpaceGroup("P3") hexagonal = GetSpaceGroup("P6") cubic = GetSpaceGroup("P23") - self.assertTrue(is_space_group_lat_par(triclinic, 1, 2, 3, 40, 50, 60)) - self.assertFalse(is_space_group_lat_par(monoclinic, 1, 2, 3, 40, 50, 60)) - self.assertTrue(is_space_group_lat_par(monoclinic, 1, 2, 3, 90, 50, 90)) - self.assertFalse(is_space_group_lat_par(orthorhombic, 1, 2, 3, 90, 50, 90)) - self.assertTrue(is_space_group_lat_par(orthorhombic, 1, 2, 3, 90, 90, 90)) - self.assertFalse(is_space_group_lat_par(tetragonal, 1, 2, 3, 90, 90, 90)) - self.assertTrue(is_space_group_lat_par(tetragonal, 2, 2, 3, 90, 90, 90)) - self.assertFalse(is_space_group_lat_par(trigonal, 2, 2, 3, 90, 90, 90)) - self.assertTrue(is_space_group_lat_par(trigonal, 2, 2, 2, 80, 80, 80)) - self.assertFalse(is_space_group_lat_par(hexagonal, 2, 2, 2, 80, 80, 80)) - self.assertTrue(is_space_group_lat_par(hexagonal, 2, 2, 3, 90, 90, 120)) - self.assertFalse(is_space_group_lat_par(cubic, 2, 2, 3, 90, 90, 120)) - self.assertTrue(is_space_group_lat_par(cubic, 3, 3, 3, 90, 90, 90)) + self.assertTrue(is_space_group_latt_parms(triclinic, 1, 2, 3, 40, 50, 60)) + self.assertFalse(is_space_group_latt_parms(monoclinic, 1, 2, 3, 40, 50, 60)) + self.assertTrue(is_space_group_latt_parms(monoclinic, 1, 2, 3, 90, 50, 90)) + self.assertFalse(is_space_group_latt_parms(orthorhombic, 1, 2, 3, 90, 50, 90)) + self.assertTrue(is_space_group_latt_parms(orthorhombic, 1, 2, 3, 90, 90, 90)) + self.assertFalse(is_space_group_latt_parms(tetragonal, 1, 2, 3, 90, 90, 90)) + self.assertTrue(is_space_group_latt_parms(tetragonal, 2, 2, 3, 90, 90, 90)) + self.assertFalse(is_space_group_latt_parms(trigonal, 2, 2, 3, 90, 90, 90)) + self.assertTrue(is_space_group_latt_parms(trigonal, 2, 2, 2, 80, 80, 80)) + self.assertFalse(is_space_group_latt_parms(hexagonal, 2, 2, 2, 80, 80, 80)) + self.assertTrue(is_space_group_latt_parms(hexagonal, 2, 2, 3, 90, 90, 120)) + self.assertFalse(is_space_group_latt_parms(cubic, 2, 2, 3, 90, 90, 120)) + self.assertTrue(is_space_group_latt_parms(cubic, 3, 3, 3, 90, 90, 90)) return def test_sgtbx_spacegroup_aliases(self): From 358df45177d4d7f92b4d8d5a4813f6ef8c4d6206 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 16:42:31 -0500 Subject: [PATCH 164/226] chore:deprecate method in and add test for methods --- news/deprecate-symmetryutilities-2.rst | 26 ++++++++++++ src/diffpy/structure/symmetryutilities.py | 51 +++++++++++++++++++---- tests/test_symmetryutilities.py | 28 +++++++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 news/deprecate-symmetryutilities-2.rst diff --git a/news/deprecate-symmetryutilities-2.rst b/news/deprecate-symmetryutilities-2.rst new file mode 100644 index 00000000..4e2d5abe --- /dev/null +++ b/news/deprecate-symmetryutilities-2.rst @@ -0,0 +1,26 @@ +**Added:** + +* Added ``position_difference`` method in ``symmetryutilities.py`` +* Added ``nearest_site_index`` method in ``symmetryutilities.py`` +* Added ``_find_invariants`` method in ``symmetryutilities.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``positionDifference`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``nearestSiteIndex`` method in ``symmetryutilities.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 57d6b433..edb04de4 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -48,6 +48,18 @@ "is_constant_formula", removal_version, ) +positionDifference_deprecation_msg = build_deprecation_message( + base, + "positionDifference", + "position_difference", + removal_version, +) +nearestSiteIndex_deprecation_msg = build_deprecation_message( + base, + "nearestSiteIndex", + "nearest_site_index", + removal_version, +) # Constants ------------------------------------------------------------------ @@ -223,7 +235,17 @@ def __call__(self, xyz): # End of class _Position2Tuple +@deprecated(positionDifference_deprecation_msg) def positionDifference(xyz0, xyz1): + """'diffpy.structure.positionDifference' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.position_difference' instead. + """ + return position_difference(xyz0, xyz1) + + +def position_difference(xyz0, xyz1): """Smallest difference between two coordinates in periodic lattice. Parameters @@ -245,7 +267,18 @@ def positionDifference(xyz0, xyz1): return dxyz +@deprecated(nearestSiteIndex_deprecation_msg) def nearestSiteIndex(sites, xyz): + """'diffpy.structure.nearestSiteIndex' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.nearest_site_index' instead. + """ + # we use box distance to be consistent with _Position2Tuple conversion + return nearest_site_index(sites, xyz) + + +def nearest_site_index(sites, xyz): """Index of the nearest site to a specified position. Parameters @@ -261,7 +294,7 @@ def nearestSiteIndex(sites, xyz): Index of the nearest site. """ # we use box distance to be consistent with _Position2Tuple conversion - dbox = positionDifference(sites, xyz).max(axis=1) + dbox = position_difference(sites, xyz).max(axis=1) nearindex = numpy.argmin(dbox) return nearindex @@ -282,7 +315,7 @@ def equalPositions(xyz0, xyz1, eps): ``True`` when two coordinates are closer than `eps`. """ # we use box distance to be consistent with _Position2Tuple conversion - dxyz = positionDifference(xyz0, xyz1) + dxyz = position_difference(xyz0, xyz1) return numpy.all(dxyz <= eps) @@ -323,7 +356,7 @@ def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): site_symops[tpl] = [] # double check if there is any position nearby if positions: - nearpos = positions[nearestSiteIndex(positions, pos)] + nearpos = positions[nearest_site_index(positions, pos)] # is it an equivalent position? if equalPositions(nearpos, pos, eps): # tpl should map to the same list as nearpos @@ -352,7 +385,7 @@ def nullSpace(A): return null_space -def _findInvariants(symops): +def _find_invariants(symops): """Find a list of symmetry operations which contains identity. Parameters @@ -495,7 +528,7 @@ def __init__( self.Uparameters = [] # fill in the values sites, ops, mult = expandPosition(spacegroup, xyz, sgoffset, eps) - invariants = _findInvariants(ops) + invariants = _find_invariants(ops) # shift self.xyz exactly to the special position if mult > 1: xyzdups = numpy.array([op(xyz + self.sgoffset) - self.sgoffset for op in invariants]) @@ -506,7 +539,7 @@ def __init__( self.xyz = xyz + dxyz self.xyz[numpy.fabs(self.xyz) < self.eps] = 0.0 sites, ops, mult = expandPosition(spacegroup, self.xyz, self.sgoffset, eps) - invariants = _findInvariants(ops) + invariants = _find_invariants(ops) # self.xyz, sites, ops are all adjusted here self.eqxyz = sites self.symops = ops @@ -681,7 +714,7 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): ``-x``, ``z +0.5``, ``0.25``. """ # find pos in eqxyz - idx = nearestSiteIndex(self.eqxyz, pos) + idx = nearest_site_index(self.eqxyz, pos) eqpos = self.eqxyz[idx] if not equalPositions(eqpos, pos, self.eps): return {} @@ -733,7 +766,7 @@ def UFormula(self, pos, Usymbols=stdUsymbols): pos is not equivalent to generator. """ # find pos in eqxyz - idx = nearestSiteIndex(self.eqxyz, pos) + idx = nearest_site_index(self.eqxyz, pos) eqpos = self.eqxyz[idx] if not equalPositions(eqpos, pos, self.eps): return {} @@ -772,7 +805,7 @@ def eqIndex(self, pos): int Index of the nearest generator equivalent site. """ - return nearestSiteIndex(self.eqxyz, pos) + return nearest_site_index(self.eqxyz, pos) # End of class GeneratorSite diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index fabe40ec..6e142a32 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -31,6 +31,10 @@ is_space_group_latt_parms, isconstantFormula, isSpaceGroupLatPar, + nearest_site_index, + nearestSiteIndex, + position_difference, + positionDifference, pruneFormulaDictionary, ) @@ -99,6 +103,30 @@ def test_sgtbx_spacegroup_aliases(self): self.assertIs(GetSpaceGroup("Ia3d"), GetSpaceGroup("I a -3 d")) return + def test_positionDifference(self): + """Check positionDifference in normal and boundary cases.""" + self.assertTrue(numpy.allclose(positionDifference([0.1, 0.9, 0.2], [0.9, 0.1, 0.8]), [0.2, 0.2, 0.4])) + self.assertTrue(numpy.allclose(positionDifference([1.2, -0.1, 2.75], [0.1, 0.4, 0.25]), [0.1, 0.5, 0.5])) + return + + def test_position_difference(self): + """Check positionDifference in normal and boundary cases.""" + self.assertTrue(numpy.allclose(position_difference([0.1, 0.9, 0.2], [0.8, 0.1, 0.8]), [0.3, 0.2, 0.4])) + self.assertTrue(numpy.allclose(position_difference([1.2, -0.1, 2.75], [0.1, 0.4, 0.25]), [0.1, 0.5, 0.5])) + return + + def test_nearestSiteIndex(self): + """Check nearestSiteIndex with single and multiple sites.""" + self.assertEqual(nearestSiteIndex([[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], [0.8, 0.1, 0.8]), 1) + self.assertEqual(nearestSiteIndex([[1.2, -0.1, 2.75]], [0.7, 0.4, 0.25]), 0) + return + + def test_nearest_site_index(self): + """Check nearestSiteIndex with single and multiple sites.""" + self.assertEqual(nearest_site_index([[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], [0.8, 0.1, 0.8]), 1) + self.assertEqual(nearest_site_index([[1.2, -0.1, 2.75]], [0.7, 0.4, 0.25]), 0) + return + def test_expandPosition(self): """Check expandPosition()""" # ok again Ni example From d19c025cc7f26cbbc628b699434a6b662351f782 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 16:44:04 -0500 Subject: [PATCH 165/226] fix: fix docstring for method in test. --- tests/test_symmetryutilities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 6e142a32..04156b8a 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -110,7 +110,7 @@ def test_positionDifference(self): return def test_position_difference(self): - """Check positionDifference in normal and boundary cases.""" + """Check position_difference in normal and boundary cases.""" self.assertTrue(numpy.allclose(position_difference([0.1, 0.9, 0.2], [0.8, 0.1, 0.8]), [0.3, 0.2, 0.4])) self.assertTrue(numpy.allclose(position_difference([1.2, -0.1, 2.75], [0.1, 0.4, 0.25]), [0.1, 0.5, 0.5])) return @@ -122,7 +122,7 @@ def test_nearestSiteIndex(self): return def test_nearest_site_index(self): - """Check nearestSiteIndex with single and multiple sites.""" + """Check nearest_site_index with single and multiple sites.""" self.assertEqual(nearest_site_index([[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], [0.8, 0.1, 0.8]), 1) self.assertEqual(nearest_site_index([[1.2, -0.1, 2.75]], [0.7, 0.4, 0.25]), 0) return From 6a25991bd695ac46e46366316227719a7b92a2f5 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 19:55:57 -0500 Subject: [PATCH 166/226] chore: changeg unittest to pytest --- tests/test_symmetryutilities.py | 54 +++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 04156b8a..289c22bb 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -19,6 +19,7 @@ import unittest import numpy +import pytest from diffpy.structure.spacegroups import GetSpaceGroup from diffpy.structure.symmetryutilities import ( @@ -109,24 +110,12 @@ def test_positionDifference(self): self.assertTrue(numpy.allclose(positionDifference([1.2, -0.1, 2.75], [0.1, 0.4, 0.25]), [0.1, 0.5, 0.5])) return - def test_position_difference(self): - """Check position_difference in normal and boundary cases.""" - self.assertTrue(numpy.allclose(position_difference([0.1, 0.9, 0.2], [0.8, 0.1, 0.8]), [0.3, 0.2, 0.4])) - self.assertTrue(numpy.allclose(position_difference([1.2, -0.1, 2.75], [0.1, 0.4, 0.25]), [0.1, 0.5, 0.5])) - return - def test_nearestSiteIndex(self): """Check nearestSiteIndex with single and multiple sites.""" self.assertEqual(nearestSiteIndex([[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], [0.8, 0.1, 0.8]), 1) self.assertEqual(nearestSiteIndex([[1.2, -0.1, 2.75]], [0.7, 0.4, 0.25]), 0) return - def test_nearest_site_index(self): - """Check nearest_site_index with single and multiple sites.""" - self.assertEqual(nearest_site_index([[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], [0.8, 0.1, 0.8]), 1) - self.assertEqual(nearest_site_index([[1.2, -0.1, 2.75]], [0.7, 0.4, 0.25]), 0) - return - def test_expandPosition(self): """Check expandPosition()""" # ok again Ni example @@ -674,5 +663,46 @@ def test_UparValues(self): # ---------------------------------------------------------------------------- + +@pytest.mark.parametrize( + "xyz0, xyz1, expected", + [ + pytest.param( # C1: Generic case for symmetry mapping for periodic lattice + [0.1, 0.9, 0.2], + [0.8, 0.1, 0.8], + [0.3, 0.2, 0.4], + ), + pytest.param( # C2: Boundary case for entries with mapping on difference equal to 0.5 + [1.2, -0.1, 2.75], + [0.1, 0.4, 0.25], + [0.1, 0.5, 0.5], + ), + ], +) +def test_position_difference(xyz0, xyz1, expected): + actual = position_difference(xyz0, xyz1) + assert numpy.allclose(actual, expected) + + +@pytest.mark.parametrize( + "sites, xyz, expected", + [ + pytest.param( # C1: We have two sites, and the xyz is closest to the index 1 site + [[0.1, 0.9, 0.2], [0.8, 0.1, 0.8]], + [0.8, 0.1, 0.8], + 1, + ), + pytest.param( # C2: we have one site, and the xyz is closest to the index 0 site by default + [[1.2, -0.1, 2.75]], + [0.7, 0.4, 0.25], + 0, + ), + ], +) +def test_nearest_site_index(sites, xyz, expected): + actual = nearest_site_index(sites, xyz) + assert actual == expected + + if __name__ == "__main__": unittest.main() From ba5eabec0b89d1ed2803801705987ca32c3f0bcd Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Feb 2026 23:10:51 -0500 Subject: [PATCH 167/226] chore: deprecate method in symmetryutilities --- news/deprecate-symmetryutilities-3.rst | 27 ++++++ src/diffpy/structure/symmetryutilities.py | 58 ++++++++++-- tests/test_symmetryutilities.py | 102 ++++++++++++++++++++++ 3 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 news/deprecate-symmetryutilities-3.rst diff --git a/news/deprecate-symmetryutilities-3.rst b/news/deprecate-symmetryutilities-3.rst new file mode 100644 index 00000000..0527f8ba --- /dev/null +++ b/news/deprecate-symmetryutilities-3.rst @@ -0,0 +1,27 @@ +**Added:** + +* Added ``equal_positions`` method in ``symmetryutilities.py`` +* Added ``expand_position`` method in ``symmetryutilities.py`` +* Added ``null_space`` method in ``symmetryutilities.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``equalPositions`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``expandPosition`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``nullSpace`` method in ``symmetryutilities.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index edb04de4..7f504712 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -60,6 +60,24 @@ "nearest_site_index", removal_version, ) +equalPositions_deprecation_msg = build_deprecation_message( + base, + "equalPositions", + "equal_positions", + removal_version, +) +expandPosition_deprecation_msg = build_deprecation_message( + base, + "expandPosition", + "expand_position", + removal_version, +) +nullSpace_deprecation_msg = build_deprecation_message( + base, + "nullSpace", + "null_space", + removal_version, +) # Constants ------------------------------------------------------------------ @@ -299,7 +317,17 @@ def nearest_site_index(sites, xyz): return nearindex +@deprecated(equalPositions_deprecation_msg) def equalPositions(xyz0, xyz1, eps): + """'diffpy.structure.equalPositions' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.equal_positions' instead. + """ + return equal_positions(xyz0, xyz1, eps) + + +def equal_positions(xyz0, xyz1, eps): """Equality of two coordinates with optional tolerance. Parameters @@ -319,7 +347,17 @@ def equalPositions(xyz0, xyz1, eps): return numpy.all(dxyz <= eps) +@deprecated(expandPosition_deprecation_msg) def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): + """'diffpy.structure.expandPosition' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.expand_position' instead. + """ + return expand_position(spacegroup, xyz, sgoffset, eps) + + +def expand_position(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): """Obtain unique equivalent positions and corresponding operations. Parameters @@ -358,7 +396,7 @@ def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): if positions: nearpos = positions[nearest_site_index(positions, pos)] # is it an equivalent position? - if equalPositions(nearpos, pos, eps): + if equal_positions(nearpos, pos, eps): # tpl should map to the same list as nearpos site_symops[tpl] = site_symops[pos2tuple(nearpos)] pos_is_new = False @@ -372,7 +410,17 @@ def expandPosition(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): return positions, pos_symops, multiplicity +@deprecated(nullSpace_deprecation_msg) def nullSpace(A): + """'diffpy.structure.nullSpace' is deprecated and will be + removed in version 4.0.0. + + Please use 'diffpy.structure.null_space' instead. + """ + return null_space(A) + + +def null_space(A): """Null space of matrix A.""" from numpy import linalg @@ -588,7 +636,7 @@ def _findNullSpace(self): R0 = self.invariants[0].R Rdiff = [(symop.R - R0) for symop in self.invariants] Rdiff = numpy.concatenate(Rdiff, axis=0) - self.null_space = nullSpace(Rdiff) + self.null_space = null_space(Rdiff) if self.null_space.size == 0: return # reverse sort rows of null_space rows by absolute value @@ -649,7 +697,7 @@ def _findUSpace(self): Ucj2 = numpy.dot(R, numpy.dot(Ucj, R.T)) for i, kl in i6kl: R6z[i, j] += Ucj2[kl] - Usp6 = nullSpace(R6zall) + Usp6 = null_space(R6zall) # normalize Usp6 by its maximum component mxcols = numpy.argmax(numpy.fabs(Usp6), axis=1) mxrows = numpy.arange(len(mxcols)) @@ -716,7 +764,7 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): # find pos in eqxyz idx = nearest_site_index(self.eqxyz, pos) eqpos = self.eqxyz[idx] - if not equalPositions(eqpos, pos, self.eps): + if not equal_positions(eqpos, pos, self.eps): return {} # any rotation matrix should do fine R = self.symops[idx][0].R @@ -768,7 +816,7 @@ def UFormula(self, pos, Usymbols=stdUsymbols): # find pos in eqxyz idx = nearest_site_index(self.eqxyz, pos) eqpos = self.eqxyz[idx] - if not equalPositions(eqpos, pos, self.eps): + if not equal_positions(eqpos, pos, self.eps): return {} # any rotation matrix should do fine R = self.symops[idx][0].R diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 289c22bb..e618c5f0 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -27,6 +27,9 @@ GeneratorSite, SymmetryConstraints, _Position2Tuple, + equal_positions, + equalPositions, + expand_position, expandPosition, is_constant_formula, is_space_group_latt_parms, @@ -34,6 +37,8 @@ isSpaceGroupLatPar, nearest_site_index, nearestSiteIndex, + null_space, + nullSpace, position_difference, positionDifference, pruneFormulaDictionary, @@ -127,6 +132,17 @@ def test_expandPosition(self): self.assertEqual(4, pmult) return + def test_expand_position(self): + """Check expand_position()""" + # ok again Ni example + fcc = GetSpaceGroup(225) + pos, pops, pmult = expand_position(fcc, [0, 0, 0]) + self.assertTrue(numpy.all(pos[0] == 0.0)) + self.assertEqual(4, len(pos)) + self.assertEqual(192, sum([len(line) for line in pops])) + self.assertEqual(4, pmult) + return + def test_pruneFormulaDictionary(self): """Check pruneFormulaDictionary()""" fmdict = {"x": "3*y-0.17", "y": "0", "z": "0.13"} @@ -152,6 +168,12 @@ def test_is_constant_formula(self): self.assertTrue(is_constant_formula("+13/ 9")) return + def test_equalPositions(self): + """Check equalPositions()""" + self.assertTrue(equalPositions([0.1, 0.2, 0.3], [0.1, 0.2, 0.3], 1.0e-5)) + self.assertTrue(equalPositions([0.1 + 0.5e-5, 0.2 + 0.5e-5, 0.3 + 0.5e-5], [0.1, 0.2, 0.3], 1.0e-5)) + self.assertFalse(equalPositions([0.2, 0.2, 0.3], [0.1, 0.2, 0.3], 1.0e-5)) + # End of class TestRoutines @@ -704,5 +726,85 @@ def test_nearest_site_index(sites, xyz, expected): assert actual == expected +@pytest.mark.parametrize( + "xyz0, xyz1, eps, expected", + [ + pytest.param([0.1, 0.2, 0.3], [0.1, 0.2, 0.3], 1.0e-5, True), # C1: same position + pytest.param( + [0.1 + 0.5e-5, 0.2 + 0.5e-5, 0.3 + 0.5e-5], [0.1, 0.2, 0.3], 1.0e-5, True + ), # C2: same position with some tolerance + pytest.param([0.2, 0.2, 0.3], [0.1, 0.2, 0.3], 1.0e-5, False), # C3: different positions + ], +) +def test_equal_positions(xyz0, xyz1, eps, expected): + """Check equalPositions.""" + actual = equal_positions(xyz0, xyz1, eps) + assert actual == expected + + +@pytest.mark.parametrize( + "A, expected_dim", + [ + pytest.param( # C1: full-rank 2x2 matrix + [[1.0, 0.0], [0.0, 1.0]], + 0, + ), + pytest.param( # C2: Nullspace has dim 1 + [[1.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 2.0]], + 1, + ), + pytest.param( # C3: Nullspace has dim 2 + [[1.0, 2.0, 3.0], [2.0, 4.0, 6.0], [0.0, 0.0, 0.0]], + 2, + ), + pytest.param( # C4: Nullspace has dim 2 + [[0.0, 0.0], [0.0, 0.0]], + 2, + ), + ], +) +def test_nullSpace(A, expected_dim): + """Check nullSpace returns an orthonormal basis on supported square + matrices.""" + A = numpy.asarray(A, dtype=float) + actual = nullSpace(A) + + assert actual.shape == (expected_dim, A.shape[1]) + assert numpy.allclose(A @ actual.T, numpy.zeros((A.shape[0], expected_dim)), atol=1e-12) + assert numpy.allclose(actual @ actual.T, numpy.eye(expected_dim), atol=1e-12) + + +@pytest.mark.parametrize( + "A, expected_dim", + [ + pytest.param( # C1: full-rank 2x2 matrix + [[1.0, 0.0], [0.0, 1.0]], + 0, + ), + pytest.param( # C2: Nullspace has dim 1 + [[1.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 2.0]], + 1, + ), + pytest.param( # C3: Nullspace has dim 2 + [[1.0, 2.0, 3.0], [2.0, 4.0, 6.0], [0.0, 0.0, 0.0]], + 2, + ), + pytest.param( # C4: Nullspace has dim 2 + [[0.0, 0.0], [0.0, 0.0]], + 2, + ), + ], +) +def test_null_space(A, expected_dim): + """Check null_space returns an orthonormal basis on supported square + matrices.""" + A = numpy.asarray(A, dtype=float) + actual = null_space(A) + + assert actual.shape == (expected_dim, A.shape[1]) + assert numpy.allclose(A @ actual.T, numpy.zeros((A.shape[0], expected_dim)), atol=1e-12) + assert numpy.allclose(actual @ actual.T, numpy.eye(expected_dim), atol=1e-12) + + if __name__ == "__main__": unittest.main() From f93a859ee10c04536bdd7f6334ed645bf02fe6c2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 04:12:41 +0000 Subject: [PATCH 168/226] [pre-commit.ci] auto fixes from pre-commit hooks --- src/diffpy/structure/symmetryutilities.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 7f504712..63a3bc3d 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -412,8 +412,8 @@ def expand_position(spacegroup, xyz, sgoffset=[0, 0, 0], eps=None): @deprecated(nullSpace_deprecation_msg) def nullSpace(A): - """'diffpy.structure.nullSpace' is deprecated and will be - removed in version 4.0.0. + """'diffpy.structure.nullSpace' is deprecated and will be removed in + version 4.0.0. Please use 'diffpy.structure.null_space' instead. """ From 7bd0db12fe5f41f283498555d53bb5c566794d98 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Wed, 25 Feb 2026 20:40:59 -0500 Subject: [PATCH 169/226] chore: deprecate method in GeneratorSite class --- news/deprecate-symmetryutilities-4.rst | 28 +++++++++++++++ src/diffpy/structure/symmetryutilities.py | 43 ++++++++++++++++------- tests/test_symmetryutilities.py | 7 ++++ 3 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 news/deprecate-symmetryutilities-4.rst diff --git a/news/deprecate-symmetryutilities-4.rst b/news/deprecate-symmetryutilities-4.rst new file mode 100644 index 00000000..0fa11e83 --- /dev/null +++ b/news/deprecate-symmetryutilities-4.rst @@ -0,0 +1,28 @@ +**Added:** + +* Added ``convert_fp_num_to_signed_rational`` method in ``GeneratorSite`` class +* Added ``_find_null_space`` method in ``GeneratorSite`` class +* Added ``_find_pos_parameters`` method in ``GeneratorSite`` class +* Added ``_find_u_space`` method in ``GeneratorSite`` class +* Added ``_find_u_parameters`` method in ``GeneratorSite`` class +* Added ``_find_equij`` method in ``GeneratorSite`` class + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``signedRatStr`` method in in ``GeneratorSite`` class for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 63a3bc3d..2f0674eb 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -469,6 +469,14 @@ def _find_invariants(symops): # ---------------------------------------------------------------------------- +generator_site = "diffpy.symmetryutilities.GeneratorSite" +signedRatStr_deprecation_msg = build_deprecation_message( + generator_site, + "signedRatStr", + "convert_fp_num_to_signed_rational", + removal_version, +) + class GeneratorSite(object): """Storage of data related to a generator positions. @@ -593,14 +601,14 @@ def __init__( self.symops = ops self.multiplicity = mult self.invariants = invariants - self._findNullSpace() - self._findPosParameters() - self._findUSpace() - self._findUParameters() - self._findeqUij() + self._find_null_space() + self._find_pos_parameters() + self._find_u_space() + self._find_u_parameters() + self._find_equij() return - def signedRatStr(self, x): + def convert_fp_num_to_signed_rational(self, x): """Convert floating point number to signed rational representation. @@ -628,7 +636,16 @@ def signedRatStr(self, x): # here we have fraction return "%+.0f/%.0f" % (nom[idx[0]], den[idx[0]]) - def _findNullSpace(self): + @deprecated(signedRatStr_deprecation_msg) + def signedRatStr(self, x): + """'diffpy.structure.GeneratorSite.signedRatStr' is deprecated + and will be removed in version 4.0.0. + + Please use 'diffpy.structure.GeneratorSite.convert_fp_num_to_signed_rational' instead. + """ + return self.convert_fp_num_to_signed_rational(x) + + def _find_null_space(self): """Calculate `self.null_space` from `self.invariants`. Try to represent `self.null_space` using small integers. @@ -660,7 +677,7 @@ def _findNullSpace(self): row[:] = (sgrow * abrow) / sgrow[idx] / abrow[idx] return - def _findPosParameters(self): + def _find_pos_parameters(self): """Find pparameters and their values for expressing `self.xyz`.""" usedsymbol = {} @@ -677,7 +694,7 @@ def _findPosParameters(self): usedsymbol[vname] = True return - def _findUSpace(self): + def _find_u_space(self): """Find independent U components with respect to invariant rotations.""" n = len(self.invariants) @@ -710,7 +727,7 @@ def _findUSpace(self): self.Uisotropy = len(self.Uspace) == 1 return - def _findUParameters(self): + def _find_u_parameters(self): """Find Uparameters and their values for expressing `self.Uij`.""" # permute indices as 00 11 22 01 02 12 10 20 21 @@ -726,7 +743,7 @@ def _findUParameters(self): self.Uparameters.append((vname, varvalue)) return - def _findeqUij(self): + def _find_equij(self): """Adjust `self.Uij` and `self.eqUij` to be consistent with spacegroup.""" self.Uij = numpy.zeros((3, 3), dtype=float) @@ -782,14 +799,14 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): if abs(nvec[i]) < epsilon: continue xyzformula[i] += "%s*%s " % ( - self.signedRatStr(nvec[i]), + self.convert_fp_num_to_signed_rational(nvec[i]), name2sym[vname], ) # add constant offset teqpos to all formulas for i in range(3): if xyzformula[i] and abs(teqpos[i]) < epsilon: continue - xyzformula[i] += self.signedRatStr(teqpos[i]) + xyzformula[i] += self.convert_fp_num_to_signed_rational(teqpos[i]) # reduce unnecessary +1* and -1* xyzformula = [re.sub("^[+]1[*]|(?<=[+-])1[*]", "", f).strip() for f in xyzformula] return dict(zip(("x", "y", "z"), xyzformula)) diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index e618c5f0..2bded26a 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -302,6 +302,13 @@ def test_signedRatStr(self): self.assertEqual("+1", g.signedRatStr(1.00000000000002)) return + def test_convert_fp_num_to_signed_rational(self): + "check GeneratorSite.test_convert_fp_num_to_signed_rational()" + g = self.g117c + self.assertEqual("-1", g.convert_fp_num_to_signed_rational(-1.00000000000002)) + self.assertEqual("+1", g.convert_fp_num_to_signed_rational(1.00000000000002)) + return + def test_positionFormula(self): """Check GeneratorSite.positionFormula()""" # 117c From 0d60a73b527131f4d3f5472e5394ac7483ff37c3 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Wed, 25 Feb 2026 22:45:23 -0500 Subject: [PATCH 170/226] chore: rename function to make it readable --- news/deprecate-symmetryutilities-4.rst | 2 +- src/diffpy/structure/symmetryutilities.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/news/deprecate-symmetryutilities-4.rst b/news/deprecate-symmetryutilities-4.rst index 0fa11e83..35d02131 100644 --- a/news/deprecate-symmetryutilities-4.rst +++ b/news/deprecate-symmetryutilities-4.rst @@ -5,7 +5,7 @@ * Added ``_find_pos_parameters`` method in ``GeneratorSite`` class * Added ``_find_u_space`` method in ``GeneratorSite`` class * Added ``_find_u_parameters`` method in ``GeneratorSite`` class -* Added ``_find_equij`` method in ``GeneratorSite`` class +* Added ``_find_eq_uij`` method in ``GeneratorSite`` class **Changed:** diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 2f0674eb..b4a215dd 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -605,7 +605,7 @@ def __init__( self._find_pos_parameters() self._find_u_space() self._find_u_parameters() - self._find_equij() + self._find_eq_uij() return def convert_fp_num_to_signed_rational(self, x): @@ -743,7 +743,7 @@ def _find_u_parameters(self): self.Uparameters.append((vname, varvalue)) return - def _find_equij(self): + def _find_eq_uij(self): """Adjust `self.Uij` and `self.eqUij` to be consistent with spacegroup.""" self.Uij = numpy.zeros((3, 3), dtype=float) From a2e253a37572efa2f1517aa94d3db9b9febed634 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 26 Feb 2026 16:44:46 -0500 Subject: [PATCH 171/226] chore: deprecate methods in GeneratorSite class --- news/deprecate-symmetryutilities-5.rst | 29 +++ src/diffpy/structure/symmetryutilities.py | 81 +++++++- tests/test_symmetryutilities.py | 243 ++++++++++++++++++++++ 3 files changed, 346 insertions(+), 7 deletions(-) create mode 100644 news/deprecate-symmetryutilities-5.rst diff --git a/news/deprecate-symmetryutilities-5.rst b/news/deprecate-symmetryutilities-5.rst new file mode 100644 index 00000000..8e572454 --- /dev/null +++ b/news/deprecate-symmetryutilities-5.rst @@ -0,0 +1,29 @@ +**Added:** + +* Added ``position_formula`` method in ``GeneratorSite`` class +* Added ``u_formula`` method in ``GeneratorSite`` class +* Added ``eq_index`` method in ``GeneratorSite`` class +* Added ``prune_formula_dictionary`` method in ``symmetryutilities.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``positionFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``UFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``eqIndex`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``pruneFormulaDictionary`` method in ``symmetryutilities.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index b4a215dd..8c605e50 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -476,6 +476,24 @@ def _find_invariants(symops): "convert_fp_num_to_signed_rational", removal_version, ) +positionFormula_deprecation_msg = build_deprecation_message( + generator_site, + "positionFormula", + "position_formula", + removal_version, +) +UFormula_deprecation_msg = build_deprecation_message( + generator_site, + "UFormula", + "u_formula", + removal_version, +) +eqIndex_deprecation_msg = build_deprecation_message( + generator_site, + "eqIndex", + "eq_index", + removal_version, +) class GeneratorSite(object): @@ -759,7 +777,17 @@ def _find_eq_uij(self): self.eqUij.append(numpy.dot(R, numpy.dot(self.Uij, Rt))) return + @deprecated(positionFormula_deprecation_msg) def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): + """'diffpy.structure.GeneratorSite.positionFormula' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.GeneratorSite.position_formula' + instead. + """ + return self.position_formula(pos, xyzsymbols) + + def position_formula(self, pos, xyzsymbols=("x", "y", "z")): """Formula of equivalent position with respect to generator site. @@ -811,7 +839,16 @@ def positionFormula(self, pos, xyzsymbols=("x", "y", "z")): xyzformula = [re.sub("^[+]1[*]|(?<=[+-])1[*]", "", f).strip() for f in xyzformula] return dict(zip(("x", "y", "z"), xyzformula)) + @deprecated(UFormula_deprecation_msg) def UFormula(self, pos, Usymbols=stdUsymbols): + """'diffpy.structure.GeneratorSite.UFormula' is deprecated and + will be removed in version 4.0.0. + + Please use 'diffpy.structure.GeneratorSite.u_formula' instead. + """ + return self.u_formula(pos, Usymbols) + + def u_formula(self, pos, Usymbols=stdUsymbols): """List of atom displacement formulas with custom parameter symbols. @@ -857,7 +894,16 @@ def UFormula(self, pos, Usymbols=stdUsymbols): Uformula[smbl] = f return Uformula + @deprecated(eqIndex_deprecation_msg) def eqIndex(self, pos): + """'diffpy.structure.GeneratorSite.eqIndex' is deprecated and + will be removed in version 4.0.0. + + Please use 'diffpy.structure.GeneratorSite.eq_index' instead. + """ + return self.eq_index(pos) + + def eq_index(self, pos): """Index of the nearest generator equivalent site. Parameters @@ -954,8 +1000,29 @@ def __init__(self, spacegroup, corepos, coreUijs=None, sgoffset=[0, 0, 0], eps=N # Helper function for SymmetryConstraints class. It may be useful # elsewhere therefore its name does not start with underscore. +pruneFormulaDictionary_deprecation_msg = build_deprecation_message( + base, + "pruneFormulaDictionary", + "prune_formula_dictionary", + removal_version, +) + +@deprecated(pruneFormulaDictionary_deprecation_msg) def pruneFormulaDictionary(eqdict): + """'diffpy.structure.pruneFormulaDictionary' is deprecated and will + be removed in version 4.0.0. + + Please use 'diffpy.structure.prune_formula_dictionary' instead. + """ + pruned = {} + for smb, eq in eqdict.items(): + if not is_constant_formula(eq): + pruned[smb] = eq + return pruned + + +def prune_formula_dictionary(eqdict): """Remove constant items from formula dictionary. Parameters @@ -1097,7 +1164,7 @@ def _findConstraints(self): indies = sorted(independent) for indidx in indies: indpos = self.positions[indidx] - formula = gen.positionFormula(indpos, gxyzsymbols) + formula = gen.position_formula(indpos, gxyzsymbols) # formula is empty when indidx is independent if not formula: continue @@ -1105,9 +1172,9 @@ def _findConstraints(self): independent.remove(indidx) self.coremap[genidx].append(indidx) self.poseqns[indidx] = formula - self.Ueqns[indidx] = gen.UFormula(indpos, gUsymbols) + self.Ueqns[indidx] = gen.u_formula(indpos, gUsymbols) # make sure positions and Uijs are consistent with spacegroup - eqidx = gen.eqIndex(indpos) + eqidx = gen.eq_index(indpos) dxyz = gen.eqxyz[eqidx] - indpos self.positions[indidx] += dxyz - dxyz.round() self.Uijs[indidx] = gen.eqUij[eqidx] @@ -1179,7 +1246,7 @@ def positionFormulasPruned(self, xyzsymbols=None): list List of coordinate formula dictionaries. """ - rv = [pruneFormulaDictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] + rv = [prune_formula_dictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] return rv def UparSymbols(self): @@ -1248,7 +1315,7 @@ def UFormulasPruned(self, Usymbols=None): List of atom displacement formulas in tuples of ``(U11, U22, U33, U12, U13, U23)``. """ - rv = [pruneFormulaDictionary(eqns) for eqns in self.UFormulas(Usymbols)] + rv = [prune_formula_dictionary(eqns) for eqns in self.UFormulas(Usymbols)] return rv @@ -1263,9 +1330,9 @@ def UFormulasPruned(self, Usymbols=None): site = [0.125, 0.625, 0.13] Uij = [[1, 2, 3], [2, 4, 5], [3, 5, 6]] g = GeneratorSite(sg100, site, Uij=Uij) - fm100 = g.positionFormula(site) + fm100 = g.position_formula(site) print("g = GeneratorSite(sg100, %r)" % site) print("g.positionFormula(%r) = %s" % (site, fm100)) print("g.pparameters =", g.pparameters) print("g.Uparameters =", g.Uparameters) - print("g.UFormula(%r) =" % site, g.UFormula(site)) + print("g.UFormula(%r) =" % site, g.u_formula(site)) diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 2bded26a..f4294b6a 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -41,6 +41,7 @@ nullSpace, position_difference, positionDifference, + prune_formula_dictionary, pruneFormulaDictionary, ) @@ -150,6 +151,13 @@ def test_pruneFormulaDictionary(self): self.assertEqual({"x": "3*y-0.17"}, pruned) return + def test_prune_formula_dictionary(self): + """Check prune_formula_dictionary()""" + fmdict = {"x": "3*y-0.17", "y": "0", "z": "0.13"} + pruned = prune_formula_dictionary(fmdict) + self.assertEqual({"x": "3*y-0.17"}, pruned) + return + def test_isconstantFormula(self): """Check isconstantFormula()""" self.assertFalse(isconstantFormula("x-y+z")) @@ -333,6 +341,30 @@ def test_positionFormula(self): self.assertEqual([], self.g227oc.pparameters) return + def test_position_formula(self): + """Check GeneratorSite.positionFormula()""" + # 117c + self.assertEqual([], self.g117c.pparameters) + self.assertEqual([("x", self.x)], self.g117h.pparameters) + # 143c + pfm143c = self.g143c.position_formula(self.g143c.xyz) + self.assertEqual("+2/3", pfm143c["x"]) + self.assertEqual("+1/3", pfm143c["y"]) + self.assertEqual("z", pfm143c["z"]) + # 143d + x, y, z = self.x, self.y, self.z + pfm143d = self.g143d.position_formula([-x + y, -x, z]) + self.assertEqual("-x+y", pfm143d["x"].replace(" ", "")) + self.assertEqual("-x+1", pfm143d["y"].replace(" ", "")) + self.assertTrue(re.match("[+]?z", pfm143d["z"].strip())) + # 227a + self.assertEqual([], self.g227a.pparameters) + self.assertEqual([], self.g227oa.pparameters) + # 227c + self.assertEqual([], self.g227c.pparameters) + self.assertEqual([], self.g227oc.pparameters) + return + def test_positionFormula_sg209(self): "check positionFormula at [x, 1-x, -x] site of the F432 space group." sg209 = GetSpaceGroup("F 4 3 2") @@ -344,6 +376,17 @@ def test_positionFormula_sg209(self): self.assertEqual("-x+1", pfm["z"].replace(" ", "")) return + def test_position_formula_sg209(self): + "check positionFormula at [x, 1-x, -x] site of the F432 space group." + sg209 = GetSpaceGroup("F 4 3 2") + xyz = [0.05198, 0.94802, -0.05198] + g209e = GeneratorSite(sg209, xyz) + pfm = g209e.position_formula(xyz) + self.assertEqual("x", pfm["x"]) + self.assertEqual("-x+1", pfm["y"].replace(" ", "")) + self.assertEqual("-x+1", pfm["z"].replace(" ", "")) + return + def test_UFormula(self): """Check GeneratorSite.UFormula()""" # Ref: Willis and Pryor, Thermal Vibrations in Crystallography, @@ -450,6 +493,112 @@ def test_UFormula(self): self.assertEqual(rule06, ufm) return + def test_u_formula(self): + """Check GeneratorSite.UFormula()""" + # Ref: Willis and Pryor, Thermal Vibrations in Crystallography, + # Cambridge University Press 1975, p. 104-110 + smbl = ("A", "B", "C", "D", "E", "F") + norule = { + "U11": "A", + "U22": "B", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "F", + } + rule05 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "0", + "U23": "0", + } + rule06 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "E", + } + rule07 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "-E", + } + rule15 = { + "U11": "A", + "U22": "B", + "U33": "C", + "U12": "0.5*B", + "U13": "0.5*F", + "U23": "F", + } + rule16 = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + "U13": "0", + "U23": "0", + } + rule17 = { + "U11": "A", + "U22": "A", + "U33": "A", + "U12": "0", + "U13": "0", + "U23": "0", + } + rule18 = { + "U11": "A", + "U22": "A", + "U33": "A", + "U12": "D", + "U13": "D", + "U23": "D", + } + ufm = self.g117c.u_formula(self.g117c.xyz, smbl) + self.assertEqual(rule05, ufm) + ufm = self.g117h.u_formula(self.g117h.xyz, smbl) + self.assertEqual(rule07, ufm) + ufm = self.g143a.u_formula(self.g143a.xyz, smbl) + self.assertEqual(rule16, ufm) + ufm = self.g143b.u_formula(self.g143b.xyz, smbl) + self.assertEqual(rule16, ufm) + ufm = self.g143c.u_formula(self.g143c.xyz, smbl) + self.assertEqual(rule16, ufm) + ufm = self.g143d.u_formula(self.g143d.xyz, smbl) + self.assertEqual(norule, ufm) + ufm = self.g164e.u_formula(self.g164e.xyz, smbl) + self.assertEqual(rule15, ufm) + ufm = self.g164f.u_formula(self.g164f.xyz, smbl) + self.assertEqual(rule15, ufm) + ufm = self.g164g.u_formula(self.g164g.xyz, smbl) + self.assertEqual(rule15, ufm) + ufm = self.g164h.u_formula(self.g164h.xyz, smbl) + self.assertEqual(rule15, ufm) + ufm = self.g186c.u_formula(self.g186c.xyz, smbl) + self.assertEqual(rule07, ufm) + ufm = self.g227a.u_formula(self.g227a.xyz, smbl) + self.assertEqual(rule17, ufm) + ufm = self.g227c.u_formula(self.g227c.xyz, smbl) + self.assertEqual(rule18, ufm) + ufm = self.g227oa.u_formula(self.g227oa.xyz, smbl) + self.assertEqual(rule17, ufm) + ufm = self.g227oc.u_formula(self.g227oc.xyz, smbl) + self.assertEqual(rule18, ufm) + # SG 167 in hexagonal and rhombohedral setting + ufm = self.gh167e.u_formula(self.gh167e.xyz, smbl) + self.assertEqual(rule15, ufm) + ufm = self.gr167e.u_formula(self.gr167e.xyz, smbl) + self.assertEqual(rule06, ufm) + return + def test_UFormula_g186c_eqxyz(self): """Check rotated U formulas at the symmetry positions of c-site in 186.""" @@ -532,6 +681,88 @@ def test_UFormula_g186c_eqxyz(self): self.assertEqual(uisod[n], eval(fm, upd)) return + def test_u_formula_g186c_eqxyz(self): + """Check rotated U formulas at the symmetry positions of c-site + in 186.""" + sg186 = GetSpaceGroup(186) + crules = [ + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "E", + "U23": "-E", + }, + { + "U11": "A", + "U22": "2*A-2*D", + "U33": "C", + "U12": "A-D", + "U13": "E", + "U23": "2*E", + }, + { + "U11": "2*A-2*D", + "U22": "A", + "U33": "C", + "U12": "A-D", + "U13": "-2*E", + "U23": "-E", + }, + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "D", + "U13": "-E", + "U23": "E", + }, + { + "U11": "A", + "U22": "2*A-2*D", + "U33": "C", + "U12": "A-D", + "U13": "-E", + "U23": "-2*E", + }, + { + "U11": "2*A-2*D", + "U22": "A", + "U33": "C", + "U12": "A-D", + "U13": "2*E", + "U23": "E", + }, + ] + self.assertEqual(6, len(self.g186c.eqxyz)) + gc = self.g186c + for idx in range(6): + self.assertEqual(crules[idx], gc.u_formula(gc.eqxyz[idx], "ABCDEF")) + uiso = numpy.array([[2, 1, 0], [1, 2, 0], [0, 0, 2]]) + eau = ExpandAsymmetricUnit(sg186, [gc.xyz], [uiso]) + for u in eau.expandedUijs: + du = numpy.linalg.norm((uiso - u).flatten()) + self.assertAlmostEqual(0.0, du, 8) + symcon = SymmetryConstraints(sg186, sum(eau.expandedpos, []), sum(eau.expandedUijs, [])) + upd = dict(symcon.Upars) + self.assertEqual(2.0, upd["U110"]) + self.assertEqual(2.0, upd["U330"]) + self.assertEqual(1.0, upd["U120"]) + self.assertEqual(0.0, upd["U130"]) + uisod = { + "U11": 2.0, + "U22": 2.0, + "U33": 2.0, + "U12": 1.0, + "U13": 0.0, + "U23": 0.0, + } + for ufms in symcon.UFormulas(): + for n, fm in ufms.items(): + self.assertEqual(uisod[n], eval(fm, upd)) + return + def test_UFormula_self_reference(self): "Ensure U formulas have no self reference such as U13=0.5*U13." for g in self.generators.values(): @@ -539,6 +770,13 @@ def test_UFormula_self_reference(self): self.assertEqual([], badformulas) return + def test_u_formula_self_reference(self): + "Ensure U formulas have no self reference such as U13=0.5*U13." + for g in self.generators.values(): + badformulas = [(n, fm) for n, fm in g.u_formula(g.xyz).items() if n in fm and n != fm] + self.assertEqual([], badformulas) + return + def test__findUParameters(self): """Check GeneratorSite._findUParameters()""" # by default all Uparameters equal zero, this would fail for NaNs @@ -561,6 +799,11 @@ def test_eqIndex(self): self.assertEqual(13, self.g227oc.eqIndex(self.g227oc.eqxyz[13])) return + def test_eq_index(self): + """Check GeneratorSite.eqIndex()""" + self.assertEqual(13, self.g227oc.eq_index(self.g227oc.eqxyz[13])) + return + # End of class TestGeneratorSite From 40e30aa2fe90becdd26b925dd154450188712721 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 27 Feb 2026 23:26:31 -0500 Subject: [PATCH 172/226] chore: deprecate SymmetryConstraints class method --- news/deprecate-symmetryutilities-6.rst | 32 ++++++++ src/diffpy/structure/symmetryutilities.py | 90 +++++++++++++++++++++-- tests/test_symmetryutilities.py | 59 ++++++++++++++- 3 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 news/deprecate-symmetryutilities-6.rst diff --git a/news/deprecate-symmetryutilities-6.rst b/news/deprecate-symmetryutilities-6.rst new file mode 100644 index 00000000..c31ab914 --- /dev/null +++ b/news/deprecate-symmetryutilities-6.rst @@ -0,0 +1,32 @@ +**Added:** + +* Added ``_find_constraints`` method in ``SymmetryConstraints`` class +* Added ``pospar_symbols`` method in ``SymmetryConstraints`` class +* Added ``pospar_values`` method in ``SymmetryConstraints`` class +* Added ``upar_symbols`` method in ``SymmetryConstraints`` class +* Added ``upar_values`` method in ``SymmetryConstraints`` class +* Added ``u_formulas`` method in ``SymmetryConstraints`` class + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``posparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``posparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 8c605e50..412882e7 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -1043,6 +1043,39 @@ def prune_formula_dictionary(eqdict): return pruned +symmetry_constraints = "diffpy.symmetryutilities.SymmetryConstraints" +posparSymbols_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "posparSymbols", + "pospar_symbols", + removal_version, +) +posparValues_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "posparValues", + "pospar_values", + removal_version, +) +UparSymbols_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "UparSymbols", + "upar_symbols", + removal_version, +) +UparValues_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "UparValues", + "upar_values", + removal_version, +) +UFormulas_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "UFormulas", + "u_formulas", + removal_version, +) + + class SymmetryConstraints(object): """Generate symmetry constraints for specified positions. @@ -1132,10 +1165,10 @@ def __init__(self, spacegroup, positions, Uijs=None, sgoffset=[0, 0, 0], eps=Non self.Ueqns = numpos * [None] self.Uisotropy = numpos * [False] # all members should be initialized here - self._findConstraints() + self._find_constraints() return - def _findConstraints(self): + def _find_constraints(self): """Find constraints for positions and anisotropic displacements `Uij`.""" numpos = len(self.positions) @@ -1184,11 +1217,29 @@ def _findConstraints(self): self.corepos = [self.positions[i] for i in coreidx] return + @deprecated(posparSymbols_deprecation_msg) def posparSymbols(self): + """'diffpy.structure.SymmetryConstraints.posparSymbols' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.pospar_symbols' instead. + """ + return self.pospar_symbols() + + def pospar_symbols(self): """Return list of standard position parameter symbols.""" return [n for n, v in self.pospars] + @deprecated(posparValues_deprecation_msg) def posparValues(self): + """'diffpy.structure.SymmetryConstraints.posparValues' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.pospar_values' instead. + """ + return self.pospar_values() + + def pospar_values(self): """Return list of position parameters values.""" return [v for n, v in self.pospars] @@ -1214,7 +1265,7 @@ def positionFormulas(self, xyzsymbols=None): emsg = "Not enough symbols for %i position parameters" % len(self.pospars) raise SymmetryError(emsg) # build translation dictionary - trsmbl = dict(zip(self.posparSymbols(), xyzsymbols)) + trsmbl = dict(zip(self.pospar_symbols(), xyzsymbols)) def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] @@ -1249,16 +1300,45 @@ def positionFormulasPruned(self, xyzsymbols=None): rv = [prune_formula_dictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] return rv + @deprecated(UparSymbols_deprecation_msg) def UparSymbols(self): + """'diffpy.structure.SymmetryConstraints.UparSymbols' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.upar_symbols' instead. + """ + return self.upar_symbols() + + def upar_symbols(self): """Return list of standard atom displacement parameter symbols.""" return [n for n, v in self.Upars] + @deprecated(UparValues_deprecation_msg) def UparValues(self): + """'diffpy.structure.SymmetryConstraints.UparValues' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.upar_values' + instead. + """ + return [v for n, v in self.Upars] + + def upar_values(self): """Return list of atom displacement parameters values.""" return [v for n, v in self.Upars] + @deprecated(UFormula_deprecation_msg) def UFormulas(self, Usymbols=None): + """'diffpy.structure.SymmetryConstraints.UFormulas' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.u_formulas' + instead. + """ + return self.u_formulas(Usymbols) + + def u_formulas(self, Usymbols=None): """List of atom displacement formulas with custom parameter symbols. @@ -1282,7 +1362,7 @@ def UFormulas(self, Usymbols=None): emsg = "Not enough symbols for %i U parameters" % len(self.Upars) raise SymmetryError(emsg) # build translation dictionary - trsmbl = dict(zip(self.UparSymbols(), Usymbols)) + trsmbl = dict(zip(self.upar_symbols(), Usymbols)) def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] @@ -1315,7 +1395,7 @@ def UFormulasPruned(self, Usymbols=None): List of atom displacement formulas in tuples of ``(U11, U22, U33, U12, U13, U23)``. """ - rv = [prune_formula_dictionary(eqns) for eqns in self.UFormulas(Usymbols)] + rv = [prune_formula_dictionary(eqns) for eqns in self.u_formulas(Usymbols)] return rv diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index f4294b6a..ef5da84b 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -758,7 +758,7 @@ def test_u_formula_g186c_eqxyz(self): "U13": 0.0, "U23": 0.0, } - for ufms in symcon.UFormulas(): + for ufms in symcon.u_formulas(): for n, fm in ufms.items(): self.assertEqual(uisod[n], eval(fm, upd)) return @@ -905,6 +905,18 @@ def test_UparSymbols(self): self.assertEqual(["U110"], sc225.UparSymbols()) return + def test_upar_symbols(self): + """Check SymmetryConstraints.UparSymbols()""" + sg1 = GetSpaceGroup(1) + sg225 = GetSpaceGroup(225) + pos = [[0, 0, 0]] + Uijs = numpy.zeros((1, 3, 3)) + sc1 = SymmetryConstraints(sg1, pos, Uijs) + self.assertEqual(6, len(sc1.upar_symbols())) + sc225 = SymmetryConstraints(sg225, pos, Uijs) + self.assertEqual(["U110"], sc225.upar_symbols()) + return + def test_UparValues(self): """Check SymmetryConstraints.UparValues()""" places = 12 @@ -920,6 +932,34 @@ def test_UparValues(self): self.assertAlmostEqual(0.2, sc225.UparValues()[0], places) return + def test_upar_values(self): + """Check SymmetryConstraints.UparValues()""" + places = 12 + sg1 = GetSpaceGroup(1) + sg225 = GetSpaceGroup(225) + pos = [[0, 0, 0]] + Uijs = [[[0.1, 0.4, 0.5], [0.4, 0.2, 0.6], [0.5, 0.6, 0.3]]] + sc1 = SymmetryConstraints(sg1, pos, Uijs) + duv = 0.1 * numpy.arange(1, 7) - sc1.upar_values() + self.assertAlmostEqual(0, max(numpy.fabs(duv)), places) + sc225 = SymmetryConstraints(sg225, pos, Uijs) + self.assertEqual(1, len(sc225.upar_values())) + self.assertAlmostEqual(0.2, sc225.upar_values()[0], places) + return + + def test_posparSymbols_and_posparValues(self): + """Check SymmetryConstraints.posparSymbols and_posparValues()""" + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.pospars = [("x", 0.12), ("y", 0.34), ("z", 0.56)] + actual_symbols = sc.posparSymbols() + actual_values = sc.posparValues() + expected_symbols = ["x", "y", "z"] + expected_values = [0.12, 0.34, 0.56] + assert expected_symbols == actual_symbols + assert expected_values == actual_values + # def test_UFormulas(self): # """check SymmetryConstraints.UFormulas() @@ -1056,5 +1096,22 @@ def test_null_space(A, expected_dim): assert numpy.allclose(actual @ actual.T, numpy.eye(expected_dim), atol=1e-12) +@pytest.mark.parametrize( + "params, expected_symbols, expected_values", + [ + pytest.param([("x", 0.12), ("y", 0.34), ("z", 0.56)], ["x", "y", "z"], [0.12, 0.34, 0.56]), + ], +) +def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_values): + """Check SymmetryConstraints.pospar_symbols and_pospar_values()""" + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.pospars = params + actual_symbols, actual_values = sc.pospar_symbols(), sc.pospar_values() + assert actual_symbols == expected_symbols + assert actual_values == expected_values + + if __name__ == "__main__": unittest.main() From 71b6a3fead185e71ae5e4405fb95895a59da394d Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 28 Feb 2026 09:20:24 -0500 Subject: [PATCH 173/226] chore: rename the function to increase readability --- news/deprecate-symmetryutilities-6.rst | 8 ++++---- src/diffpy/structure/symmetryutilities.py | 18 +++++++++--------- tests/test_symmetryutilities.py | 12 ++++++------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/news/deprecate-symmetryutilities-6.rst b/news/deprecate-symmetryutilities-6.rst index c31ab914..b78e0917 100644 --- a/news/deprecate-symmetryutilities-6.rst +++ b/news/deprecate-symmetryutilities-6.rst @@ -1,10 +1,10 @@ **Added:** * Added ``_find_constraints`` method in ``SymmetryConstraints`` class -* Added ``pospar_symbols`` method in ``SymmetryConstraints`` class -* Added ``pospar_values`` method in ``SymmetryConstraints`` class -* Added ``upar_symbols`` method in ``SymmetryConstraints`` class -* Added ``upar_values`` method in ``SymmetryConstraints`` class +* Added ``pos_parm_symbols`` method in ``SymmetryConstraints`` class +* Added ``pos_parm_values`` method in ``SymmetryConstraints`` class +* Added ``u_parm_symbols`` method in ``SymmetryConstraints`` class +* Added ``u_parm_values`` method in ``SymmetryConstraints`` class * Added ``u_formulas`` method in ``SymmetryConstraints`` class **Changed:** diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 412882e7..6e58e151 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -1224,9 +1224,9 @@ def posparSymbols(self): Please use 'diffpy.structure.SymmetryConstraints.pospar_symbols' instead. """ - return self.pospar_symbols() + return self.pos_parm_symbols() - def pospar_symbols(self): + def pos_parm_symbols(self): """Return list of standard position parameter symbols.""" return [n for n, v in self.pospars] @@ -1237,9 +1237,9 @@ def posparValues(self): Please use 'diffpy.structure.SymmetryConstraints.pospar_values' instead. """ - return self.pospar_values() + return self.pos_parm_values() - def pospar_values(self): + def pos_parm_values(self): """Return list of position parameters values.""" return [v for n, v in self.pospars] @@ -1265,7 +1265,7 @@ def positionFormulas(self, xyzsymbols=None): emsg = "Not enough symbols for %i position parameters" % len(self.pospars) raise SymmetryError(emsg) # build translation dictionary - trsmbl = dict(zip(self.pospar_symbols(), xyzsymbols)) + trsmbl = dict(zip(self.pos_parm_symbols(), xyzsymbols)) def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] @@ -1307,9 +1307,9 @@ def UparSymbols(self): Please use 'diffpy.structure.SymmetryConstraints.upar_symbols' instead. """ - return self.upar_symbols() + return self.u_parm_symbols() - def upar_symbols(self): + def u_parm_symbols(self): """Return list of standard atom displacement parameter symbols.""" return [n for n, v in self.Upars] @@ -1324,7 +1324,7 @@ def UparValues(self): """ return [v for n, v in self.Upars] - def upar_values(self): + def u_parm_values(self): """Return list of atom displacement parameters values.""" return [v for n, v in self.Upars] @@ -1362,7 +1362,7 @@ def u_formulas(self, Usymbols=None): emsg = "Not enough symbols for %i U parameters" % len(self.Upars) raise SymmetryError(emsg) # build translation dictionary - trsmbl = dict(zip(self.upar_symbols(), Usymbols)) + trsmbl = dict(zip(self.u_parm_symbols(), Usymbols)) def translatesymbol(matchobj): return trsmbl[matchobj.group(0)] diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index ef5da84b..8fd2d5c4 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -912,9 +912,9 @@ def test_upar_symbols(self): pos = [[0, 0, 0]] Uijs = numpy.zeros((1, 3, 3)) sc1 = SymmetryConstraints(sg1, pos, Uijs) - self.assertEqual(6, len(sc1.upar_symbols())) + self.assertEqual(6, len(sc1.u_parm_symbols())) sc225 = SymmetryConstraints(sg225, pos, Uijs) - self.assertEqual(["U110"], sc225.upar_symbols()) + self.assertEqual(["U110"], sc225.u_parm_symbols()) return def test_UparValues(self): @@ -940,11 +940,11 @@ def test_upar_values(self): pos = [[0, 0, 0]] Uijs = [[[0.1, 0.4, 0.5], [0.4, 0.2, 0.6], [0.5, 0.6, 0.3]]] sc1 = SymmetryConstraints(sg1, pos, Uijs) - duv = 0.1 * numpy.arange(1, 7) - sc1.upar_values() + duv = 0.1 * numpy.arange(1, 7) - sc1.u_parm_values() self.assertAlmostEqual(0, max(numpy.fabs(duv)), places) sc225 = SymmetryConstraints(sg225, pos, Uijs) - self.assertEqual(1, len(sc225.upar_values())) - self.assertAlmostEqual(0.2, sc225.upar_values()[0], places) + self.assertEqual(1, len(sc225.u_parm_values())) + self.assertAlmostEqual(0.2, sc225.u_parm_values()[0], places) return def test_posparSymbols_and_posparValues(self): @@ -1108,7 +1108,7 @@ def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_val eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.pospars = params - actual_symbols, actual_values = sc.pospar_symbols(), sc.pospar_values() + actual_symbols, actual_values = sc.pos_parm_symbols(), sc.pos_parm_values() assert actual_symbols == expected_symbols assert actual_values == expected_values From 820a3d6b2027e964666e91fd4382f27c6c88b324 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 28 Feb 2026 09:22:00 -0500 Subject: [PATCH 174/226] chore: rename the api in the docstring --- src/diffpy/structure/symmetryutilities.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index 6e58e151..b596e17d 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -1222,7 +1222,7 @@ def posparSymbols(self): """'diffpy.structure.SymmetryConstraints.posparSymbols' is deprecated and will be removed in version 4.0.0. - Please use 'diffpy.structure.SymmetryConstraints.pospar_symbols' instead. + Please use 'diffpy.structure.SymmetryConstraints.pos_parm_symbols' instead. """ return self.pos_parm_symbols() @@ -1235,7 +1235,7 @@ def posparValues(self): """'diffpy.structure.SymmetryConstraints.posparValues' is deprecated and will be removed in version 4.0.0. - Please use 'diffpy.structure.SymmetryConstraints.pospar_values' instead. + Please use 'diffpy.structure.SymmetryConstraints.pos_parm_values' instead. """ return self.pos_parm_values() @@ -1305,7 +1305,7 @@ def UparSymbols(self): """'diffpy.structure.SymmetryConstraints.UparSymbols' is deprecated and will be removed in version 4.0.0. - Please use 'diffpy.structure.SymmetryConstraints.upar_symbols' instead. + Please use 'diffpy.structure.SymmetryConstraints.u_parm_symbols' instead. """ return self.u_parm_symbols() @@ -1319,7 +1319,7 @@ def UparValues(self): """'diffpy.structure.SymmetryConstraints.UparValues' is deprecated and will be removed in version 4.0.0. - Please use 'diffpy.structure.SymmetryConstraints.upar_values' + Please use 'diffpy.structure.SymmetryConstraints.u_parm_values' instead. """ return [v for n, v in self.Upars] From 259532ce76ef1973ecb27b755c0fbc5ae40aff56 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Mon, 2 Mar 2026 17:04:00 -0500 Subject: [PATCH 175/226] chore: deprecate symmetryutilities method --- news/deprecate-symmetryutilities-7.rst | 27 ++++ src/diffpy/structure/symmetryutilities.py | 48 +++++- tests/test_symmetryutilities.py | 171 ++++++++++++++++++++++ 3 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 news/deprecate-symmetryutilities-7.rst diff --git a/news/deprecate-symmetryutilities-7.rst b/news/deprecate-symmetryutilities-7.rst new file mode 100644 index 00000000..30411474 --- /dev/null +++ b/news/deprecate-symmetryutilities-7.rst @@ -0,0 +1,27 @@ +**Added:** + +* Added ``position_formulas`` method in ``SymmetryConstraints`` class +* Added ``position_formulas_pruned`` method in ``SymmetryConstraints`` class +* Added ``u_formula_pruned`` method in ``SymmetryConstraints`` class + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``positionFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``positionFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/symmetryutilities.py b/src/diffpy/structure/symmetryutilities.py index b596e17d..5e744fbd 100644 --- a/src/diffpy/structure/symmetryutilities.py +++ b/src/diffpy/structure/symmetryutilities.py @@ -1074,6 +1074,24 @@ def prune_formula_dictionary(eqdict): "u_formulas", removal_version, ) +positionFormulas_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "positionFormulas", + "position_formulas", + removal_version, +) +positionFormulasPruned_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "positionFormulasPruned", + "position_formulas_pruned", + removal_version, +) +UFormulasPruned_deprecation_msg = build_deprecation_message( + symmetry_constraints, + "UFormulasPruned", + "u_formulas_pruned", + removal_version, +) class SymmetryConstraints(object): @@ -1243,7 +1261,16 @@ def pos_parm_values(self): """Return list of position parameters values.""" return [v for n, v in self.pospars] + @deprecated(posparValues_deprecation_msg) def positionFormulas(self, xyzsymbols=None): + """'diffpy.structure.SymmetryConstraints.positionFormulas' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.position_formulas' instead. + """ + return self.position_formulas(xyzsymbols) + + def position_formulas(self, xyzsymbols=None): """List of position formulas with custom parameter symbols. Parameters @@ -1279,7 +1306,16 @@ def translatesymbol(matchobj): rv.append(treqns) return rv + @deprecated(positionFormulasPruned_deprecation_msg) def positionFormulasPruned(self, xyzsymbols=None): + """'diffpy.structure.SymmetryConstraints.positionFormulasPruned' + is deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.position_formulas_pruned' instead. + """ + return self.position_formulas_pruned(xyzsymbols) + + def position_formulas_pruned(self, xyzsymbols=None): """List of position formula dictionaries with constant items removed. @@ -1297,7 +1333,7 @@ def positionFormulasPruned(self, xyzsymbols=None): list List of coordinate formula dictionaries. """ - rv = [prune_formula_dictionary(eqns) for eqns in self.positionFormulas(xyzsymbols)] + rv = [prune_formula_dictionary(eqns) for eqns in self.position_formulas(xyzsymbols)] return rv @deprecated(UparSymbols_deprecation_msg) @@ -1376,7 +1412,17 @@ def translatesymbol(matchobj): rv.append(treqns) return rv + @deprecated(UFormulasPruned_deprecation_msg) def UFormulasPruned(self, Usymbols=None): + """'diffpy.structure.SymmetryConstraints.UFormulasPruned' is + deprecated and will be removed in version 4.0.0. + + Please use 'diffpy.structure.SymmetryConstraints.u_formulas_pruned' + instead. + """ + return self.u_formulas_pruned(Usymbols) + + def u_formulas_pruned(self, Usymbols=None): """List of atom displacement formula dictionaries with constant items removed. diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index 8fd2d5c4..b767190f 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -22,6 +22,7 @@ import pytest from diffpy.structure.spacegroups import GetSpaceGroup +from diffpy.structure.structureerrors import SymmetryError from diffpy.structure.symmetryutilities import ( ExpandAsymmetricUnit, GeneratorSite, @@ -960,6 +961,69 @@ def test_posparSymbols_and_posparValues(self): assert expected_symbols == actual_symbols assert expected_values == actual_values + def test_positionFormulas(self): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + # C1: Simulate the "not enough symbols" branch + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] + sc.poseqns = [ + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, + ] + with pytest.raises(SymmetryError): + sc.positionFormulas(["x1"]) # too few custom symbols + # C2: Normal case, does substitution of x0/y0/z0 tokens in formulas + # Make pospars consistent with what positionFormulas expects to replace + actual = sc.positionFormulas(["xA", "yA", "zA"]) + expected = [ + {"x": "xA", "y": "yA +0.5", "z": "-zA +0.25"}, + {"x": "-xA +0.5", "y": "yA", "z": "zA +0.5"}, + ] + assert actual == expected + + def test_positionFormulasPruned(self): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + # C1: Remove any key-value pairs with constant values + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] + sc.poseqns = [ + {"x": "x1", "y": "0.25", "z": "-z1 +0.5"}, + {"x": "0", "y": "y1 +0.5", "z": "0.125"}, + ] + actual = sc.positionFormulasPruned(["xA", "yA", "zA"]) + expected = [ + {"x": "xA", "z": "-zA +0.5"}, + {"y": "yA +0.5"}, + ] + assert actual == expected + + def test_UFormulasPruned(self): + """Check SymmetryConstraints.UFormulasPruned()""" + u_formulas = { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + "U13": "0", + "U23": "0", + } + expected = [ + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + } + ] + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.Ueqns = [u_formulas] + actual = sc.UFormulasPruned(u_formulas) + assert actual == expected + # def test_UFormulas(self): # """check SymmetryConstraints.UFormulas() @@ -1113,5 +1177,112 @@ def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_val assert actual_values == expected_values +@pytest.mark.parametrize( + "params", + [ + pytest.param(["x1"]), + ], +) +def test_position_formulas_raises_SymmetryError(params): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] + sc.poseqns = [ + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, + ] + # C1: Simulate the "not enough symbols" in position_formula + with pytest.raises(SymmetryError): + sc.position_formulas(params) + + +@pytest.mark.parametrize( + "params, expected", + [ + pytest.param( # C2: Normal case, does substitution of x1/y1/z1 tokens in formulas + # Make pospars consistent with what position_formulas expects to replace + ["xA", "yA", "zA"], + [ + {"x": "xA", "y": "yA +0.5", "z": "-zA +0.25"}, + {"x": "-xA +0.5", "y": "yA", "z": "zA +0.5"}, + ], + ), + ], +) +def test_position_formulas(params, expected): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] + sc.poseqns = [ + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, + ] + actual = sc.position_formulas(params) + assert actual == expected + + +@pytest.mark.parametrize( + "poseqns, expected", + [ + pytest.param( + [ + {"x": "x1", "y": "0.25", "z": "-z1 +0.5"}, + {"x": "0", "y": "y1 +0.5", "z": "0.125"}, + ], + [ + {"x": "xA", "z": "-zA +0.5"}, + {"y": "yA +0.5"}, + ], + ) + ], +) +def test_position_formulas_pruned(poseqns, expected): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] + sc.poseqns = poseqns + + actual = sc.position_formulas_pruned(["xA", "yA", "zA"]) + assert actual == expected + + +@pytest.mark.parametrize( + "u_formulas, expected", + [ + pytest.param( + [ + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + "U13": "0", + "U23": "0", + } + ], + [ + { + "U11": "A", + "U22": "A", + "U33": "C", + "U12": "0.5*A", + } + ], + ) + ], +) +def test_u_formula_pruned(u_formulas, expected): + sg225 = GetSpaceGroup(225) + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) + sc = SymmetryConstraints(sg225, eau.expandedpos) + sc.Ueqns = u_formulas + actual = sc.u_formulas_pruned(u_formulas) + assert actual == expected + + if __name__ == "__main__": unittest.main() From f489b30c03b7d23b83ae7debfa1c45bac9f897d9 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Mon, 2 Mar 2026 20:25:29 -0500 Subject: [PATCH 176/226] chore: rename the method to correct one in news --- news/deprecate-symmetryutilities-7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/news/deprecate-symmetryutilities-7.rst b/news/deprecate-symmetryutilities-7.rst index 30411474..e014dac4 100644 --- a/news/deprecate-symmetryutilities-7.rst +++ b/news/deprecate-symmetryutilities-7.rst @@ -2,7 +2,7 @@ * Added ``position_formulas`` method in ``SymmetryConstraints`` class * Added ``position_formulas_pruned`` method in ``SymmetryConstraints`` class -* Added ``u_formula_pruned`` method in ``SymmetryConstraints`` class +* Added ``u_formulas_pruned`` method in ``SymmetryConstraints`` class **Changed:** From 84b879ef2eb97dbb8548133bdc57d54a89ac96a9 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 3 Mar 2026 13:37:40 -0500 Subject: [PATCH 177/226] chore: deprecate utils method and private methods in parsers. --- news/deprecate-utils.rst | 39 +++++++++++++++++ src/diffpy/structure/parsers/p_auto.py | 12 +++--- src/diffpy/structure/parsers/p_cif.py | 60 +++++++++++++------------- src/diffpy/structure/utils.py | 29 +++++++++++-- tests/test_utils.py | 37 ++++++++++++++++ 5 files changed, 137 insertions(+), 40 deletions(-) create mode 100644 news/deprecate-utils.rst create mode 100644 tests/test_utils.py diff --git a/news/deprecate-utils.rst b/news/deprecate-utils.rst new file mode 100644 index 00000000..693b86ca --- /dev/null +++ b/news/deprecate-utils.rst @@ -0,0 +1,39 @@ +**Added:** + +* Added ``atom_bare_symbol`` method in ``utils.py`` +* Added ``_get_ordered_formats`` method in ``p_auto.py`` +* Added ``_wrap_parse_method`` method in ``p_auto.py`` +* Added ``_tr_atom_site_u_iso_or_equiv`` method in ``p_cif.py`` +* Added ``_tr_atom_site_b_iso_or_equiv`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_11`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_22`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_33`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_12`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_13`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_23`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_11`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_22`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_33`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_12`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_13`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_23`` method in ``p_cif.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``atomBareSymbol`` method in ``utils.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 27b0d1ad..681bb840 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -51,7 +51,7 @@ def __init__(self, **kw): return # parseLines helpers - def _getOrderedFormats(self): + def _get_ordered_formats(self): """Build a list of relevance ordered structure formats. This only works when `self.filename` has a known extension. @@ -96,7 +96,7 @@ def parseLines(self, lines): ------ StructureFormatError """ - return self._wrapParseMethod("parseLines", lines) + return self._wrap_parse_method("parseLines", lines) def parse(self, s): """Detect format and create `Structure` instance from a string. @@ -117,7 +117,7 @@ def parse(self, s): ------ StructureFormatError """ - return self._wrapParseMethod("parse", s) + return self._wrap_parse_method("parse", s) def parseFile(self, filename): """Detect format and create Structure instance from an existing @@ -143,9 +143,9 @@ def parseFile(self, filename): If the file cannot be read. """ self.filename = filename - return self._wrapParseMethod("parseFile", filename) + return self._wrap_parse_method("parseFile", filename) - def _wrapParseMethod(self, method, *args, **kwargs): + def _wrap_parse_method(self, method, *args, **kwargs): """A helper evaluator method that try the specified parse method with each registered structure parser and return the first successful result. @@ -173,7 +173,7 @@ def _wrapParseMethod(self, method, *args, **kwargs): """ from diffpy.structure.parsers import getParser - ofmts = self._getOrderedFormats() + ofmts = self._get_ordered_formats() stru = None # try all parsers in sequence parsers_emsgs = [] diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index e8029cde..585d5927 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -185,15 +185,15 @@ def _tr_atom_site_cartn_z(a, value): _tr_atom_site_cartn_z = staticmethod(_tr_atom_site_cartn_z) - def _tr_atom_site_U_iso_or_equiv(a, value): + def _tr_atom_site_u_iso_or_equiv(a, value): a.Uisoequiv = leading_float(value) - _tr_atom_site_U_iso_or_equiv = staticmethod(_tr_atom_site_U_iso_or_equiv) + _tr_atom_site_u_iso_or_equiv = staticmethod(_tr_atom_site_u_iso_or_equiv) - def _tr_atom_site_B_iso_or_equiv(a, value): + def _tr_atom_site_b_iso_or_equiv(a, value): a.Uisoequiv = P_cif.BtoU * leading_float(value) - _tr_atom_site_B_iso_or_equiv = staticmethod(_tr_atom_site_B_iso_or_equiv) + _tr_atom_site_b_iso_or_equiv = staticmethod(_tr_atom_site_b_iso_or_equiv) def _tr_atom_site_adp_type(a, value): a.anisotropy = value not in ("Uiso", "Biso") @@ -206,65 +206,65 @@ def _tr_atom_site_occupancy(a, value): _tr_atom_site_occupancy = staticmethod(_tr_atom_site_occupancy) - def _tr_atom_site_aniso_U_11(a, value): + def _tr_atom_site_aniso_u_11(a, value): a.U11 = leading_float(value) - _tr_atom_site_aniso_U_11 = staticmethod(_tr_atom_site_aniso_U_11) + _tr_atom_site_aniso_u_11 = staticmethod(_tr_atom_site_aniso_u_11) - def _tr_atom_site_aniso_U_22(a, value): + def _tr_atom_site_aniso_u_22(a, value): a.U22 = leading_float(value) - _tr_atom_site_aniso_U_22 = staticmethod(_tr_atom_site_aniso_U_22) + _tr_atom_site_aniso_u_22 = staticmethod(_tr_atom_site_aniso_u_22) - def _tr_atom_site_aniso_U_33(a, value): + def _tr_atom_site_aniso_u_33(a, value): a.U33 = leading_float(value) - _tr_atom_site_aniso_U_33 = staticmethod(_tr_atom_site_aniso_U_33) + _tr_atom_site_aniso_u_33 = staticmethod(_tr_atom_site_aniso_u_33) - def _tr_atom_site_aniso_U_12(a, value): + def _tr_atom_site_aniso_u_12(a, value): a.U12 = leading_float(value) - _tr_atom_site_aniso_U_12 = staticmethod(_tr_atom_site_aniso_U_12) + _tr_atom_site_aniso_u_12 = staticmethod(_tr_atom_site_aniso_u_12) - def _tr_atom_site_aniso_U_13(a, value): + def _tr_atom_site_aniso_u_13(a, value): a.U13 = leading_float(value) - _tr_atom_site_aniso_U_13 = staticmethod(_tr_atom_site_aniso_U_13) + _tr_atom_site_aniso_u_13 = staticmethod(_tr_atom_site_aniso_u_13) - def _tr_atom_site_aniso_U_23(a, value): + def _tr_atom_site_aniso_u_23(a, value): a.U23 = leading_float(value) - _tr_atom_site_aniso_U_23 = staticmethod(_tr_atom_site_aniso_U_23) + _tr_atom_site_aniso_u_23 = staticmethod(_tr_atom_site_aniso_u_23) - def _tr_atom_site_aniso_B_11(a, value): + def _tr_atom_site_aniso_b_11(a, value): a.U11 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_11 = staticmethod(_tr_atom_site_aniso_B_11) + _tr_atom_site_aniso_b_11 = staticmethod(_tr_atom_site_aniso_b_11) - def _tr_atom_site_aniso_B_22(a, value): + def _tr_atom_site_aniso_b_22(a, value): a.U22 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_22 = staticmethod(_tr_atom_site_aniso_B_22) + _tr_atom_site_aniso_b_22 = staticmethod(_tr_atom_site_aniso_b_22) - def _tr_atom_site_aniso_B_33(a, value): + def _tr_atom_site_aniso_b_33(a, value): a.U33 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_33 = staticmethod(_tr_atom_site_aniso_B_33) + _tr_atom_site_aniso_b_33 = staticmethod(_tr_atom_site_aniso_b_33) - def _tr_atom_site_aniso_B_12(a, value): + def _tr_atom_site_aniso_b_12(a, value): a.U12 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_12 = staticmethod(_tr_atom_site_aniso_B_12) + _tr_atom_site_aniso_b_12 = staticmethod(_tr_atom_site_aniso_b_12) - def _tr_atom_site_aniso_B_13(a, value): + def _tr_atom_site_aniso_b_13(a, value): a.U13 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_13 = staticmethod(_tr_atom_site_aniso_B_13) + _tr_atom_site_aniso_b_13 = staticmethod(_tr_atom_site_aniso_b_13) - def _tr_atom_site_aniso_B_23(a, value): + def _tr_atom_site_aniso_b_23(a, value): a.U23 = P_cif.BtoU * leading_float(value) - _tr_atom_site_aniso_B_23 = staticmethod(_tr_atom_site_aniso_B_23) + _tr_atom_site_aniso_b_23 = staticmethod(_tr_atom_site_aniso_b_23) def _get_atom_setters(cifloop): """Static method for finding translators of CifLoop items to @@ -602,10 +602,10 @@ def _parse_space_group_symop_operation_xyz(self, block): if self.spacegroup is None: emsg = "CIF file has unknown space group identifier {!r}." raise StructureFormatError(emsg.format(sgid)) - self._expandAsymmetricUnit(block) + self._expand_asymmetric_unit(block) return - def _expandAsymmetricUnit(self, block): + def _expand_asymmetric_unit(self, block): """Perform symmetry expansion of `self.stru` using `self.spacegroup`. diff --git a/src/diffpy/structure/utils.py b/src/diffpy/structure/utils.py index db7b21d2..1e1a6deb 100644 --- a/src/diffpy/structure/utils.py +++ b/src/diffpy/structure/utils.py @@ -18,6 +18,17 @@ import numpy +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure" +removal_version = "4.0.0" +atomBareSymbol_deprecation_msg = build_deprecation_message( + base, + "atomBareSymbol", + "atom_bare_symbol", + removal_version, +) + def isiterable(obj): """``True`` if argument is iterable.""" @@ -35,7 +46,18 @@ def isfloat(s): return False +@deprecated(atomBareSymbol_deprecation_msg) def atomBareSymbol(smbl): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.atom_bare_symbol instead. + """ + + return atom_bare_symbol(smbl) + + +def atom_bare_symbol(smbl): """Remove atom type string stripped of isotope and ion charge symbols. @@ -54,14 +76,13 @@ def atomBareSymbol(smbl): Examples -------- - >>> atomBareSymbol("Cl-") + >>> atom_bare_symbol("Cl-") 'Cl' - >>> atomBareSymbol("Ca2+") + >>> atom_bare_symbol("Ca2+") 'Ca' - >>> atomBareSymbol("12-C") + >>> atom_bare_symbol("12-C") 'C' """ - rv = smbl.strip().lstrip("0123456789-").rstrip("123456789+-") return rv diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..0c89ae09 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +############################################################################## +# +# diffpy.structure Complex Modeling Initiative +# (c) 2016 Brookhaven Science Associates, +# Brookhaven National Laboratory. +# All rights reserved. +# +# File coded by: Pavol Juhas +# +# See AUTHORS.txt for a list of people who contributed. +# See LICENSE.txt for license information. +# +############################################################################## +"""Test for Structure utilities.""" +import pytest + +from diffpy.structure.utils import atom_bare_symbol, atomBareSymbol + + +def test_atomBareSymbol(): + assert atomBareSymbol("Cl-") == "Cl" + assert atomBareSymbol("Ca2+") == "Ca" + assert atomBareSymbol("12-C") == "C" + + +@pytest.mark.parametrize( + "symbol, expected", + [ + ("Cl-", "Cl"), + ("Ca2+", "Ca"), + ("12-C", "C"), + ], +) +def test_atom_bare_symbol(symbol, expected): + actual = atom_bare_symbol(symbol) + assert actual == expected From 62862340375bfecd338b59c2e06ca4e1af5578f6 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 3 Mar 2026 13:49:03 -0500 Subject: [PATCH 178/226] fix: change cif parser attribute name to construct Structure object --- src/diffpy/structure/parsers/p_cif.py | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 585d5927..60860399 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -104,23 +104,23 @@ class P_cif(StructureParser): "_tr_atom_site_cartn_x", "_tr_atom_site_cartn_y", "_tr_atom_site_cartn_z", - "_tr_atom_site_U_iso_or_equiv", - "_tr_atom_site_B_iso_or_equiv", + "_tr_atom_site_u_iso_or_equiv", + "_tr_atom_site_b_iso_or_equiv", "_tr_atom_site_adp_type", "_tr_atom_site_thermal_displace_type", "_tr_atom_site_occupancy", - "_tr_atom_site_aniso_U_11", - "_tr_atom_site_aniso_U_22", - "_tr_atom_site_aniso_U_33", - "_tr_atom_site_aniso_U_12", - "_tr_atom_site_aniso_U_13", - "_tr_atom_site_aniso_U_23", - "_tr_atom_site_aniso_B_11", - "_tr_atom_site_aniso_B_22", - "_tr_atom_site_aniso_B_33", - "_tr_atom_site_aniso_B_12", - "_tr_atom_site_aniso_B_13", - "_tr_atom_site_aniso_B_23", + "_tr_atom_site_aniso_u_11", + "_tr_atom_site_aniso_u_22", + "_tr_atom_site_aniso_u_33", + "_tr_atom_site_aniso_u_12", + "_tr_atom_site_aniso_u_13", + "_tr_atom_site_aniso_u_23", + "_tr_atom_site_aniso_b_11", + "_tr_atom_site_aniso_b_22", + "_tr_atom_site_aniso_b_33", + "_tr_atom_site_aniso_b_12", + "_tr_atom_site_aniso_b_13", + "_tr_atom_site_aniso_b_23", ) ) # make _atom_setters case insensitive From 0f4ddda8b172098c2e4224b2fb4d6c79c32db1e3 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 3 Mar 2026 17:03:51 -0500 Subject: [PATCH 179/226] chore: deprecate parseLines method in all parsers --- news/deprecate-parser-1.rst | 40 ++++++++++ src/diffpy/structure/parsers/p_auto.py | 24 +++++- src/diffpy/structure/parsers/p_cif.py | 25 ++++++- src/diffpy/structure/parsers/p_discus.py | 75 +++++++++++++++++++ src/diffpy/structure/parsers/p_pdb.py | 19 +++++ src/diffpy/structure/parsers/p_pdffit.py | 19 +++++ src/diffpy/structure/parsers/p_rawxyz.py | 19 +++++ src/diffpy/structure/parsers/p_xcfg.py | 19 +++++ src/diffpy/structure/parsers/p_xyz.py | 19 +++++ .../structure/parsers/structureparser.py | 22 +++++- tests/test_p_cif.py | 16 ++++ 11 files changed, 292 insertions(+), 5 deletions(-) create mode 100644 news/deprecate-parser-1.rst diff --git a/news/deprecate-parser-1.rst b/news/deprecate-parser-1.rst new file mode 100644 index 00000000..f6d7b3ff --- /dev/null +++ b/news/deprecate-parser-1.rst @@ -0,0 +1,40 @@ +**Added:** + +* Added ``parse_lines`` method in ``p_auto.py`` +* Added ``parse_lines`` method in ``p_cif.py`` +* Added ``parse_lines`` method in ``p_discus.py`` +* Added ``parse_lines`` method in ``p_pdb.py`` +* Added ``parse_lines`` method in ``p_pdffit.py`` +* Added ``parse_lines`` method in ``p_rawxyz.py`` +* Added ``parse_lines`` method in ``p_xcfg.py`` +* Added ``parse_lines`` method in ``p_xyz.py`` +* Added ``parse_lines`` method in ``structureparser.py`` +* Added ``_suppress_cif_parser_output`` method in ``p_cif.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``parseLines`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdffit.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``structureparser.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 681bb840..5d861f24 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -18,9 +18,20 @@ """ import os +from typing import Any from diffpy.structure.parsers import StructureParser, parser_index from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_auto" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_auto(StructureParser): @@ -76,7 +87,16 @@ def _get_ordered_formats(self): ofmts.insert(0, fmt) return ofmts + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_auto.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Detect format and create `Structure` instance from a list of lines. @@ -96,7 +116,7 @@ def parseLines(self, lines): ------ StructureFormatError """ - return self._wrap_parse_method("parseLines", lines) + return self._wrap_parse_method("parse_lines", lines) def parse(self, s): """Detect format and create `Structure` instance from a string. @@ -145,7 +165,7 @@ def parseFile(self, filename): self.filename = filename return self._wrap_parse_method("parseFile", filename) - def _wrap_parse_method(self, method, *args, **kwargs): + def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> Any: """A helper evaluator method that try the specified parse method with each registered structure parser and return the first successful result. diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 60860399..d3b33484 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -37,10 +37,21 @@ from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- +base = "diffpy.structure.P_cif" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + + class P_cif(StructureParser): """Simple parser for CIF structure format. @@ -330,7 +341,17 @@ def parse(self, s): rv = self._parseCifDataSource(fp) return rv + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_cif.parse_lines instead. + """ + return self.parse_lines(lines) + + @deprecated(parseLines_deprecation_msg) + def parse_lines(self, lines): """Parse list of lines in CIF format. Parameters @@ -400,7 +421,7 @@ def _parseCifDataSource(self, datasource): self.stru = None try: - with _suppressCifParserOutput(): + with _suppress_cif_parser_output(): # Use `grammar` option to digest values with curly-brackets. # Ref: https://bitbucket.org/jamesrhester/pycifrw/issues/19 self.ciffile = CifFile(datasource, grammar="auto") @@ -871,7 +892,7 @@ def getParser(eps=None): @contextmanager -def _suppressCifParserOutput(): +def _suppress_cif_parser_output(): """Context manager which suppresses diagnostic messages from CIF parser.""" from CifFile import yapps3_compiled_rt diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 8039c7c5..e239b168 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -134,6 +134,81 @@ def parseLines(self, lines): raise e.with_traceback(exc_traceback) return self.stru + def parse_lines(self, lines): + """Parse list of lines in DISCUS format. + + Parameters + ---------- + lines : list of str + List of lines from the input file. + + Returns + ------- + PDFFitStructure + Parsed `PDFFitStructure` instance. + + Raises + ------ + StructureFormatError + If the file is not in DISCUS format. + """ + self.lines = lines + ilines = self._linesIterator() + self.stru = PDFFitStructure() + record_parsers = { + "cell": self._parse_cell, + "format": self._parse_format, + "generator": self._parse_not_implemented, + "molecule": self._parse_not_implemented, + "ncell": self._parse_ncell, + "spcgr": self._parse_spcgr, + "symmetry": self._parse_not_implemented, + "title": self._parse_title, + "shape": self._parse_shape, + } + try: + # parse header + for self.line in ilines: + words = self.line.split() + if not words or words[0][0] == "#": + continue + if words[0] == "atoms": + break + rp = record_parsers.get(words[0], self._parse_unknown_record) + rp(words) + # check if cell has been defined + if not self.cell_read: + emsg = "%d: unit cell not defined" % self.nl + raise StructureFormatError(emsg) + # parse atoms + for self.line in ilines: + words = self.line.replace(",", " ").split() + if not words or words[0][0] == "#": + continue + self._parse_atom(words) + # self consistency check + exp_natoms = reduce(lambda x, y: x * y, self.stru.pdffit["ncell"]) + # only check if ncell record exists + if self.ncell_read and exp_natoms != len(self.stru): + emsg = "Expected %d atoms, read %d." % ( + exp_natoms, + len(self.stru), + ) + raise StructureFormatError(emsg) + # take care of superlattice + if self.stru.pdffit["ncell"][:3] != [1, 1, 1]: + latpars = list(self.stru.lattice.abcABG()) + superlatpars = [latpars[i] * self.stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] + superlattice = Lattice(*superlatpars) + self.stru.place_in_lattice(superlattice) + self.stru.pdffit["ncell"] = [1, 1, 1, exp_natoms] + except (ValueError, IndexError): + exc_type, exc_value, exc_traceback = sys.exc_info() + emsg = "%d: file is not in DISCUS format" % self.nl + e = StructureFormatError(emsg) + raise e.with_traceback(exc_traceback) + return self.stru + def toLines(self, stru): """Convert `Structure` stru to a list of lines in DISCUS format. diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 7dc2f327..2264157d 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -29,6 +29,16 @@ from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_pdb" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_pdb(StructureParser): @@ -111,7 +121,16 @@ def __init__(self): self.format = "pdb" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_pdb.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in PDB format. Parameters diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 822a8e26..d35f18a1 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -22,6 +22,16 @@ from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_pdffit" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_pdffit(StructureParser): @@ -44,7 +54,16 @@ def __init__(self): self.stru = None return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_pdffit.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in PDFfit format. Parameters diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index ab28ec41..a3af5812 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -24,6 +24,16 @@ from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_rawxyz" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_rawxyz(StructureParser): @@ -40,7 +50,16 @@ def __init__(self): self.format = "rawxyz" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_rawxyz.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in RAWXYZ format. Parameters diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index ee626293..e8cfec66 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -29,6 +29,7 @@ from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat +from diffpy.utils._deprecator import build_deprecation_message, deprecated # Constants ------------------------------------------------------------------ @@ -151,6 +152,15 @@ # ---------------------------------------------------------------------------- +base = "diffpy.structure.P_xcfg" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + class P_xcfg(StructureParser): """Parser for AtomEye extended CFG format. @@ -171,7 +181,16 @@ def __init__(self): self.format = "xcfg" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xcfg.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in XCFG format. Parameters diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index a91c431f..a13af70f 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -24,6 +24,16 @@ from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_xyz" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_xyz(StructureParser): @@ -40,7 +50,16 @@ def __init__(self): self.format = "xyz" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xyz.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in XYZ format. Parameters diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index f785b52e..45eb2043 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -14,6 +14,17 @@ ############################################################################## """Definition of StructureParser, a base class for specific parsers.""" +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.StructureParser" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + class StructureParser(object): """Base class for all structure parsers. @@ -31,7 +42,16 @@ def __init__(self): self.filename = None return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.StructureParser.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Create Structure instance from a list of lines. Return Structure object or raise StructureFormatError exception. @@ -40,7 +60,7 @@ def parseLines(self, lines): ---- This method has to be overloaded in derived class. """ - raise NotImplementedError("parseLines not defined for '%s' format" % self.format) + raise NotImplementedError("parse lines not defined for '%s' format" % self.format) return def toLines(self, stru): diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index 4558c397..e0c4a407 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -114,6 +114,22 @@ def test_parseLines(self): self.assertRaises(StructureFormatError, ptest2.parseLines, badlines) return + def test_parse_lines(self): + """Check P_cif.parseLines()""" + with open(self.pbteciffile) as fp1: + goodlines = fp1.readlines() + with open(self.badciffile) as fp2: + badlines = fp2.readlines() + pfile, ptest = self.pfile, self.ptest + stru_check = pfile.parseFile(self.pbteciffile) + stru = ptest.parse_lines(goodlines) + self.assertEqual(str(stru_check), str(stru)) + self.assertEqual(str(stru_check.lattice), str(stru.lattice)) + self.assertEqual(pfile.spacegroup.short_name, ptest.spacegroup.short_name) + ptest2 = P_cif() + self.assertRaises(StructureFormatError, ptest2.parse_lines, badlines) + return + def test_parseFile(self): """Check P_cif.parseFile()""" # pbteciffile From 00987ec28a7b8803b265b7a8e936f22e559e33d9 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Wed, 4 Mar 2026 14:00:38 -0500 Subject: [PATCH 180/226] chore: deprecate parseFile method --- news/deprecate-parsefile.rst | 27 ++++++++ src/diffpy/structure/__init__.py | 2 +- src/diffpy/structure/parsers/p_auto.py | 18 ++++- src/diffpy/structure/parsers/p_cif.py | 16 +++++ .../structure/parsers/structureparser.py | 15 +++++ src/diffpy/structure/structure.py | 2 +- tests/test_p_cif.py | 65 +++++++++++++++---- 7 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 news/deprecate-parsefile.rst diff --git a/news/deprecate-parsefile.rst b/news/deprecate-parsefile.rst new file mode 100644 index 00000000..855b4bb2 --- /dev/null +++ b/news/deprecate-parsefile.rst @@ -0,0 +1,27 @@ +**Added:** + +* Added ``parse_file`` method in ``structureparser.py`` +* Added ``parse_lines`` method in ``p_cif.py`` +* Added ``parse_lines`` method in ``p_auto.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``parse_file`` method in ``structureparser.py`` for removal in version 4.0.0 +* Deprecated ``parse_file`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``parse_file`` method in ``p_auto.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 58d7e3a8..36240480 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -98,7 +98,7 @@ def loadStructure(filename, fmt="auto", **kw): """ p = getParser(fmt, **kw) - rv = p.parseFile(filename) + rv = p.parse_file(filename) return rv diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 5d861f24..d2937323 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -32,6 +32,12 @@ "parse_lines", removal_version, ) +parseFile_deprecation_msg = build_deprecation_message( + base, + "parseFile", + "parse_file", + removal_version, +) class P_auto(StructureParser): @@ -139,7 +145,16 @@ def parse(self, s): """ return self._wrap_parse_method("parse", s) + @deprecated(parseFile_deprecation_msg) def parseFile(self, filename): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_auto.parse_file instead. + """ + return self.parse_file(filename) + + def parse_file(self, filename): """Detect format and create Structure instance from an existing file. @@ -163,7 +178,8 @@ def parseFile(self, filename): If the file cannot be read. """ self.filename = filename - return self._wrap_parse_method("parseFile", filename) + return self._wrap_parse_method("parse_file", filename) + def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> Any: """A helper evaluator method that try the specified parse method diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index d3b33484..2b32bc1a 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -50,6 +50,12 @@ "parse_lines", removal_version, ) +parseFile_deprecation_msg = build_deprecation_message( + base, + "parseFile", + "parse_file", + removal_version, +) class P_cif(StructureParser): @@ -372,7 +378,17 @@ def parse_lines(self, lines): s = "\n".join(lines) + "\n" return self.parse(s) + @deprecated(parseFile_deprecation_msg) def parseFile(self, filename): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_cif.parse_file instead. + """ + return self.parse_file(filename) + + + def parse_file(self, filename): """Create Structure from an existing CIF file. Parameters diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index 45eb2043..a5d89aa2 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -24,6 +24,12 @@ "parse_lines", removal_version, ) +parseFile_deprecation_msg = build_deprecation_message( + base, + "parseFile", + "parse_file", + removal_version, +) class StructureParser(object): @@ -86,7 +92,16 @@ def tostring(self, stru): s = "\n".join(lines) + "\n" return s + @deprecated(parseFile_deprecation_msg) def parseFile(self, filename): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.StructureParser.parse_file instead. + """ + return self.parse_file(filename) + + def parse_file(self, filename): """Create Structure instance from an existing file.""" self.filename = filename with open(filename) as fp: diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 7ba7f8ab..ec1e86aa 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -357,7 +357,7 @@ def read(self, filename, format="auto"): getParser = diffpy.structure.parsers.getParser p = getParser(format) - new_structure = p.parseFile(filename) + new_structure = p.parse_file(filename) # reinitialize data after successful parsing # avoid calling __init__ from a derived class Structure.__init__(self) diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index e0c4a407..b4c88b3f 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -173,6 +173,49 @@ def test_parseFile(self): self.assertEqual(16, len(ptei)) return + def test_parse_file(self): + """Check P_cif.parse_file()""" + # pbteciffile + stru = self.pfile.parse_file(self.pbteciffile) + self.assertEqual(8, len(stru)) + self.assertEqual(6.461, stru.lattice.a) + self.assertEqual(6.461, stru.lattice.b) + self.assertEqual(6.461, stru.lattice.c) + self.assertEqual(90.0, stru.lattice.alpha) + self.assertEqual(90.0, stru.lattice.beta) + self.assertEqual(90.0, stru.lattice.gamma) + self.assertEqual("Fm-3m", self.pfile.spacegroup.short_name) + a0 = stru[0] + self.assertEqual(0.5, a0.x) + self.assertEqual(0.5, a0.y) + self.assertEqual(0.5, a0.z) + self.assertEqual(False, a0.anisotropy) + self.assertEqual(1.0, a0.occupancy) + self.assertEqual(0.0225566, a0.Uisoequiv) + # badciffile + pfile2 = P_cif() + self.assertRaises(StructureFormatError, pfile2.parse_file, self.badciffile) + # graphite + pgraphite = P_cif() + graphite = pgraphite.parse_file(self.graphiteciffile) + self.assertEqual(4, len(graphite)) + c1 = graphite[0] + self.assertEqual(str, type(c1.element)) + self.assertEqual("C", c1.element) + self.assertEqual(str, type(c1.label)) + self.assertEqual("C1", c1.label) + # filename with unicode encoding + hasbs = "\\" in self.graphiteciffile + uciffile = self.graphiteciffile.replace("\\", "/") + if hasbs: # pragma: no cover + uciffile = uciffile.replace("/", "\\") + ugraphite = P_cif().parse_file(uciffile) + self.assertEqual(4, len(ugraphite)) + # File with full space group name + ptei = P_cif().parse_file(self.teiciffile) + self.assertEqual(16, len(ptei)) + return + # def test__parseCifBlock(self): # """check P_cif._parseCifBlock() # """ @@ -271,19 +314,19 @@ def test_eps(self): """Test the P_cif.eps coordinates resolution.""" pcif = P_cif() pcif.eps = 1e-8 - grph = pcif.parseFile(self.graphiteciffile) + grph = pcif.parse_file(self.graphiteciffile) self.assertEqual(8, len(grph)) self.assertTrue(all(a.label.startswith("C1") for a in grph[:2])) self.assertTrue(all(a.label.startswith("C2") for a in grph[2:])) pcif2 = P_cif() pcif2.eps = 1e-3 - grph2 = pcif2.parseFile(self.graphiteciffile) + grph2 = pcif2.parse_file(self.graphiteciffile) self.assertEqual(4, len(grph2)) return def test_unknown_occupancy(self): "test CIF file with unknown occupancy data" - stru = self.ptest.parseFile(self.datafile("TeI-unkocc.cif")) + stru = self.ptest.parse_file(self.datafile("TeI-unkocc.cif")) self.assertTrue(numpy.array_equal(16 * [1], stru.occupancy)) return @@ -311,7 +354,7 @@ def test_unknown_spacegroup_number(self): def test_nosites_cif(self): """Test reading of CIF file with no valid sites.""" ptest = self.ptest - stru = ptest.parseFile(self.datafile("nosites.cif")) + stru = ptest.parse_file(self.datafile("nosites.cif")) self.assertEqual(0, len(stru)) self.assertEqual(10.413, stru.lattice.a) self.assertEqual(10.413, stru.lattice.b) @@ -322,14 +365,14 @@ def test_badspacegroup_cif(self): """Test reading of CIF file with unrecognized space group.""" ptest = self.ptest filename = self.datafile("badspacegroup.cif") - self.assertRaises(StructureFormatError, ptest.parseFile, filename) + self.assertRaises(StructureFormatError, ptest.parse_file, filename) return def test_custom_spacegroup_cif(self): """Test parsing of nonstandard symops-defined space group.""" pfile = self.pfile filename = self.datafile("customsg.cif") - pfile.parseFile(filename) + pfile.parse_file(filename) sg = pfile.spacegroup self.assertEqual("CIF data", sg.short_name) self.assertEqual(6, len(sg.symop_list)) @@ -349,14 +392,14 @@ def test_spacegroup_isotropy(self): def test_spacegroup_anisotropy(self): "verify site anisotropy due to site symmetry." - stru = self.ptest.parseFile(self.graphiteciffile) + stru = self.ptest.parse_file(self.graphiteciffile) self.assertTrue(all(stru.anisotropy)) return def test_spacegroup_ref(self): "verify space group reference" pfile = self.pfile - pfile.parseFile(self.refciffile) + pfile.parse_file(self.refciffile) sg = pfile.spacegroup self.assertEqual("Fm-3m", sg.short_name) @@ -406,7 +449,7 @@ def test_unknown_aniso(self): def test_curly_brace(self): "verify loading of a CIF file with unquoted curly brace" ptest = self.ptest - stru = ptest.parseFile(self.datafile("curlybrackets.cif")) + stru = ptest.parse_file(self.datafile("curlybrackets.cif")) self.assertEqual(20, len(stru)) return @@ -414,12 +457,12 @@ def test_getParser(self): """Test passing of eps keyword argument by getParser function.""" pcif = getParser("cif", eps=1e-6) - grph = pcif.parseFile(self.graphiteciffile) + grph = pcif.parse_file(self.graphiteciffile) self.assertEqual(8, len(grph)) self.assertTrue(all(a.label.startswith("C1") for a in grph[:2])) self.assertTrue(all(a.label.startswith("C2") for a in grph[2:])) pcif2 = getParser("cif") - grph2 = pcif2.parseFile(self.graphiteciffile) + grph2 = pcif2.parse_file(self.graphiteciffile) self.assertEqual(4, len(grph2)) return From 284bc84889d6b5e289cd5202e1d2c10618b88c7a Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Wed, 4 Mar 2026 14:01:35 -0500 Subject: [PATCH 181/226] chore: run pre-commit --- src/diffpy/structure/parsers/p_auto.py | 1 - src/diffpy/structure/parsers/p_cif.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index d2937323..ed00dcbe 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -180,7 +180,6 @@ def parse_file(self, filename): self.filename = filename return self._wrap_parse_method("parse_file", filename) - def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> Any: """A helper evaluator method that try the specified parse method with each registered structure parser and return the first diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 2b32bc1a..39c8d696 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -387,7 +387,6 @@ def parseFile(self, filename): """ return self.parse_file(filename) - def parse_file(self, filename): """Create Structure from an existing CIF file. From 10ac932b7a5f09b416b97b3ee9b2fa7562172a2b Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 5 Mar 2026 11:44:41 -0500 Subject: [PATCH 182/226] chore: deprecate toLines method across of parsers --- news/deprecate-toLine.rst | 38 +++++++++ src/diffpy/structure/parsers/p_cif.py | 25 ++++-- src/diffpy/structure/parsers/p_discus.py | 32 +++++++- src/diffpy/structure/parsers/p_pdb.py | 15 ++++ src/diffpy/structure/parsers/p_pdffit.py | 77 +++++++++++++++++++ src/diffpy/structure/parsers/p_rawxyz.py | 15 ++++ src/diffpy/structure/parsers/p_xcfg.py | 15 ++++ src/diffpy/structure/parsers/p_xyz.py | 15 ++++ .../structure/parsers/structureparser.py | 19 ++++- 9 files changed, 241 insertions(+), 10 deletions(-) create mode 100644 news/deprecate-toLine.rst diff --git a/news/deprecate-toLine.rst b/news/deprecate-toLine.rst new file mode 100644 index 00000000..ca25c38c --- /dev/null +++ b/news/deprecate-toLine.rst @@ -0,0 +1,38 @@ +**Added:** + +* Added ``_parse_cif_data_source`` method in ``p_cif.py`` +* Added ``_parse_cif_block`` method in ``p_cif.py`` +* Added ``to_lines`` method in ``p_cif.py`` +* Added ``to_lines`` method in ``p_pdb.py`` +* Added ``to_lines`` method in ``p_rawxyz.py`` +* Added ``to_lines`` method in ``p_xcfg.py`` +* Added ``to_lines`` method in ``p_xyz.py`` +* Added ``to_lines`` method in ``structureparser.py`` +* Added ``_lines_iterator`` method in ``p_discus.py`` +* Added ``to_lines`` method in ``p_discus.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``toLines`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``structureparser.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_discus.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 39c8d696..4a889832 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -56,6 +56,12 @@ "parse_file", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_cif(StructureParser): @@ -344,7 +350,7 @@ def parse(self, s): self.ciffile = None self.filename = "" fp = io.StringIO(s) - rv = self._parseCifDataSource(fp) + rv = self._parse_cif_data_source(fp) return rv @deprecated(parseLines_deprecation_msg) @@ -409,11 +415,11 @@ def parse_file(self, filename): """ self.ciffile = None self.filename = filename - rv = self._parseCifDataSource(filename) + rv = self._parse_cif_data_source(filename) # all good here return rv - def _parseCifDataSource(self, datasource): + def _parse_cif_data_source(self, datasource): """Open and process CIF data from the specified `datasource`. Parameters @@ -441,7 +447,7 @@ def _parseCifDataSource(self, datasource): # Ref: https://bitbucket.org/jamesrhester/pycifrw/issues/19 self.ciffile = CifFile(datasource, grammar="auto") for blockname in self.ciffile.keys(): - self._parseCifBlock(blockname) + self._parse_cif_block(blockname) # stop after reading the first structure if self.stru is not None: break @@ -452,7 +458,7 @@ def _parseCifDataSource(self, datasource): raise e.with_traceback(exc_traceback) return self.stru - def _parseCifBlock(self, blockname): + def _parse_cif_block(self, blockname): """Translate CIF file block, skip blocks without `_atom_site_label`. Updates data members `stru`, `eau`. @@ -682,7 +688,16 @@ def _expand_asymmetric_unit(self, block): # conversion to CIF ------------------------------------------------------ + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_cif.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert `Structure` to a list of lines in basic CIF format. Parameters diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index e239b168..46b52541 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -20,6 +20,22 @@ from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_discus" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_discus(StructureParser): @@ -59,6 +75,7 @@ def __init__(self): self.ncell_read = False return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): """Parse list of lines in DISCUS format. @@ -78,7 +95,7 @@ def parseLines(self, lines): If the file is not in DISCUS format. """ self.lines = lines - ilines = self._linesIterator() + ilines = self._lines_iterator() self.stru = PDFFitStructure() record_parsers = { "cell": self._parse_cell, @@ -153,7 +170,7 @@ def parse_lines(self, lines): If the file is not in DISCUS format. """ self.lines = lines - ilines = self._linesIterator() + ilines = self._lines_iterator() self.stru = PDFFitStructure() record_parsers = { "cell": self._parse_cell, @@ -209,7 +226,16 @@ def parse_lines(self, lines): raise e.with_traceback(exc_traceback) return self.stru + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_discus.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert `Structure` stru to a list of lines in DISCUS format. Parameters @@ -257,7 +283,7 @@ def toLines(self, stru): ) return lines - def _linesIterator(self): + def _lines_iterator(self): """Iterator over `self.lines`, which increments `self.nl`""" # ignore trailing empty lines stop = len(self.lines) diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 2264157d..3dd72947 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -39,6 +39,12 @@ "parse_lines", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_pdb(StructureParser): @@ -396,7 +402,16 @@ def atomLines(self, stru, idx): lines.append(line) return lines + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_pdb.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert `Structure` stru to a list of lines in PDB format. Parameters diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index d35f18a1..5d4ae57d 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -274,6 +274,83 @@ def toLines(self, stru): lines.append(" %18.8f %17.8f %17.8f" % sigUij) return lines + def to_lines(self, stru): + """Convert `Structure` stru to a list of lines in PDFfit format. + + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + List of lines in PDFfit format. + """ + # build the stru_pdffit dictionary initialized from the defaults + # in PDFFitStructure + stru_pdffit = PDFFitStructure().pdffit + if stru.pdffit: + stru_pdffit.update(stru.pdffit) + lines = [] + # default values of standard deviations + d_sigxyz = numpy.zeros(3, dtype=float) + d_sigo = 0.0 + d_sigU = numpy.zeros((3, 3), dtype=float) + # here we can start + line = "title " + stru.title + lines.append(line.strip()) + lines.append("format pdffit") + lines.append("scale %9.6f" % stru_pdffit["scale"]) + lines.append( + "sharp %9.6f, %9.6f, %9.6f, %9.6f" + % ( + stru_pdffit["delta2"], + stru_pdffit["delta1"], + stru_pdffit["sratio"], + stru_pdffit["rcut"], + ) + ) + lines.append("spcgr " + stru_pdffit["spcgr"]) + if stru_pdffit.get("spdiameter", 0.0) > 0.0: + line = "shape sphere, %g" % stru_pdffit["spdiameter"] + lines.append(line) + if stru_pdffit.get("stepcut", 0.0) > 0.0: + line = "shape stepcut, %g" % stru_pdffit["stepcut"] + lines.append(line) + lat = stru.lattice + lines.append( + "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" + % (lat.a, lat.b, lat.c, lat.alpha, lat.beta, lat.gamma) + ) + lines.append("dcell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % tuple(stru_pdffit["dcell"])) + lines.append("ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(stru))) + lines.append("atoms") + for a in stru: + ad = a.__dict__ + lines.append( + "%-4s %17.8f %17.8f %17.8f %12.4f" + % ( + a.element.upper(), + a.xyz[0], + a.xyz[1], + a.xyz[2], + a.occupancy, + ) + ) + sigmas = numpy.concatenate((ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)])) + lines.append(" %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas)) + sigU = ad.get("sigU", d_sigU) + Uii = (a.U[0][0], a.U[1][1], a.U[2][2]) + Uij = (a.U[0][1], a.U[0][2], a.U[1][2]) + sigUii = (sigU[0][0], sigU[1][1], sigU[2][2]) + sigUij = (sigU[0][1], sigU[0][2], sigU[1][2]) + lines.append(" %18.8f %17.8f %17.8f" % Uii) + lines.append(" %18.8f %17.8f %17.8f" % sigUii) + lines.append(" %18.8f %17.8f %17.8f" % Uij) + lines.append(" %18.8f %17.8f %17.8f" % sigUij) + return lines + # Protected methods ------------------------------------------------------ def _parse_shape(self, line): diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index a3af5812..d4627396 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -34,6 +34,12 @@ "parse_lines", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_rawxyz(StructureParser): @@ -130,7 +136,16 @@ def parse_lines(self, lines): raise e.with_traceback(exc_traceback) return stru + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_rawxyz.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert Structure stru to a list of lines in RAWXYZ format. Parameters diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index e8cfec66..b1006be7 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -160,6 +160,12 @@ "parse_lines", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_xcfg(StructureParser): @@ -309,7 +315,16 @@ def parse_lines(self, lines): raise e.with_traceback(exc_traceback) return stru + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xcfg.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert Structure stru to a list of lines in XCFG atomeye format. diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index a13af70f..b94def8b 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -34,6 +34,12 @@ "parse_lines", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class P_xyz(StructureParser): @@ -140,7 +146,16 @@ def parse_lines(self, lines): raise StructureFormatError(emsg) return stru + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xyz.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert Structure stru to a list of lines in XYZ format. Parameters diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index a5d89aa2..270fbb32 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -30,6 +30,12 @@ "parse_file", removal_version, ) +toLines_deprecation_msg = build_deprecation_message( + base, + "toLines", + "to_lines", + removal_version, +) class StructureParser(object): @@ -69,7 +75,16 @@ def parse_lines(self, lines): raise NotImplementedError("parse lines not defined for '%s' format" % self.format) return + @deprecated(toLines_deprecation_msg) def toLines(self, stru): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.StructureParser.to_lines instead. + """ + return self.to_lines(stru) + + def to_lines(self, stru): """Convert Structure stru to a list of lines. Return list of strings. @@ -78,7 +93,7 @@ def toLines(self, stru): ---- This method has to be overloaded in derived class. """ - raise NotImplementedError("toLines not defined for '%s' format" % self.format) + raise NotImplementedError("to_lines not defined for '%s' format" % self.format) def parse(self, s): """Create `Structure` instance from a string.""" @@ -88,7 +103,7 @@ def parse(self, s): def tostring(self, stru): """Convert `Structure` instance to a string.""" - lines = self.toLines(stru) + lines = self.to_lines(stru) s = "\n".join(lines) + "\n" return s From 70aa6751a786cfa911166395f058f29cdce0816c Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 5 Mar 2026 19:14:34 -0500 Subject: [PATCH 183/226] chore: deprecate getParser method across all parsers format. --- news/deprecate-getParser.rst | 39 ++++++++++++++++++++++++ src/diffpy/structure/__init__.py | 4 +-- src/diffpy/structure/parsers/__init__.py | 36 +++++++++++++++++++++- src/diffpy/structure/parsers/p_auto.py | 30 ++++++++++++++++-- src/diffpy/structure/parsers/p_cif.py | 25 +++++++++++++++ src/diffpy/structure/parsers/p_discus.py | 22 +++++++++++++ src/diffpy/structure/parsers/p_pdb.py | 20 ++++++++++++ src/diffpy/structure/parsers/p_pdffit.py | 11 +++++++ src/diffpy/structure/parsers/p_rawxyz.py | 20 ++++++++++++ src/diffpy/structure/parsers/p_xcfg.py | 20 ++++++++++++ src/diffpy/structure/parsers/p_xyz.py | 20 ++++++++++++ src/diffpy/structure/structure.py | 16 +++++----- tests/test_p_cif.py | 15 ++++++++- 13 files changed, 264 insertions(+), 14 deletions(-) create mode 100644 news/deprecate-getParser.rst diff --git a/news/deprecate-getParser.rst b/news/deprecate-getParser.rst new file mode 100644 index 00000000..99e3f33d --- /dev/null +++ b/news/deprecate-getParser.rst @@ -0,0 +1,39 @@ +**Added:** + +* Added ``get_parser`` method in ``p_auto.py`` +* Added ``get_parser`` method in ``p_cif.py`` +* Added ``get_parser`` method in ``p_discus.py`` +* Added ``get_parser`` method in ``p_pdb.py`` +* Added ``get_parser`` method in ``p_pdffit.py`` +* Added ``get_parser`` method in ``p_rawxyz.py`` +* Added ``get_parser`` method in ``p_xcfg.py`` +* Added ``get_parser`` method in ``p_xyz.py`` +* Added ``get_parser`` method in ``parsers/__init__.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``getParser`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_pdffit.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``parsers/__init__.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 36240480..969b7323 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -39,7 +39,7 @@ import diffpy.structure as _structure from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice -from diffpy.structure.parsers import getParser +from diffpy.structure.parsers import get_parser from diffpy.structure.pdffitstructure import PDFFitStructure from diffpy.structure.structure import Structure from diffpy.structure.structureerrors import LatticeError, StructureFormatError, SymmetryError @@ -97,7 +97,7 @@ def loadStructure(filename, fmt="auto", **kw): and 'discus' formats. """ - p = getParser(fmt, **kw) + p = get_parser(fmt, **kw) rv = p.parse_file(filename) return rv diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index cb9bd4f8..6bf12317 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -33,14 +33,48 @@ from diffpy.structure.parsers.parser_index_mod import parser_index from diffpy.structure.parsers.structureparser import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated # silence pyflakes checker assert StructureParser +parsers_base = "diffpy.structure" +removal_version = "4.0.0" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(format, **kw): """Return Parser instance for a given structure format. + Parameters + ---------- + format : str + String with the format name, see `parser_index_mod`. + **kw : dict + Keyword arguments passed to the Parser init function. + + Returns + ------- + Parser + Parser instance for the given format. + + Raises + ------ + StructureFormatError + When the format is not defined. + """ + return get_parser(format, **kw) + + +def get_parser(format, **kw): + """Return Parser instance for a given structure format. + Parameters ---------- format : str @@ -65,7 +99,7 @@ def getParser(format, **kw): ns = {} import_cmd = "from diffpy.structure.parsers import %s as pm" % pmod exec(import_cmd, ns) - return ns["pm"].getParser(**kw) + return ns["pm"].get_parser(**kw) def inputFormats(): diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index ed00dcbe..eb5fbe34 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -206,14 +206,14 @@ def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> ------ StructureFormatError """ - from diffpy.structure.parsers import getParser + from diffpy.structure.parsers import get_parser ofmts = self._get_ordered_formats() stru = None # try all parsers in sequence parsers_emsgs = [] for fmt in ofmts: - p = getParser(fmt, **self.pkw) + p = get_parser(fmt, **self.pkw) try: pmethod = getattr(p, method) stru = pmethod(*args, **kwargs) @@ -240,10 +240,36 @@ def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +removal_version = "4.0.0" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(**kw): """Return a new instance of the automatic parser. + Parameters + ---------- + **kw : dict + Keyword arguments for the structure parser + + Returns + ------- + P_auto + Instance of `P_auto`. + """ + return get_parser(**kw) + + +def get_parser(**kw): + """Return a new instance of the automatic parser. + Parameters ---------- **kw : dict diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 39c8d696..492860da 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -802,6 +802,13 @@ def toLines(self, stru): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) # constant regular expression for leading_float() rx_float = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?") @@ -886,9 +893,27 @@ def getSymOp(s): return rv +@deprecated(getParser_deprecation_msg) def getParser(eps=None): """Return new `parser` object for CIF format. + Parameters + ---------- + eps : float, Optional + fractional coordinates cutoff for duplicate positions. + When ``None`` use the default for `ExpandAsymmetricUnit`: ``1.0e-5``. + + Returns + ------- + P_cif + Instance of `P_cif`. + """ + return get_parser(eps) + + +def get_parser(eps=None): + """Return new `parser` object for CIF format. + Parameters ---------- eps : float, Optional diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index e239b168..66b5fa65 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -20,6 +20,7 @@ from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated class P_discus(StructureParser): @@ -386,10 +387,31 @@ def _parse_not_implemented(self, words): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +removal_version = "4.0.0" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(): """Return new `parser` object for DISCUS format. + Returns + ------- + P_discus + Instance of `P_discus`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for DISCUS format. + Returns ------- P_discus diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 2264157d..c057a52d 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -439,10 +439,30 @@ def toLines(self, stru): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(): """Return new `parser` object for PDB format. + Returns + ------- + P_pdb + Instance of `P_pdb`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for PDB format. + Returns ------- P_pdb diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index d35f18a1..9a1935b5 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -311,6 +311,17 @@ def _parse_shape(self, line): def getParser(): """Return new `parser` object for PDFfit format. + Returns + ------- + P_pdffit + Instance of `P_pdffit`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for PDFfit format. + Returns ------- P_pdffit diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index a3af5812..45e5a53c 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -155,10 +155,30 @@ def toLines(self, stru): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(): """Return new `parser` object for RAWXYZ format. + Returns + ------- + P_rawxyz + Instance of `P_rawxyz`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for RAWXYZ format. + Returns ------- P_rawxyz diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index e8cfec66..ddb35c4f 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -432,10 +432,30 @@ def toLines(self, stru): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(): """Return new `parser` object for XCFG format. + Returns + ------- + P_xcfg + Instance of `P_xcfg`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for XCFG format. + Returns ------- P_xcfg diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index a13af70f..014b7672 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -167,10 +167,30 @@ def toLines(self, stru): # Routines ------------------------------------------------------------------- +parsers_base = "diffpy.structure" +getParser_deprecation_msg = build_deprecation_message( + parsers_base, + "getParser", + "get_parser", + removal_version, +) + +@deprecated(getParser_deprecation_msg) def getParser(): """Return new `parser` object for XYZ format. + Returns + ------- + P_xcfg + Instance of `P_xyz`. + """ + return get_parser() + + +def get_parser(): + """Return new `parser` object for XYZ format. + Returns ------- P_xcfg diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index ec1e86aa..c351e931 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -355,8 +355,8 @@ def read(self, filename, format="auto"): import diffpy.structure import diffpy.structure.parsers - getParser = diffpy.structure.parsers.getParser - p = getParser(format) + get_parser = diffpy.structure.parsers.get_parser + p = get_parser(format) new_structure = p.parse_file(filename) # reinitialize data after successful parsing # avoid calling __init__ from a derived class @@ -398,9 +398,9 @@ def read_structure(self, s, format="auto"): Return instance of data Parser used to process input string. This can be inspected for information related to particular format. """ - from diffpy.structure.parsers import getParser + from diffpy.structure.parsers import get_parser - p = getParser(format) + p = get_parser(format) new_structure = p.parse(s) # reinitialize data after successful parsing # avoid calling __init__ from a derived class @@ -426,9 +426,9 @@ def write(self, filename, format): ``from parsers import formats`` """ - from diffpy.structure.parsers import getParser + from diffpy.structure.parsers import get_parser - p = getParser(format) + p = get_parser(format) p.filename = filename s = p.tostring(self) with open(filename, "w", encoding="utf-8", newline="") as fp: @@ -454,9 +454,9 @@ def write_structure(self, format): ``from parsers import formats`` """ - from diffpy.structure.parsers import getParser + from diffpy.structure.parsers import get_parser - p = getParser(format) + p = get_parser(format) s = p.tostring(self) return s diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index b4c88b3f..fd63f03b 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -20,7 +20,7 @@ import pytest from diffpy.structure import Structure -from diffpy.structure.parsers import getParser +from diffpy.structure.parsers import get_parser, getParser from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float from diffpy.structure.structureerrors import StructureFormatError @@ -466,6 +466,19 @@ def test_getParser(self): self.assertEqual(4, len(grph2)) return + def test_get_parser(self): + """Test passing of eps keyword argument by get_parser + function.""" + pcif = get_parser("cif", eps=1e-6) + grph = pcif.parse_file(self.graphiteciffile) + self.assertEqual(8, len(grph)) + self.assertTrue(all(a.label.startswith("C1") for a in grph[:2])) + self.assertTrue(all(a.label.startswith("C2") for a in grph[2:])) + pcif2 = get_parser("cif") + grph2 = pcif2.parse_file(self.graphiteciffile) + self.assertEqual(4, len(grph2)) + return + # End of class TestP_cif From c89466cf4b2d2db222b8175b037662cf342cf478 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 5 Mar 2026 23:01:16 -0500 Subject: [PATCH 184/226] chore: derepcate P_pdb method --- news/deprecate-parser-display.rst | 31 +++++++++ src/diffpy/structure/apps/anyeye.py | 4 +- src/diffpy/structure/apps/transtru.py | 12 ++-- src/diffpy/structure/parsers/__init__.py | 52 ++++++++++----- src/diffpy/structure/parsers/p_auto.py | 17 ++--- src/diffpy/structure/parsers/p_cif.py | 14 +--- src/diffpy/structure/parsers/p_discus.py | 8 +-- src/diffpy/structure/parsers/p_pdb.py | 40 ++++++++++- src/diffpy/structure/parsers/p_pdffit.py | 85 ++---------------------- src/diffpy/structure/parsers/p_rawxyz.py | 8 +-- src/diffpy/structure/parsers/p_xcfg.py | 8 +-- src/diffpy/structure/parsers/p_xyz.py | 8 +-- 12 files changed, 138 insertions(+), 149 deletions(-) create mode 100644 news/deprecate-parser-display.rst diff --git a/news/deprecate-parser-display.rst b/news/deprecate-parser-display.rst new file mode 100644 index 00000000..4aaa4e08 --- /dev/null +++ b/news/deprecate-parser-display.rst @@ -0,0 +1,31 @@ +**Added:** + +* Added ``input_formats`` method in ``parsers/__init__.py`` +* Added ``output_formats`` method in ``parsers/__init__.py`` +* Added ``title_lines`` method in ``p_pdb.py`` +* Added ``cryst1_lines`` method in ``p_pdb.py`` +* Added ``atom_lines`` method in ``p_pdb.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``inputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 +* Deprecated ``outputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 +* Deprecated ``titleLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``crystl1Lines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``atomLines`` method in ``p_pdb.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index b75c5bdb..56e16f45 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -72,9 +72,9 @@ def usage(style=None): if style == "brief": msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname else: - from diffpy.structure.parsers import inputFormats + from diffpy.structure.parsers import input_formats - fmts = [f for f in inputFormats() if f != "auto"] + fmts = [f for f in input_formats() if f != "auto"] msg = msg.replace("inputFormats", " ".join(fmts)) print(msg) return diff --git a/src/diffpy/structure/apps/transtru.py b/src/diffpy/structure/apps/transtru.py index 7155a86f..d942564e 100755 --- a/src/diffpy/structure/apps/transtru.py +++ b/src/diffpy/structure/apps/transtru.py @@ -52,10 +52,10 @@ def usage(style=None): if style == "brief": msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname else: - from diffpy.structure.parsers import inputFormats, outputFormats + from diffpy.structure.parsers import input_formats, output_formats - msg = msg.replace("inputFormats", " ".join(inputFormats())) - msg = msg.replace("outputFormats", " ".join(outputFormats())) + msg = msg.replace("inputFormats", " ".join(input_formats())) + msg = msg.replace("outputFormats", " ".join(output_formats())) print(msg) return @@ -88,14 +88,14 @@ def main(): usage("brief") sys.exit() # process arguments - from diffpy.structure.parsers import inputFormats, outputFormats + from diffpy.structure.parsers import input_formats, output_formats try: infmt, outfmt = args[0].split("..", 1) - if infmt not in inputFormats(): + if infmt not in input_formats(): print("'%s' is not valid input format" % infmt, file=sys.stderr) sys.exit(2) - if outfmt not in outputFormats(): + if outfmt not in output_formats(): print("'%s' is not valid output format" % outfmt, file=sys.stderr) sys.exit(2) except ValueError: diff --git a/src/diffpy/structure/parsers/__init__.py b/src/diffpy/structure/parsers/__init__.py index 6bf12317..124b91a7 100644 --- a/src/diffpy/structure/parsers/__init__.py +++ b/src/diffpy/structure/parsers/__init__.py @@ -46,28 +46,26 @@ "get_parser", removal_version, ) +inputFormats_deprecation_msg = build_deprecation_message( + parsers_base, + "inputFormats", + "input_formats", + removal_version, +) +outputFormats_deprecation_msg = build_deprecation_message( + parsers_base, + "outputFormats", + "output_formats", + removal_version, +) @deprecated(getParser_deprecation_msg) def getParser(format, **kw): - """Return Parser instance for a given structure format. - - Parameters - ---------- - format : str - String with the format name, see `parser_index_mod`. - **kw : dict - Keyword arguments passed to the Parser init function. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - Parser - Parser instance for the given format. - - Raises - ------ - StructureFormatError - When the format is not defined. + Please use diffpy.structure.get_parser instead. """ return get_parser(format, **kw) @@ -102,14 +100,34 @@ def get_parser(format, **kw): return ns["pm"].get_parser(**kw) +@deprecated(inputFormats_deprecation_msg) def inputFormats(): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.input_formats instead. + """ + return input_formats() + + +def input_formats(): """Return list of implemented input structure formats.""" input_formats = [fmt for fmt, prop in parser_index.items() if prop["has_input"]] input_formats.sort() return input_formats +@deprecated(outputFormats_deprecation_msg) def outputFormats(): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.output_formats instead. + """ + return output_formats() + + +def output_formats(): """Return list of implemented output structure formats.""" output_formats = [fmt for fmt, prop in parser_index.items() if prop["has_output"]] output_formats.sort() diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index eb5fbe34..a0683d58 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -73,9 +73,9 @@ def _get_ordered_formats(self): This only works when `self.filename` has a known extension. """ - from diffpy.structure.parsers import inputFormats + from diffpy.structure.parsers import input_formats - ofmts = [fmt for fmt in inputFormats() if fmt != "auto"] + ofmts = [fmt for fmt in input_formats() if fmt != "auto"] if not self.filename: return ofmts # filename is defined here @@ -252,17 +252,10 @@ def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> @deprecated(getParser_deprecation_msg) def getParser(**kw): - """Return a new instance of the automatic parser. - - Parameters - ---------- - **kw : dict - Keyword arguments for the structure parser + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_auto - Instance of `P_auto`. + Please use diffpy.structure.P_auto.get_parser instead. """ return get_parser(**kw) diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 2f58bd58..679c4ccf 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -910,18 +910,10 @@ def getSymOp(s): @deprecated(getParser_deprecation_msg) def getParser(eps=None): - """Return new `parser` object for CIF format. + """This function has been deprecated and will be removed in version + 4.0.0. - Parameters - ---------- - eps : float, Optional - fractional coordinates cutoff for duplicate positions. - When ``None`` use the default for `ExpandAsymmetricUnit`: ``1.0e-5``. - - Returns - ------- - P_cif - Instance of `P_cif`. + Please use diffpy.structure.P_cif.get_parser instead. """ return get_parser(eps) diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 0fc7122f..3e77b55f 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -424,12 +424,10 @@ def _parse_not_implemented(self, words): @deprecated(getParser_deprecation_msg) def getParser(): - """Return new `parser` object for DISCUS format. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_discus - Instance of `P_discus`. + Please use diffpy.structure.P_discus.get_parser instead. """ return get_parser() diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 7e3bbefb..98bc4b74 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -45,6 +45,24 @@ "to_lines", removal_version, ) +titleLines_deprecation_msg = build_deprecation_message( + base, + "titleLines", + "title_lines", + removal_version, +) +cryst1Lines_deprecation_msg = build_deprecation_message( + base, + "cryst1Lines", + "cryst1_lines", + removal_version, +) +atomLines_deprecation_msg = build_deprecation_message( + base, + "atomLines", + "atom_lines", + removal_version, +) class P_pdb(StructureParser): @@ -269,7 +287,12 @@ def parse_lines(self, lines): raise e.with_traceback(exc_traceback) return stru + @deprecated(titleLines_deprecation_msg) def titleLines(self, stru): + """Build lines corresponding to `TITLE` record.""" + return self.title_lines(stru) + + def title_lines(self, stru): """Build lines corresponding to `TITLE` record.""" lines = [] title = stru.title @@ -288,7 +311,12 @@ def titleLines(self, stru): title = title[stop:] return lines + @deprecated(cryst1Lines_deprecation_msg) def cryst1Lines(self, stru): + """Build lines corresponding to `CRYST1` record.""" + return self.cryst1_lines(stru) + + def cryst1_lines(self, stru): """Build lines corresponding to `CRYST1` record.""" lines = [] latpar = ( @@ -304,7 +332,13 @@ def cryst1Lines(self, stru): lines.append("%-80s" % line) return lines + @deprecated(atomLines_deprecation_msg) def atomLines(self, stru, idx): + """Build `ATOM` records and possibly `SIGATM`, `ANISOU` or + `SIGUIJ` records for `structure` stru `atom` number aidx.""" + return self.atom_lines(stru, idx) + + def atom_lines(self, stru, idx): """Build `ATOM` records and possibly `SIGATM`, `ANISOU` or `SIGUIJ` records for `structure` stru `atom` number aidx.""" lines = [] @@ -425,10 +459,10 @@ def to_lines(self, stru): List of lines in PDB format. """ lines = [] - lines.extend(self.titleLines(stru)) - lines.extend(self.cryst1Lines(stru)) + lines.extend(self.title_lines(stru)) + lines.extend(self.cryst1_lines(stru)) for idx in range(len(stru)): - lines.extend(self.atomLines(stru, idx)) + lines.extend(self.atom_lines(stru, idx)) line = ( "TER " # 1-6 + "%(serial)5i " # 7-11, 12-17 diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index bc3f1876..2347f3ff 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -198,81 +198,12 @@ def parse_lines(self, lines): return stru def toLines(self, stru): - """Convert `Structure` stru to a list of lines in PDFfit format. - - Parameters - ---------- - stru : Structure - Structure to be converted. + """This function has been deprecated and will be removed in + version 4.0.0. - Returns - ------- - list of str - List of lines in PDFfit format. + Please use diffpy.structure.P_pdffit.toLines instead. """ - # build the stru_pdffit dictionary initialized from the defaults - # in PDFFitStructure - stru_pdffit = PDFFitStructure().pdffit - if stru.pdffit: - stru_pdffit.update(stru.pdffit) - lines = [] - # default values of standard deviations - d_sigxyz = numpy.zeros(3, dtype=float) - d_sigo = 0.0 - d_sigU = numpy.zeros((3, 3), dtype=float) - # here we can start - line = "title " + stru.title - lines.append(line.strip()) - lines.append("format pdffit") - lines.append("scale %9.6f" % stru_pdffit["scale"]) - lines.append( - "sharp %9.6f, %9.6f, %9.6f, %9.6f" - % ( - stru_pdffit["delta2"], - stru_pdffit["delta1"], - stru_pdffit["sratio"], - stru_pdffit["rcut"], - ) - ) - lines.append("spcgr " + stru_pdffit["spcgr"]) - if stru_pdffit.get("spdiameter", 0.0) > 0.0: - line = "shape sphere, %g" % stru_pdffit["spdiameter"] - lines.append(line) - if stru_pdffit.get("stepcut", 0.0) > 0.0: - line = "shape stepcut, %g" % stru_pdffit["stepcut"] - lines.append(line) - lat = stru.lattice - lines.append( - "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" - % (lat.a, lat.b, lat.c, lat.alpha, lat.beta, lat.gamma) - ) - lines.append("dcell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % tuple(stru_pdffit["dcell"])) - lines.append("ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(stru))) - lines.append("atoms") - for a in stru: - ad = a.__dict__ - lines.append( - "%-4s %17.8f %17.8f %17.8f %12.4f" - % ( - a.element.upper(), - a.xyz[0], - a.xyz[1], - a.xyz[2], - a.occupancy, - ) - ) - sigmas = numpy.concatenate((ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)])) - lines.append(" %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas)) - sigU = ad.get("sigU", d_sigU) - Uii = (a.U[0][0], a.U[1][1], a.U[2][2]) - Uij = (a.U[0][1], a.U[0][2], a.U[1][2]) - sigUii = (sigU[0][0], sigU[1][1], sigU[2][2]) - sigUij = (sigU[0][1], sigU[0][2], sigU[1][2]) - lines.append(" %18.8f %17.8f %17.8f" % Uii) - lines.append(" %18.8f %17.8f %17.8f" % sigUii) - lines.append(" %18.8f %17.8f %17.8f" % Uij) - lines.append(" %18.8f %17.8f %17.8f" % sigUij) - return lines + return self.to_lines(stru) def to_lines(self, stru): """Convert `Structure` stru to a list of lines in PDFfit format. @@ -386,12 +317,10 @@ def _parse_shape(self, line): def getParser(): - """Return new `parser` object for PDFfit format. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_pdffit - Instance of `P_pdffit`. + Please use diffpy.structure.P_pdffit.get_parser instead. """ return get_parser() diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index fc115fa9..2a8332b8 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -181,12 +181,10 @@ def to_lines(self, stru): @deprecated(getParser_deprecation_msg) def getParser(): - """Return new `parser` object for RAWXYZ format. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_rawxyz - Instance of `P_rawxyz`. + Please use diffpy.structure.P_rawxyz.get_parser instead. """ return get_parser() diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index c5709a83..7965767a 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -458,12 +458,10 @@ def to_lines(self, stru): @deprecated(getParser_deprecation_msg) def getParser(): - """Return new `parser` object for XCFG format. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_xcfg - Instance of `P_xcfg`. + Please use diffpy.structure.P_xcfg.get_parser instead. """ return get_parser() diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index 0238ecc9..60c8dd8a 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -193,12 +193,10 @@ def to_lines(self, stru): @deprecated(getParser_deprecation_msg) def getParser(): - """Return new `parser` object for XYZ format. + """This function has been deprecated and will be removed in version + 4.0.0. - Returns - ------- - P_xcfg - Instance of `P_xyz`. + Please use diffpy.structure.P_xyz.get_parser instead. """ return get_parser() From 5f64982363999d96543df9934fc6e13250454032 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 6 Mar 2026 16:17:28 -0500 Subject: [PATCH 185/226] chore: deprecate expansion functional utilities method. --- news/deprecate-expansion-utilities-1.rst | 27 ++++ .../structure/expansion/makeellipsoid.py | 56 ++++++-- src/diffpy/structure/expansion/shapeutils.py | 20 +++ tests/test_expansion.py | 122 ++++++++++++++++++ 4 files changed, 215 insertions(+), 10 deletions(-) create mode 100644 news/deprecate-expansion-utilities-1.rst create mode 100644 tests/test_expansion.py diff --git a/news/deprecate-expansion-utilities-1.rst b/news/deprecate-expansion-utilities-1.rst new file mode 100644 index 00000000..ba3c4b6a --- /dev/null +++ b/news/deprecate-expansion-utilities-1.rst @@ -0,0 +1,27 @@ +**Added:** + +* Added ``find_center`` method in ``expansion/shapeutils.py`` +* Added ``make_sphere`` method in ``expansion/makeellipsoid.py`` +* Added ``make_ellipsoid`` method in ``expansion/makeellipsoid.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``findCenter`` method in ``expansion/shapeutils.py`` for removal in version 4.0.0 +* Deprecated ``makeSphere`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 +* Deprecated ``makeEllipsoid`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/expansion/makeellipsoid.py b/src/diffpy/structure/expansion/makeellipsoid.py index 547096c2..217b1dd3 100644 --- a/src/diffpy/structure/expansion/makeellipsoid.py +++ b/src/diffpy/structure/expansion/makeellipsoid.py @@ -19,10 +19,36 @@ from numpy import array from diffpy.structure import Structure -from diffpy.structure.expansion.shapeutils import findCenter +from diffpy.structure.expansion.shapeutils import find_center +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure" +removal_version = "4.0.0" +makeSphere_deprecation_msg = build_deprecation_message( + base, + "makeSphere", + "make_sphere", + removal_version, +) +makeEllipsoid_deprecation_msg = build_deprecation_message( + base, + "makeEllipsoid", + "make_ellipsoid", + removal_version, +) + + +@deprecated(makeSphere_deprecation_msg) +def makeSphere(S, radius): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.make_sphere instead. + """ + return make_sphere(S, radius) -def makeSphere(S, radius): +def make_sphere(S, radius): """Create a spherical nanoparticle. Parameters @@ -37,10 +63,20 @@ def makeSphere(S, radius): Structure A new `Structure` instance. """ - return makeEllipsoid(S, radius) + return make_ellipsoid(S, radius) +@deprecated(makeEllipsoid_deprecation_msg) def makeEllipsoid(S, a, b=None, c=None): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.make_ellipsoid instead. + """ + return make_ellipsoid(S, a, b, c) + + +def make_ellipsoid(S, a, b=None, c=None): """Cut a `Structure` out of another one. Parameters @@ -78,7 +114,7 @@ def makeEllipsoid(S, a, b=None, c=None): lat = newS.lattice # Find the central atom - ncenter = findCenter(newS) + ncenter = find_center(newS) cxyz = lat.cartesian(newS[ncenter].xyz) @@ -111,17 +147,17 @@ def makeEllipsoid(S, a, b=None, c=None): datadir = "../../tests/testdata" S = Structure() S.read(os.path.join(datadir, "CdSe_bulk.stru"), "pdffit") - newS = makeEllipsoid(S, 12) + newS = make_ellipsoid(S, 12) newS.write("CdSe_d24.stru", "pdffit") - newS = makeEllipsoid(S, 20, 10, 10) + newS = make_ellipsoid(S, 20, 10, 10) newS.write("CdSe_a20_b10_c10.stru", "pdffit") - newS = makeEllipsoid(S, 20, 15, 10) + newS = make_ellipsoid(S, 20, 15, 10) newS.write("CdSe_a20_b15_c10.stru", "pdffit") S = Structure() S.read(os.path.join(datadir, "Ni.stru"), "pdffit") - newS = makeEllipsoid(S, 10) + newS = make_ellipsoid(S, 10) newS.write("Ni_d20.stru", "pdffit") - newS = makeEllipsoid(S, 20, 4) + newS = make_ellipsoid(S, 20, 4) newS.write("Ni_a20_b4_c20.stru", "pdffit") - newS = makeEllipsoid(S, 20, 15, 10) + newS = make_ellipsoid(S, 20, 15, 10) newS.write("Ni_a20_b15_c10.stru", "pdffit") diff --git a/src/diffpy/structure/expansion/shapeutils.py b/src/diffpy/structure/expansion/shapeutils.py index 16f6c4c3..0b1de0c0 100644 --- a/src/diffpy/structure/expansion/shapeutils.py +++ b/src/diffpy/structure/expansion/shapeutils.py @@ -12,10 +12,30 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure" +removal_version = "4.0.0" +findCenter_deprecation_msg = build_deprecation_message( + base, + "findCenter", + "find_center", + removal_version, +) """Utilities for making shapes.""" +@deprecated(findCenter_deprecation_msg) def findCenter(S): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.find_center instead. + """ + return find_center(S) + + +def find_center(S): """Find the approximate center `Atom` of a `Structure`. The center of the `Structure` is the `Atom` closest to ``(0.5, 0.5, 0.5)``. diff --git a/tests/test_expansion.py b/tests/test_expansion.py new file mode 100644 index 00000000..481f7670 --- /dev/null +++ b/tests/test_expansion.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +############################################################################## +# +# diffpy.structure Complex Modeling Initiative +# (c) 2016 Brookhaven Science Associates, +# Brookhaven National Laboratory. +# All rights reserved. +# +# File coded by: Pavol Juhas +# +# See AUTHORS.rst for a list of people who contributed. +# See LICENSE.rst for license information. +# +############################################################################## +"""Tests for the expansion module utilities.""" +import pytest + +from diffpy.structure.atom import Atom +from diffpy.structure.expansion.makeellipsoid import make_ellipsoid, make_sphere, makeEllipsoid, makeSphere +from diffpy.structure.expansion.shapeutils import find_center, findCenter +from diffpy.structure.lattice import Lattice +from diffpy.structure.structure import Structure + + +def test_findCenter(): + # C1: We have single atom, expect to return the index of the single atom. + structure_1 = Structure([Atom("Ni", [0.8, 1.2, 0.9])], lattice=Lattice()) + expected = 0 + actual = findCenter(structure_1) + assert actual == expected + + # C2: We have multiple atoms. + # Expect to find the index of the atom which has the closest distance to [0.5, 0.5, 0.5]. + # In this case it corresponds to atom "C". + structure_2 = Structure( + [Atom("Ni", [0.8, 1.2, 0.9]), Atom("C", [0.1, 0.2, 0.3])], + lattice=Lattice(), + ) + actual = findCenter(structure_2) + expected = 1 + assert actual == expected + + +def test_makeEllipsoid_and_makeSphere(): + structure = Structure( + [ + Atom("Ni", [0.0, 0.0, 0.0]), + Atom("C", [0.5, 0.5, 0.5]), + Atom("O", [1.0, 0.0, 0.0]), + Atom("H", [1.1, 0.0, 0.0]), + ], + lattice=Lattice(1, 1, 1, 90, 90, 90), + ) + # C1: set primary, secondary, and polar radius the same in makeEllipsoid, expect to be the same as makeSphere + ellipsoid_1 = makeEllipsoid(structure, 1, 1, 1) + sphere = makeSphere(structure, 1) + assert [atom.element for atom in ellipsoid_1] == [atom.element for atom in sphere] + assert [tuple(atom.xyz) for atom in ellipsoid_1] == [tuple(atom.xyz) for atom in sphere] + # C2: set the radius to be 0.5, expect to exclude the atom that is too far from the center of ellipsoid. + ellipsoid_2 = makeEllipsoid(structure, 0.5) + actual = [(atom.element, tuple(atom.xyz)) for atom in ellipsoid_2] + expected = [("C", (0.5, 0.5, 0.5))] + assert actual == expected + + +@pytest.mark.parametrize( + "atom_params, expected", + [ + pytest.param([Atom("Ni", [0.8, 1.2, 0.9])], 0), + pytest.param([Atom("Ni", [0.8, 1.2, 0.9]), Atom("C", [0.1, 0.2, 0.3])], 1), + ], +) +def test_find_center(atom_params, expected): + structure = Structure(atom_params, lattice=Lattice()) + actual = find_center(structure) + assert actual == expected + + +@pytest.mark.parametrize( + ("ellipsoid_args", "sphere_radius"), + [ + ((1, 1, 1), 1), + ((0.8, 0.8, 0.8), 0.8), + ((0.5, 0.5, 0.5), 0.5), + ], +) +def test_make_ellipsoid_equiv_to_make_sphere(ellipsoid_args, sphere_radius): + structure = Structure( + [ + Atom("Ni", [0.0, 0.0, 0.0]), + Atom("C", [0.5, 0.5, 0.5]), + Atom("O", [1.0, 0.0, 0.0]), + Atom("H", [1.1, 0.0, 0.0]), + ], + lattice=Lattice(1, 1, 1, 90, 90, 90), + ) + + actual = [(atom.element, tuple(atom.xyz)) for atom in make_ellipsoid(structure, *ellipsoid_args)] + expected = [(atom.element, tuple(atom.xyz)) for atom in make_sphere(structure, sphere_radius)] + + assert actual == expected + + +@pytest.mark.parametrize( + ("ellipsoid_args", "expected"), + [ + ((0.5,), [("C", (0.5, 0.5, 0.5))]), + ((0.4,), [("C", (0.5, 0.5, 0.5))]), + ], +) +def test_make_ellipsoid(ellipsoid_args, expected): + structure = Structure( + [ + Atom("Ni", [0.0, 0.0, 0.0]), + Atom("C", [0.5, 0.5, 0.5]), + Atom("O", [1.0, 0.0, 0.0]), + Atom("H", [1.1, 0.0, 0.0]), + ], + lattice=Lattice(1, 1, 1, 90, 90, 90), + ) + actual = [(atom.element, tuple(atom.xyz)) for atom in make_ellipsoid(structure, *ellipsoid_args)] + assert actual == expected From 279d29dc1a8408707f1e9d41db19b440564f46c3 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 6 Mar 2026 18:29:15 -0500 Subject: [PATCH 186/226] chore: deprecate apps method --- news/deprecate-apps.rst | 33 +++++++++ src/diffpy/structure/apps/anyeye.py | 111 +++++++++++++++++++++++++--- 2 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 news/deprecate-apps.rst diff --git a/news/deprecate-apps.rst b/news/deprecate-apps.rst new file mode 100644 index 00000000..f9ebb7af --- /dev/null +++ b/news/deprecate-apps.rst @@ -0,0 +1,33 @@ +**Added:** + +* Added ``load_structure_file`` method in ``apps/anyeye.py`` +* Added ``convert_structure_file`` method in ``apps/anyeye.py`` +* Added ``watch_structure_file`` method in ``apps/anyeye.py`` +* Added ``clean_up`` method in ``apps/anyeye.py`` +* Added ``parse_formula`` method in ``apps/anyeye.py`` +* Added ``signal_handler`` method in ``apps/anyeye.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``loadStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``convertStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``watchStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``cleanUp`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``parseFormula`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``signalHandler`` method in ``apps/anyeye.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/apps/anyeye.py b/src/diffpy/structure/apps/anyeye.py index 56e16f45..c00756c6 100755 --- a/src/diffpy/structure/apps/anyeye.py +++ b/src/diffpy/structure/apps/anyeye.py @@ -52,6 +52,46 @@ import sys from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure" +removal_version = "4.0.0" +loadStructureFile_deprecation_msg = build_deprecation_message( + base, + "loadStructureFile", + "load_structure_file", + removal_version, +) +convertStructureFile_deprecation_msg = build_deprecation_message( + base, + "loadStructureFile", + "load_structure_file", + removal_version, +) +watchStructureFile_deprecation_msg = build_deprecation_message( + base, + "watchStructureFile", + "watch_structure_file", + removal_version, +) +cleanUp_deprecation_msg = build_deprecation_message( + base, + "cleanUp", + "clean_up", + removal_version, +) +parseFormula_deprecation_msg = build_deprecation_message( + base, + "parseFormula", + "parse_formula", + removal_version, +) +signalHandler_deprecation_msg = build_deprecation_message( + base, + "signalHandler", + "signal_handler", + removal_version, +) # parameter dictionary pd = { @@ -87,9 +127,28 @@ def version(): return +@deprecated(loadStructureFile_deprecation_msg) def loadStructureFile(filename, format="auto"): """Load structure from specified file. + Parameters + ---------- + filename : str + Path to the structure file. + format : str, Optional + File format, by default "auto". + + Returns + ------- + tuple + A tuple of (Structure, fileformat). + """ + return load_structure_file(filename, format) + + +def load_structure_file(filename, format="auto"): + """Load structure from specified file. + Parameters ---------- filename : str @@ -110,7 +169,12 @@ def loadStructureFile(filename, format="auto"): return (stru, fileformat) +@deprecated(convertStructureFile_deprecation_msg) def convertStructureFile(pd): + return convert_structure_file(pd) + + +def convert_structure_file(pd): # make temporary directory on the first pass if "tmpdir" not in pd: from tempfile import mkdtemp @@ -134,7 +198,7 @@ def convertStructureFile(pd): return # otherwise convert to the first recognized viewer format if stru is None: - stru = loadStructureFile(strufile, fmt)[0] + stru = load_structure_file(strufile, fmt)[0] if pd["formula"]: formula = pd["formula"] if len(formula) != len(stru): @@ -154,19 +218,29 @@ def convertStructureFile(pd): return +@deprecated(watchStructureFile_deprecation_msg) def watchStructureFile(pd): + return watch_structure_file(pd) + + +def watch_structure_file(pd): from time import sleep strufile = pd["strufile"] tmpfile = pd["tmpfile"] while pd["watch"]: if os.path.getmtime(tmpfile) < os.path.getmtime(strufile): - convertStructureFile(pd) + convert_structure_file(pd) sleep(1) return +@deprecated(cleanUp_deprecation_msg) def cleanUp(pd): + return clean_up(pd) + + +def clean_up(pd): if "tmpfile" in pd: os.remove(pd["tmpfile"]) del pd["tmpfile"] @@ -176,7 +250,14 @@ def cleanUp(pd): return +@deprecated(parseFormula_deprecation_msg) def parseFormula(formula): + """Parse chemical formula and return a list of elements.""" + # remove all blanks + return parse_formula(formula) + + +def parse_formula(formula): """Parse chemical formula and return a list of elements.""" # remove all blanks formula = re.sub(r"\s", "", formula) @@ -197,11 +278,17 @@ def parseFormula(formula): def die(exit_status=0, pd={}): - cleanUp(pd) + clean_up(pd) sys.exit(exit_status) +@deprecated(signalHandler_deprecation_msg) def signalHandler(signum, stackframe): + # revert to default handler + return signal_handler(signum, stackframe) + + +def signal_handler(signum, stackframe): # revert to default handler signal.signal(signum, signal.SIG_DFL) if signum == signal.SIGCHLD: @@ -231,7 +318,7 @@ def main(): for o, a in opts: if o in ("-f", "--formula"): try: - pd["formula"] = parseFormula(a) + pd["formula"] = parse_formula(a) except RuntimeError as msg: print(msg, file=sys.stderr) die(2) @@ -255,23 +342,23 @@ def main(): die(2) pd["strufile"] = args[0] # trap the following signals - signal.signal(signal.SIGHUP, signalHandler) - signal.signal(signal.SIGQUIT, signalHandler) - signal.signal(signal.SIGSEGV, signalHandler) - signal.signal(signal.SIGTERM, signalHandler) - signal.signal(signal.SIGINT, signalHandler) + signal.signal(signal.SIGHUP, signal_handler) + signal.signal(signal.SIGQUIT, signal_handler) + signal.signal(signal.SIGSEGV, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) env = os.environ.copy() if os.path.basename(pd["viewer"]).startswith("atomeye"): env["XLIB_SKIP_ARGB_VISUALS"] = "1" # try to run the thing: try: - convertStructureFile(pd) + convert_structure_file(pd) spawnargs = (pd["viewer"], pd["viewer"], pd["tmpfile"], env) # load strufile in atomeye if pd["watch"]: - signal.signal(signal.SIGCHLD, signalHandler) + signal.signal(signal.SIGCHLD, signal_handler) os.spawnlpe(os.P_NOWAIT, *spawnargs) - watchStructureFile(pd) + watch_structure_file(pd) else: status = os.spawnlpe(os.P_WAIT, *spawnargs) die(status, pd) From d2d6285c612f83e97602b16747b84b6c281dabfc Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 6 Mar 2026 23:34:50 -0500 Subject: [PATCH 187/226] chore: deprecate spacegroup method --- devutils/sgtbx_extra_groups.py | 4 +- news/deprecate-spacegroup.rst | 33 ++++++++ src/diffpy/structure/parsers/p_cif.py | 33 ++++++-- src/diffpy/structure/spacegroups.py | 84 +++++++++++++++++++-- tests/test_p_cif.py | 22 +++++- tests/test_spacegroups.py | 68 ++++++++++++++--- tests/test_symmetryutilities.py | 104 +++++++++++++------------- 7 files changed, 265 insertions(+), 83 deletions(-) create mode 100644 news/deprecate-spacegroup.rst diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py index 1c718fa8..e5a96189 100644 --- a/devutils/sgtbx_extra_groups.py +++ b/devutils/sgtbx_extra_groups.py @@ -17,7 +17,7 @@ import numpy from cctbx import sgtbx -from diffpy.structure.spacegroups import IsSpaceGroupIdentifier, SpaceGroup, SymOp, mmLibSpaceGroupList +from diffpy.structure.spacegroups import SpaceGroup, SymOp, is_space_group_identifier, mmLibSpaceGroupList def tupleToSGArray(tpl): @@ -196,7 +196,7 @@ def main(): if findEquivalentMMSpaceGroup(grp): continue shn = smbls.hermann_mauguin().replace(" ", "") - if IsSpaceGroupIdentifier(shn): + if is_space_group_identifier(shn): continue sg = mmSpaceGroupFromSymbol(uhm) hsg = hashMMSpaceGroup(sg) diff --git a/news/deprecate-spacegroup.rst b/news/deprecate-spacegroup.rst new file mode 100644 index 00000000..902e4fdb --- /dev/null +++ b/news/deprecate-spacegroup.rst @@ -0,0 +1,33 @@ +**Added:** + +* Added ``get_symop`` method in ``parsers/p_cif.py`` +* Added ``get_space_group`` method in ``spacegroups.py`` +* Added ``find_space_group`` method in ``spacegroups.py`` +* Added ``is_space_group_identifier`` method in ``spacegroups.py`` +* Added ``_hash_symop_list`` method in ``spacegroups.py`` +* Added ``_build_sg_lookup_table`` method in ``spacegroups.py`` +* Added ``_get_sg_hash_lookup_table`` method in ``spacegroups.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``getSymOp`` method in ``parsers/p_cif.py`` for removal in version 4.0.0 +* Deprecated ``GetSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``IsSpaceGroupIdentifier`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``FindSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``_hashSymOpList`` method in ``spacegroups.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 679c4ccf..1dc39d7c 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -593,7 +593,12 @@ def _parse_space_group_symop_operation_xyz(self, block): block : CifBlock Instance of `CifBlock`. """ - from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, IsSpaceGroupIdentifier, SpaceGroup + from diffpy.structure.spacegroups import ( + SpaceGroup, + find_space_group, + get_space_group, + is_space_group_identifier, + ) self.asymmetric_unit = list(self.stru) sym_synonyms = ( @@ -608,7 +613,7 @@ def _parse_space_group_symop_operation_xyz(self, block): sym_loop_name = sym_loop_name[0] sym_loop = block.GetLoop(sym_loop_name) for eqxyz in sym_loop[sym_loop_name]: - opcif = getSymOp(eqxyz) + opcif = get_symop(eqxyz) symop_list.append(opcif) # determine space group number sg_nameHall = block.get("_space_group_name_Hall", "") or block.get("_symmetry_space_group_name_Hall", "") @@ -623,12 +628,12 @@ def _parse_space_group_symop_operation_xyz(self, block): # try to reuse existing space group from symmetry operations if symop_list: try: - self.spacegroup = FindSpaceGroup(symop_list) + self.spacegroup = find_space_group(symop_list) except ValueError: pass # otherwise lookup the space group from its identifier - if self.spacegroup is None and sgid and IsSpaceGroupIdentifier(sgid): - self.spacegroup = GetSpaceGroup(sgid) + if self.spacegroup is None and sgid and is_space_group_identifier(sgid): + self.spacegroup = get_space_group(sgid) # define new spacegroup when symmetry operations were listed, but # there is no match to an existing definition if symop_list and self.spacegroup is None: @@ -824,6 +829,12 @@ def to_lines(self, stru): "get_parser", removal_version, ) +getSymOp_deprecation_msg = build_deprecation_message( + parsers_base, + "getSymOp", + "get_symop", + removal_version, +) # constant regular expression for leading_float() rx_float = re.compile(r"[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?") @@ -878,7 +889,17 @@ def leading_float(s, d=0.0): symvec["+z"] = symvec["z"] +@deprecated(getSymOp_deprecation_msg) def getSymOp(s): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.get_symop instead. + """ + return get_symop(s) + + +def get_symop(s): """Create `SpaceGroups.SymOp` instance from a string. Parameters @@ -913,7 +934,7 @@ def getParser(eps=None): """This function has been deprecated and will be removed in version 4.0.0. - Please use diffpy.structure.P_cif.get_parser instead. + Please use diffpy.structure.get_parser instead. """ return get_parser(eps) diff --git a/src/diffpy/structure/spacegroups.py b/src/diffpy/structure/spacegroups.py index a5d33372..8b6fb8c5 100644 --- a/src/diffpy/structure/spacegroups.py +++ b/src/diffpy/structure/spacegroups.py @@ -643,14 +643,50 @@ Tr_34_34_14, Tr_34_34_34, ) +from diffpy.utils._deprecator import build_deprecation_message, deprecated # Import SpaceGroup objects -------------------------------------------------- - +base = "diffpy.structure" +removal_version = "4.0.0" +GetSpaceGroup_deprecation_msg = build_deprecation_message( + base, + "GetSpaceGroup", + "get_space_group", + removal_version, +) +FindSpaceGroup_deprecation_msg = build_deprecation_message( + base, + "FindSpaceGroup", + "find_space_group", + removal_version, +) +IsSpaceGroupIdentifier_deprecation_msg = build_deprecation_message( + base, + "IsSpaceGroupIdentifier", + "is_space_group_identifier", + removal_version, +) +_hashSymOpList_deprecation_msg = build_deprecation_message( + base, + "_hashSymOpList", + "_hash_symop_list", + removal_version, +) SpaceGroupList = mmLibSpaceGroupList + sgtbxSpaceGroupList +@deprecated(GetSpaceGroup_deprecation_msg) def GetSpaceGroup(sgid): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.get_space_group instead. + """ + return get_space_group(sgid) + + +def get_space_group(sgid): """Returns the SpaceGroup instance for the given identifier. Parameters @@ -670,7 +706,7 @@ def GetSpaceGroup(sgid): When the identifier is not found. """ if not _sg_lookup_table: - _buildSGLookupTable() + _build_sg_lookup_table() if sgid in _sg_lookup_table: return _sg_lookup_table[sgid] # Try different versions of sgid, first make sure it is a string @@ -691,10 +727,22 @@ def GetSpaceGroup(sgid): raise ValueError(emsg) +@deprecated(IsSpaceGroupIdentifier_deprecation_msg) def IsSpaceGroupIdentifier(sgid): """Check if identifier can be used as an argument to `GetSpaceGroup`. + Returns + ------- + bool + """ + return is_space_group_identifier(sgid) + + +def is_space_group_identifier(sgid): + """Check if identifier can be used as an argument to + `GetSpaceGroup`. + Returns ------- bool @@ -707,7 +755,17 @@ def IsSpaceGroupIdentifier(sgid): return rv +@deprecated(FindSpaceGroup_deprecation_msg) def FindSpaceGroup(symops, shuffle=False): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.find_space_group instead. + """ + return find_space_group(symops, shuffle=shuffle) + + +def find_space_group(symops, shuffle=False): """Lookup SpaceGroup from a given list of symmetry operations. Parameters @@ -732,8 +790,8 @@ def FindSpaceGroup(symops, shuffle=False): When `symops` do not match any known SpaceGroup. """ - tb = _getSGHashLookupTable() - hh = _hashSymOpList(symops) + tb = _get_sg_hash_lookup_table() + hh = _hash_symop_list(symops) if hh not in tb: raise ValueError("Cannot find SpaceGroup for the specified symops.") rv = tb[hh] @@ -746,7 +804,17 @@ def FindSpaceGroup(symops, shuffle=False): return rv +@deprecated(_hashSymOpList_deprecation_msg) def _hashSymOpList(symops): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure._hash_symop_list instead. + """ + return _hash_symop_list(symops) + + +def _hash_symop_list(symops): """Return hash value for a sequence of `SymOp` objects. The symops are sorted so the results is independent of symops order. @@ -766,7 +834,7 @@ def _hashSymOpList(symops): return rv -def _buildSGLookupTable(): +def _build_sg_lookup_table(): """Rebuild space group lookup table from the `SpaceGroupList` data. This routine updates the global `_sg_lookup_table` dictionary. @@ -809,16 +877,16 @@ def _buildSGLookupTable(): _sg_lookup_table = {} -def _getSGHashLookupTable(): +def _get_sg_hash_lookup_table(): """Return lookup table of symop hashes to standard `SpaceGroup` objects.""" if _sg_hash_lookup_table: return _sg_hash_lookup_table for sg in SpaceGroupList: - h = _hashSymOpList(sg.symop_list) + h = _hash_symop_list(sg.symop_list) _sg_hash_lookup_table[h] = sg assert len(_sg_hash_lookup_table) == len(SpaceGroupList) - return _getSGHashLookupTable() + return _get_sg_hash_lookup_table() _sg_hash_lookup_table = {} diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index fd63f03b..5784ecfd 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -21,7 +21,7 @@ from diffpy.structure import Structure from diffpy.structure.parsers import get_parser, getParser -from diffpy.structure.parsers.p_cif import P_cif, getSymOp, leading_float +from diffpy.structure.parsers.p_cif import P_cif, get_symop, getSymOp, leading_float from diffpy.structure.structureerrors import StructureFormatError # ---------------------------------------------------------------------------- @@ -56,6 +56,20 @@ def test_getSymOp(self): self.assertEqual(str(op1_std), str(op1)) return + def test_get_symop(self): + """Check get_symop()""" + from diffpy.structure.spacegroups import Rot_X_mY_Z, SymOp, Tr_0_12_12 + + op = get_symop("x,1/2-y,1/2+z") + op_std = SymOp(Rot_X_mY_Z, Tr_0_12_12) + self.assertEqual(str(op_std), str(op)) + from diffpy.structure.spacegroups import Rot_mX_mXY_Z, Tr_0_0_12 + + op1 = get_symop("-x,-x+y,1/2+z") + op1_std = SymOp(Rot_mX_mXY_Z, Tr_0_0_12) + self.assertEqual(str(op1_std), str(op1)) + return + # End of class TestRoutines @@ -332,7 +346,7 @@ def test_unknown_occupancy(self): def test_unknown_spacegroup_number(self): "test CIF file with unknown space group symbol" - from diffpy.structure.spacegroups import GetSpaceGroup, _hashSymOpList + from diffpy.structure.spacegroups import _hash_symop_list, get_space_group with open(self.pbteciffile) as fp: lines = fp.readlines() @@ -346,9 +360,9 @@ def test_unknown_spacegroup_number(self): ciftxt = "".join(lines) stru = self.ptest.parse(ciftxt) self.assertEqual(8, len(stru)) - h225 = _hashSymOpList(GetSpaceGroup(225).iter_symops()) + h225 = _hash_symop_list(get_space_group(225).iter_symops()) sgcif = self.ptest.spacegroup - self.assertEqual(h225, _hashSymOpList(sgcif.iter_symops())) + self.assertEqual(h225, _hash_symop_list(sgcif.iter_symops())) return def test_nosites_cif(self): diff --git a/tests/test_spacegroups.py b/tests/test_spacegroups.py index 7eb3f97d..de5fd69d 100644 --- a/tests/test_spacegroups.py +++ b/tests/test_spacegroups.py @@ -17,7 +17,15 @@ import unittest -from diffpy.structure.spacegroups import FindSpaceGroup, GetSpaceGroup, SpaceGroupList, _hashSymOpList +from diffpy.structure.spacegroups import ( + FindSpaceGroup, + GetSpaceGroup, + SpaceGroupList, + _hash_symop_list, + _hashSymOpList, + find_space_group, + get_space_group, +) # ---------------------------------------------------------------------------- @@ -50,7 +58,7 @@ def test_old_alt_name(self): ("I A 3 D", 230), ) for name, sgno in altnames_sgnos: - self.assertIs(GetSpaceGroup(sgno), GetSpaceGroup(name)) + self.assertIs(get_space_group(sgno), get_space_group(name)) return def test_GetSpaceGroup(self): @@ -70,9 +78,26 @@ def test_GetSpaceGroup(self): self.assertIs(sg125, GetSpaceGroup("P 4/N 2/B 2/M")) return + def test_get_space_group(self): + "check get_space_group function" + from diffpy.structure.spacegroups import sg125 + + self.assertRaises(ValueError, get_space_group, 0) + self.assertRaises(ValueError, get_space_group, 300) + self.assertRaises(ValueError, get_space_group, "300") + self.assertIs(sg125, get_space_group(125)) + self.assertIs(sg125, get_space_group("125")) + self.assertIs(sg125, get_space_group("P4/nbm")) + self.assertIs(sg125, get_space_group("P 4/n 2/b 2/m")) + # old alt_name + self.assertIs(sg125, get_space_group("P 4/N B M")) + # upper case pdb_name + self.assertIs(sg125, get_space_group("P 4/N 2/B 2/M")) + return + def test_FindSpaceGroup(self): "check FindSpaceGroup function" - sg123 = GetSpaceGroup(123) + sg123 = get_space_group(123) ops123 = list(sg123.iter_symops()) self.assertRaises(ValueError, FindSpaceGroup, []) self.assertRaises(ValueError, FindSpaceGroup, 2 * ops123) @@ -81,44 +106,65 @@ def test_FindSpaceGroup(self): self.assertIsNot(sg123, sg123r) self.assertIsNot(sg123.symop_list, sg123r.symop_list) self.assertEqual(ops123[::-1], sg123r.symop_list) - self.assertEqual(_hashSymOpList(sg123.symop_list), _hashSymOpList(sg123r.symop_list)) + self.assertEqual(_hash_symop_list(sg123.symop_list), _hash_symop_list(sg123r.symop_list)) self.assertIs(sg123, FindSpaceGroup(ops123[::-1], shuffle=True)) return + def test_find_space_group(self): + "check find_space_group function" + sg123 = get_space_group(123) + ops123 = list(sg123.iter_symops()) + self.assertRaises(ValueError, find_space_group, []) + self.assertRaises(ValueError, find_space_group, 2 * ops123) + self.assertIs(sg123, find_space_group(ops123)) + sg123r = find_space_group(ops123[::-1]) + self.assertIsNot(sg123, sg123r) + self.assertIsNot(sg123.symop_list, sg123r.symop_list) + self.assertEqual(ops123[::-1], sg123r.symop_list) + self.assertEqual(_hash_symop_list(sg123.symop_list), _hash_symop_list(sg123r.symop_list)) + self.assertIs(sg123, find_space_group(ops123[::-1], shuffle=True)) + return + def test__hashSymOpList(self): "verify _hashSymOpList is unique for each spacegroup" hset = set(_hashSymOpList(sg.symop_list) for sg in SpaceGroupList) self.assertEqual(len(SpaceGroupList), len(hset)) return + def test__hash_symop_list(self): + "verify _hash_symop_list is unique for each spacegroup" + hset = set(_hash_symop_list(sg.symop_list) for sg in SpaceGroupList) + self.assertEqual(len(SpaceGroupList), len(hset)) + return + def test_spacegroup_representation(self): """Verify SpaceGroup.__repr__().""" self.assertEqual( - repr(GetSpaceGroup(1)), + repr(get_space_group(1)), "SpaceGroup #1 (P1, Triclinic). Symmetry matrices: 1, point sym. matr.: 1", ) self.assertEqual( - repr(GetSpaceGroup(3)), + repr(get_space_group(3)), "SpaceGroup #3 (P2, Monoclinic). Symmetry matrices: 2, point sym. matr.: 2", ) self.assertEqual( - repr(GetSpaceGroup(16)), + repr(get_space_group(16)), ("SpaceGroup #16 (P222, Orthorhombic). Symmetry matrices: 4, point sym. " "matr.: 4"), ) self.assertEqual( - repr(GetSpaceGroup(75)), + repr(get_space_group(75)), "SpaceGroup #75 (P4, Tetragonal). Symmetry matrices: 4, point sym. matr.: 4", ) self.assertEqual( - repr(GetSpaceGroup(143)), + repr(get_space_group(143)), "SpaceGroup #143 (P3, Trigonal). Symmetry matrices: 3, point sym. matr.: 3", ) self.assertEqual( - repr(GetSpaceGroup(168)), + repr(get_space_group(168)), "SpaceGroup #168 (P6, Hexagonal). Symmetry matrices: 6, point sym. matr.: 6", ) self.assertEqual( - repr(GetSpaceGroup(229)), + repr(get_space_group(229)), ("SpaceGroup #229 (Im-3m, Cubic). Symmetry matrices: 96, point sym. " "matr.: 48"), ) return diff --git a/tests/test_symmetryutilities.py b/tests/test_symmetryutilities.py index b767190f..c5b37fc8 100644 --- a/tests/test_symmetryutilities.py +++ b/tests/test_symmetryutilities.py @@ -21,7 +21,7 @@ import numpy import pytest -from diffpy.structure.spacegroups import GetSpaceGroup +from diffpy.structure.spacegroups import get_space_group from diffpy.structure.structureerrors import SymmetryError from diffpy.structure.symmetryutilities import ( ExpandAsymmetricUnit, @@ -59,13 +59,13 @@ def tearDown(self): def test_isSpaceGroupLatPar(self): """Check isSpaceGroupLatPar()""" - triclinic = GetSpaceGroup("P1") - monoclinic = GetSpaceGroup("P2") - orthorhombic = GetSpaceGroup("P222") - tetragonal = GetSpaceGroup("P4") - trigonal = GetSpaceGroup("P3") - hexagonal = GetSpaceGroup("P6") - cubic = GetSpaceGroup("P23") + triclinic = get_space_group("P1") + monoclinic = get_space_group("P2") + orthorhombic = get_space_group("P222") + tetragonal = get_space_group("P4") + trigonal = get_space_group("P3") + hexagonal = get_space_group("P6") + cubic = get_space_group("P23") self.assertTrue(isSpaceGroupLatPar(triclinic, 1, 2, 3, 40, 50, 60)) self.assertFalse(isSpaceGroupLatPar(monoclinic, 1, 2, 3, 40, 50, 60)) self.assertTrue(isSpaceGroupLatPar(monoclinic, 1, 2, 3, 90, 50, 90)) @@ -83,13 +83,13 @@ def test_isSpaceGroupLatPar(self): def test_is_space_group_lat_par(self): """Check isSpaceGroupLatPar()""" - triclinic = GetSpaceGroup("P1") - monoclinic = GetSpaceGroup("P2") - orthorhombic = GetSpaceGroup("P222") - tetragonal = GetSpaceGroup("P4") - trigonal = GetSpaceGroup("P3") - hexagonal = GetSpaceGroup("P6") - cubic = GetSpaceGroup("P23") + triclinic = get_space_group("P1") + monoclinic = get_space_group("P2") + orthorhombic = get_space_group("P222") + tetragonal = get_space_group("P4") + trigonal = get_space_group("P3") + hexagonal = get_space_group("P6") + cubic = get_space_group("P23") self.assertTrue(is_space_group_latt_parms(triclinic, 1, 2, 3, 40, 50, 60)) self.assertFalse(is_space_group_latt_parms(monoclinic, 1, 2, 3, 40, 50, 60)) self.assertTrue(is_space_group_latt_parms(monoclinic, 1, 2, 3, 90, 50, 90)) @@ -106,9 +106,9 @@ def test_is_space_group_lat_par(self): return def test_sgtbx_spacegroup_aliases(self): - """Check GetSpaceGroup for non-standard aliases from sgtbx.""" - self.assertIs(GetSpaceGroup("Fm3m"), GetSpaceGroup(225)) - self.assertIs(GetSpaceGroup("Ia3d"), GetSpaceGroup("I a -3 d")) + """Check get_space_group for non-standard aliases from sgtbx.""" + self.assertIs(get_space_group("Fm3m"), get_space_group(225)) + self.assertIs(get_space_group("Ia3d"), get_space_group("I a -3 d")) return def test_positionDifference(self): @@ -126,7 +126,7 @@ def test_nearestSiteIndex(self): def test_expandPosition(self): """Check expandPosition()""" # ok again Ni example - fcc = GetSpaceGroup(225) + fcc = get_space_group(225) pos, pops, pmult = expandPosition(fcc, [0, 0, 0]) self.assertTrue(numpy.all(pos[0] == 0.0)) self.assertEqual(4, len(pos)) @@ -137,7 +137,7 @@ def test_expandPosition(self): def test_expand_position(self): """Check expand_position()""" # ok again Ni example - fcc = GetSpaceGroup(225) + fcc = get_space_group(225) pos, pops, pmult = expand_position(fcc, [0, 0, 0]) self.assertTrue(numpy.all(pos[0] == 0.0)) self.assertEqual(4, len(pos)) @@ -234,13 +234,13 @@ def setUp(self): if TestGeneratorSite.generators: self.__dict__.update(TestGeneratorSite.generators) return - sg117 = GetSpaceGroup(117) - sg143 = GetSpaceGroup(143) - sg164 = GetSpaceGroup(164) - sg167h = GetSpaceGroup("H-3c") - sg167r = GetSpaceGroup("R-3c") - sg186 = GetSpaceGroup(186) - sg227 = GetSpaceGroup(227) + sg117 = get_space_group(117) + sg143 = get_space_group(143) + sg164 = get_space_group(164) + sg167h = get_space_group("H-3c") + sg167r = get_space_group("R-3c") + sg186 = get_space_group(186) + sg227 = get_space_group(227) g117c = GeneratorSite(sg117, [0, 0.5, 0]) g117h = GeneratorSite(sg117, [x, x + 0.5, 0.5]) g143a = GeneratorSite(sg143, [0, 0, z]) @@ -368,7 +368,7 @@ def test_position_formula(self): def test_positionFormula_sg209(self): "check positionFormula at [x, 1-x, -x] site of the F432 space group." - sg209 = GetSpaceGroup("F 4 3 2") + sg209 = get_space_group("F 4 3 2") xyz = [0.05198, 0.94802, -0.05198] g209e = GeneratorSite(sg209, xyz) pfm = g209e.positionFormula(xyz) @@ -379,7 +379,7 @@ def test_positionFormula_sg209(self): def test_position_formula_sg209(self): "check positionFormula at [x, 1-x, -x] site of the F432 space group." - sg209 = GetSpaceGroup("F 4 3 2") + sg209 = get_space_group("F 4 3 2") xyz = [0.05198, 0.94802, -0.05198] g209e = GeneratorSite(sg209, xyz) pfm = g209e.position_formula(xyz) @@ -603,7 +603,7 @@ def test_u_formula(self): def test_UFormula_g186c_eqxyz(self): """Check rotated U formulas at the symmetry positions of c-site in 186.""" - sg186 = GetSpaceGroup(186) + sg186 = get_space_group(186) crules = [ { "U11": "A", @@ -685,7 +685,7 @@ def test_UFormula_g186c_eqxyz(self): def test_u_formula_g186c_eqxyz(self): """Check rotated U formulas at the symmetry positions of c-site in 186.""" - sg186 = GetSpaceGroup(186) + sg186 = get_space_group(186) crules = [ { "U11": "A", @@ -786,7 +786,7 @@ def test__findUParameters(self): self.assertEqual(0.0, uval) # special test for g117h Uij = numpy.array([[1, 3, 4], [3, 1, -4], [4, -4, 2]]) - sg117 = GetSpaceGroup(117) + sg117 = get_space_group(117) g117h = GeneratorSite(sg117, self.g117h.xyz, Uij) upd = dict(g117h.Uparameters) self.assertEqual(1, upd["U11"]) @@ -821,7 +821,7 @@ def tearDown(self): def test___init__(self): """Check SymmetryConstraints.__init__()""" - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) # initialize from nested lists and arrays from ExpandAsymmetricUnit eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc0 = SymmetryConstraints(sg225, eau.expandedpos) @@ -845,7 +845,7 @@ def test___init__(self): def test_corepos(self): """test_corepos - find positions in the asymmetric unit.""" - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) corepos = [[0, 0, 0], [0.1, 0.13, 0.17]] eau = ExpandAsymmetricUnit(sg225, corepos) sc = SymmetryConstraints(sg225, eau.expandedpos) @@ -861,7 +861,7 @@ def test_corepos(self): def test_Uisotropy(self): """Check isotropy value for ADP-s at specified sites.""" - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) corepos = [[0, 0, 0], [0.1, 0.13, 0.17]] eau = ExpandAsymmetricUnit(sg225, corepos) self.assertEqual([True, False], eau.Uisotropy) @@ -896,8 +896,8 @@ def test_Uisotropy(self): # def test_UparSymbols(self): """Check SymmetryConstraints.UparSymbols()""" - sg1 = GetSpaceGroup(1) - sg225 = GetSpaceGroup(225) + sg1 = get_space_group(1) + sg225 = get_space_group(225) pos = [[0, 0, 0]] Uijs = numpy.zeros((1, 3, 3)) sc1 = SymmetryConstraints(sg1, pos, Uijs) @@ -908,8 +908,8 @@ def test_UparSymbols(self): def test_upar_symbols(self): """Check SymmetryConstraints.UparSymbols()""" - sg1 = GetSpaceGroup(1) - sg225 = GetSpaceGroup(225) + sg1 = get_space_group(1) + sg225 = get_space_group(225) pos = [[0, 0, 0]] Uijs = numpy.zeros((1, 3, 3)) sc1 = SymmetryConstraints(sg1, pos, Uijs) @@ -921,8 +921,8 @@ def test_upar_symbols(self): def test_UparValues(self): """Check SymmetryConstraints.UparValues()""" places = 12 - sg1 = GetSpaceGroup(1) - sg225 = GetSpaceGroup(225) + sg1 = get_space_group(1) + sg225 = get_space_group(225) pos = [[0, 0, 0]] Uijs = [[[0.1, 0.4, 0.5], [0.4, 0.2, 0.6], [0.5, 0.6, 0.3]]] sc1 = SymmetryConstraints(sg1, pos, Uijs) @@ -936,8 +936,8 @@ def test_UparValues(self): def test_upar_values(self): """Check SymmetryConstraints.UparValues()""" places = 12 - sg1 = GetSpaceGroup(1) - sg225 = GetSpaceGroup(225) + sg1 = get_space_group(1) + sg225 = get_space_group(225) pos = [[0, 0, 0]] Uijs = [[[0.1, 0.4, 0.5], [0.4, 0.2, 0.6], [0.5, 0.6, 0.3]]] sc1 = SymmetryConstraints(sg1, pos, Uijs) @@ -950,7 +950,7 @@ def test_upar_values(self): def test_posparSymbols_and_posparValues(self): """Check SymmetryConstraints.posparSymbols and_posparValues()""" - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.pospars = [("x", 0.12), ("y", 0.34), ("z", 0.56)] @@ -962,7 +962,7 @@ def test_posparSymbols_and_posparValues(self): assert expected_values == actual_values def test_positionFormulas(self): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) # C1: Simulate the "not enough symbols" branch @@ -983,7 +983,7 @@ def test_positionFormulas(self): assert actual == expected def test_positionFormulasPruned(self): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) # C1: Remove any key-value pairs with constant values @@ -1017,7 +1017,7 @@ def test_UFormulasPruned(self): "U12": "0.5*A", } ] - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.Ueqns = [u_formulas] @@ -1168,7 +1168,7 @@ def test_null_space(A, expected_dim): ) def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_values): """Check SymmetryConstraints.pospar_symbols and_pospar_values()""" - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.pospars = params @@ -1184,7 +1184,7 @@ def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_val ], ) def test_position_formulas_raises_SymmetryError(params): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] @@ -1211,7 +1211,7 @@ def test_position_formulas_raises_SymmetryError(params): ], ) def test_position_formulas(params, expected): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] @@ -1239,7 +1239,7 @@ def test_position_formulas(params, expected): ], ) def test_position_formulas_pruned(poseqns, expected): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) @@ -1276,7 +1276,7 @@ def test_position_formulas_pruned(poseqns, expected): ], ) def test_u_formula_pruned(u_formulas, expected): - sg225 = GetSpaceGroup(225) + sg225 = get_space_group(225) eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) sc = SymmetryConstraints(sg225, eau.expandedpos) sc.Ueqns = u_formulas From e19e6287e940f79ee7e4f54af708dd3038a15e22 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 7 Mar 2026 00:35:36 -0500 Subject: [PATCH 188/226] chore: deprecate Atom class method --- news/deprecate-atom.rst | 28 +++++++ src/diffpy/structure/atom.py | 85 +++++++++++++------ tests/test_atom.py | 155 +++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 26 deletions(-) create mode 100644 news/deprecate-atom.rst diff --git a/news/deprecate-atom.rst b/news/deprecate-atom.rst new file mode 100644 index 00000000..2ddd8b79 --- /dev/null +++ b/news/deprecate-atom.rst @@ -0,0 +1,28 @@ +**Added:** + +* Added ``msd_latt`` method in ``atom.py`` +* Added ``msd_cart`` method in ``atom.py`` +* Added ``_get_uij`` method in ``atom.py`` +* Added ``_set_uij`` method in ``atom.py`` + + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``msdLat`` method in ``atom.py`` for removal in version 4.0.0 +* Deprecated ``msdCart`` method in ``atom.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/atom.py b/src/diffpy/structure/atom.py index 6571a815..75581454 100644 --- a/src/diffpy/structure/atom.py +++ b/src/diffpy/structure/atom.py @@ -18,12 +18,27 @@ import numpy from diffpy.structure.lattice import cartesian as cartesian_lattice +from diffpy.utils._deprecator import build_deprecation_message, deprecated # conversion constants _BtoU = 1.0 / (8 * numpy.pi**2) _UtoB = 1.0 / _BtoU # ---------------------------------------------------------------------------- +base = "diffpy.structure.Atom" +removal_version = "4.0.0" +msdLat_deprecation_msg = build_deprecation_message( + base, + "msdLat", + "msd_latt", + removal_version, +) +msdCart_deprecation_msg = build_deprecation_message( + base, + "msdCart", + "msd_cart", + removal_version, +) class Atom(object): @@ -149,7 +164,16 @@ def __init__( self.anisotropy = bool(anisotropy) return + @deprecated(msdLat_deprecation_msg) def msdLat(self, vl): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Atom.msd_latt instead. + """ + return self.msd_latt(vl) + + def msd_latt(self, vl): """Calculate mean square displacement along the lattice vector. Parameters @@ -173,7 +197,16 @@ def msdLat(self, vl): msd = numpy.dot(rhs, numpy.dot(self.U, rhs)) return msd + @deprecated(msdLat_deprecation_msg) def msdCart(self, vc): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.Atom.msd_cart instead. + """ + return self.msd_cart(vc) + + def msd_cart(self, vc): """Calculate mean square displacement along the Cartesian vector. @@ -336,14 +369,14 @@ def U(self, value): # Uij elements - def _get_Uij(self, i, j): + def _get_uij(self, i, j): """The getter function for the `U11`, `U22`, ..., properties.""" if self.anisotropy: return self._U[i, j] lat = self.lattice or cartesian_lattice return self._U[0, 0] * lat.isotropicunit[i, j] - def _set_Uij(self, i, j, value): + def _set_uij(self, i, j, value): """The setter function for the `U11`, `U22`, ..., properties.""" self._U[i, j] = value self._U[j, i] = value @@ -361,18 +394,18 @@ def _set_Uij(self, i, j, value): """ U11 = property( - lambda self: self._get_Uij(0, 0), - lambda self, value: self._set_Uij(0, 0, value), + lambda self: self._get_uij(0, 0), + lambda self, value: self._set_uij(0, 0, value), doc=_doc_uii.format(0), ) U22 = property( - lambda self: self._get_Uij(1, 1), - lambda self, value: self._set_Uij(1, 1, value), + lambda self: self._get_uij(1, 1), + lambda self, value: self._set_uij(1, 1, value), doc=_doc_uii.format(1), ) U33 = property( - lambda self: self._get_Uij(2, 2), - lambda self, value: self._set_Uij(2, 2, value), + lambda self: self._get_uij(2, 2), + lambda self, value: self._set_uij(2, 2, value), doc=_doc_uii.format(2), ) @@ -384,18 +417,18 @@ def _set_Uij(self, i, j, value): """ U12 = property( - lambda self: self._get_Uij(0, 1), - lambda self, value: self._set_Uij(0, 1, value), + lambda self: self._get_uij(0, 1), + lambda self, value: self._set_uij(0, 1, value), doc=_doc_uij.format(0, 1), ) U13 = property( - lambda self: self._get_Uij(0, 2), - lambda self, value: self._set_Uij(0, 2, value), + lambda self: self._get_uij(0, 2), + lambda self, value: self._set_uij(0, 2, value), doc=_doc_uij.format(0, 2), ) U23 = property( - lambda self: self._get_Uij(1, 2), - lambda self, value: self._set_Uij(1, 2, value), + lambda self: self._get_uij(1, 2), + lambda self, value: self._set_uij(1, 2, value), doc=_doc_uij.format(1, 2), ) @@ -463,33 +496,33 @@ def Uisoequiv(self, value): """ B11 = property( - lambda self: _UtoB * self._get_Uij(0, 0), - lambda self, value: self._set_Uij(0, 0, _BtoU * value), + lambda self: _UtoB * self._get_uij(0, 0), + lambda self, value: self._set_uij(0, 0, _BtoU * value), doc=_doc_bii.format(1), ) B22 = property( - lambda self: _UtoB * self._get_Uij(1, 1), - lambda self, value: self._set_Uij(1, 1, _BtoU * value), + lambda self: _UtoB * self._get_uij(1, 1), + lambda self, value: self._set_uij(1, 1, _BtoU * value), doc=_doc_bii.format(2), ) B33 = property( - lambda self: _UtoB * self._get_Uij(2, 2), - lambda self, value: self._set_Uij(2, 2, _BtoU * value), + lambda self: _UtoB * self._get_uij(2, 2), + lambda self, value: self._set_uij(2, 2, _BtoU * value), doc=_doc_bii.format(3), ) B12 = property( - lambda self: _UtoB * self._get_Uij(0, 1), - lambda self, value: self._set_Uij(0, 1, _BtoU * value), + lambda self: _UtoB * self._get_uij(0, 1), + lambda self, value: self._set_uij(0, 1, _BtoU * value), doc=_doc_bij.format(1, 2), ) B13 = property( - lambda self: _UtoB * self._get_Uij(0, 2), - lambda self, value: self._set_Uij(0, 2, _BtoU * value), + lambda self: _UtoB * self._get_uij(0, 2), + lambda self, value: self._set_uij(0, 2, _BtoU * value), doc=_doc_bij.format(1, 3), ) B23 = property( - lambda self: _UtoB * self._get_Uij(1, 2), - lambda self, value: self._set_Uij(1, 2, _BtoU * value), + lambda self: _UtoB * self._get_uij(1, 2), + lambda self, value: self._set_uij(1, 2, _BtoU * value), doc=_doc_bij.format(2, 3), ) diff --git a/tests/test_atom.py b/tests/test_atom.py index 6c7dd32d..4097603f 100644 --- a/tests/test_atom.py +++ b/tests/test_atom.py @@ -18,6 +18,7 @@ import unittest import numpy +import pytest from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice @@ -74,6 +75,50 @@ def test___init__(self): # """ # return + def test_msdLat(self): + """Check Atom.msd_latt (and deprecated Atom.msdLat alias).""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom_1 = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=0.0123) + assert atom_1.msdLat([1, 2, 3]) == pytest.approx(0.0123, rel=0, abs=1e-15) + assert atom_1.msdLat([9, 0, -4]) == pytest.approx(0.0123, rel=0, abs=1e-15) + U = numpy.array( + [ + [0.010, 0.002, 0.001], + [0.002, 0.020, 0.003], + [0.001, 0.003, 0.030], + ], + dtype=float, + ) + atom_2 = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) + + vc = numpy.array([1.2, -0.3, 0.7], dtype=float) + vl = hexagonal.fractional(vc) + + assert atom_2.msdLat(vl) == pytest.approx(atom_2.msd_cart(vc), rel=1e-13, abs=1e-13) + return + + def test_msdCart(self): + """Check Atom.msd_cart (and deprecated Atom.msdCart alias).""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom_1 = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=0.0456) + assert atom_1.msdCart([1, 0, 0]) == pytest.approx(0.0456, rel=0, abs=1e-15) + assert atom_1.msdCart([0, 5, -2]) == pytest.approx(0.0456, rel=0, abs=1e-15) + assert atom_1.msdCart([0, 5, -2]) == pytest.approx(0.0456, rel=0, abs=1e-15) + + U = numpy.array( + [ + [0.011, 0.001, 0.000], + [0.001, 0.019, 0.002], + [0.000, 0.002, 0.027], + ], + dtype=float, + ) + atom_2 = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) + + vc = numpy.array([0.4, 1.1, -0.6], dtype=float) + assert atom_2.msdCart(vc) == pytest.approx(atom_2.msdCart(3.7 * vc), rel=1e-13, abs=1e-13) + return + def test_xyz_cartn(self): """Check Atom.xyz_cartn property.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) @@ -146,7 +191,117 @@ def test_xyz_cartn(self): # End of class TestAtom + # ---------------------------------------------------------------------------- +@pytest.mark.parametrize( + "uiso, vl", + [ + (0.0123, [1, 2, 3]), + ], +) +def test_msd_latt_isotropic(uiso, vl): + """Check Atom.msd_latt().""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=uiso) + + actual = atom.msd_latt(vl) + expected = pytest.approx(uiso, rel=0, abs=1e-15) + assert actual == expected + + +@pytest.mark.parametrize( + "U, vc", + [ + ( + numpy.array( + [ + [0.010, 0.002, 0.001], + [0.002, 0.020, 0.003], + [0.001, 0.003, 0.030], + ], + dtype=float, + ), + numpy.array([1.2, -0.3, 0.7], dtype=float), + ), + ( + numpy.array( + [ + [0.018, -0.001, 0.002], + [-0.001, 0.012, 0.004], + [0.002, 0.004, 0.025], + ], + dtype=float, + ), + numpy.array([-0.8, 0.9, 0.1], dtype=float), + ), + ], +) +def test_msd_latt_anisotropic(U, vc): + """Check Atom.msd_latt() anisotropic coordinate-invariance.""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) + + vl = hexagonal.fractional(vc) + + actual = atom.msd_latt(vl) + expected = pytest.approx(atom.msd_cart(vc), rel=1e-13, abs=1e-13) + assert actual == expected + + +@pytest.mark.parametrize( + "uiso, vc", + [ + (0.0456, [0, 5, -2]), + ], +) +def test_msd_cart_isotropic(uiso, vc): + """Check Atom.msd_cart().""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=uiso) + + actual = atom.msd_cart(vc) + expected = pytest.approx(uiso, rel=0, abs=1e-15) + assert actual == expected + + +@pytest.mark.parametrize( + "U, vc, scale", + [ + ( + numpy.array( + [ + [0.011, 0.001, 0.000], + [0.001, 0.019, 0.002], + [0.000, 0.002, 0.027], + ], + dtype=float, + ), + numpy.array([0.4, 1.1, -0.6], dtype=float), + 3.7, + ), + ( + numpy.array( + [ + [0.020, 0.003, -0.001], + [0.003, 0.014, 0.002], + [-0.001, 0.002, 0.009], + ], + dtype=float, + ), + numpy.array([2.0, -1.0, 0.5], dtype=float), + 0.25, + ), + ], +) +def test_msd_cart_anisotropic(U, vc, scale): + """Check Atom.msd_cart() anisotropic normalization invariance.""" + hexagonal = Lattice(1, 1, 1, 90, 90, 120) + atom = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) + + actual = atom.msd_cart(vc) + expected = pytest.approx(atom.msd_cart(scale * vc), rel=1e-13, abs=1e-13) + assert actual == expected + if __name__ == "__main__": unittest.main() From 9751d1e5918457a0ee422cf063352b06516310be Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 7 Mar 2026 00:38:56 -0500 Subject: [PATCH 189/226] chore: change docstring --- tests/test_atom.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_atom.py b/tests/test_atom.py index 4097603f..66a7f283 100644 --- a/tests/test_atom.py +++ b/tests/test_atom.py @@ -76,7 +76,7 @@ def test___init__(self): # return def test_msdLat(self): - """Check Atom.msd_latt (and deprecated Atom.msdLat alias).""" + """Check Atom.msdLat.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom_1 = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=0.0123) assert atom_1.msdLat([1, 2, 3]) == pytest.approx(0.0123, rel=0, abs=1e-15) @@ -95,10 +95,9 @@ def test_msdLat(self): vl = hexagonal.fractional(vc) assert atom_2.msdLat(vl) == pytest.approx(atom_2.msd_cart(vc), rel=1e-13, abs=1e-13) - return def test_msdCart(self): - """Check Atom.msd_cart (and deprecated Atom.msdCart alias).""" + """Check Atom.msdCart.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom_1 = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=0.0456) assert atom_1.msdCart([1, 0, 0]) == pytest.approx(0.0456, rel=0, abs=1e-15) @@ -117,7 +116,6 @@ def test_msdCart(self): vc = numpy.array([0.4, 1.1, -0.6], dtype=float) assert atom_2.msdCart(vc) == pytest.approx(atom_2.msdCart(3.7 * vc), rel=1e-13, abs=1e-13) - return def test_xyz_cartn(self): """Check Atom.xyz_cartn property.""" From d6d852514d5131230618d0301ed2980428059652 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 7 Mar 2026 11:58:57 -0500 Subject: [PATCH 190/226] chore: rename variables to more explicit one, add test case descriptions. --- tests/test_atom.py | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/test_atom.py b/tests/test_atom.py index 66a7f283..2d2b4f5e 100644 --- a/tests/test_atom.py +++ b/tests/test_atom.py @@ -192,24 +192,25 @@ def test_xyz_cartn(self): # ---------------------------------------------------------------------------- @pytest.mark.parametrize( - "uiso, vl", - [ + "uiso, lattice_vector", + [ # C1: isotropic displacement, msd is direction-independent in lattice coordinates. + # Expected the msd_latt equals Uisoequiv for any direction. (0.0123, [1, 2, 3]), ], ) -def test_msd_latt_isotropic(uiso, vl): +def test_msd_latt_isotropic(uiso, lattice_vector): """Check Atom.msd_latt().""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=uiso) - - actual = atom.msd_latt(vl) + actual = atom.msd_latt(lattice_vector) expected = pytest.approx(uiso, rel=0, abs=1e-15) assert actual == expected @pytest.mark.parametrize( - "U, vc", - [ + "U, cartesian_vector", + [ # C2: anisotropic displacement with same physical direction expressed in lattice vs cartesian coords + # Expected msd_latt(fractional(cartesian_vector)) == msd_cart(cartesian_vector) ( numpy.array( [ @@ -234,37 +235,37 @@ def test_msd_latt_isotropic(uiso, vl): ), ], ) -def test_msd_latt_anisotropic(U, vc): +def test_msd_latt_anisotropic(U, cartesian_vector): """Check Atom.msd_latt() anisotropic coordinate-invariance.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) - - vl = hexagonal.fractional(vc) - - actual = atom.msd_latt(vl) - expected = pytest.approx(atom.msd_cart(vc), rel=1e-13, abs=1e-13) + lattice_vector = hexagonal.fractional(cartesian_vector) + actual = atom.msd_latt(lattice_vector) + expected = pytest.approx(atom.msd_cart(cartesian_vector), rel=1e-13, abs=1e-13) assert actual == expected @pytest.mark.parametrize( - "uiso, vc", - [ + "uiso, cartesian_vector", + [ # C1: isotropic displacement with msd is direction-independent in cartesian coordinates + # Expected msd_cart equals Uisoequiv for any direction (0.0456, [0, 5, -2]), ], ) -def test_msd_cart_isotropic(uiso, vc): +def test_msd_cart_isotropic(uiso, cartesian_vector): """Check Atom.msd_cart().""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom = Atom("C", [0, 0, 0], lattice=hexagonal, Uisoequiv=uiso) - actual = atom.msd_cart(vc) + actual = atom.msd_cart(cartesian_vector) expected = pytest.approx(uiso, rel=0, abs=1e-15) assert actual == expected @pytest.mark.parametrize( - "U, vc, scale", - [ + "U, cartesian_vector, scale", + [ # C2: anisotropic displacement with msd_cart normalizes direction vector internally + # Expected msd_cart(cartesian_vector) == msd_cart(scale * cartesian_vector) ( numpy.array( [ @@ -291,13 +292,12 @@ def test_msd_cart_isotropic(uiso, vc): ), ], ) -def test_msd_cart_anisotropic(U, vc, scale): +def test_msd_cart_anisotropic(U, cartesian_vector, scale): """Check Atom.msd_cart() anisotropic normalization invariance.""" hexagonal = Lattice(1, 1, 1, 90, 90, 120) atom = Atom("C", [0, 0, 0], lattice=hexagonal, U=U) - - actual = atom.msd_cart(vc) - expected = pytest.approx(atom.msd_cart(scale * vc), rel=1e-13, abs=1e-13) + actual = atom.msd_cart(cartesian_vector) + expected = pytest.approx(atom.msd_cart(scale * cartesian_vector), rel=1e-13, abs=1e-13) assert actual == expected From 991889b210c48d40d49b038819ecc0451f0bd35f Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 7 Mar 2026 12:04:22 -0500 Subject: [PATCH 191/226] chore: change utility script to snake_case method. --- devutils/sgtbx_extra_groups.py | 64 +++++++++++++++++----------------- news/change-utility-script.rst | 23 ++++++++++++ 2 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 news/change-utility-script.rst diff --git a/devutils/sgtbx_extra_groups.py b/devutils/sgtbx_extra_groups.py index e5a96189..48dfdb99 100644 --- a/devutils/sgtbx_extra_groups.py +++ b/devutils/sgtbx_extra_groups.py @@ -20,7 +20,7 @@ from diffpy.structure.spacegroups import SpaceGroup, SymOp, is_space_group_identifier, mmLibSpaceGroupList -def tupleToSGArray(tpl): +def tuple_to_sg_array(tpl): if not _rtarrays: import diffpy.structure.SpaceGroups as sgmod @@ -40,19 +40,19 @@ def tupleToSGArray(tpl): _rtarrays = {} -def mmSpaceGroupFromSymbol(symbol): +def mm_space_group_from_symbol(symbol): """Construct SpaceGroup instance from a string symbol using sgtbx data.""" sginfo = sgtbx.space_group_info(symbol) symop_list = [] - symop_list = getSymOpList(sginfo.group()) + symop_list = get_symop_list(sginfo.group()) sgtype = sginfo.type() uhm = sgtype.lookup_symbol() sgsmbls = sgtbx.space_group_symbols(uhm) kw = {} kw["number"] = sgtype.number() kw["num_sym_equiv"] = len(symop_list) - kw["num_primitive_sym_equiv"] = countUniqueRotations(symop_list) + kw["num_primitive_sym_equiv"] = count_unique_rotations(symop_list) kw["short_name"] = sgsmbls.hermann_mauguin().replace(" ", "") pgt = sgsmbls.point_group_type() pgn = "PG" + re.sub(r"-(\d)", "\\1bar", pgt) @@ -64,27 +64,27 @@ def mmSpaceGroupFromSymbol(symbol): return mmsg -def adjustMMSpaceGroupNumber(mmsg): +def adjust_mm_space_group_number(mmsg): sg0 = [x for x in mmLibSpaceGroupList if x.number == mmsg.number] - if sg0 and cmpSpaceGroups(sg0[0], mmsg): + if sg0 and cmp_space_groups(sg0[0], mmsg): return while mmsg.number in sgnumbers: mmsg.number += 1000 sgnumbers.append(mmsg.number) -def getSymOpList(grp): +def get_symop_list(grp): symop_list = [] for op in grp: r_sgtbx = op.r().as_double() t_sgtbx = op.t().as_double() - R = tupleToSGArray(r_sgtbx) - t = tupleToSGArray(t_sgtbx) + R = tuple_to_sg_array(r_sgtbx) + t = tuple_to_sg_array(t_sgtbx) symop_list.append(SymOp(R, t)) return symop_list -def countUniqueRotations(symop_list): +def count_unique_rotations(symop_list): unique_rotations = set() for op in symop_list: tpl = tuple(op.R.flatten()) @@ -92,49 +92,49 @@ def countUniqueRotations(symop_list): return len(unique_rotations) -def cmpSpaceGroups(sg0, sg1): +def cmp_space_groups(sg0, sg1): if sg0 is sg1: return True - s0 = hashMMSpaceGroup(sg0) - s1 = hashMMSpaceGroup(sg1) + s0 = hash_mm_space_group(sg0) + s1 = hash_mm_space_group(sg1) return s0 == s1 -def findEquivalentMMSpaceGroup(grp): +def find_equivalent_mm_space_group(grp): if not _equivmmsg: for sgn in mmLibSpaceGroupList: - ssgn = hashMMSpaceGroup(sgn) + ssgn = hash_mm_space_group(sgn) _equivmmsg.setdefault(ssgn, sgn) - ssg = hashSgtbxGroup(grp) + ssg = hash_sgtbx_group(grp) return _equivmmsg.get(ssg) _equivmmsg = {} -def findEquivalentSgtbxSpaceGroup(sgmm): +def find_equivalent_sgtbx_space_group(sgmm): if not _equivsgtbx: for smbls in sgtbx.space_group_symbol_iterator(): uhm = smbls.universal_hermann_mauguin() grp = sgtbx.space_group_info(uhm).group() - hgrp = hashSgtbxGroup(grp) + hgrp = hash_sgtbx_group(grp) _equivsgtbx.setdefault(hgrp, grp) - hgmm = hashMMSpaceGroup(sgmm) + hgmm = hash_mm_space_group(sgmm) return _equivsgtbx.get(hgmm) _equivsgtbx = {} -def hashMMSpaceGroup(sg): +def hash_mm_space_group(sg): lines = [str(sg.number % 1000)] + sorted(map(str, sg.iter_symops())) s = "\n".join(lines) return s -def hashSgtbxGroup(grp): +def hash_sgtbx_group(grp): n = grp.type().number() - lines = [str(n)] + sorted(map(str, getSymOpList(grp))) + lines = [str(n)] + sorted(map(str, get_symop_list(grp))) s = "\n".join(lines) return s @@ -157,19 +157,19 @@ def hashSgtbxGroup(grp): """ -def SGCode(mmsg): +def sg_code(mmsg): src0 = _SGsrc % mmsg.__dict__ - src1 = src0.replace("@SYMOPS@", SymOpsCode(mmsg)) + src1 = src0.replace("@SYMOPS@", symops_code(mmsg)) return src1 -def SymOpsCode(mmsg): - lst = ["%8s%s," % ("", SymOpCode(op)) for op in mmsg.iter_symops()] +def symops_code(mmsg): + lst = ["%8s%s," % ("", symop_code(op)) for op in mmsg.iter_symops()] src = "\n".join(lst).strip() return src -def SymOpCode(op): +def symop_code(op): if not _rtnames: import diffpy.structure.SpaceGroups as sgmod @@ -193,18 +193,18 @@ def main(): for smbls in sgtbx.space_group_symbol_iterator(): uhm = smbls.universal_hermann_mauguin() grp = sgtbx.space_group_info(uhm).group() - if findEquivalentMMSpaceGroup(grp): + if find_equivalent_mm_space_group(grp): continue shn = smbls.hermann_mauguin().replace(" ", "") if is_space_group_identifier(shn): continue - sg = mmSpaceGroupFromSymbol(uhm) - hsg = hashMMSpaceGroup(sg) + sg = mm_space_group_from_symbol(uhm) + hsg = hash_mm_space_group(sg) if hsg in duplicates: continue - adjustMMSpaceGroupNumber(sg) + adjust_mm_space_group_number(sg) duplicates.add(hsg) - print(SGCode(sg)) + print(sg_code(sg)) return diff --git a/news/change-utility-script.rst b/news/change-utility-script.rst new file mode 100644 index 00000000..04546e44 --- /dev/null +++ b/news/change-utility-script.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: Change any utility scripts that outside of package distribution method to snake_cae method + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From d4726b1596c443ccf0c25660733dc43606a7bd36 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 13 Mar 2026 23:57:02 -0400 Subject: [PATCH 192/226] chore: add readme.md for devutils files --- devutils/README.md | 1 + news/add-devutils-readme.rst | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 devutils/README.md create mode 100644 news/add-devutils-readme.rst diff --git a/devutils/README.md b/devutils/README.md new file mode 100644 index 00000000..773f4f74 --- /dev/null +++ b/devutils/README.md @@ -0,0 +1 @@ +Library of scripts used as part of the code development,please keep it out of the package but in the same repo. diff --git a/news/add-devutils-readme.rst b/news/add-devutils-readme.rst new file mode 100644 index 00000000..9cf9b8b6 --- /dev/null +++ b/news/add-devutils-readme.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: add devutils readme + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 4f7656c065c74f223168908d44b87d6fd74dfcfc Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 14 Mar 2026 01:13:13 -0400 Subject: [PATCH 193/226] fix: fix load_structure method with loading Path object. --- news/fix-load-structure.rst | 23 ++++++++++++++++++ src/diffpy/structure/__init__.py | 22 +++++++++++++++++- tests/test_loadstructure.py | 40 ++++++++++++++++++++++++++------ 3 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 news/fix-load-structure.rst diff --git a/news/fix-load-structure.rst b/news/fix-load-structure.rst new file mode 100644 index 00000000..a324ad4f --- /dev/null +++ b/news/fix-load-structure.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added method ``load_structure`` in ``__init__.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated method ``loadStructure`` in ``__init__.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* Fixed ``load_structure`` with successfully loading `Path` object + +**Security:** + +* diff --git a/src/diffpy/structure/__init__.py b/src/diffpy/structure/__init__.py index 969b7323..0b07bb8c 100644 --- a/src/diffpy/structure/__init__.py +++ b/src/diffpy/structure/__init__.py @@ -34,6 +34,7 @@ """ +import os import sys import diffpy.structure as _structure @@ -46,8 +47,17 @@ # package version from diffpy.structure.version import __version__ +from diffpy.utils._deprecator import build_deprecation_message, deprecated # Deprecations ------------------------------------------------------- +base = "diffpy.structure" +removal_version = "4.0.0" +loadStructure_deprecation_msg = build_deprecation_message( + base, + "loadStructure", + "load_structure", + removal_version, +) # @deprecated @@ -72,7 +82,17 @@ def __getattr__(self, name): # top level routines +@deprecated(loadStructure_deprecation_msg) def loadStructure(filename, fmt="auto", **kw): + """This function has been deprecated and will be removed in version + 4.0.0. + + Please use diffpy.structure.load_structure instead. + """ + return load_structure(filename, fmt, **kw) + + +def load_structure(filename, fmt="auto", **kw): """Load new structure object from the specified file. Parameters @@ -96,7 +116,7 @@ def loadStructure(filename, fmt="auto", **kw): Return a more specific PDFFitStructure type for 'pdffit' and 'discus' formats. """ - + filename = os.fspath(filename) p = get_parser(fmt, **kw) rv = p.parse_file(filename) return rv diff --git a/tests/test_loadstructure.py b/tests/test_loadstructure.py index 8bd1ec21..ae6979ba 100644 --- a/tests/test_loadstructure.py +++ b/tests/test_loadstructure.py @@ -6,7 +6,7 @@ import pytest -from diffpy.structure import PDFFitStructure, Structure, loadStructure +from diffpy.structure import PDFFitStructure, Structure, load_structure, loadStructure from diffpy.structure.structureerrors import StructureFormatError @@ -19,22 +19,22 @@ def prepare_fixture(self, datafile): def test_xcfg(self): """Check loading of atomeye xcfg format.""" f = self.datafile("BubbleRaftShort.xcfg") - stru = loadStructure(f) + stru = load_structure(f) self.assertTrue(type(stru) is Structure) - self.assertRaises(StructureFormatError, loadStructure, f, "xyz") + self.assertRaises(StructureFormatError, load_structure, f, "xyz") return def test_discus(self): """Check loading of discus file format.""" f = self.datafile("Ni-discus.stru") - stru = loadStructure(f) + stru = load_structure(f) self.assertTrue(type(stru) is PDFFitStructure) return def test_cif(self): """Check loading of CIF file format.""" f = self.datafile("PbTe.cif") - stru = loadStructure(f) + stru = load_structure(f) self.assertTrue(isinstance(stru, Structure)) self.assertFalse(isinstance(stru, PDFFitStructure)) return @@ -45,11 +45,17 @@ def test_badfile(self): self.assertRaises(StructureFormatError, loadStructure, f) return + def test_load_bad_file(self): + """Check loading of CIF file format.""" + f = self.datafile("Ni-bad.stru") + self.assertRaises(StructureFormatError, load_structure, f) + return + def test_goodkwarg(self): """Check loading of CIF file and passing of parser keyword argument.""" f = self.datafile("graphite.cif") - stru = loadStructure(f, eps=1e-10) + stru = load_structure(f, eps=1e-10) self.assertEqual(8, len(stru)) return @@ -57,13 +63,33 @@ def test_badkwarg(self): """Check loading of xyz file format with invalid keyword argument.""" f = self.datafile("bucky.xyz") - self.assertRaises(TypeError, loadStructure, f, eps=1e-10) + self.assertRaises(TypeError, load_structure, f, eps=1e-10) return # End of class TestLoadStructure + # ---------------------------------------------------------------------------- +@pytest.mark.parametrize( + "filename, expected", + [ # C1: Load the cif file in Path object, expected to load the Structure instance. + ("PbTe.cif", (True, False)), + ], +) +def test_load_structure_cif_in_path(datafile, filename, expected): + from pathlib import Path + + f = datafile(filename) + f_path = Path(f) + stru = load_structure(f_path) + actual = ( + isinstance(stru, Structure), + isinstance(stru, PDFFitStructure), + ) + + assert actual == expected + if __name__ == "__main__": unittest.main() From b252ea3a41486044e9261875b80d240c26055629 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Mar 2026 16:24:30 -0400 Subject: [PATCH 194/226] get_chemical_symbols function and test --- src/diffpy/structure/structure.py | 174 ++++++++++++++++++++++++++++++ tests/test_structure.py | 45 ++++++++ 2 files changed, 219 insertions(+) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index ccba4044..aab9029d 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -17,6 +17,7 @@ import copy as copymod import numpy +from ase import Atoms as ASEAtoms from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice @@ -173,6 +174,179 @@ def getLastAtom(self): last_atom = self[-1] return last_atom + def get_chemical_symbols(self, include_charge_state=False): + """Return list of chemical symbols for all `Atoms` in this + structure. + + Parameters + ---------- + include_charge_state : bool, optional + If ``True``, include charge state in the chemical symbol (e.g., "Fe2+"). + Returns + ------- + list of str + The list of chemical symbols for all `Atoms` in this structure. + """ + symbols_with_charge = [a.element for a in self] + if include_charge_state: + return symbols_with_charge + else: + symbols = [atomBareSymbol(sym) for sym in symbols_with_charge] + return symbols + + def get_fractional_coordinates(self): + """Return array of fractional coordinates of all `Atoms` in this + structure. + + Returns + ------- + numpy.ndarray + The array of fractional coordinates of all `Atoms` in this structure. + """ + coords = numpy.array([a.xyz for a in self]) + return coords + + def get_cartesian_coordinates(self): + """Return array of Cartesian coordinates of all `Atoms` in this + structure. + + Returns + ------- + numpy.ndarray + The array of Cartesian coordinates of all `Atoms` in this structure. + """ + cartn_coords = numpy.array([a.xyz_cartn for a in self]) + return cartn_coords + + def get_anisotropic_displacement_parameters(self): + """Return array of anisotropic displacement parameters of all + `Atoms` in this structure. + + Returns + ------- + numpy.ndarray + The array of anisotropic displacement parameters of all `Atoms` in this structure. + """ + adps = numpy.array([a.U for a in self]) + return adps + + def get_isotropic_displacement_parameters(self): + """Return array of isotropic displacement parameters of all + `Atoms` in this structure. + + Returns + ------- + numpy.ndarray + The array of isotropic displacement parameters of all `Atoms` in this structure. + """ + idps = numpy.array([a.Uisoequiv for a in self]) + return idps + + def get_occupancies(self): + """Return array of occupancies of all `Atoms` in this structure. + + Returns + ------- + numpy.ndarray + The array of occupancies of all `Atoms` in this structure. + """ + occupancies = numpy.array([a.occupancy for a in self]) + return occupancies + + def convert_ase_to_diffpy_structure( + self, + ase_atoms: ASEAtoms, + lost_info: list[str] | None = None, + ) -> Structure | tuple[Structure, dict]: # noqa + """Convert ASE `Atoms` object to this `Structure` instance. + + Parameters + ---------- + ase_structure : ase.Atoms + The ASE `Atoms` object to be converted. + lost_info : list of str, optional + The list of attribute names to extract from the ASE `Atoms` + object that do not have a direct equivalent in the `Structure` class. + object that is not currently available in the `Structure` class. + Default is False. + + Returns + ------- + Structure + Reference to this `Structure` object with updated attributes and `Atom` instances. + lost_info : dict, optional + The dictionary containing any information from the ASE `Atoms` + object that is not currently available in the `Structure` class. + Default behavior is to return only the `Structure` instance. + If `lost_info` is provided, it will be a dictionary containing + any information from the ASE `Atoms`. + This may include information such as magnetic moments, charge states, + or other ASE-specific properties that do not have a direct equivalent + in the `Structure` class. + + Raises + ------ + TypeError + If the input `ase_structure` is not an instance of `ase.Atoms`. + ValueError + If any of the specified `lost_info` attributes are not present in the ASE `Atoms` object. + + Examples + -------- + An example of converting an `ASE.Atoms` instance to a `Structure` instance, + + .. code-block:: python + from ase import Atoms + from diffpy.structure import Structure + + # Create an ASE Atoms object + ase_atoms = Atoms('H2O', positions=[[0, 0, 0], [0, 0, 1], [1, 0, 0]]) + + # Convert to a diffpy Structure object + structure = Structure() + structure.convert_ase_to_diffpy(ase_atoms, + + + To extract additional information from the ASE `Atoms` object that is not + directly represented in the `Structure` class, such as magnetic moments, + you can specify an attribute or method of `ASE.Atoms` as + a list of strings in `lost_info` list. For example, + + .. code-block:: python + lost_info = structure.convert_ase_to_diffpy( + ase_atoms, + lost_info=['get_magnetic_moments'] + ) + + will return a dictionary with the magnetic moments of the atoms in the ASE `Atoms` object. + """ + if not isinstance(ase_atoms, ASEAtoms): + raise TypeError("Input must be an instance of ase.Atoms.") + # --- structure conversion --- + symbols = ase_atoms.get_chemical_symbols() + scaled_positions = ase_atoms.get_scaled_positions() + for sym, xyz in zip(symbols, scaled_positions): + self.append(Atom(sym, xyz=xyz)) + # --- optional extraction --- + if lost_info is None: + return + extracted_info = {} + for name in lost_info: + if not hasattr(ase_atoms, name): + raise ValueError(f"ASE.Atoms object has no attribute '{name}'.") + try: + attr = getattr(ase_atoms, name) + value = attr() if callable(attr) else attr + # try to copy (safe for numpy arrays, dicts, etc.) + try: + value = value.copy() + except Exception: + pass + extracted_info[name] = value + except Exception as e: + extracted_info[name] = f"ERROR: {type(e).__name__}: {e}" + return extracted_info + def assign_unique_labels(self): """Set a unique label string for each `Atom` in this structure. diff --git a/tests/test_structure.py b/tests/test_structure.py index 818cc265..d6de5614 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -609,6 +609,51 @@ def test_pickling(self): # End of class TestStructure + +@pytest.mark.parametrize( + "include_charge_state,expected", + [ + (False, ["Pb"] * 4 + ["Te"] * 4), + (True, ["Pb"] * 4 + ["Te"] * 4), + ], +) +def test_get_chemical_symbols(datafile, include_charge_state, expected): + """Check Structure.get_chemical_symbols()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_chemical_symbols = pbte_stru.get_chemical_symbols(include_charge_state=include_charge_state) + expected_chemical_symbols = expected + assert actual_chemical_symbols == expected_chemical_symbols + + +# def test_get_fractional_coordinates(datafile): +# """Check Structure.get_fractional_coordinates()""" +# pbte_cif = Structure(filename=datafile("PbTe.cif")) +# assert False + + +# def test_get_cartesian_coordinates(datafile): +# """Check Structure.get_cartesian_coordinates()""" +# assert False + + +# def test_get_anisotropic_displacement_parameters(datafile): +# """Check Structure.get_anisotropic_displacement_parameters()""" +# assert False + + +# def test_get_isotropic_displacement_parameters(datafile): +# """Check Structure.get_isotropic_displacement_parameters()""" +# assert False + + +# def test_get_occupancies(datafile): +# """Check Structure.get_occupancies()""" +# assert False + +# def test_convert_ase_to_diffpy_structure(datafile): +# """Check convert_ase_to_diffpy_structure()""" +# assert False + # ---------------------------------------------------------------------------- if __name__ == "__main__": From f339f4ed2016815dc634d9aaeca7cbbb9425cd9c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Mar 2026 16:29:32 -0400 Subject: [PATCH 195/226] get_fractional_coordinates code and test --- src/diffpy/structure/structure.py | 11 ++-------- tests/test_structure.py | 34 ++++++++++++++++++------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index aab9029d..2c08c988 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -178,21 +178,14 @@ def get_chemical_symbols(self, include_charge_state=False): """Return list of chemical symbols for all `Atoms` in this structure. - Parameters - ---------- - include_charge_state : bool, optional - If ``True``, include charge state in the chemical symbol (e.g., "Fe2+"). Returns ------- list of str The list of chemical symbols for all `Atoms` in this structure. """ symbols_with_charge = [a.element for a in self] - if include_charge_state: - return symbols_with_charge - else: - symbols = [atomBareSymbol(sym) for sym in symbols_with_charge] - return symbols + symbols = [atomBareSymbol(sym) for sym in symbols_with_charge] + return symbols def get_fractional_coordinates(self): """Return array of fractional coordinates of all `Atoms` in this diff --git a/tests/test_structure.py b/tests/test_structure.py index d6de5614..1245866a 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -610,25 +610,31 @@ def test_pickling(self): # End of class TestStructure -@pytest.mark.parametrize( - "include_charge_state,expected", - [ - (False, ["Pb"] * 4 + ["Te"] * 4), - (True, ["Pb"] * 4 + ["Te"] * 4), - ], -) -def test_get_chemical_symbols(datafile, include_charge_state, expected): +def test_get_chemical_symbols(datafile): """Check Structure.get_chemical_symbols()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) - actual_chemical_symbols = pbte_stru.get_chemical_symbols(include_charge_state=include_charge_state) - expected_chemical_symbols = expected + actual_chemical_symbols = pbte_stru.get_chemical_symbols() + expected_chemical_symbols = ["Pb"] * 4 + ["Te"] * 4 assert actual_chemical_symbols == expected_chemical_symbols -# def test_get_fractional_coordinates(datafile): -# """Check Structure.get_fractional_coordinates()""" -# pbte_cif = Structure(filename=datafile("PbTe.cif")) -# assert False +def test_get_fractional_coordinates(datafile): + """Check Structure.get_fractional_coordinates()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_fractional_coords = pbte_stru.get_fractional_coordinates() + expected_fractional_coords = numpy.array( + [ + [0.5, 0.5, 0.5], + [0.5, 0.0, 0.0], + [0.0, 0.5, 0.0], + [0.0, 0.0, 0.5], + [0.0, 0.0, 0.0], + [0.0, 0.5, 0.5], + [0.5, 0.0, 0.5], + [0.5, 0.5, 0.0], + ] + ) + assert actual_fractional_coords.tolist() == expected_fractional_coords.tolist() # def test_get_cartesian_coordinates(datafile): From 37f642681b298238fd71a48f444a7f742925367c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Mar 2026 16:39:05 -0400 Subject: [PATCH 196/226] get_cartesian_coordinates function and test --- src/diffpy/structure/structure.py | 10 +++++++--- tests/test_structure.py | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 2c08c988..cacf9478 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -174,7 +174,7 @@ def getLastAtom(self): last_atom = self[-1] return last_atom - def get_chemical_symbols(self, include_charge_state=False): + def get_chemical_symbols(self): """Return list of chemical symbols for all `Atoms` in this structure. @@ -194,7 +194,8 @@ def get_fractional_coordinates(self): Returns ------- numpy.ndarray - The array of fractional coordinates of all `Atoms` in this structure. + The array of fractional coordinates of all `Atoms` in this structure + in the same order as `Structure.get_chemical_symbols()`. """ coords = numpy.array([a.xyz for a in self]) return coords @@ -206,9 +207,12 @@ def get_cartesian_coordinates(self): Returns ------- numpy.ndarray - The array of Cartesian coordinates of all `Atoms` in this structure. + The array of Cartesian coordinates of all `Atoms` in this structure + in the same order as `Structure.get_chemical_symbols()`. """ cartn_coords = numpy.array([a.xyz_cartn for a in self]) + # round coordinates to avoid negative numbers close to zero + cartn_coords = numpy.round(cartn_coords, 5) return cartn_coords def get_anisotropic_displacement_parameters(self): diff --git a/tests/test_structure.py b/tests/test_structure.py index 1245866a..71ae2c27 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -634,12 +634,22 @@ def test_get_fractional_coordinates(datafile): [0.5, 0.5, 0.0], ] ) - assert actual_fractional_coords.tolist() == expected_fractional_coords.tolist() + assert numpy.allclose(actual_fractional_coords, expected_fractional_coords) -# def test_get_cartesian_coordinates(datafile): -# """Check Structure.get_cartesian_coordinates()""" -# assert False +def test_get_cartesian_coordinates(datafile): + """Check Structure.get_cartesian_coordinates()""" + cdse_stru = Structure(filename=datafile("CdSe_bulk.stru")) + actual_cartesian_coords = cdse_stru.get_cartesian_coordinates() + expected_cartesian_coords = numpy.array( + [ + [1.22284, 2.1176, 0.0], + [2.44495, 0.0, 3.45301], + [1.22284, 2.1176, 2.60129], + [2.44495, 0.0, 6.05431], + ] + ) + assert numpy.allclose(actual_cartesian_coords, expected_cartesian_coords) # def test_get_anisotropic_displacement_parameters(datafile): From 48c115e19b118256034d263fe7b8cd4f67a90493 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Mar 2026 16:53:47 -0400 Subject: [PATCH 197/226] get_isotropic_displacement_parameters tests and func --- src/diffpy/structure/structure.py | 8 ++++---- tests/test_structure.py | 28 ++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index cacf9478..60c2771c 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -224,8 +224,8 @@ def get_anisotropic_displacement_parameters(self): numpy.ndarray The array of anisotropic displacement parameters of all `Atoms` in this structure. """ - adps = numpy.array([a.U for a in self]) - return adps + aniso_adps = numpy.array([a.U for a in self]) + return aniso_adps def get_isotropic_displacement_parameters(self): """Return array of isotropic displacement parameters of all @@ -236,8 +236,8 @@ def get_isotropic_displacement_parameters(self): numpy.ndarray The array of isotropic displacement parameters of all `Atoms` in this structure. """ - idps = numpy.array([a.Uisoequiv for a in self]) - return idps + iso_adps = numpy.array([a.Uisoequiv for a in self]) + return iso_adps def get_occupancies(self): """Return array of occupancies of all `Atoms` in this structure. diff --git a/tests/test_structure.py b/tests/test_structure.py index 71ae2c27..f7c3e118 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -652,14 +652,30 @@ def test_get_cartesian_coordinates(datafile): assert numpy.allclose(actual_cartesian_coords, expected_cartesian_coords) -# def test_get_anisotropic_displacement_parameters(datafile): -# """Check Structure.get_anisotropic_displacement_parameters()""" -# assert False +def test_get_anisotropic_displacement_parameters(datafile): + """Check Structure.get_anisotropic_displacement_parameters()""" + tei_stru = Structure(filename=datafile("TeI.cif")) + actual_displacement = tei_stru.get_anisotropic_displacement_parameters() + expected_one_atom = numpy.array( + [ + [[0.0211, 0.0, 0.0109], [0.0, 0.0195, 0.0], [0.0109, 0.0, 0.016]], + [[0.0223, 0.0, 0.0179], [0.0, 0.018, 0.0], [0.0179, 0.0, 0.0254]], + [[0.025, 0.0, 0.0226], [0.0, 0.0234, 0.0], [0.0226, 0.0, 0.0345]], + [[0.0234, 0.0, 0.0138], [0.0, 0.0295, 0.0], [0.0138, 0.0, 0.0253]], + ] + ) + expected_displacement = numpy.repeat(expected_one_atom, 4, axis=0) + assert numpy.allclose(actual_displacement, expected_displacement) -# def test_get_isotropic_displacement_parameters(datafile): -# """Check Structure.get_isotropic_displacement_parameters()""" -# assert False +def test_get_isotropic_displacement_parameters(datafile): + """Check Structure.get_isotropic_displacement_parameters()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_isotropic_displacement = pbte_stru.get_isotropic_displacement_parameters() + expected_isotropic_displacement = numpy.array( + [0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528] + ) + assert numpy.allclose(actual_isotropic_displacement, expected_isotropic_displacement) # def test_get_occupancies(datafile): From 1f51263d81356ff06f5ba3dd21620434e93876ad Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Mon, 23 Mar 2026 16:54:52 -0400 Subject: [PATCH 198/226] get_occupancies test and func --- tests/test_structure.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index f7c3e118..86cd7a5d 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -678,9 +678,13 @@ def test_get_isotropic_displacement_parameters(datafile): assert numpy.allclose(actual_isotropic_displacement, expected_isotropic_displacement) -# def test_get_occupancies(datafile): -# """Check Structure.get_occupancies()""" -# assert False +def test_get_occupancies(datafile): + """Check Structure.get_occupancies()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_occupancies = pbte_stru.get_occupancies() + expected_occupancies = numpy.ones(8) + assert numpy.allclose(actual_occupancies, expected_occupancies) + # def test_convert_ase_to_diffpy_structure(datafile): # """Check convert_ase_to_diffpy_structure()""" From bd4a6c054a6a75d22c167bb0a204591322f3f4f9 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 10:30:02 -0400 Subject: [PATCH 199/226] add get_lattice_vectors, get_lattice_vector_angles and their respective tests --- src/diffpy/structure/structure.py | 48 ++++++++----- tests/conftest.py | 46 +++++++++++++ tests/test_structure.py | 109 +++++++++++++++++++++++++++++- 3 files changed, 184 insertions(+), 19 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 60c2771c..2a68334a 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -250,6 +250,31 @@ def get_occupancies(self): occupancies = numpy.array([a.occupancy for a in self]) return occupancies + def get_lattice_vectors(self): + """Return array of lattice vectors for this structure. + + Returns + ------- + numpy.ndarray + The array of lattice vectors for this structure. + """ + lattice_vectors = self.lattice.base + return lattice_vectors + + def get_lattice_vector_angles(self): + """Return array of lattice vector angles for this structure. + + Returns + ------- + numpy.ndarray + The array of lattice vector angles for this structure. + """ + a, b, c = self.lattice.base + alpha = self.lattice.angle(b, c) + beta = self.lattice.angle(a, c) + gamma = self.lattice.angle(a, b) + return numpy.array([alpha, beta, gamma]) + def convert_ase_to_diffpy_structure( self, ase_atoms: ASEAtoms, @@ -269,8 +294,6 @@ def convert_ase_to_diffpy_structure( Returns ------- - Structure - Reference to this `Structure` object with updated attributes and `Atom` instances. lost_info : dict, optional The dictionary containing any information from the ASE `Atoms` object that is not currently available in the `Structure` class. @@ -317,31 +340,24 @@ def convert_ase_to_diffpy_structure( will return a dictionary with the magnetic moments of the atoms in the ASE `Atoms` object. """ + # clear structure before populating it with new atoms + del self[:] if not isinstance(ase_atoms, ASEAtoms): - raise TypeError("Input must be an instance of ase.Atoms.") - # --- structure conversion --- + raise TypeError(f"Input must be an instance of ase.Atoms but got type {ase_atoms}.") + cell = ase_atoms.get_cell() + self.lattice = Lattice(base=numpy.array(cell)) symbols = ase_atoms.get_chemical_symbols() scaled_positions = ase_atoms.get_scaled_positions() for sym, xyz in zip(symbols, scaled_positions): self.append(Atom(sym, xyz=xyz)) - # --- optional extraction --- if lost_info is None: return extracted_info = {} for name in lost_info: if not hasattr(ase_atoms, name): raise ValueError(f"ASE.Atoms object has no attribute '{name}'.") - try: - attr = getattr(ase_atoms, name) - value = attr() if callable(attr) else attr - # try to copy (safe for numpy arrays, dicts, etc.) - try: - value = value.copy() - except Exception: - pass - extracted_info[name] = value - except Exception as e: - extracted_info[name] = f"ERROR: {type(e).__name__}: {e}" + attr = getattr(ase_atoms, name) + extracted_info[name] = attr() if callable(attr) else attr return extracted_info def assign_unique_labels(self): diff --git a/tests/conftest.py b/tests/conftest.py index 5471acc1..abe71b67 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,11 @@ import json from pathlib import Path +import numpy as np import pytest +from ase import Atoms + +from diffpy.structure import Atom, Lattice, Structure @pytest.fixture @@ -27,3 +31,45 @@ def _load(filename): return "tests/testdata/" + filename return _load + + +@pytest.fixture +def build_ase_atom_object(): + """Helper function to build an ASE.Atoms object for testing.""" + a = 5.409 + frac_coords = np.array( + [ + [0.0, 0.0, 0.0], + [0.5, 0.5, 0.5], + [0.25, 0.25, 0.25], + [0.75, 0.75, 0.75], + ] + ) + cart_coords = frac_coords * a + symbols = ["Zn", "Zn", "S", "S"] + ase_zb = Atoms(symbols=symbols, positions=cart_coords, cell=[[a, 0, 0], [0, a, 0], [0, 0, a]], pbc=True) + return ase_zb + + +@pytest.fixture +def build_diffpy_structure_object(): + """Helper function to build a diffpy.structure.Structure object for + testing.""" + a = 5.409 + frac_coords = np.array( + [ + [0.0, 0.0, 0.0], + [0.5, 0.5, 0.5], + [0.25, 0.25, 0.25], + [0.75, 0.75, 0.75], + ] + ) + lattice = Lattice(base=[[a, 0, 0], [0, a, 0], [0, 0, a]]) + atoms = [ + Atom("Zn", frac_coords[0]), + Atom("Zn", frac_coords[1]), + Atom("S", frac_coords[2]), + Atom("S", frac_coords[3]), + ] + diffpy_zb = Structure(atoms=atoms, lattice=lattice) + return diffpy_zb diff --git a/tests/test_structure.py b/tests/test_structure.py index 86cd7a5d..7dcb7225 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -686,9 +686,112 @@ def test_get_occupancies(datafile): assert numpy.allclose(actual_occupancies, expected_occupancies) -# def test_convert_ase_to_diffpy_structure(datafile): -# """Check convert_ase_to_diffpy_structure()""" -# assert False +def test_get_lattice_vectors(datafile): + """Check Structure.get_lattice_vectors()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_lattice_vectors = pbte_stru.get_lattice_vectors() + expected_lattice_vectors = numpy.array([[6.461, 0.0, 0.0], [0.0, 6.461, 0.0], [0.0, 0.0, 6.461]]) + assert numpy.allclose(actual_lattice_vectors, expected_lattice_vectors) + + +def test_get_lattice_vector_angles(datafile): + """Check Structure.get_lattice_vector_angles()""" + pbte_stru = Structure(filename=datafile("PbTe.cif")) + actual_lattice_vector_angles = pbte_stru.get_lattice_vector_angles() + expected_lattice_vector_angles = numpy.array([90.0, 90.0, 90.0]) + assert numpy.allclose(actual_lattice_vector_angles, expected_lattice_vector_angles) + + +@pytest.mark.parametrize( + "input", + [ + # case: user calls the conversion function on a Structure object that already contains + # a structure + # expected: the structure is wiped clean and replaced with the converted structure + # we use the fixture to create a Structure object that already contains a structure. + "use_diffpy_structure_fixture", + # case: user calls the conversion function on an empty Structure object + # expected: the converted structure is added to the empty Structure object without issue + Structure(), + ], +) +def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_diffpy_structure_object): + """Check convert_ase_to_diffpy_structure()""" + # input: User wants to convert an ASE.Atoms object to a diffpy.structure.Structure object + # expected: All similar data is transferred correctly, + # including chemical symbols, fractional coordinates, and lattice parameters. + + # Create an ASE.Atoms object + ase_zb = build_ase_atom_object + # Create an identical expected diffpy Structure object + expected_structure = build_diffpy_structure_object + + # Create new Structure object and convert ase to diffpy structure. + # Use the string input to determine which type of Structure object to create for the test + if isinstance(input, str): + actual_structure = build_diffpy_structure_object + else: + actual_structure = input + # set the lost_info variable, which gets the attribute of method from ASE.Atoms object, gets the values + # and stores it in a dict. This is used because ASE.Atoms stores more/different + # info that a diffpy.structure object + lost_info_dict = actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info=["get_masses"]) + actual_masses = lost_info_dict["get_masses"] + expected_masses = ase_zb.get_masses() + assert numpy.allclose(actual_masses, expected_masses) + + # Compare the actual and expected values + expected_lattice_vectors = expected_structure.get_lattice_vectors() + actual_lattice_vectors = actual_structure.get_lattice_vectors() + assert numpy.allclose(expected_lattice_vectors, actual_lattice_vectors) + + expected_lattice_angle = expected_structure.get_lattice_vector_angles() + actual_lattice_angle = actual_structure.get_lattice_vector_angles() + assert numpy.allclose(expected_lattice_angle, actual_lattice_angle) + + expected_symbols = expected_structure.get_chemical_symbols() + actual_symbols = actual_structure.get_chemical_symbols() + assert actual_symbols == expected_symbols + + expected_coords = expected_structure.get_fractional_coordinates() + actual_coords = actual_structure.get_fractional_coordinates() + assert numpy.allclose(actual_coords, expected_coords) + + +def test_convert_ase_to_diffpy_structure_bad_typeerror(): + """Check convert_ase_to_diffpy_structure() with bad input.""" + bad_input = "string" # pass a string instead of ase.Atoms + expected_error_msg = "Input must be an instance of ase.Atoms but got type str." + actual_structure = Structure() + with pytest.raises(TypeError, match=expected_error_msg): + actual_structure.convert_ase_to_diffpy_structure(bad_input) + + +@pytest.mark.parametrize( + "bad_lost_info,error,expected_error_msg", + [ # case: User provides an ASE.Atoms object but requests lost_info that is not an attribute of ASE.Atoms + # expected: A ValueError is raised with a clear error message indicating the requested lost_info + # attribute is invalid. + (["invalid_method"], ValueError, "ASE.Atoms object has no attribute 'invalid_method'"), + # case: User provides an ASE.Atoms object but requests lost_info that is an attribute of ASE.Atoms + # but has not been set yet. + # expected: The error message from ase is raised indicating the specific issue with the + # requested lost_info attribute. + # We set the expected error message to None because this expectation is + # out of our control, but it is good to make sure that we are + # raising the error from ASE. + (["get_magnetic_moments"], RuntimeError, None), + ], +) +def test_convert_ase_to_diffpy_structure_bad_valueerror( + bad_lost_info, error, expected_error_msg, build_ase_atom_object +): + """Check convert_ase_to_diffpy_structure() with bad lost_info.""" + ase_zb = build_ase_atom_object + actual_structure = Structure() + with pytest.raises(error, match=expected_error_msg): + actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info=bad_lost_info) + # ---------------------------------------------------------------------------- From 67d978a14162ce14ae69413f58e1bdf4f0decc7a Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 10:34:08 -0400 Subject: [PATCH 200/226] news --- news/ase-adapter.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 news/ase-adapter.rst diff --git a/news/ase-adapter.rst b/news/ase-adapter.rst new file mode 100644 index 00000000..2cf7507a --- /dev/null +++ b/news/ase-adapter.rst @@ -0,0 +1,31 @@ +**Added:** + +* Added ``Structure.get_lattice_vectors()`` method to return the lattice vectors. +* Added ``Structure.get_lattice_vector_angles()`` method to return the angles between the lattice vectors. +* Added ``Structure.get_isotropic_displacement_parameters()`` method to return the isotropic displacement parameters. +* Added ``Structure.get_anisotropic_displacement_parameters()`` method to return the anisotropic displacement parameters. +* Added ``Structure.get_occupancies()`` method to return the occupancies of the sites. +* Added ``Structure.get_cartesian_coordinates()`` method to return the Cartesian coordinates of the sites. +* Added ``Structure.get_fractional_coordinates()`` method to return the fractional coordinates of the sites. +* Added ``Structure.get_chemical_symbols()`` method to return the chemical symbols of the sites. +* Added ``Structure.convert_ase_to_diffpy_structure()`` method to convert an ASE Atoms object to a DiffPy Structure object. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From bb207e0f78596323f8a6ac80fd719c91743e1595 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 10:51:38 -0400 Subject: [PATCH 201/226] make ase converter take str or list of strs --- src/diffpy/structure/structure.py | 32 ++++++++++++++++++++----------- tests/test_structure.py | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 2a68334a..a5692fa8 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -282,15 +282,23 @@ def convert_ase_to_diffpy_structure( ) -> Structure | tuple[Structure, dict]: # noqa """Convert ASE `Atoms` object to this `Structure` instance. + The conversion process involves extracting the lattice parameters, chemical symbols, + and fractional coordinates from the ASE `Atoms` object and populating the corresponding + attributes of this `Structure` instance. The `lattice` attribute is set based on the + cell parameters of the ASE `Atoms` object, and each `Atom` in this `Structure` is created + with the chemical symbol and fractional coordinates extracted from the ASE `Atoms`. + Parameters ---------- ase_structure : ase.Atoms The ASE `Atoms` object to be converted. - lost_info : list of str, optional - The list of attribute names to extract from the ASE `Atoms` + lost_info : str or list of str, optional + The method(s) or attribute(s) to extract from the ASE `Atoms` object that do not have a direct equivalent in the `Structure` class. - object that is not currently available in the `Structure` class. - Default is False. + This will be provided in a dictionary format where keys are the + method/attribute name(s) and value(s) are the corresponding data + extracted from the ASE `Atoms` object. + Default is None. See `Examples` for usage. Returns ------- @@ -324,7 +332,7 @@ def convert_ase_to_diffpy_structure( # Convert to a diffpy Structure object structure = Structure() - structure.convert_ase_to_diffpy(ase_atoms, + structure.convert_ase_to_diffpy(ase_atoms) To extract additional information from the ASE `Atoms` object that is not @@ -333,10 +341,10 @@ def convert_ase_to_diffpy_structure( a list of strings in `lost_info` list. For example, .. code-block:: python - lost_info = structure.convert_ase_to_diffpy( - ase_atoms, - lost_info=['get_magnetic_moments'] - ) + lost_info = structure.convert_ase_to_diffpy( + ase_atoms, + lost_info='get_magnetic_moments' + ) will return a dictionary with the magnetic moments of the atoms in the ASE `Atoms` object. """ @@ -348,11 +356,13 @@ def convert_ase_to_diffpy_structure( self.lattice = Lattice(base=numpy.array(cell)) symbols = ase_atoms.get_chemical_symbols() scaled_positions = ase_atoms.get_scaled_positions() - for sym, xyz in zip(symbols, scaled_positions): - self.append(Atom(sym, xyz=xyz)) + for atom_symbol, frac_coord in zip(symbols, scaled_positions): + self.append(Atom(atom_symbol, xyz=frac_coord)) if lost_info is None: return extracted_info = {} + if isinstance(lost_info, str): + lost_info = [lost_info] for name in lost_info: if not hasattr(ase_atoms, name): raise ValueError(f"ASE.Atoms object has no attribute '{name}'.") diff --git a/tests/test_structure.py b/tests/test_structure.py index 7dcb7225..334d8cc7 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -735,7 +735,7 @@ def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_dif # set the lost_info variable, which gets the attribute of method from ASE.Atoms object, gets the values # and stores it in a dict. This is used because ASE.Atoms stores more/different # info that a diffpy.structure object - lost_info_dict = actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info=["get_masses"]) + lost_info_dict = actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info="get_masses") actual_masses = lost_info_dict["get_masses"] expected_masses = ase_zb.get_masses() assert numpy.allclose(actual_masses, expected_masses) From 7199c465b893063d6d96d8a58242c2c73c018374 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 11:13:54 -0400 Subject: [PATCH 202/226] update cartesian coordinate getter so it doesnt round --- src/diffpy/structure/structure.py | 2 -- tests/test_structure.py | 10 +++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index a5692fa8..9dd92044 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -211,8 +211,6 @@ def get_cartesian_coordinates(self): in the same order as `Structure.get_chemical_symbols()`. """ cartn_coords = numpy.array([a.xyz_cartn for a in self]) - # round coordinates to avoid negative numbers close to zero - cartn_coords = numpy.round(cartn_coords, 5) return cartn_coords def get_anisotropic_displacement_parameters(self): diff --git a/tests/test_structure.py b/tests/test_structure.py index 334d8cc7..80e96ff2 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -643,13 +643,13 @@ def test_get_cartesian_coordinates(datafile): actual_cartesian_coords = cdse_stru.get_cartesian_coordinates() expected_cartesian_coords = numpy.array( [ - [1.22284, 2.1176, 0.0], - [2.44495, 0.0, 3.45301], - [1.22284, 2.1176, 2.60129], - [2.44495, 0.0, 6.05431], + [1.22284264, 2.11760202, 0.0], + [2.44495161, 0.0, 3.4530135], + [1.22284264, 2.11760202, 2.60129319], + [2.44495161, 0.0, 6.05430669], ] ) - assert numpy.allclose(actual_cartesian_coords, expected_cartesian_coords) + assert numpy.allclose(actual_cartesian_coords, expected_cartesian_coords, atol=1e-6) def test_get_anisotropic_displacement_parameters(datafile): From 8fa8327fd1e9391f0c012d32148213e2e17510fd Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 11:25:02 -0400 Subject: [PATCH 203/226] add ase to conda.txt and pip.txt --- requirements/conda.txt | 1 + requirements/pip.txt | 1 + src/diffpy/structure/structure.py | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index 4c4ff50e..bb3d289c 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,3 +1,4 @@ numpy pycifrw diffpy.utils +ase diff --git a/requirements/pip.txt b/requirements/pip.txt index 4c4ff50e..bb3d289c 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,3 +1,4 @@ numpy pycifrw diffpy.utils +ase diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 9dd92044..80e1eabe 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -301,11 +301,11 @@ def convert_ase_to_diffpy_structure( Returns ------- lost_info : dict, optional - The dictionary containing any information from the ASE `Atoms` + If specified, the dictionary containing any information from the ASE `Atoms` object that is not currently available in the `Structure` class. - Default behavior is to return only the `Structure` instance. - If `lost_info` is provided, it will be a dictionary containing - any information from the ASE `Atoms`. + Default behavior is to return `None`. + If `lost_info` is provided, a dictionary containing + any information from the ASE `Atoms` will be returned. This may include information such as magnetic moments, charge states, or other ASE-specific properties that do not have a direct equivalent in the `Structure` class. From beec69ccf868a401485962c7a289f32962d7e689 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Tue, 24 Mar 2026 13:08:37 -0400 Subject: [PATCH 204/226] add option to return ADPs as an array or dictionary --- src/diffpy/structure/structure.py | 60 ++++-- tests/test_structure.py | 322 +++++++++++++++++++++--------- 2 files changed, 275 insertions(+), 107 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 80e1eabe..c418afe8 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -213,29 +213,61 @@ def get_cartesian_coordinates(self): cartn_coords = numpy.array([a.xyz_cartn for a in self]) return cartn_coords - def get_anisotropic_displacement_parameters(self): - """Return array of anisotropic displacement parameters of all - `Atoms` in this structure. + def get_anisotropic_displacement_parameters(self, return_array=False): + """Return a dictionary of anisotropic displacement parameters + for all atoms. + + Parameters + ---------- + return_array : bool, optional + If True, return anisotropic displacement parameters as a numpy array instead of a dictionary. Returns ------- - numpy.ndarray - The array of anisotropic displacement parameters of all `Atoms` in this structure. + dict + The dictionary of anisotropic displacement parameters for all atoms in this structure. + Keys are of the form 'Element_i_Ujk', e.g. 'C_0_11', 'C_0_12'. """ - aniso_adps = numpy.array([a.U for a in self]) - return aniso_adps + if return_array: + aniso_adps = numpy.array([a.U for a in self]) + return aniso_adps + else: + adp_dict = {} + for i, atom in enumerate(self): + element = atomBareSymbol(atom.element) + adp_dict[f"{element}_{i}_11"] = self.U11[i] + adp_dict[f"{element}_{i}_22"] = self.U22[i] + adp_dict[f"{element}_{i}_33"] = self.U33[i] + adp_dict[f"{element}_{i}_12"] = self.U12[i] + adp_dict[f"{element}_{i}_13"] = self.U13[i] + adp_dict[f"{element}_{i}_23"] = self.U23[i] + return adp_dict + + def get_isotropic_displacement_parameters(self, return_array=False): + """Return a dictionary of isotropic displacement parameters for + all atoms. - def get_isotropic_displacement_parameters(self): - """Return array of isotropic displacement parameters of all - `Atoms` in this structure. + Parameters + ---------- + return_array : bool, optional + If True, return isotropic displacement parameters as a numpy array instead of a dictionary. + Default is False. Returns ------- - numpy.ndarray - The array of isotropic displacement parameters of all `Atoms` in this structure. + dict + The dictionary of isotropic displacement parameters for all atoms in this structure. + Keys are of the form 'Element_i_Uiso', e.g. 'C_0_Uiso'. """ - iso_adps = numpy.array([a.Uisoequiv for a in self]) - return iso_adps + if return_array: + iso_adps = numpy.array([a.Uisoequiv for a in self]) + return iso_adps + else: + iso_dict = {} + for i, atom in enumerate(self): + element = atomBareSymbol(atom.element) + iso_dict[f"{element}_{i+1}_Uiso"] = self.Uisoequiv[i] + return iso_dict def get_occupancies(self): """Return array of occupancies of all `Atoms` in this structure. diff --git a/tests/test_structure.py b/tests/test_structure.py index 80e96ff2..8d89b42a 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -19,7 +19,7 @@ import pickle import unittest -import numpy +import numpy as np import pytest from diffpy.structure import Atom, Lattice, Structure @@ -87,8 +87,8 @@ def __copy__(self): pbte = self.pbte pbte2 = pbte.copy() self.assertFalse(pbte2.lattice is pbte.lattice) - self.assertTrue(numpy.array_equal(pbte.xyz_cartn, pbte2.xyz_cartn)) - self.assertTrue(numpy.array_equal(pbte.U, pbte2.U)) + self.assertTrue(np.array_equal(pbte.xyz_cartn, pbte2.xyz_cartn)) + self.assertTrue(np.array_equal(pbte.U, pbte2.U)) stru = MyDerivedStructure() stru += pbte2[pbte2.element.startswith("Pb")] pb3 = stru.copy() @@ -163,9 +163,9 @@ def test_placeInLattice(self): new_lattice = Lattice(0.5, 0.5, 0.5, 90, 90, 60) stru.placeInLattice(new_lattice) a0 = stru[0] - self.assertTrue(numpy.allclose(a0.xyz, [0.0, 0.0, 0.0])) + self.assertTrue(np.allclose(a0.xyz, [0.0, 0.0, 0.0])) a1 = stru[1] - self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0])) + self.assertTrue(np.allclose(a1.xyz, [2.0, 0.0, 2.0])) # def test_read(self): # """check Structure.read()""" @@ -199,7 +199,7 @@ def test_append(self): self.assertEqual(3, len(self.stru)) self.assertEqual("Si", alast.element) self.assertTrue(lat is alast.lattice) - self.assertTrue(numpy.array_equal(a.xyz, alast.xyz)) + self.assertTrue(np.array_equal(a.xyz, alast.xyz)) self.assertFalse(a is alast) self.assertFalse(lat is a.lattice) return @@ -213,7 +213,7 @@ def test_insert(self): self.assertEqual(3, len(self.stru)) self.assertEqual("Si", a1.element) self.assertTrue(lat is a1.lattice) - self.assertTrue(numpy.array_equal(a.xyz, a1.xyz)) + self.assertTrue(np.array_equal(a.xyz, a1.xyz)) self.assertFalse(a is a1) self.assertFalse(lat is a.lattice) return @@ -236,7 +236,7 @@ def test___getitem__(self): self.assertTrue(stru[0] is stru.tolist()[0]) intidx = list(range(len(stru)))[::-1] self.assertEqual(stru[intidx].tolist(), stru.tolist()[::-1]) - flagidx = numpy.arange(len(stru)) > 0 + flagidx = np.arange(len(stru)) > 0 self.assertEqual(stru[flagidx].tolist(), stru.tolist()[1:]) cdse = Structure(self.cdse) self.assertEqual([cdse[0], cdse[-2]], cdse[0, -2].tolist()) @@ -273,7 +273,7 @@ def test___setitem__(self): self.assertEqual(2, len(self.stru)) self.assertEqual("Si", a1.element) self.assertTrue(lat is a1.lattice) - self.assertTrue(numpy.array_equal(a.xyz, a1.xyz)) + self.assertTrue(np.array_equal(a.xyz, a1.xyz)) self.assertFalse(a is a1) self.assertFalse(lat is a.lattice) return @@ -287,7 +287,7 @@ def test___setitem__slice(self): self.assertEqual(1, len(self.stru)) self.assertEqual("Si", a0.element) self.assertTrue(lat is a0.lattice) - self.assertTrue(numpy.array_equal(a.xyz, a0.xyz)) + self.assertTrue(np.array_equal(a.xyz, a0.xyz)) self.assertFalse(a is a0) self.assertFalse(lat is a.lattice) return @@ -301,9 +301,9 @@ def test___add__(self): ta0 = total[0] tam1 = total[-1] self.assertEqual("C", ta0.element) - self.assertTrue(numpy.array_equal(stru[0].xyz, ta0.xyz)) + self.assertTrue(np.array_equal(stru[0].xyz, ta0.xyz)) self.assertEqual("Se", tam1.element) - self.assertTrue(numpy.array_equal(cdse[-1].xyz, tam1.xyz)) + self.assertTrue(np.array_equal(cdse[-1].xyz, tam1.xyz)) self.assertFalse(total.lattice in (stru.lattice, cdse.lattice)) self.assertTrue(all([a.lattice is total.lattice for a in total])) return @@ -319,7 +319,7 @@ def test___iadd__(self): self.assertEqual(lst, stru[:2].tolist()) am1 = stru[-1] self.assertEqual("Se", am1.element) - self.assertTrue(numpy.array_equal(cdse[-1].xyz, am1.xyz)) + self.assertTrue(np.array_equal(cdse[-1].xyz, am1.xyz)) self.assertTrue(lat0 is stru.lattice) self.assertFalse(stru.lattice is cdse.lattice) self.assertTrue(all([a.lattice is stru.lattice for a in stru])) @@ -332,8 +332,8 @@ def test___sub__(self): self.assertEqual(2, len(cadmiums)) self.assertEqual("Cd", cadmiums[0].element) self.assertEqual("Cd", cadmiums[1].element) - self.assertTrue(numpy.array_equal(cdse[0].xyz, cadmiums[0].xyz)) - self.assertTrue(numpy.array_equal(cdse[1].xyz, cadmiums[1].xyz)) + self.assertTrue(np.array_equal(cdse[0].xyz, cadmiums[0].xyz)) + self.assertTrue(np.array_equal(cdse[1].xyz, cadmiums[1].xyz)) self.assertFalse(cdse[0] is cadmiums[0]) self.assertFalse(cdse.lattice is cadmiums.lattice) return @@ -360,7 +360,7 @@ def test___mul__(self): cdsex3 = 3 * cdse self.assertEqual(12, len(cdsex3)) self.assertEqual(3 * "Cd Cd Se Se".split(), [a.element for a in cdsex3]) - self.assertTrue(numpy.array_equal(3 * [a.xyz for a in cdse], [a.xyz for a in cdsex3])) + self.assertTrue(np.array_equal(3 * [a.xyz for a in cdse], [a.xyz for a in cdsex3])) self.assertFalse(set(cdse).intersection(cdsex3)) self.assertFalse(cdse.lattice is cdsex3.lattice) return @@ -375,8 +375,8 @@ def test___imul__(self): cdse *= 2 self.assertEqual(8, len(cdse)) self.assertEqual(lst, cdse[:4].tolist()) - self.assertEqual(numpy.tile(els, 2).tolist(), cdse.element.tolist()) - self.assertTrue(numpy.array_equal(numpy.tile(xyz, (2, 1)), cdse.xyz)) + self.assertEqual(np.tile(els, 2).tolist(), cdse.element.tolist()) + self.assertTrue(np.array_equal(np.tile(xyz, (2, 1)), cdse.xyz)) self.assertEqual(8, len(set(cdse))) self.assertEqual(8 * [lat], [a.lattice for a in cdse]) self.stru *= -3 @@ -423,18 +423,18 @@ def test_xyz(self): """Check Structure.xyz.""" stru = self.stru self.assertEqual((2, 3), stru.xyz.shape) - self.assertTrue(numpy.array_equal([1, 1, 1], stru.xyz[1])) + self.assertTrue(np.array_equal([1, 1, 1], stru.xyz[1])) stru.xyz += 0.1 - self.assertTrue(numpy.array_equal([0.1, 0.1, 0.1], stru[0].xyz)) - self.assertTrue(numpy.array_equal([1.1, 1.1, 1.1], stru[1].xyz)) + self.assertTrue(np.array_equal([0.1, 0.1, 0.1], stru[0].xyz)) + self.assertTrue(np.array_equal([1.1, 1.1, 1.1], stru[1].xyz)) stru.xyz = 0 stru[1].xyz[:] = 1 - self.assertTrue(numpy.array_equal([0, 0, 0], stru[0].xyz)) - self.assertTrue(numpy.array_equal([1, 1, 1], stru[1].xyz)) + self.assertTrue(np.array_equal([0, 0, 0], stru[0].xyz)) + self.assertTrue(np.array_equal([1, 1, 1], stru[1].xyz)) # verify noop when changing empty slice - xyz0 = numpy.copy(stru.xyz) + xyz0 = np.copy(stru.xyz) stru[1:1].xyz += 1 - self.assertTrue(numpy.array_equal(xyz0, stru.xyz)) + self.assertTrue(np.array_equal(xyz0, stru.xyz)) return def test_x(self): @@ -483,7 +483,7 @@ def test_label(self): def test_occupancy(self): """Check Structure.occupancy.""" cdse = self.cdse - self.assertTrue(numpy.array_equal(numpy.ones(4), cdse.occupancy)) + self.assertTrue(np.array_equal(np.ones(4), cdse.occupancy)) self.stru.occupancy *= 0.5 self.assertEqual(1.0, sum([a.occupancy for a in self.stru])) cdse.occupancy = 1 @@ -494,25 +494,25 @@ def test_xyz_cartn(self): """Check Structure.xyz_cartn.""" pbte = copy.copy(self.pbte) self.assertEqual((8, 3), pbte.xyz_cartn.shape) - self.assertTrue(numpy.allclose(6.461 / 2.0 * numpy.ones(3), pbte.xyz_cartn[0])) - pbte.xyz_cartn += numpy.array([0.1, 0.2, 0.3]) * 6.461 - self.assertTrue(numpy.allclose([0.6, 0.7, 0.8], pbte[0].xyz)) - self.assertTrue(numpy.allclose([0.6, 0.7, 0.3], pbte[7].xyz)) + self.assertTrue(np.allclose(6.461 / 2.0 * np.ones(3), pbte.xyz_cartn[0])) + pbte.xyz_cartn += np.array([0.1, 0.2, 0.3]) * 6.461 + self.assertTrue(np.allclose([0.6, 0.7, 0.8], pbte[0].xyz)) + self.assertTrue(np.allclose([0.6, 0.7, 0.3], pbte[7].xyz)) return def test_anisotropy(self): """Check Structure.anisotropy.""" self.assertEqual((2,), self.stru.anisotropy.shape) - self.assertFalse(numpy.any(self.stru.anisotropy)) + self.assertFalse(np.any(self.stru.anisotropy)) tei = copy.copy(self.tei) - self.assertTrue(numpy.all(tei.anisotropy)) + self.assertTrue(np.all(tei.anisotropy)) tei.anisotropy = False - self.assertFalse(numpy.any(tei.anisotropy)) + self.assertFalse(np.any(tei.anisotropy)) self.assertAlmostEqual(0.019227, tei[0].U11, 6) self.assertAlmostEqual(0.019227, tei[0].U22, 6) self.assertAlmostEqual(0.019227, tei[0].U33, 6) self.assertAlmostEqual(0.0, tei[0].U12, 6) - self.assertAlmostEqual(0.019227 * -numpy.cos(numpy.radians(128.09)), tei[0].U13, 6) + self.assertAlmostEqual(0.019227 * -np.cos(np.radians(128.09)), tei[0].U13, 6) self.assertAlmostEqual(0.0, tei[0].U23, 6) self.assertAlmostEqual(0.019227, tei[0].Uisoequiv, 6) return @@ -521,22 +521,22 @@ def test_U(self): """Check Structure.U.""" stru = self.stru self.assertEqual((2, 3, 3), stru.U.shape) - self.assertFalse(numpy.any(stru.anisotropy)) - stru.U = numpy.identity(3) + self.assertFalse(np.any(stru.anisotropy)) + stru.U = np.identity(3) self.assertEqual(2, len(set([id(a.U) for a in stru]))) isou = stru.lattice.isotropicunit - self.assertTrue(numpy.array_equal(2 * [isou], stru.U)) - self.assertFalse(numpy.any(stru.anisotropy)) + self.assertTrue(np.array_equal(2 * [isou], stru.U)) + self.assertFalse(np.any(stru.anisotropy)) stru.anisotropy = True - stru.U = numpy.identity(3) - self.assertTrue(numpy.array_equal(2 * [numpy.identity(3)], stru.U)) - self.assertTrue(numpy.all(stru.anisotropy)) + stru.U = np.identity(3) + self.assertTrue(np.array_equal(2 * [np.identity(3)], stru.U)) + self.assertTrue(np.all(stru.anisotropy)) stru.U = 0 - self.assertTrue(numpy.all(stru.anisotropy)) - self.assertFalse(numpy.any(stru.U != 0.0)) + self.assertTrue(np.all(stru.anisotropy)) + self.assertFalse(np.any(stru.U != 0.0)) stru[1].U[:] = 1 - self.assertTrue(numpy.all(stru[0].U == 0.0)) - self.assertTrue(numpy.all(stru[1].U == 1.0)) + self.assertTrue(np.all(stru[0].U == 0.0)) + self.assertTrue(np.all(stru[1].U == 1.0)) return def test_Uisoequiv(self): @@ -557,19 +557,19 @@ def test_Uij(self): stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] - self.assertTrue(numpy.array_equal([0, 1.1], stru.U11)) - self.assertTrue(numpy.array_equal([0, 2.2], stru.U22)) - self.assertTrue(numpy.array_equal([0, 3.3], stru.U33)) - self.assertTrue(numpy.array_equal([0, 0.12], stru.U12)) - self.assertTrue(numpy.array_equal([0, 0.13], stru.U13)) - self.assertTrue(numpy.array_equal([0, 0.23], stru.U23)) + self.assertTrue(np.array_equal([0, 1.1], stru.U11)) + self.assertTrue(np.array_equal([0, 2.2], stru.U22)) + self.assertTrue(np.array_equal([0, 3.3], stru.U33)) + self.assertTrue(np.array_equal([0, 0.12], stru.U12)) + self.assertTrue(np.array_equal([0, 0.13], stru.U13)) + self.assertTrue(np.array_equal([0, 0.23], stru.U23)) stru.U11 = stru.U22 = stru.U33 = stru.U12 = stru.U13 = stru.U23 = 0.0 - self.assertFalse(numpy.any(stru.U != 0.0)) + self.assertFalse(np.any(stru.U != 0.0)) return def test_Bisoequiv(self): """Check Structure.Bisoequiv.""" - utob = 8 * numpy.pi**2 + utob = 8 * np.pi**2 tei = copy.copy(self.tei) self.assertEqual((16,), tei.Bisoequiv.shape) self.assertAlmostEqual(utob * 0.019227, tei.Bisoequiv[0], 4) @@ -586,15 +586,15 @@ def test_Bij(self): stru = self.stru stru[1].anisotropy = True stru[1].U = [[1.1, 0.12, 0.13], [0.12, 2.2, 0.23], [0.13, 0.23, 3.3]] - stru[1].U /= 8 * numpy.pi**2 - self.assertTrue(numpy.allclose([0, 1.1], stru.B11)) - self.assertTrue(numpy.allclose([0, 2.2], stru.B22)) - self.assertTrue(numpy.allclose([0, 3.3], stru.B33)) - self.assertTrue(numpy.allclose([0, 0.12], stru.B12)) - self.assertTrue(numpy.allclose([0, 0.13], stru.B13)) - self.assertTrue(numpy.allclose([0, 0.23], stru.B23)) + stru[1].U /= 8 * np.pi**2 + self.assertTrue(np.allclose([0, 1.1], stru.B11)) + self.assertTrue(np.allclose([0, 2.2], stru.B22)) + self.assertTrue(np.allclose([0, 3.3], stru.B33)) + self.assertTrue(np.allclose([0, 0.12], stru.B12)) + self.assertTrue(np.allclose([0, 0.13], stru.B13)) + self.assertTrue(np.allclose([0, 0.23], stru.B23)) stru.B11 = stru.B22 = stru.B33 = stru.B12 = stru.B13 = stru.B23 = 0.0 - self.assertFalse(numpy.any(stru.U != 0.0)) + self.assertFalse(np.any(stru.U != 0.0)) return def test_pickling(self): @@ -622,7 +622,7 @@ def test_get_fractional_coordinates(datafile): """Check Structure.get_fractional_coordinates()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) actual_fractional_coords = pbte_stru.get_fractional_coordinates() - expected_fractional_coords = numpy.array( + expected_fractional_coords = np.array( [ [0.5, 0.5, 0.5], [0.5, 0.0, 0.0], @@ -634,14 +634,14 @@ def test_get_fractional_coordinates(datafile): [0.5, 0.5, 0.0], ] ) - assert numpy.allclose(actual_fractional_coords, expected_fractional_coords) + assert np.allclose(actual_fractional_coords, expected_fractional_coords) def test_get_cartesian_coordinates(datafile): """Check Structure.get_cartesian_coordinates()""" cdse_stru = Structure(filename=datafile("CdSe_bulk.stru")) actual_cartesian_coords = cdse_stru.get_cartesian_coordinates() - expected_cartesian_coords = numpy.array( + expected_cartesian_coords = np.array( [ [1.22284264, 2.11760202, 0.0], [2.44495161, 0.0, 3.4530135], @@ -649,57 +649,193 @@ def test_get_cartesian_coordinates(datafile): [2.44495161, 0.0, 6.05430669], ] ) - assert numpy.allclose(actual_cartesian_coords, expected_cartesian_coords, atol=1e-6) + assert np.allclose(actual_cartesian_coords, expected_cartesian_coords, atol=1e-6) -def test_get_anisotropic_displacement_parameters(datafile): +@pytest.mark.parametrize( + "return_array", + [ # case: user wants ADPs as an array + # expected: a 3D array of shape (num_atoms, 3, 3) with the Uij values + True, + # case: user wants ADPs as a dictionary + # expected: a dictionary with keys like "I_8_11" and values as the corresponding Uij values + False, + ], +) +def test_get_anisotropic_displacement_parameters(datafile, return_array): """Check Structure.get_anisotropic_displacement_parameters()""" tei_stru = Structure(filename=datafile("TeI.cif")) - actual_displacement = tei_stru.get_anisotropic_displacement_parameters() - expected_one_atom = numpy.array( - [ - [[0.0211, 0.0, 0.0109], [0.0, 0.0195, 0.0], [0.0109, 0.0, 0.016]], - [[0.0223, 0.0, 0.0179], [0.0, 0.018, 0.0], [0.0179, 0.0, 0.0254]], - [[0.025, 0.0, 0.0226], [0.0, 0.0234, 0.0], [0.0226, 0.0, 0.0345]], - [[0.0234, 0.0, 0.0138], [0.0, 0.0295, 0.0], [0.0138, 0.0, 0.0253]], - ] - ) - expected_displacement = numpy.repeat(expected_one_atom, 4, axis=0) - assert numpy.allclose(actual_displacement, expected_displacement) + actual_displacement = tei_stru.get_anisotropic_displacement_parameters(return_array=return_array) + if return_array: + expected_one_atom = np.array( + [ + [[0.0211, 0.0, 0.0109], [0.0, 0.0195, 0.0], [0.0109, 0.0, 0.016]], + [[0.0223, 0.0, 0.0179], [0.0, 0.018, 0.0], [0.0179, 0.0, 0.0254]], + [[0.025, 0.0, 0.0226], [0.0, 0.0234, 0.0], [0.0226, 0.0, 0.0345]], + [[0.0234, 0.0, 0.0138], [0.0, 0.0295, 0.0], [0.0138, 0.0, 0.0253]], + ] + ) + expected_displacement = np.repeat(expected_one_atom, 4, axis=0) + assert np.allclose(actual_displacement, expected_displacement) + else: + expected_displacement = { + # Iodine + "I_8_11": np.float64(0.025), + "I_8_12": np.float64(0.0), + "I_8_13": np.float64(0.0226), + "I_8_22": np.float64(0.0234), + "I_8_23": np.float64(0.0), + "I_8_33": np.float64(0.0345), + "I_9_11": np.float64(0.025), + "I_9_12": np.float64(0.0), + "I_9_13": np.float64(0.0226), + "I_9_22": np.float64(0.0234), + "I_9_23": np.float64(0.0), + "I_9_33": np.float64(0.0345), + "I_10_11": np.float64(0.025), + "I_10_12": np.float64(0.0), + "I_10_13": np.float64(0.0226), + "I_10_22": np.float64(0.0234), + "I_10_23": np.float64(0.0), + "I_10_33": np.float64(0.0345), + "I_11_11": np.float64(0.025), + "I_11_12": np.float64(0.0), + "I_11_13": np.float64(0.0226), + "I_11_22": np.float64(0.0234), + "I_11_23": np.float64(0.0), + "I_11_33": np.float64(0.0345), + "I_12_11": np.float64(0.0234), + "I_12_12": np.float64(0.0), + "I_12_13": np.float64(0.0138), + "I_12_22": np.float64(0.0295), + "I_12_23": np.float64(0.0), + "I_12_33": np.float64(0.0253), + "I_13_11": np.float64(0.0234), + "I_13_12": np.float64(0.0), + "I_13_13": np.float64(0.0138), + "I_13_22": np.float64(0.0295), + "I_13_23": np.float64(0.0), + "I_13_33": np.float64(0.0253), + "I_14_11": np.float64(0.0234), + "I_14_12": np.float64(0.0), + "I_14_13": np.float64(0.0138), + "I_14_22": np.float64(0.0295), + "I_14_23": np.float64(0.0), + "I_14_33": np.float64(0.0253), + "I_15_11": np.float64(0.0234), + "I_15_12": np.float64(0.0), + "I_15_13": np.float64(0.0138), + "I_15_22": np.float64(0.0295), + "I_15_23": np.float64(0.0), + "I_15_33": np.float64(0.0253), + # Tellurium + "Te_0_11": np.float64(0.0211), + "Te_0_12": np.float64(0.0), + "Te_0_13": np.float64(0.0109), + "Te_0_22": np.float64(0.0195), + "Te_0_23": np.float64(0.0), + "Te_0_33": np.float64(0.016), + "Te_1_11": np.float64(0.0211), + "Te_1_12": np.float64(0.0), + "Te_1_13": np.float64(0.0109), + "Te_1_22": np.float64(0.0195), + "Te_1_23": np.float64(0.0), + "Te_1_33": np.float64(0.016), + "Te_2_11": np.float64(0.0211), + "Te_2_12": np.float64(0.0), + "Te_2_13": np.float64(0.0109), + "Te_2_22": np.float64(0.0195), + "Te_2_23": np.float64(0.0), + "Te_2_33": np.float64(0.016), + "Te_3_11": np.float64(0.0211), + "Te_3_12": np.float64(0.0), + "Te_3_13": np.float64(0.0109), + "Te_3_22": np.float64(0.0195), + "Te_3_23": np.float64(0.0), + "Te_3_33": np.float64(0.016), + "Te_4_11": np.float64(0.0223), + "Te_4_12": np.float64(0.0), + "Te_4_13": np.float64(0.0179), + "Te_4_22": np.float64(0.018), + "Te_4_23": np.float64(0.0), + "Te_4_33": np.float64(0.0254), + "Te_5_11": np.float64(0.0223), + "Te_5_12": np.float64(0.0), + "Te_5_13": np.float64(0.0179), + "Te_5_22": np.float64(0.018), + "Te_5_23": np.float64(0.0), + "Te_5_33": np.float64(0.0254), + "Te_6_11": np.float64(0.0223), + "Te_6_12": np.float64(0.0), + "Te_6_13": np.float64(0.0179), + "Te_6_22": np.float64(0.018), + "Te_6_23": np.float64(0.0), + "Te_6_33": np.float64(0.0254), + "Te_7_11": np.float64(0.0223), + "Te_7_12": np.float64(0.0), + "Te_7_13": np.float64(0.0179), + "Te_7_22": np.float64(0.018), + "Te_7_23": np.float64(0.0), + "Te_7_33": np.float64(0.0254), + } + assert actual_displacement == expected_displacement -def test_get_isotropic_displacement_parameters(datafile): +@pytest.mark.parametrize( + "return_array", + [ # case: user wants isotropic displacement parameters as an array + # expected: a 1D array of shape (num_atoms,) with the Uiso values + True, + # case: user wants isotropic displacement parameters as a dictionary + # expected: a dictionary with keys like "I_Uiso" and values as the corresponding Uiso values + False, + ], +) +def test_get_isotropic_displacement_parameters(datafile, return_array): """Check Structure.get_isotropic_displacement_parameters()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) - actual_isotropic_displacement = pbte_stru.get_isotropic_displacement_parameters() - expected_isotropic_displacement = numpy.array( - [0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528] - ) - assert numpy.allclose(actual_isotropic_displacement, expected_isotropic_displacement) + actual_isotropic_displacement = pbte_stru.get_isotropic_displacement_parameters(return_array=return_array) + if return_array: + expected_isotropic_displacement = np.array( + [0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528] + ) + assert np.allclose(actual_isotropic_displacement, expected_isotropic_displacement) + else: + expected_isotropic_displacement = { + "Pb_1_Uiso": np.float64(0.0225566), + "Pb_2_Uiso": np.float64(0.0225566), + "Pb_3_Uiso": np.float64(0.0225566), + "Pb_4_Uiso": np.float64(0.0225566), + "Te_5_Uiso": np.float64(0.0155528), + "Te_6_Uiso": np.float64(0.0155528), + "Te_7_Uiso": np.float64(0.0155528), + "Te_8_Uiso": np.float64(0.0155528), + } + assert actual_isotropic_displacement == expected_isotropic_displacement def test_get_occupancies(datafile): """Check Structure.get_occupancies()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) actual_occupancies = pbte_stru.get_occupancies() - expected_occupancies = numpy.ones(8) - assert numpy.allclose(actual_occupancies, expected_occupancies) + expected_occupancies = np.ones(8) + assert np.allclose(actual_occupancies, expected_occupancies) def test_get_lattice_vectors(datafile): """Check Structure.get_lattice_vectors()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) actual_lattice_vectors = pbte_stru.get_lattice_vectors() - expected_lattice_vectors = numpy.array([[6.461, 0.0, 0.0], [0.0, 6.461, 0.0], [0.0, 0.0, 6.461]]) - assert numpy.allclose(actual_lattice_vectors, expected_lattice_vectors) + expected_lattice_vectors = np.array([[6.461, 0.0, 0.0], [0.0, 6.461, 0.0], [0.0, 0.0, 6.461]]) + assert np.allclose(actual_lattice_vectors, expected_lattice_vectors) def test_get_lattice_vector_angles(datafile): """Check Structure.get_lattice_vector_angles()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) actual_lattice_vector_angles = pbte_stru.get_lattice_vector_angles() - expected_lattice_vector_angles = numpy.array([90.0, 90.0, 90.0]) - assert numpy.allclose(actual_lattice_vector_angles, expected_lattice_vector_angles) + expected_lattice_vector_angles = np.array([90.0, 90.0, 90.0]) + assert np.allclose(actual_lattice_vector_angles, expected_lattice_vector_angles) @pytest.mark.parametrize( @@ -738,16 +874,16 @@ def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_dif lost_info_dict = actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info="get_masses") actual_masses = lost_info_dict["get_masses"] expected_masses = ase_zb.get_masses() - assert numpy.allclose(actual_masses, expected_masses) + assert np.allclose(actual_masses, expected_masses) # Compare the actual and expected values expected_lattice_vectors = expected_structure.get_lattice_vectors() actual_lattice_vectors = actual_structure.get_lattice_vectors() - assert numpy.allclose(expected_lattice_vectors, actual_lattice_vectors) + assert np.allclose(expected_lattice_vectors, actual_lattice_vectors) expected_lattice_angle = expected_structure.get_lattice_vector_angles() actual_lattice_angle = actual_structure.get_lattice_vector_angles() - assert numpy.allclose(expected_lattice_angle, actual_lattice_angle) + assert np.allclose(expected_lattice_angle, actual_lattice_angle) expected_symbols = expected_structure.get_chemical_symbols() actual_symbols = actual_structure.get_chemical_symbols() @@ -755,7 +891,7 @@ def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_dif expected_coords = expected_structure.get_fractional_coordinates() actual_coords = actual_structure.get_fractional_coordinates() - assert numpy.allclose(actual_coords, expected_coords) + assert np.allclose(actual_coords, expected_coords) def test_convert_ase_to_diffpy_structure_bad_typeerror(): From 009b5be8066f8dd6c66cbadf5262d53133f95a0d Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Mar 2026 15:17:51 -0400 Subject: [PATCH 205/226] feat: add parser for vesta files and vesta app viewer. --- .codespell/ignore_words.txt | 4 + news/vesta_view.rst | 23 ++ src/diffpy/structure/apps/vesta_viewer.py | 377 +++++++++++++++++ src/diffpy/structure/parsers/p_vesta.py | 474 ++++++++++++++++++++++ src/diffpy/structure/parsers/p_xcfg.py | 2 +- 5 files changed, 879 insertions(+), 1 deletion(-) create mode 100644 news/vesta_view.rst create mode 100644 src/diffpy/structure/apps/vesta_viewer.py create mode 100644 src/diffpy/structure/parsers/p_vesta.py diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt index e2ee211b..eccf37a8 100644 --- a/.codespell/ignore_words.txt +++ b/.codespell/ignore_words.txt @@ -22,3 +22,7 @@ CONECT ;; /src/diffpy/structure/parsers/p_xcfg.py:452 ;; used in a function BU + +;; /src/diffpy/structure/parsers/p_vesta.py:452 +;; abbreviation for Structure in vesta +STRUC diff --git a/news/vesta_view.rst b/news/vesta_view.rst new file mode 100644 index 00000000..b8564ee6 --- /dev/null +++ b/news/vesta_view.rst @@ -0,0 +1,23 @@ +**Added:** + +* Added parser for vesta specific files and viewer for vesta + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/apps/vesta_viewer.py b/src/diffpy/structure/apps/vesta_viewer.py new file mode 100644 index 00000000..9b53f06e --- /dev/null +++ b/src/diffpy/structure/apps/vesta_viewer.py @@ -0,0 +1,377 @@ +#!/usr/bin/env python +############################################################################## +# +# diffpy.structure by DANSE Diffraction group +# Simon J. L. Billinge +# (c) 2006 trustees of the Michigan State University. +# All rights reserved. +# +# File coded by: Pavol Juhas +# +# See AUTHORS.txt for a list of people who contributed. +# See LICENSE_DANSE.txt for license information. +# +############################################################################## +"""View structure file in VESTA. + +Usage: ``vestaview [options] strufile`` + +Vestaview understands more `Structure` formats than VESTA. It converts +`strufile` to a temporary VESTA or CIF file which is opened in VESTA. +See supported file formats: ``inputFormats`` + +Options: + -f, --formula + Override chemical formula in `strufile`. The formula defines + elements in the same order as in `strufile`, e.g., ``Na4Cl4``. + + -w, --watch + Watch input file for changes. + + --viewer=VIEWER + The structure viewer program, by default "vesta". + The program will be executed as "VIEWER structurefile". + + --formats=FORMATS + Comma-separated list of file formats that are understood + by the VIEWER, by default ``"vesta,cif"``. Files of other + formats will be converted to the first listed format. + + -h, --help + Display this message and exit. + + -V, --version + Show script version and exit. + +Notes +----- +VESTA is the actively maintained successor to AtomEye. Unlike AtomEye, +VESTA natively reads CIF, its own ``.vesta`` format, and several other +crystallographic file types, so format conversion is only required for +formats not in that set. + +AtomEye XCFG format is no longer a default target format but the XCFG +parser (``P_xcfg``) remains available in ``diffpy.structure.parsers`` +for backward compatibility. +""" + +from __future__ import print_function + +import os +import re +import signal +import sys + +from diffpy.structure.structureerrors import StructureFormatError + +pd = { + "formula": None, + "watch": False, + "viewer": "vesta", + "formats": ["vesta", "cif"], +} + + +def usage(style=None): + """Show usage info; for ``style=="brief"`` show only first 2 + lines.""" + import os.path + + myname = os.path.basename(sys.argv[0]) + msg = __doc__.replace("vestaview", myname) + if style == "brief": + msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname + else: + from diffpy.structure.parsers import input_formats + + fmts = [f for f in input_formats() if f != "auto"] + msg = msg.replace("inputFormats", " ".join(fmts)) + print(msg) + return + + +def version(): + from diffpy.structure import __version__ + + print("vestaview", __version__) + return + + +def load_structure_file(filename, format="auto"): + """Load structure from specified file. + + Parameters + ---------- + filename : str + Path to the structure file. + format : str, optional + File format, by default "auto". + + Returns + ------- + tuple + A tuple of (Structure, fileformat). + """ + from diffpy.structure import Structure + + stru = Structure() + p = stru.read(filename, format) + fileformat = p.format + return (stru, fileformat) + + +def convert_structure_file(pd): + """Convert `strufile` to a temporary file understood by the viewer. + + On first call a temporary directory is created and stored in *pd*. + Subsequent calls in watch mode reuse the directory. + + The VESTA viewer natively reads ``.vesta`` and ``.cif`` files, so if + the source is already in one of the formats listed in ``pd["formats"]`` + and no formula override is requested the file is copied unchanged. + Otherwise the structure is loaded and re-written in the first format + listed in ``pd["formats"]``. + + Parameters + ---------- + pd : dict + Parameter dictionary containing at minimum ``"strufile"`` and + ``"formats"`` keys. Modified in-place to add ``"tmpdir"`` and + ``"tmpfile"`` on first call. + """ + # Make temporary directory on the first pass. + if "tmpdir" not in pd: + from tempfile import mkdtemp + + pd["tmpdir"] = mkdtemp() + strufile = pd["strufile"] + tmpfile = os.path.join(pd["tmpdir"], os.path.basename(strufile)) + pd["tmpfile"] = tmpfile + # Speed up file processing in the watch mode by caching format. + fmt = pd.get("format", "auto") + stru = None + if fmt == "auto": + stru, fmt = load_structure_file(strufile) + pd["fmt"] = fmt + # If fmt is already recognised by the viewer and no override, copy as-is. + if fmt in pd["formats"] and pd["formula"] is None: + import shutil + + shutil.copyfile(strufile, tmpfile + ".tmp") + os.rename(tmpfile + ".tmp", tmpfile) + return + # Otherwise convert to the first viewer-recognised format. + if stru is None: + stru = load_structure_file(strufile, fmt)[0] + if pd["formula"]: + formula = pd["formula"] + if len(formula) != len(stru): + emsg = "Formula has %i atoms while structure %i" % ( + len(formula), + len(stru), + ) + raise RuntimeError(emsg) + for a, el in zip(stru, formula): + a.element = el + elif fmt == "rawxyz": + for a in stru: + if a.element == "": + a.element = "C" + stru.write(tmpfile + ".tmp", pd["formats"][0]) + os.rename(tmpfile + ".tmp", tmpfile) + return + + +def watch_structure_file(pd): + """Watch *strufile* for modifications and reconvert when changed. + + Polls the modification timestamps of ``pd["strufile"]`` and + ``pd["tmpfile"]`` once per second. When the source is newer the + file is reconverted via :func:`convert_structure_file`. + + Parameters + ---------- + pd : dict + Parameter dictionary as used by :func:`convert_structure_file`. + """ + from time import sleep + + strufile = pd["strufile"] + tmpfile = pd["tmpfile"] + while pd["watch"]: + if os.path.getmtime(tmpfile) < os.path.getmtime(strufile): + convert_structure_file(pd) + sleep(1) + return + + +def clean_up(pd): + """Remove temporary file and directory created by + :func:`convert_structure_file`. + + Parameters + ---------- + pd : dict + Parameter dictionary that may contain ``"tmpfile"`` and + ``"tmpdir"`` entries to be removed. + """ + if "tmpfile" in pd: + os.remove(pd["tmpfile"]) + del pd["tmpfile"] + if "tmpdir" in pd: + os.rmdir(pd["tmpdir"]) + del pd["tmpdir"] + return + + +def parse_formula(formula): + """Parse chemical formula and return a list of elements. + + Parameters + ---------- + formula : str + Chemical formula string such as ``"Na4Cl4"`` or ``"H2O"``. + + Returns + ------- + list of str + Ordered list of element symbols with repetition matching the + formula, e.g. ``["Na", "Na", "Na", "Na", "Cl", "Cl", "Cl", "Cl"]``. + + Raises + ------ + RuntimeError + When *formula* does not start with an uppercase letter or contains + a non-integer count. + """ + # Remove all whitespace. + formula = re.sub(r"\s", "", formula) + if not re.match("^[A-Z]", formula): + raise RuntimeError("InvalidFormula '%s'" % formula) + elcnt = re.split("([A-Z][a-z]?)", formula)[1:] + ellst = [] + try: + for i in range(0, len(elcnt), 2): + el = elcnt[i] + cnt = elcnt[i + 1] + cnt = (cnt == "") and 1 or int(cnt) + ellst.extend(cnt * [el]) + except ValueError: + emsg = "Invalid formula, %r is not valid count" % elcnt[i + 1] + raise RuntimeError(emsg) + return ellst + + +def die(exit_status=0, pd={}): + """Clean up temporary files and exit with *exit_status*. + + Parameters + ---------- + exit_status : int, optional + Exit code passed to :func:`sys.exit`, by default 0. + pd : dict, optional + Parameter dictionary forwarded to :func:`clean_up`. + """ + clean_up(pd) + sys.exit(exit_status) + + +def signal_handler(signum, stackframe): + """Handle OS signals by reverting to the default handler and + exiting. + + On ``SIGCHLD`` the child exit status is harvested via + :func:`os.wait`; on all other signals :func:`die` is called with + exit status 1. + + Parameters + ---------- + signum : int + Signal number. + stackframe : frame + Current stack frame (unused). + """ + # Revert to default handler before acting to avoid re-entrancy. + signal.signal(signum, signal.SIG_DFL) + if signum == signal.SIGCHLD: + pid, exit_status = os.wait() + exit_status = (exit_status >> 8) + (exit_status & 0x00FF) + die(exit_status, pd) + else: + die(1, pd) + return + + +def main(): + """Entry point for the ``vestaview`` command-line tool.""" + import getopt + + # Reset to defaults each invocation. + pd["watch"] = False + try: + opts, args = getopt.getopt( + sys.argv[1:], + "f:whV", + ["formula=", "watch", "viewer=", "formats=", "help", "version"], + ) + except getopt.GetoptError as errmsg: + print(errmsg, file=sys.stderr) + die(2) + # Process options. + for o, a in opts: + if o in ("-f", "--formula"): + try: + pd["formula"] = parse_formula(a) + except RuntimeError as msg: + print(msg, file=sys.stderr) + die(2) + elif o in ("-w", "--watch"): + pd["watch"] = True + elif o == "--viewer": + pd["viewer"] = a + elif o == "--formats": + pd["formats"] = [w.strip() for w in a.split(",")] + elif o in ("-h", "--help"): + usage() + die() + elif o in ("-V", "--version"): + version() + die() + if len(args) < 1: + usage("brief") + die() + elif len(args) > 1: + print("too many structure files", file=sys.stderr) + die(2) + pd["strufile"] = args[0] + # Trap the following signals. + signal.signal(signal.SIGHUP, signal_handler) + signal.signal(signal.SIGQUIT, signal_handler) + signal.signal(signal.SIGSEGV, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + signal.signal(signal.SIGINT, signal_handler) + env = os.environ.copy() + # VESTA does not require the XLIB_SKIP_ARGB_VISUALS workaround that + # AtomEye needed; this block is intentionally omitted. + # Try to run the viewer: + try: + convert_structure_file(pd) + spawnargs = (pd["viewer"], pd["viewer"], pd["tmpfile"], env) + if pd["watch"]: + signal.signal(signal.SIGCHLD, signal_handler) + os.spawnlpe(os.P_NOWAIT, *spawnargs) + watch_structure_file(pd) + else: + status = os.spawnlpe(os.P_WAIT, *spawnargs) + die(status, pd) + except IOError as e: + print("%s: %s" % (args[0], e.strerror), file=sys.stderr) + die(1, pd) + except StructureFormatError as e: + print("%s: %s" % (args[0], e), file=sys.stderr) + die(1, pd) + return + + +if __name__ == "__main__": + main() diff --git a/src/diffpy/structure/parsers/p_vesta.py b/src/diffpy/structure/parsers/p_vesta.py new file mode 100644 index 00000000..5ec03481 --- /dev/null +++ b/src/diffpy/structure/parsers/p_vesta.py @@ -0,0 +1,474 @@ +#!/usr/bin/env python +############################################################################## +# +# diffpy.structure by DANSE Diffraction group +# Simon J. L. Billinge +# (c) 2007 trustees of the Michigan State University. +# All rights reserved. +# +# File coded by: Pavol Juhas +# +# See AUTHORS.txt for a list of people who contributed. +# See LICENSE_DANSE.txt for license information. +# +############################################################################## +"""Parser for VESTA format used by VESTA (Visualization for Electronic +and Structural Analysis). + +This module replaces the AtomEye XCFG parser (P_xcfg). The XCFG parser and +all its original attributes are preserved for backward compatibility. +VESTA is the actively maintained successor viewer. + +Attributes +---------- +AtomicMass : dict + Dictionary of atomic masses for elements. +""" + +import sys + +import numpy + +from diffpy.structure import Structure +from diffpy.structure.parsers import StructureParser +from diffpy.structure.structureerrors import StructureFormatError + +# Constants ------------------------------------------------------------------ + +# Atomic Mass of elements +# This can be later when PeriodicTable package becomes available. + +AtomicMass = { + "H": 1.007947, # 1 H hydrogen 1.007947 + "He": 4.0026022, # 2 He helium 4.0026022 + "Li": 6.9412, # 3 Li lithium 6.9412 + "Be": 9.0121823, # 4 Be beryllium 9.0121823 + "B": 10.8117, # 5 B boron 10.8117 + "C": 12.01078, # 6 C carbon 12.01078 + "N": 14.00672, # 7 N nitrogen 14.00672 + "O": 15.99943, # 8 O oxygen 15.99943 + "F": 18.99840325, # 9 F fluorine 18.99840325 + "Ne": 20.17976, # 10 Ne neon 20.17976 + "Na": 22.9897702, # 11 Na sodium 22.9897702 + "Mg": 24.30506, # 12 Mg magnesium 24.30506 + "Al": 26.9815382, # 13 Al aluminium 26.9815382 + "Si": 28.08553, # 14 Si silicon 28.08553 + "P": 30.9737612, # 15 P phosphorus 30.9737612 + "S": 32.0655, # 16 S sulfur 32.0655 + "Cl": 35.4532, # 17 Cl chlorine 35.4532 + "Ar": 39.9481, # 18 Ar argon 39.9481 + "K": 39.09831, # 19 K potassium 39.09831 + "Ca": 40.0784, # 20 Ca calcium 40.0784 + "Sc": 44.9559108, # 21 Sc scandium 44.9559108 + "Ti": 47.8671, # 22 Ti titanium 47.8671 + "V": 50.94151, # 23 V vanadium 50.94151 + "Cr": 51.99616, # 24 Cr chromium 51.99616 + "Mn": 54.9380499, # 25 Mn manganese 54.9380499 + "Fe": 55.8452, # 26 Fe iron 55.8452 + "Co": 58.9332009, # 27 Co cobalt 58.9332009 + "Ni": 58.69342, # 28 Ni nickel 58.69342 + "Cu": 63.5463, # 29 Cu copper 63.5463 + "Zn": 65.4094, # 30 Zn zinc 65.4094 + "Ga": 69.7231, # 31 Ga gallium 69.7231 + "Ge": 72.641, # 32 Ge germanium 72.641 + "As": 74.921602, # 33 As arsenic 74.921602 + "Se": 78.963, # 34 Se selenium 78.963 + "Br": 79.9041, # 35 Br bromine 79.9041 + "Kr": 83.7982, # 36 Kr krypton 83.7982 + "Rb": 85.46783, # 37 Rb rubidium 85.46783 + "Sr": 87.621, # 38 Sr strontium 87.621 + "Y": 88.905852, # 39 Y yttrium 88.905852 + "Zr": 91.2242, # 40 Zr zirconium 91.2242 + "Nb": 92.906382, # 41 Nb niobium 92.906382 + "Mo": 95.942, # 42 Mo molybdenum 95.942 + "Tc": 98.0, # 43 Tc technetium 98 + "Ru": 101.072, # 44 Ru ruthenium 101.072 + "Rh": 102.905502, # 45 Rh rhodium 102.905502 + "Pd": 106.421, # 46 Pd palladium 106.421 + "Ag": 107.86822, # 47 Ag silver 107.86822 + "Cd": 112.4118, # 48 Cd cadmium 112.4118 + "In": 114.8183, # 49 In indium 114.8183 + "Sn": 118.7107, # 50 Sn tin 118.7107 + "Sb": 121.7601, # 51 Sb antimony 121.7601 + "Te": 127.603, # 52 Te tellurium 127.603 + "I": 126.904473, # 53 I iodine 126.904473 + "Xe": 131.2936, # 54 Xe xenon 131.2936 + "Cs": 132.905452, # 55 Cs caesium 132.905452 + "Ba": 137.3277, # 56 Ba barium 137.3277 + "La": 138.90552, # 57 La lanthanum 138.90552 + "Ce": 140.1161, # 58 Ce cerium 140.1161 + "Pr": 140.907652, # 59 Pr praseodymium 140.907652 + "Nd": 144.243, # 60 Nd neodymium 144.243 + "Pm": 145.0, # 61 Pm promethium 145 + "Sm": 150.363, # 62 Sm samarium 150.363 + "Eu": 151.9641, # 63 Eu europium 151.9641 + "Gd": 157.253, # 64 Gd gadolinium 157.253 + "Tb": 158.925342, # 65 Tb terbium 158.925342 + "Dy": 162.5001, # 66 Dy dysprosium 162.5001 + "Ho": 164.930322, # 67 Ho holmium 164.930322 + "Er": 167.2593, # 68 Er erbium 167.2593 + "Tm": 168.934212, # 69 Tm thulium 168.934212 + "Yb": 173.043, # 70 Yb ytterbium 173.043 + "Lu": 174.9671, # 71 Lu lutetium 174.9671 + "Hf": 178.492, # 72 Hf hafnium 178.492 + "Ta": 180.94791, # 73 Ta tantalum 180.94791 + "W": 183.841, # 74 W tungsten 183.841 + "Re": 186.2071, # 75 Re rhenium 186.2071 + "Os": 190.233, # 76 Os osmium 190.233 + "Ir": 192.2173, # 77 Ir iridium 192.2173 + "Pt": 195.0782, # 78 Pt platinum 195.0782 + "Au": 196.966552, # 79 Au gold 196.966552 + "Hg": 200.592, # 80 Hg mercury 200.592 + "Tl": 204.38332, # 81 Tl thallium 204.38332 + "Pb": 207.21, # 82 Pb lead 207.21 + "Bi": 208.980382, # 83 Bi bismuth 208.980382 + "Po": 209.0, # 84 Po polonium 209 + "At": 210.0, # 85 At astatine 210 + "Rn": 222.0, # 86 Rn radon 222 + "Fr": 223.0, # 87 Fr francium 223 + "Ra": 226.0, # 88 Ra radium 226 + "Ac": 227.0, # 89 Ac actinium 227 + "Th": 232.03811, # 90 Th thorium 232.03811 + "Pa": 231.035882, # 91 Pa protactinium 231.035882 + "U": 238.028913, # 92 U uranium 238.028913 + "Np": 237.0, # 93 Np neptunium 237 + "Pu": 244.0, # 94 Pu plutonium 244 + "Am": 243.0, # 95 Am americium 243 + "Cm": 247.0, # 96 Cm curium 247 + "Bk": 247.0, # 97 Bk berkelium 247 + "Cf": 251.0, # 98 Cf californium 251 + "Es": 252.0, # 99 Es einsteinium 252 + "Fm": 257.0, # 100 Fm fermium 257 + "Md": 258.0, # 101 Md mendelevium 258 + "No": 259.0, # 102 No nobelium 259 + "Lr": 262.0, # 103 Lr lawrencium 262 + "Rf": 261.0, # 104 Rf rutherfordium 261 + "Db": 262.0, # 105 Db dubnium 262 + "Sg": 266.0, # 106 Sg seaborgium 266 + "Bh": 264.0, # 107 Bh bohrium 264 + "Hs": 277.0, # 108 Hs hassium 277 + "Mt": 268.0, # 109 Mt meitnerium 268 + "Ds": 281.0, # 110 Ds darmstadtium 281 + "Rg": 272.0, # 111 Rg roentgenium 272 +} + + +class P_vesta(StructureParser): + """Parser for VESTA native structure format (.vesta). + + VESTA (Visualization for Electronic and Structural Analysis) is the + actively maintained successor to AtomEye. This parser writes the + native VESTA format understood by VESTA 3.x and later. + + Attributes + ---------- + format : str + Format name, default "vesta". + + Notes + ----- + The ``cluster_boundary`` attribute is retained from the original + AtomEye/XCFG parser for API compatibility; it is not used by VESTA + because VESTA handles periodicity natively. + """ + + cluster_boundary = 2 + """int: Width of boundary around corners of non-periodic cluster. + Retained from the original AtomEye/XCFG parser for API compatibility. + VESTA handles periodicity natively so this value has no effect on output. + """ + + def __init__(self): + StructureParser.__init__(self) + self.format = "vesta" + return + + def parse_lines(self, lines): + """Parse list of lines in VESTA format. + + Reads the ``STRUC``, ``ATOMT``, and ``COORD`` sections of a + ``.vesta`` file to reconstruct a :class:`~diffpy.structure.Structure`. + + Parameters + ---------- + lines : list of str + Lines of a VESTA format file. + + Returns + ------- + Structure + Parsed structure instance. + + Raises + ------ + StructureFormatError + When the file does not conform to the VESTA format. + """ + stru = Structure() + p_nl = 0 + + # Strip trailing blank lines for a clean iteration boundary. + stop = len(lines) + for line in reversed(lines): + if line.strip(): + break + stop -= 1 + ilines = iter(lines[:stop]) + + try: + # Lattice parameters parsed from STRUC block: + # a b c alpha beta gamma + latt_abc = None + latt_abg = None + atom_types = {} + + # Raw fractional coordinates collected from COORD block: + # list of (atom_type_index, x, y, z, occupancy) + raw_coords = [] + + section = None # tracks current block keyword + + for line in ilines: + p_nl += 1 + stripped = line.strip() + if not stripped or stripped.startswith("#"): + continue + + # Detect section transitions. + upper = stripped.split()[0].upper() + if upper in ( + "CRYSTAL", + "TITLE", + "GROUP", + "STRUC", + "ATOMT", + "COORD", + "BOUND", + "SBOND", + "VECTR", + "VECTS", + "STYLE", + "SCENE", + "EOF", + ): + section = upper + continue + + # ---- STRUC section: lattice parameters ----------------- + if section == "STRUC": + words = stripped.split() + # First data line: a b c alpha beta gamma space_group + if latt_abc is None and len(words) >= 6: + try: + latt_abc = [float(w) for w in words[:3]] + latt_abg = [float(w) for w in words[3:6]] + except ValueError: + pass + continue + + # ---- ATOMT section: atom-type definitions --------------- + if section == "ATOMT": + # Format: index Symbol radius r g b ... + words = stripped.split() + if len(words) >= 2: + try: + idx = int(words[0]) + symbol = words[1] + atom_types[idx] = symbol + except ValueError: + pass + continue + + # ---- COORD section: atomic coordinates ----------------- + if section == "COORD": + # Format: seq type_index x y z occupancy ... + words = stripped.split() + if len(words) >= 6: + try: + type_idx = int(words[1]) + x, y, z = float(words[2]), float(words[3]), float(words[4]) + occ = float(words[5]) + raw_coords.append((type_idx, x, y, z, occ)) + except ValueError: + pass + continue + if latt_abc is None: + emsg = "VESTA file is missing STRUC lattice parameters" + raise StructureFormatError(emsg) + + stru.lattice.setLatPar( + a=latt_abc[0], + b=latt_abc[1], + c=latt_abc[2], + alpha=latt_abg[0], + beta=latt_abg[1], + gamma=latt_abg[2], + ) + + for type_idx, x, y, z, occ in raw_coords: + element = atom_types.get(type_idx, "X") + stru.add_new_atom(element, xyz=[x, y, z]) + stru[-1].occupancy = occ + + except (ValueError, IndexError): + emsg = "%d: file is not in VESTA format" % p_nl + exc_type, exc_value, exc_traceback = sys.exc_info() + e = StructureFormatError(emsg) + raise e.with_traceback(exc_traceback) + + return stru + + def to_lines(self, stru): + """Convert Structure *stru* to a list of lines in VESTA format. + + Produces a ``.vesta`` file readable by VESTA 3.x and later, + containing ``STRUC``, ``ATOMT``, and ``COORD`` sections derived + from the structure's lattice and atomic data. + + Parameters + ---------- + stru : Structure + Structure to be converted. + + Returns + ------- + list of str + Lines of a VESTA format file. + + Raises + ------ + StructureFormatError + Cannot convert empty structure to VESTA format. + """ + if len(stru) == 0: + emsg = "cannot convert empty structure to VESTA format" + raise StructureFormatError(emsg) + + lines = [] + lines.append("#VESTA_FORMAT_VERSION 3.5.0") + lines.append("") + lines.append("CRYSTAL") + lines.append("") + lines.append("TITLE") + title = getattr(stru, "title", "") or "Structure" + lines.append(title) + lines.append("") + latt = stru.lattice + a, b, c, alpha, beta, gamma = latt.cell_parms() + lines.append("STRUC") + # Line 1: a b c alpha beta gamma space_group_number + lines.append(" %.8g %.8g %.8g %.8g %.8g %.8g 1" % (a, b, c, alpha, beta, gamma)) + # Line 2: origin shift (0 0 0) followed by space-group symbol placeholder + lines.append(" 0.000000 0.000000 0.000000") + lines.append("") + element_order = [] + seen = set() + for a_obj in stru: + el = a_obj.element + if el not in seen: + seen.add(el) + element_order.append(el) + type_index = {el: i + 1 for i, el in enumerate(element_order)} + lines.append("ATOMT") + for el in element_order: + idx = type_index[el] + # Default ball radius 0.5; placeholder RGB 1.0 1.0 1.0. + lines.append(" %d %s %.4f 1.0000 1.0000 1.0000 204" % (idx, el, 0.5)) + lines.append("") + lines.append("COORD") + for seq, a_obj in enumerate(stru, start=1): + el = a_obj.element + tidx = type_index[el] + x, y, z = a_obj.xyz + occ = getattr(a_obj, "occupancy", 1.0) + # Isotropic displacement parameter (Uiso), defaulting to 0. + uiso = _get_uiso(a_obj) + lines.append(" %d %d %.8g %.8g %.8g %.4f %.4f" % (seq, tidx, x, y, z, occ, uiso)) + lines.append(" 0 0 0 0 0") + lines.append("") + lines.append("BOUND") + lines.append(" 0.0 1.0 0.0 1.0 0.0 1.0") + lines.append(" 0 0 0 0 0") + lines.append("") + lines.append("EOF") + return lines +# End of class P_vesta + +from diffpy.structure.parsers.P_xcfg import P_xcfg # noqa: E402, F401 + +# Routines ------------------------------------------------------------------- + + +def get_parser(): + """Return new parser object for VESTA format. + + Returns + ------- + P_vesta + Instance of :class:`P_vesta`. + """ + return P_vesta() + + +# Local Helpers -------------------------------------------------------------- + + +def _get_uiso(a): + """Return isotropic displacement parameter for atom *a*. + + Tries ``Uisoequiv`` first, then falls back to the mean of the + diagonal of the anisotropic U tensor, then to zero. + + Parameters + ---------- + a : Atom + Atom instance. + + Returns + ------- + float + Isotropic U value in Ų. + """ + if hasattr(a, "Uisoequiv"): + return float(a.Uisoequiv) + try: + return float(numpy.trace(a.U) / 3.0) + except Exception: + return 0.0 + + +def _assign_auxiliaries(a, fields, auxiliaries, no_velocity): + """Assign auxiliary properties for an + :class:`~diffpy.structure.Atom` object. + + Retained from the original AtomEye/XCFG parser for backward + compatibility with code that calls this helper directly. + + Parameters + ---------- + a : Atom + The Atom instance for which auxiliary properties need to be set. + fields : list + Floating-point values for the current row of the processed file. + auxiliaries : dict + Dictionary of zero-based indices and names of auxiliary properties. + no_velocity : bool + When ``False``, set atom velocity ``a.v`` to ``fields[3:6]``. + Use ``fields[3:6]`` for auxiliary values otherwise. + """ + if not no_velocity: + a.v = numpy.asarray(fields[3:6], dtype=float) + auxfirst = 3 if no_velocity else 6 + for i, prop in auxiliaries.items(): + value = fields[auxfirst + i] + if prop == "Uiso": + a.Uisoequiv = value + elif prop == "Biso": + a.Bisoequiv = value + elif prop[0] in "BU" and all(d in "123" for d in prop[1:]): + nm = prop if prop[1] <= prop[2] else prop[0] + prop[2] + prop[1] + a.anisotropy = True + setattr(a, nm, value) + else: + setattr(a, prop, value) + return diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index 7965767a..e94605c6 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -353,7 +353,7 @@ def to_lines(self, stru): lo_xyz = allxyz.min(axis=0) hi_xyz = allxyz.max(axis=0) max_range_xyz = (hi_xyz - lo_xyz).max() - if numpy.allclose(stru.lattice.abcABG(), (1, 1, 1, 90, 90, 90)): + if numpy.allclose(stru.lattice.cell_parms(), (1, 1, 1, 90, 90, 90)): max_range_xyz += self.cluster_boundary # range of CFG coordinates must be less than 1 p_A = numpy.ceil(max_range_xyz + 1.0e-13) From 05c0219ef0c3d2c10a6448f37ca88918babe4b13 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Tue, 24 Mar 2026 15:18:39 -0400 Subject: [PATCH 206/226] pre-commit auto-fix --- src/diffpy/structure/parsers/p_vesta.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/diffpy/structure/parsers/p_vesta.py b/src/diffpy/structure/parsers/p_vesta.py index 5ec03481..d677d1cb 100644 --- a/src/diffpy/structure/parsers/p_vesta.py +++ b/src/diffpy/structure/parsers/p_vesta.py @@ -392,6 +392,8 @@ def to_lines(self, stru): lines.append("") lines.append("EOF") return lines + + # End of class P_vesta from diffpy.structure.parsers.P_xcfg import P_xcfg # noqa: E402, F401 From cfae5833bd2a8cf23f4537969d70e3980d541a0b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Wed, 25 Mar 2026 11:24:10 -0400 Subject: [PATCH 207/226] fix minor bug in typeerror test --- src/diffpy/structure/structure.py | 10 ++++------ tests/test_structure.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index c418afe8..0b42344c 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -214,8 +214,7 @@ def get_cartesian_coordinates(self): return cartn_coords def get_anisotropic_displacement_parameters(self, return_array=False): - """Return a dictionary of anisotropic displacement parameters - for all atoms. + """Return the anisotropic displacement parameters for all atoms. Parameters ---------- @@ -244,8 +243,7 @@ def get_anisotropic_displacement_parameters(self, return_array=False): return adp_dict def get_isotropic_displacement_parameters(self, return_array=False): - """Return a dictionary of isotropic displacement parameters for - all atoms. + """Return a the isotropic displacement parameters for all atoms. Parameters ---------- @@ -368,7 +366,7 @@ def convert_ase_to_diffpy_structure( To extract additional information from the ASE `Atoms` object that is not directly represented in the `Structure` class, such as magnetic moments, you can specify an attribute or method of `ASE.Atoms` as - a list of strings in `lost_info` list. For example, + a string or list of strings in `lost_info` list. For example, .. code-block:: python lost_info = structure.convert_ase_to_diffpy( @@ -381,7 +379,7 @@ def convert_ase_to_diffpy_structure( # clear structure before populating it with new atoms del self[:] if not isinstance(ase_atoms, ASEAtoms): - raise TypeError(f"Input must be an instance of ase.Atoms but got type {ase_atoms}.") + raise TypeError(f"Input must be an instance of ase.Atoms but got type {type(ase_atoms)}.") cell = ase_atoms.get_cell() self.lattice = Lattice(base=numpy.array(cell)) symbols = ase_atoms.get_chemical_symbols() diff --git a/tests/test_structure.py b/tests/test_structure.py index 8d89b42a..aa6e6ca1 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -897,7 +897,7 @@ def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_dif def test_convert_ase_to_diffpy_structure_bad_typeerror(): """Check convert_ase_to_diffpy_structure() with bad input.""" bad_input = "string" # pass a string instead of ase.Atoms - expected_error_msg = "Input must be an instance of ase.Atoms but got type str." + expected_error_msg = "Input must be an instance of ase.Atoms but got type ." actual_structure = Structure() with pytest.raises(TypeError, match=expected_error_msg): actual_structure.convert_ase_to_diffpy_structure(bad_input) From 842b92a742229787d4dbfda330a6fa843567e5fe Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 26 Mar 2026 13:52:40 -0400 Subject: [PATCH 208/226] fix: change every os.path to Path() object and replace string to f-string. --- src/diffpy/structure/apps/vesta_viewer.py | 229 ++++++++++------------ src/diffpy/structure/parsers/p_vesta.py | 143 ++------------ 2 files changed, 130 insertions(+), 242 deletions(-) diff --git a/src/diffpy/structure/apps/vesta_viewer.py b/src/diffpy/structure/apps/vesta_viewer.py index 9b53f06e..b90ae0f4 100644 --- a/src/diffpy/structure/apps/vesta_viewer.py +++ b/src/diffpy/structure/apps/vesta_viewer.py @@ -3,10 +3,10 @@ # # diffpy.structure by DANSE Diffraction group # Simon J. L. Billinge -# (c) 2006 trustees of the Michigan State University. +# (c) 2026 University of California, Santa Barbara. # All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Simon J. L. Billinge, Rundong Hua # # See AUTHORS.txt for a list of people who contributed. # See LICENSE_DANSE.txt for license information. @@ -55,12 +55,11 @@ for backward compatibility. """ -from __future__ import print_function - import os import re import signal import sys +from pathlib import Path from diffpy.structure.structureerrors import StructureFormatError @@ -73,155 +72,148 @@ def usage(style=None): - """Show usage info; for ``style=="brief"`` show only first 2 - lines.""" - import os.path + """Show usage info. for ``style=="brief"`` show only first 2 lines. - myname = os.path.basename(sys.argv[0]) + Parameters + ---------- + style : str, optional + The usage display style. + """ + myname = Path(sys.argv[0]).name msg = __doc__.replace("vestaview", myname) if style == "brief": - msg = msg.split("\n")[1] + "\n" + "Try `%s --help' for more information." % myname + msg = f"{msg.splitlines()[1]}\n" f"Try `{myname} --help' for more information." else: from diffpy.structure.parsers import input_formats - fmts = [f for f in input_formats() if f != "auto"] + fmts = [fmt for fmt in input_formats() if fmt != "auto"] msg = msg.replace("inputFormats", " ".join(fmts)) print(msg) - return def version(): + """Print the script version.""" from diffpy.structure import __version__ - print("vestaview", __version__) - return + print(f"vestaview {__version__}") def load_structure_file(filename, format="auto"): - """Load structure from specified file. + """Load structure from the specified file. Parameters ---------- - filename : str - Path to the structure file. + filename : str or Path + The path to the structure file. format : str, optional - File format, by default "auto". + The file format, by default ``"auto"``. Returns ------- tuple - A tuple of (Structure, fileformat). + The loaded ``(Structure, fileformat)`` pair. """ from diffpy.structure import Structure stru = Structure() - p = stru.read(filename, format) - fileformat = p.format - return (stru, fileformat) + parser = stru.read(str(filename), format) + return stru, parser.format def convert_structure_file(pd): - """Convert `strufile` to a temporary file understood by the viewer. + """Convert ``strufile`` to a temporary file understood by the + viewer. - On first call a temporary directory is created and stored in *pd*. - Subsequent calls in watch mode reuse the directory. + On the first call, a temporary directory is created and stored in + ``pd``. Subsequent calls in watch mode reuse the directory. The VESTA viewer natively reads ``.vesta`` and ``.cif`` files, so if - the source is already in one of the formats listed in ``pd["formats"]`` - and no formula override is requested the file is copied unchanged. - Otherwise the structure is loaded and re-written in the first format - listed in ``pd["formats"]``. + the source is already in one of the formats listed in + ``pd["formats"]`` and no formula override is requested, the file is + copied unchanged. Otherwise the structure is loaded and re-written in + the first format listed in ``pd["formats"]``. Parameters ---------- pd : dict - Parameter dictionary containing at minimum ``"strufile"`` and - ``"formats"`` keys. Modified in-place to add ``"tmpdir"`` and - ``"tmpfile"`` on first call. + The parameter dictionary containing at minimum ``"strufile"`` + and ``"formats"`` keys. It is modified in place to add + ``"tmpdir"`` and ``"tmpfile"`` on the first call. """ - # Make temporary directory on the first pass. if "tmpdir" not in pd: from tempfile import mkdtemp - pd["tmpdir"] = mkdtemp() - strufile = pd["strufile"] - tmpfile = os.path.join(pd["tmpdir"], os.path.basename(strufile)) + pd["tmpdir"] = Path(mkdtemp()) + strufile = Path(pd["strufile"]) + tmpfile = pd["tmpdir"] / strufile.name + tmpfile_tmp = Path(f"{tmpfile}.tmp") pd["tmpfile"] = tmpfile - # Speed up file processing in the watch mode by caching format. - fmt = pd.get("format", "auto") stru = None + fmt = pd.get("fmt", "auto") if fmt == "auto": stru, fmt = load_structure_file(strufile) pd["fmt"] = fmt - # If fmt is already recognised by the viewer and no override, copy as-is. if fmt in pd["formats"] and pd["formula"] is None: import shutil - shutil.copyfile(strufile, tmpfile + ".tmp") - os.rename(tmpfile + ".tmp", tmpfile) + shutil.copyfile(strufile, tmpfile_tmp) + tmpfile_tmp.replace(tmpfile) return - # Otherwise convert to the first viewer-recognised format. if stru is None: stru = load_structure_file(strufile, fmt)[0] if pd["formula"]: formula = pd["formula"] if len(formula) != len(stru): - emsg = "Formula has %i atoms while structure %i" % ( - len(formula), - len(stru), - ) + emsg = f"Formula has {len(formula)} atoms while structure has " f"{len(stru)}" raise RuntimeError(emsg) - for a, el in zip(stru, formula): - a.element = el + for atom, element in zip(stru, formula): + atom.element = element elif fmt == "rawxyz": - for a in stru: - if a.element == "": - a.element = "C" - stru.write(tmpfile + ".tmp", pd["formats"][0]) - os.rename(tmpfile + ".tmp", tmpfile) - return + for atom in stru: + if atom.element == "": + atom.element = "C" + stru.write(str(tmpfile_tmp), pd["formats"][0]) + tmpfile_tmp.replace(tmpfile) def watch_structure_file(pd): - """Watch *strufile* for modifications and reconvert when changed. + """Watch ``strufile`` for modifications and reconvert when changed. Polls the modification timestamps of ``pd["strufile"]`` and - ``pd["tmpfile"]`` once per second. When the source is newer the + ``pd["tmpfile"]`` once per second. When the source is newer, the file is reconverted via :func:`convert_structure_file`. Parameters ---------- pd : dict - Parameter dictionary as used by :func:`convert_structure_file`. + The parameter dictionary as used by + :func:`convert_structure_file`. """ from time import sleep - strufile = pd["strufile"] - tmpfile = pd["tmpfile"] + strufile = Path(pd["strufile"]) + tmpfile = Path(pd["tmpfile"]) while pd["watch"]: - if os.path.getmtime(tmpfile) < os.path.getmtime(strufile): + if tmpfile.stat().st_mtime < strufile.stat().st_mtime: convert_structure_file(pd) sleep(1) - return def clean_up(pd): - """Remove temporary file and directory created by - :func:`convert_structure_file`. + """Remove temporary file and directory created during conversion. Parameters ---------- pd : dict - Parameter dictionary that may contain ``"tmpfile"`` and + The parameter dictionary that may contain ``"tmpfile"`` and ``"tmpdir"`` entries to be removed. """ - if "tmpfile" in pd: - os.remove(pd["tmpfile"]) - del pd["tmpfile"] - if "tmpdir" in pd: - os.rmdir(pd["tmpdir"]) - del pd["tmpdir"] - return + tmpfile = pd.pop("tmpfile", None) + if tmpfile is not None and Path(tmpfile).exists(): + Path(tmpfile).unlink() + tmpdir = pd.pop("tmpdir", None) + if tmpdir is not None and Path(tmpdir).exists(): + Path(tmpdir).rmdir() def parse_formula(formula): @@ -230,49 +222,48 @@ def parse_formula(formula): Parameters ---------- formula : str - Chemical formula string such as ``"Na4Cl4"`` or ``"H2O"``. + The chemical formula string such as ``"Na4Cl4"`` or ``"H2O"``. Returns ------- list of str - Ordered list of element symbols with repetition matching the - formula, e.g. ``["Na", "Na", "Na", "Na", "Cl", "Cl", "Cl", "Cl"]``. + The ordered list of element symbols with repetition matching the + formula. Raises ------ RuntimeError - When *formula* does not start with an uppercase letter or contains - a non-integer count. + Raised when ``formula`` does not start with an uppercase letter + or contains a non-integer count. """ - # Remove all whitespace. formula = re.sub(r"\s", "", formula) - if not re.match("^[A-Z]", formula): - raise RuntimeError("InvalidFormula '%s'" % formula) - elcnt = re.split("([A-Z][a-z]?)", formula)[1:] + if not re.match(r"^[A-Z]", formula): + raise RuntimeError(f"InvalidFormula '{formula}'") + + elcnt = re.split(r"([A-Z][a-z]?)", formula)[1:] ellst = [] try: for i in range(0, len(elcnt), 2): - el = elcnt[i] - cnt = elcnt[i + 1] - cnt = (cnt == "") and 1 or int(cnt) - ellst.extend(cnt * [el]) + element = elcnt[i] + count = int(elcnt[i + 1]) if elcnt[i + 1] else 1 + ellst.extend([element] * count) except ValueError: - emsg = "Invalid formula, %r is not valid count" % elcnt[i + 1] + emsg = f"Invalid formula, {elcnt[i + 1]!r} is not valid count" raise RuntimeError(emsg) return ellst -def die(exit_status=0, pd={}): - """Clean up temporary files and exit with *exit_status*. +def die(exit_status=0, pd=None): + """Clean up temporary files and exit with ``exit_status``. Parameters ---------- exit_status : int, optional - Exit code passed to :func:`sys.exit`, by default 0. + The exit code passed to :func:`sys.exit`, by default 0. pd : dict, optional - Parameter dictionary forwarded to :func:`clean_up`. + The parameter dictionary forwarded to :func:`clean_up`. """ - clean_up(pd) + clean_up({} if pd is None else pd) sys.exit(exit_status) @@ -287,26 +278,24 @@ def signal_handler(signum, stackframe): Parameters ---------- signum : int - Signal number. + The signal number. stackframe : frame - Current stack frame (unused). + The current stack frame. Unused. """ - # Revert to default handler before acting to avoid re-entrancy. + del stackframe signal.signal(signum, signal.SIG_DFL) if signum == signal.SIGCHLD: - pid, exit_status = os.wait() + _, exit_status = os.wait() exit_status = (exit_status >> 8) + (exit_status & 0x00FF) die(exit_status, pd) else: die(1, pd) - return def main(): """Entry point for the ``vestaview`` command-line tool.""" import getopt - # Reset to defaults each invocation. pd["watch"] = False try: opts, args = getopt.getopt( @@ -317,46 +306,47 @@ def main(): except getopt.GetoptError as errmsg: print(errmsg, file=sys.stderr) die(2) - # Process options. - for o, a in opts: - if o in ("-f", "--formula"): + + for option, argument in opts: + if option in ("-f", "--formula"): try: - pd["formula"] = parse_formula(a) - except RuntimeError as msg: - print(msg, file=sys.stderr) + pd["formula"] = parse_formula(argument) + except RuntimeError as err: + print(err, file=sys.stderr) die(2) - elif o in ("-w", "--watch"): + elif option in ("-w", "--watch"): pd["watch"] = True - elif o == "--viewer": - pd["viewer"] = a - elif o == "--formats": - pd["formats"] = [w.strip() for w in a.split(",")] - elif o in ("-h", "--help"): + elif option == "--viewer": + pd["viewer"] = argument + elif option == "--formats": + pd["formats"] = [word.strip() for word in argument.split(",")] + elif option in ("-h", "--help"): usage() die() - elif o in ("-V", "--version"): + elif option in ("-V", "--version"): version() die() if len(args) < 1: usage("brief") die() - elif len(args) > 1: + if len(args) > 1: print("too many structure files", file=sys.stderr) die(2) - pd["strufile"] = args[0] - # Trap the following signals. + pd["strufile"] = Path(args[0]) signal.signal(signal.SIGHUP, signal_handler) signal.signal(signal.SIGQUIT, signal_handler) signal.signal(signal.SIGSEGV, signal_handler) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) env = os.environ.copy() - # VESTA does not require the XLIB_SKIP_ARGB_VISUALS workaround that - # AtomEye needed; this block is intentionally omitted. - # Try to run the viewer: try: convert_structure_file(pd) - spawnargs = (pd["viewer"], pd["viewer"], pd["tmpfile"], env) + spawnargs = ( + pd["viewer"], + pd["viewer"], + str(pd["tmpfile"]), + env, + ) if pd["watch"]: signal.signal(signal.SIGCHLD, signal_handler) os.spawnlpe(os.P_NOWAIT, *spawnargs) @@ -364,13 +354,12 @@ def main(): else: status = os.spawnlpe(os.P_WAIT, *spawnargs) die(status, pd) - except IOError as e: - print("%s: %s" % (args[0], e.strerror), file=sys.stderr) + except IOError as err: + print(f"{args[0]}: {err.strerror}", file=sys.stderr) die(1, pd) - except StructureFormatError as e: - print("%s: %s" % (args[0], e), file=sys.stderr) + except StructureFormatError as err: + print(f"{args[0]}: {err}", file=sys.stderr) die(1, pd) - return if __name__ == "__main__": diff --git a/src/diffpy/structure/parsers/p_vesta.py b/src/diffpy/structure/parsers/p_vesta.py index d677d1cb..f37eec7a 100644 --- a/src/diffpy/structure/parsers/p_vesta.py +++ b/src/diffpy/structure/parsers/p_vesta.py @@ -3,10 +3,10 @@ # # diffpy.structure by DANSE Diffraction group # Simon J. L. Billinge -# (c) 2007 trustees of the Michigan State University. +# (c) 2026 University of California, Santa Barbara. # All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Simon J. L. Billinge, Rundong Hua # # See AUTHORS.txt for a list of people who contributed. # See LICENSE_DANSE.txt for license information. @@ -25,12 +25,14 @@ Dictionary of atomic masses for elements. """ +import re import sys import numpy from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser +from diffpy.structure.parsers.p_xcfg import AtomicMass from diffpy.structure.structureerrors import StructureFormatError # Constants ------------------------------------------------------------------ @@ -38,120 +40,6 @@ # Atomic Mass of elements # This can be later when PeriodicTable package becomes available. -AtomicMass = { - "H": 1.007947, # 1 H hydrogen 1.007947 - "He": 4.0026022, # 2 He helium 4.0026022 - "Li": 6.9412, # 3 Li lithium 6.9412 - "Be": 9.0121823, # 4 Be beryllium 9.0121823 - "B": 10.8117, # 5 B boron 10.8117 - "C": 12.01078, # 6 C carbon 12.01078 - "N": 14.00672, # 7 N nitrogen 14.00672 - "O": 15.99943, # 8 O oxygen 15.99943 - "F": 18.99840325, # 9 F fluorine 18.99840325 - "Ne": 20.17976, # 10 Ne neon 20.17976 - "Na": 22.9897702, # 11 Na sodium 22.9897702 - "Mg": 24.30506, # 12 Mg magnesium 24.30506 - "Al": 26.9815382, # 13 Al aluminium 26.9815382 - "Si": 28.08553, # 14 Si silicon 28.08553 - "P": 30.9737612, # 15 P phosphorus 30.9737612 - "S": 32.0655, # 16 S sulfur 32.0655 - "Cl": 35.4532, # 17 Cl chlorine 35.4532 - "Ar": 39.9481, # 18 Ar argon 39.9481 - "K": 39.09831, # 19 K potassium 39.09831 - "Ca": 40.0784, # 20 Ca calcium 40.0784 - "Sc": 44.9559108, # 21 Sc scandium 44.9559108 - "Ti": 47.8671, # 22 Ti titanium 47.8671 - "V": 50.94151, # 23 V vanadium 50.94151 - "Cr": 51.99616, # 24 Cr chromium 51.99616 - "Mn": 54.9380499, # 25 Mn manganese 54.9380499 - "Fe": 55.8452, # 26 Fe iron 55.8452 - "Co": 58.9332009, # 27 Co cobalt 58.9332009 - "Ni": 58.69342, # 28 Ni nickel 58.69342 - "Cu": 63.5463, # 29 Cu copper 63.5463 - "Zn": 65.4094, # 30 Zn zinc 65.4094 - "Ga": 69.7231, # 31 Ga gallium 69.7231 - "Ge": 72.641, # 32 Ge germanium 72.641 - "As": 74.921602, # 33 As arsenic 74.921602 - "Se": 78.963, # 34 Se selenium 78.963 - "Br": 79.9041, # 35 Br bromine 79.9041 - "Kr": 83.7982, # 36 Kr krypton 83.7982 - "Rb": 85.46783, # 37 Rb rubidium 85.46783 - "Sr": 87.621, # 38 Sr strontium 87.621 - "Y": 88.905852, # 39 Y yttrium 88.905852 - "Zr": 91.2242, # 40 Zr zirconium 91.2242 - "Nb": 92.906382, # 41 Nb niobium 92.906382 - "Mo": 95.942, # 42 Mo molybdenum 95.942 - "Tc": 98.0, # 43 Tc technetium 98 - "Ru": 101.072, # 44 Ru ruthenium 101.072 - "Rh": 102.905502, # 45 Rh rhodium 102.905502 - "Pd": 106.421, # 46 Pd palladium 106.421 - "Ag": 107.86822, # 47 Ag silver 107.86822 - "Cd": 112.4118, # 48 Cd cadmium 112.4118 - "In": 114.8183, # 49 In indium 114.8183 - "Sn": 118.7107, # 50 Sn tin 118.7107 - "Sb": 121.7601, # 51 Sb antimony 121.7601 - "Te": 127.603, # 52 Te tellurium 127.603 - "I": 126.904473, # 53 I iodine 126.904473 - "Xe": 131.2936, # 54 Xe xenon 131.2936 - "Cs": 132.905452, # 55 Cs caesium 132.905452 - "Ba": 137.3277, # 56 Ba barium 137.3277 - "La": 138.90552, # 57 La lanthanum 138.90552 - "Ce": 140.1161, # 58 Ce cerium 140.1161 - "Pr": 140.907652, # 59 Pr praseodymium 140.907652 - "Nd": 144.243, # 60 Nd neodymium 144.243 - "Pm": 145.0, # 61 Pm promethium 145 - "Sm": 150.363, # 62 Sm samarium 150.363 - "Eu": 151.9641, # 63 Eu europium 151.9641 - "Gd": 157.253, # 64 Gd gadolinium 157.253 - "Tb": 158.925342, # 65 Tb terbium 158.925342 - "Dy": 162.5001, # 66 Dy dysprosium 162.5001 - "Ho": 164.930322, # 67 Ho holmium 164.930322 - "Er": 167.2593, # 68 Er erbium 167.2593 - "Tm": 168.934212, # 69 Tm thulium 168.934212 - "Yb": 173.043, # 70 Yb ytterbium 173.043 - "Lu": 174.9671, # 71 Lu lutetium 174.9671 - "Hf": 178.492, # 72 Hf hafnium 178.492 - "Ta": 180.94791, # 73 Ta tantalum 180.94791 - "W": 183.841, # 74 W tungsten 183.841 - "Re": 186.2071, # 75 Re rhenium 186.2071 - "Os": 190.233, # 76 Os osmium 190.233 - "Ir": 192.2173, # 77 Ir iridium 192.2173 - "Pt": 195.0782, # 78 Pt platinum 195.0782 - "Au": 196.966552, # 79 Au gold 196.966552 - "Hg": 200.592, # 80 Hg mercury 200.592 - "Tl": 204.38332, # 81 Tl thallium 204.38332 - "Pb": 207.21, # 82 Pb lead 207.21 - "Bi": 208.980382, # 83 Bi bismuth 208.980382 - "Po": 209.0, # 84 Po polonium 209 - "At": 210.0, # 85 At astatine 210 - "Rn": 222.0, # 86 Rn radon 222 - "Fr": 223.0, # 87 Fr francium 223 - "Ra": 226.0, # 88 Ra radium 226 - "Ac": 227.0, # 89 Ac actinium 227 - "Th": 232.03811, # 90 Th thorium 232.03811 - "Pa": 231.035882, # 91 Pa protactinium 231.035882 - "U": 238.028913, # 92 U uranium 238.028913 - "Np": 237.0, # 93 Np neptunium 237 - "Pu": 244.0, # 94 Pu plutonium 244 - "Am": 243.0, # 95 Am americium 243 - "Cm": 247.0, # 96 Cm curium 247 - "Bk": 247.0, # 97 Bk berkelium 247 - "Cf": 251.0, # 98 Cf californium 251 - "Es": 252.0, # 99 Es einsteinium 252 - "Fm": 257.0, # 100 Fm fermium 257 - "Md": 258.0, # 101 Md mendelevium 258 - "No": 259.0, # 102 No nobelium 259 - "Lr": 262.0, # 103 Lr lawrencium 262 - "Rf": 261.0, # 104 Rf rutherfordium 261 - "Db": 262.0, # 105 Db dubnium 262 - "Sg": 266.0, # 106 Sg seaborgium 266 - "Bh": 264.0, # 107 Bh bohrium 264 - "Hs": 277.0, # 108 Hs hassium 277 - "Mt": 268.0, # 109 Mt meitnerium 268 - "Ds": 281.0, # 110 Ds darmstadtium 281 - "Rg": 272.0, # 111 Rg roentgenium 272 -} - class P_vesta(StructureParser): """Parser for VESTA native structure format (.vesta). @@ -268,13 +156,20 @@ def parse_lines(self, lines): # ---- ATOMT section: atom-type definitions --------------- if section == "ATOMT": - # Format: index Symbol radius r g b ... + # Format: index Symbol radius r g b style # mass= words = stripped.split() if len(words) >= 2: try: idx = int(words[0]) symbol = words[1] - atom_types[idx] = symbol + atom_types[idx] = {"symbol": symbol, "mass": None} + # Recover mass from the trailing comment if present. + mass_match = re.search(r"#\s*mass\s*=\s*([0-9.eE+\-]+)", stripped) + if mass_match: + atom_types[idx]["mass"] = float(mass_match.group(1)) + else: + # Fall back to the built-in lookup table. + atom_types[idx]["mass"] = AtomicMass.get(symbol, 0.0) except ValueError: pass continue @@ -304,11 +199,15 @@ def parse_lines(self, lines): beta=latt_abg[1], gamma=latt_abg[2], ) - for type_idx, x, y, z, occ in raw_coords: - element = atom_types.get(type_idx, "X") + type_info = atom_types.get(type_idx, {"symbol": "X", "mass": 0.0}) + element = type_info["symbol"] + mass = type_info["mass"] stru.add_new_atom(element, xyz=[x, y, z]) stru[-1].occupancy = occ + if mass is None: + mass = AtomicMass.get(element, 0.0) + stru[-1].mass = mass except (ValueError, IndexError): emsg = "%d: file is not in VESTA format" % p_nl @@ -372,8 +271,8 @@ def to_lines(self, stru): lines.append("ATOMT") for el in element_order: idx = type_index[el] - # Default ball radius 0.5; placeholder RGB 1.0 1.0 1.0. - lines.append(" %d %s %.4f 1.0000 1.0000 1.0000 204" % (idx, el, 0.5)) + mass = AtomicMass.get(el, 0.0) + lines.append(" %d %s %.4f 1.0000 1.0000 1.0000 204 # mass=%.7g" % (idx, el, 0.5, mass)) lines.append("") lines.append("COORD") for seq, a_obj in enumerate(stru, start=1): From 92c1832e6ad0c93f1bde1fbbe78ee3200a6da222 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 26 Mar 2026 13:56:52 -0400 Subject: [PATCH 209/226] chore: delete unncessary AtomicTable comments. --- src/diffpy/structure/parsers/p_vesta.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/diffpy/structure/parsers/p_vesta.py b/src/diffpy/structure/parsers/p_vesta.py index f37eec7a..b365f29b 100644 --- a/src/diffpy/structure/parsers/p_vesta.py +++ b/src/diffpy/structure/parsers/p_vesta.py @@ -35,12 +35,8 @@ from diffpy.structure.parsers.p_xcfg import AtomicMass from diffpy.structure.structureerrors import StructureFormatError -# Constants ------------------------------------------------------------------ - -# Atomic Mass of elements -# This can be later when PeriodicTable package becomes available. - +# Constants ------------------------------------------------------------------ class P_vesta(StructureParser): """Parser for VESTA native structure format (.vesta). From 52748fb017375362de46686cde81489ecb55b7c3 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Thu, 26 Mar 2026 14:32:32 -0400 Subject: [PATCH 210/226] chore: remove unncessary import from p_xcfg --- src/diffpy/structure/parsers/p_vesta.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/diffpy/structure/parsers/p_vesta.py b/src/diffpy/structure/parsers/p_vesta.py index b365f29b..1be850c0 100644 --- a/src/diffpy/structure/parsers/p_vesta.py +++ b/src/diffpy/structure/parsers/p_vesta.py @@ -291,7 +291,6 @@ def to_lines(self, stru): # End of class P_vesta -from diffpy.structure.parsers.P_xcfg import P_xcfg # noqa: E402, F401 # Routines ------------------------------------------------------------------- From cba50a654b437cb84e531b868a008188f2c4d41c Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Fri, 27 Mar 2026 14:10:54 -0400 Subject: [PATCH 211/226] chore: add assignUniqueLabels deprecation message --- news/assignUniqueLabels-deprecation.rst | 23 +++++++++++++++++++++++ src/diffpy/structure/structure.py | 10 ++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 news/assignUniqueLabels-deprecation.rst diff --git a/news/assignUniqueLabels-deprecation.rst b/news/assignUniqueLabels-deprecation.rst new file mode 100644 index 00000000..76b16072 --- /dev/null +++ b/news/assignUniqueLabels-deprecation.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: add deprecation message for `assignUniqueLabels` + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index 8d240549..1593af40 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -21,13 +21,19 @@ from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice -from diffpy.structure.utils import _link_atom_attribute, atomBareSymbol, isiterable +from diffpy.structure.utils import _link_atom_attribute, atom_bare_symbol, isiterable from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- base = "diffpy.structure.Structure" removal_version = "4.0.0" +assignUniqueLabels_deprecation_msg = build_deprecation_message( + base, + "assignUniqueLabels", + "assign_unique_labels", + removal_version, +) addNewAtom_deprecation_msg = build_deprecation_message( base, "addNewAtom", @@ -242,7 +248,7 @@ def assign_unique_labels(self): for a in self: if a in islabeled: continue - baresmbl = atomBareSymbol(a.element) + baresmbl = atom_bare_symbol(a.element) elnum[baresmbl] = elnum.get(baresmbl, 0) + 1 a.label = baresmbl + str(elnum[baresmbl]) islabeled.add(a) From 87f8b1269ab4d55a0f646f2ada4c58827f945808 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sat, 28 Mar 2026 22:40:46 -0400 Subject: [PATCH 212/226] fix: fix documentation rendered properly --- docs/source/api/diffpy.structure.apps.rst | 8 +++++++ docs/source/api/diffpy.structure.parsers.rst | 8 +++++++ docs/source/api/diffpy.structure.rst | 14 ++++++++---- docs/source/conf.py | 2 +- news/documentation-fix.rst | 23 ++++++++++++++++++++ 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 news/documentation-fix.rst diff --git a/docs/source/api/diffpy.structure.apps.rst b/docs/source/api/diffpy.structure.apps.rst index 8b91adf5..3986ab73 100644 --- a/docs/source/api/diffpy.structure.apps.rst +++ b/docs/source/api/diffpy.structure.apps.rst @@ -26,3 +26,11 @@ diffpy.structure.apps.anyeye module :members: :undoc-members: :show-inheritance: + +diffpy.structure.apps.vesta_viewer module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.apps.vesta_viewer + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api/diffpy.structure.parsers.rst b/docs/source/api/diffpy.structure.parsers.rst index 74a27bcb..8a5e9476 100644 --- a/docs/source/api/diffpy.structure.parsers.rst +++ b/docs/source/api/diffpy.structure.parsers.rst @@ -83,6 +83,14 @@ diffpy.structure.parsers.p_discus module :undoc-members: :show-inheritance: +diffpy.structure.parsers.p_vesta module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.parsers.p_vesta + :members: + :undoc-members: + :show-inheritance: + diffpy.structure.parsers.p_xyz module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/api/diffpy.structure.rst b/docs/source/api/diffpy.structure.rst index d6ffb2ad..7807ec06 100644 --- a/docs/source/api/diffpy.structure.rst +++ b/docs/source/api/diffpy.structure.rst @@ -1,9 +1,7 @@ :tocdepth: -1 -|title| -======= - -.. |title| replace:: diffpy.structure package +diffpy.structure package +======================== .. automodule:: diffpy.structure :members: @@ -23,6 +21,14 @@ Subpackages Submodules ---------- +diffpy.structure.structure_app module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.structure.structure_app + :members: + :undoc-members: + :show-inheritance: + diffpy.structure.spacegroups module ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/conf.py b/docs/source/conf.py index 960f8fbb..e3c1fd99 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -23,7 +23,7 @@ fullversion = version("diffpy.structure") except Exception: fullversion = "No version found. The correct version will appear in the released version." # noqa: E501 - +autodoc_mock_imports = ["diffpy.utils"] # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use Path().resolve() to make it absolute, like shown here. # noqa: E501 diff --git a/news/documentation-fix.rst b/news/documentation-fix.rst new file mode 100644 index 00000000..30fe87e3 --- /dev/null +++ b/news/documentation-fix.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: documentation fix for diffpy.structure + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 4f4cd205cf641638affbbe4b487043565a5d173f Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 29 Mar 2026 02:09:28 -0700 Subject: [PATCH 213/226] docs: update license information --- LICENSE-DANSE.rst | 5 +---- LICENSE.rst | 3 +++ docs/source/license.rst | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/LICENSE-DANSE.rst b/LICENSE-DANSE.rst index d56af619..a650d915 100644 --- a/LICENSE-DANSE.rst +++ b/LICENSE-DANSE.rst @@ -9,14 +9,11 @@ Copyright 2006-2007, Board of Trustees of Michigan State University, Copyright 2008-2012, The Trustees of Columbia University in the City of New York. (Copyright holder indicated in each source file). -Copyright (c) 2024, The Trustees of Columbia University in the City of New York. -All rights reserved. - For more information please visit the project web-page: http://www.diffpy.org/ -or email Prof. Simon Billinge at sb2896@columbia.edu +or email Prof. Simon Billinge at sbillinge@ucsb.edu Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/LICENSE.rst b/LICENSE.rst index 1f91b0ba..c967838d 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -18,6 +18,9 @@ Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Labo Copyright (c) 2024-2025, The Trustees of Columbia University in the City of New York. All rights reserved. +Copyright (c) 2026-present, The Contributors to the diffpy.structure project. +All rights reserved. + The "DiffPy-CMI" is distributed subject to the following license conditions: .. code-block:: text diff --git a/docs/source/license.rst b/docs/source/license.rst index 00315fc7..e4c7e6c5 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -25,6 +25,9 @@ Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Labo Copyright (c) 2024-2025, The Trustees of Columbia University in the City of New York. All rights reserved. +Copyright (c) 2026-present, The Contributors to the diffpy.structure project. +All rights reserved. + The "DiffPy-CMI" is distributed subject to the following license conditions: .. code-block:: text From e2e44a0b9439461796330acb53000e414160db9b Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 29 Mar 2026 02:11:53 -0700 Subject: [PATCH 214/226] news --- news/license.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/license.rst diff --git a/news/license.rst b/news/license.rst new file mode 100644 index 00000000..09fe706f --- /dev/null +++ b/news/license.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: update copyright holders in licesnss + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 4e8dd2407ee8f2a73607d384636d26f3b58228ff Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 29 Mar 2026 02:26:36 -0700 Subject: [PATCH 215/226] chore: remove unwanted workflows --- .../matrix-and-codecov-on-merge-to-main.yml | 21 ------------------- .github/workflows/publish-docs-on-release.yml | 12 ----------- 2 files changed, 33 deletions(-) delete mode 100644 .github/workflows/matrix-and-codecov-on-merge-to-main.yml delete mode 100644 .github/workflows/publish-docs-on-release.yml 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 235c9f71..00000000 --- a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: CI - -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.structure - c_extension: false - headless: false - secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml deleted file mode 100644 index 461e8ac3..00000000 --- a/.github/workflows/publish-docs-on-release.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Deploy Documentation on Release - -on: - workflow_dispatch: - -jobs: - docs: - uses: scikit-package/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 - with: - project: diffpy.structure - c_extension: false - headless: false From acbcd8585e0ab404eddfc67402254ec9db15ca29 Mon Sep 17 00:00:00 2001 From: Simon Billinge Date: Sun, 29 Mar 2026 02:29:19 -0700 Subject: [PATCH 216/226] news --- news/clean-workflows.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/clean-workflows.rst diff --git a/news/clean-workflows.rst b/news/clean-workflows.rst new file mode 100644 index 00000000..da8bb627 --- /dev/null +++ b/news/clean-workflows.rst @@ -0,0 +1,23 @@ +**Added:** + +* No news added: chore: clean workflows + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From d1702340d20fcaceed4d131e0507e5366f806202 Mon Sep 17 00:00:00 2001 From: sbillinge <4254545+sbillinge@users.noreply.github.com> Date: Sun, 29 Mar 2026 16:01:36 +0000 Subject: [PATCH 217/226] update changelog --- CHANGELOG.rst | 221 ++++++++++++++++++++++ news/add-devutils-readme.rst | 23 --- news/assignUniqueLabels-deprecation.rst | 23 --- news/change-utility-script.rst | 23 --- news/clean-workflows.rst | 23 --- news/dep-warning1.rst | 23 --- news/deprecate-addNewItem.rst | 23 --- news/deprecate-apps.rst | 33 ---- news/deprecate-assignUniqueLabels.rst | 23 --- news/deprecate-atom.rst | 28 --- news/deprecate-expansion-utilities-1.rst | 27 --- news/deprecate-getLastAtom.rst | 23 --- news/deprecate-getParser.rst | 39 ---- news/deprecate-lattice-readstr-method.rst | 25 --- news/deprecate-lattice.rst | 25 --- news/deprecate-parsefile.rst | 27 --- news/deprecate-parser-1.rst | 40 ---- news/deprecate-parser-display.rst | 31 --- news/deprecate-private-linkatom.rst | 23 --- news/deprecate-spacegroup.rst | 33 ---- news/deprecate-structure-function.rst | 27 --- news/deprecate-symmetryutilities-1.rst | 25 --- news/deprecate-symmetryutilities-2.rst | 26 --- news/deprecate-symmetryutilities-3.rst | 27 --- news/deprecate-symmetryutilities-4.rst | 28 --- news/deprecate-symmetryutilities-5.rst | 29 --- news/deprecate-symmetryutilities-6.rst | 32 ---- news/deprecate-symmetryutilities-7.rst | 27 --- news/deprecate-toLine.rst | 38 ---- news/deprecate-utils.rst | 39 ---- news/documentation-fix.rst | 23 --- news/fix-deprecation.rst | 23 --- news/fix-load-structure.rst | 23 --- news/license.rst | 23 --- news/skpkg-update.rst | 23 --- news/vesta_view.rst | 23 --- 36 files changed, 221 insertions(+), 951 deletions(-) delete mode 100644 news/add-devutils-readme.rst delete mode 100644 news/assignUniqueLabels-deprecation.rst delete mode 100644 news/change-utility-script.rst delete mode 100644 news/clean-workflows.rst delete mode 100644 news/dep-warning1.rst delete mode 100644 news/deprecate-addNewItem.rst delete mode 100644 news/deprecate-apps.rst delete mode 100644 news/deprecate-assignUniqueLabels.rst delete mode 100644 news/deprecate-atom.rst delete mode 100644 news/deprecate-expansion-utilities-1.rst delete mode 100644 news/deprecate-getLastAtom.rst delete mode 100644 news/deprecate-getParser.rst delete mode 100644 news/deprecate-lattice-readstr-method.rst delete mode 100644 news/deprecate-lattice.rst delete mode 100644 news/deprecate-parsefile.rst delete mode 100644 news/deprecate-parser-1.rst delete mode 100644 news/deprecate-parser-display.rst delete mode 100644 news/deprecate-private-linkatom.rst delete mode 100644 news/deprecate-spacegroup.rst delete mode 100644 news/deprecate-structure-function.rst delete mode 100644 news/deprecate-symmetryutilities-1.rst delete mode 100644 news/deprecate-symmetryutilities-2.rst delete mode 100644 news/deprecate-symmetryutilities-3.rst delete mode 100644 news/deprecate-symmetryutilities-4.rst delete mode 100644 news/deprecate-symmetryutilities-5.rst delete mode 100644 news/deprecate-symmetryutilities-6.rst delete mode 100644 news/deprecate-symmetryutilities-7.rst delete mode 100644 news/deprecate-toLine.rst delete mode 100644 news/deprecate-utils.rst delete mode 100644 news/documentation-fix.rst delete mode 100644 news/fix-deprecation.rst delete mode 100644 news/fix-load-structure.rst delete mode 100644 news/license.rst delete mode 100644 news/skpkg-update.rst delete mode 100644 news/vesta_view.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 66a1a4b8..9a35bf76 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,227 @@ Release notes .. current developments +3.4.0 +===== + +**Added:** + +* Added ``set_latt_parms`` method into ``Lattice`` class +* Added ``set_new_latt_base_vec`` method into ``Lattice`` class +* Added ``parse_lines`` method in ``p_auto.py`` +* Added ``parse_lines`` method in ``p_cif.py`` +* Added ``parse_lines`` method in ``p_discus.py`` +* Added ``parse_lines`` method in ``p_pdb.py`` +* Added ``parse_lines`` method in ``p_pdffit.py`` +* Added ``parse_lines`` method in ``p_rawxyz.py`` +* Added ``parse_lines`` method in ``p_xcfg.py`` +* Added ``parse_lines`` method in ``p_xyz.py`` +* Added ``parse_lines`` method in ``structureparser.py`` +* Added ``_suppress_cif_parser_output`` method in ``p_cif.py`` +* Add deprecation warning for ``diffpy.Structure`` import. +* Added `diffpy.structure.Structure.add_new_atom` in replace of `addNewAtom` +* Added ``load_structure_file`` method in ``apps/anyeye.py`` +* Added ``convert_structure_file`` method in ``apps/anyeye.py`` +* Added ``watch_structure_file`` method in ``apps/anyeye.py`` +* Added ``clean_up`` method in ``apps/anyeye.py`` +* Added ``parse_formula`` method in ``apps/anyeye.py`` +* Added ``signal_handler`` method in ``apps/anyeye.py`` +* Added method ``load_structure`` in ``__init__.py`` +* Added `diffpy.structure.Structure.assign_unique_labels` in replace of `assignUniqueLabels` +* Support for Python 3.14 +* Added ``place_in_lattice`` method to ``Structure`` +* Added ``read_structure`` method to ``Structure`` +* Added ``write_structure`` method to ``Structure`` +* Added ``position_formula`` method in ``GeneratorSite`` class +* Added ``u_formula`` method in ``GeneratorSite`` class +* Added ``eq_index`` method in ``GeneratorSite`` class +* Added ``prune_formula_dictionary`` method in ``symmetryutilities.py`` +* Added ``_link_atom_attribute`` method in ``diffpy.structure.utils`` +* Added ``msd_latt`` method in ``atom.py`` +* Added ``msd_cart`` method in ``atom.py`` +* Added ``_get_uij`` method in ``atom.py`` +* Added ``_set_uij`` method in ``atom.py`` +* Added ``parse_file`` method in ``structureparser.py`` +* Added ``parse_lines`` method in ``p_cif.py`` +* Added ``parse_lines`` method in ``p_auto.py`` +* Added parser for vesta specific files and viewer for vesta +* Added ``atom_bare_symbol`` method in ``utils.py`` +* Added ``_get_ordered_formats`` method in ``p_auto.py`` +* Added ``_wrap_parse_method`` method in ``p_auto.py`` +* Added ``_tr_atom_site_u_iso_or_equiv`` method in ``p_cif.py`` +* Added ``_tr_atom_site_b_iso_or_equiv`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_11`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_22`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_33`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_12`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_13`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_u_23`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_11`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_22`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_33`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_12`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_13`` method in ``p_cif.py`` +* Added ``_tr_atom_site_aniso_b_23`` method in ``p_cif.py`` +* Added ``get_symop`` method in ``parsers/p_cif.py`` +* Added ``get_space_group`` method in ``spacegroups.py`` +* Added ``find_space_group`` method in ``spacegroups.py`` +* Added ``is_space_group_identifier`` method in ``spacegroups.py`` +* Added ``_hash_symop_list`` method in ``spacegroups.py`` +* Added ``_build_sg_lookup_table`` method in ``spacegroups.py`` +* Added ``_get_sg_hash_lookup_table`` method in ``spacegroups.py`` +* Added ``read_structure`` method into ``PDFFitStructure`` class +* Added ``cell_parms`` method into ``Lattice`` class +* Added ``_find_constraints`` method in ``SymmetryConstraints`` class +* Added ``pos_parm_symbols`` method in ``SymmetryConstraints`` class +* Added ``pos_parm_values`` method in ``SymmetryConstraints`` class +* Added ``u_parm_symbols`` method in ``SymmetryConstraints`` class +* Added ``u_parm_values`` method in ``SymmetryConstraints`` class +* Added ``u_formulas`` method in ``SymmetryConstraints`` class +* Added `diffpy.structure.Structure.get_last_atom` in replace of `getLastAtom` +* Added ``get_parser`` method in ``p_auto.py`` +* Added ``get_parser`` method in ``p_cif.py`` +* Added ``get_parser`` method in ``p_discus.py`` +* Added ``get_parser`` method in ``p_pdb.py`` +* Added ``get_parser`` method in ``p_pdffit.py`` +* Added ``get_parser`` method in ``p_rawxyz.py`` +* Added ``get_parser`` method in ``p_xcfg.py`` +* Added ``get_parser`` method in ``p_xyz.py`` +* Added ``get_parser`` method in ``parsers/__init__.py`` +* Added ``position_formulas`` method in ``SymmetryConstraints`` class +* Added ``position_formulas_pruned`` method in ``SymmetryConstraints`` class +* Added ``u_formulas_pruned`` method in ``SymmetryConstraints`` class +* Added ``_parse_cif_data_source`` method in ``p_cif.py`` +* Added ``_parse_cif_block`` method in ``p_cif.py`` +* Added ``to_lines`` method in ``p_cif.py`` +* Added ``to_lines`` method in ``p_pdb.py`` +* Added ``to_lines`` method in ``p_rawxyz.py`` +* Added ``to_lines`` method in ``p_xcfg.py`` +* Added ``to_lines`` method in ``p_xyz.py`` +* Added ``to_lines`` method in ``structureparser.py`` +* Added ``_lines_iterator`` method in ``p_discus.py`` +* Added ``to_lines`` method in ``p_discus.py`` +* Added ``is_space_group_latt_parms`` method in ``symmetryutilities.py`` +* Added ``is_constant_formula`` method in ``symmetryutilities.py`` +* Added ``find_center`` method in ``expansion/shapeutils.py`` +* Added ``make_sphere`` method in ``expansion/makeellipsoid.py`` +* Added ``make_ellipsoid`` method in ``expansion/makeellipsoid.py`` +* Added ``position_difference`` method in ``symmetryutilities.py`` +* Added ``nearest_site_index`` method in ``symmetryutilities.py`` +* Added ``_find_invariants`` method in ``symmetryutilities.py`` +* Added ``equal_positions`` method in ``symmetryutilities.py`` +* Added ``expand_position`` method in ``symmetryutilities.py`` +* Added ``null_space`` method in ``symmetryutilities.py`` +* Added ``input_formats`` method in ``parsers/__init__.py`` +* Added ``output_formats`` method in ``parsers/__init__.py`` +* Added ``title_lines`` method in ``p_pdb.py`` +* Added ``cryst1_lines`` method in ``p_pdb.py`` +* Added ``atom_lines`` method in ``p_pdb.py`` +* Added ``convert_fp_num_to_signed_rational`` method in ``GeneratorSite`` class +* Added ``_find_null_space`` method in ``GeneratorSite`` class +* Added ``_find_pos_parameters`` method in ``GeneratorSite`` class +* Added ``_find_u_space`` method in ``GeneratorSite`` class +* Added ``_find_u_parameters`` method in ``GeneratorSite`` class +* Added ``_find_eq_uij`` method in ``GeneratorSite`` class + +**Changed:** + +* Changed private method ``__emptySharedStructure`` to ``__empty_shared_structure`` + +**Deprecated:** + +* Deprecated ``setLatPar`` method in ``Lattice`` class for removal in version 4.0.0 +* Deprecated ``setLatBase`` method in ``Lattice`` class for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdffit.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``structureparser.py`` for removal in version 4.0.0 +* Deprecated `diffpy.structure.Structure.addNewAtom` method for removal in version 4.0.0 +* Deprecated ``loadStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``convertStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``watchStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``cleanUp`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``parseFormula`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated ``signalHandler`` method in ``apps/anyeye.py`` for removal in version 4.0.0 +* Deprecated method ``loadStructure`` in ``__init__.py`` for removal in version 4.0.0 +* Deprecated `diffpy.structure.Structure.assignUniqueLabels` for removal in 4.0.0 +* Deprecated ``placeInLattice`` method of ``Structure`` for removal in version 4.0.0 +* Deprecated ``readStr`` method of ``Structure`` for removal in version 4.0.0 +* Deprecated ``writeStr`` method of ``Structure`` for removal in version 4.0.0 +* Deprecated ``positionFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``UFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``eqIndex`` method in ``GeneratorSite`` class for removal in version 4.0.0 +* Deprecated ``pruneFormulaDictionary`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Derecated ``_linkAtomAttribute`` method in ``diffpy.structure.utils`` for removal in version 4.0.0 +* Deprecated ``msdLat`` method in ``atom.py`` for removal in version 4.0.0 +* Deprecated ``msdCart`` method in ``atom.py`` for removal in version 4.0.0 +* Deprecated ``parse_file`` method in ``structureparser.py`` for removal in version 4.0.0 +* Deprecated ``parse_file`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``parse_file`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``atomBareSymbol`` method in ``utils.py`` for removal in version 4.0.0 +* Deprecated ``getSymOp`` method in ``parsers/p_cif.py`` for removal in version 4.0.0 +* Deprecated ``GetSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``IsSpaceGroupIdentifier`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``FindSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``_hashSymOpList`` method in ``spacegroups.py`` for removal in version 4.0.0 +* Deprecated ``readStr`` method in ``PDFFitStructure`` class for removal in version 4.0.0 +* Deprecated ``abcABG`` method in ``Lattice`` class for removal in version 4.0.0 +* Deprecated ``posparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``posparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated `diffpy.structure.Structure.getLastAtom` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_pdffit.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``getParser`` method in ``parsers/__init__.py`` for removal in version 4.0.0 +* Deprecated ``positionFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``positionFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``UFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``structureparser.py`` for removal in version 4.0.0 +* Deprecated ``toLines`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``isSpaceGroupLatPar`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``isconstantFormula`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``findCenter`` method in ``expansion/shapeutils.py`` for removal in version 4.0.0 +* Deprecated ``makeSphere`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 +* Deprecated ``makeEllipsoid`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 +* Deprecated ``positionDifference`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``nearestSiteIndex`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``equalPositions`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``expandPosition`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``nullSpace`` method in ``symmetryutilities.py`` for removal in version 4.0.0 +* Deprecated ``inputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 +* Deprecated ``outputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 +* Deprecated ``titleLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``crystl1Lines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``atomLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``signedRatStr`` method in in ``GeneratorSite`` class for removal in version 4.0.0 + +**Fixed:** + +* Fixed ``load_structure`` with successfully loading `Path` object +* Fix deprecation for open file for Python 3.14 + +**Removed:** + +* Support for Python 3.11 + + 3.3.1 ===== diff --git a/news/add-devutils-readme.rst b/news/add-devutils-readme.rst deleted file mode 100644 index 9cf9b8b6..00000000 --- a/news/add-devutils-readme.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: add devutils readme - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/assignUniqueLabels-deprecation.rst b/news/assignUniqueLabels-deprecation.rst deleted file mode 100644 index 76b16072..00000000 --- a/news/assignUniqueLabels-deprecation.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: add deprecation message for `assignUniqueLabels` - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/change-utility-script.rst b/news/change-utility-script.rst deleted file mode 100644 index 04546e44..00000000 --- a/news/change-utility-script.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: Change any utility scripts that outside of package distribution method to snake_cae method - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/clean-workflows.rst b/news/clean-workflows.rst deleted file mode 100644 index da8bb627..00000000 --- a/news/clean-workflows.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: chore: clean workflows - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/dep-warning1.rst b/news/dep-warning1.rst deleted file mode 100644 index bd4b2fbd..00000000 --- a/news/dep-warning1.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Add deprecation warning for ``diffpy.Structure`` import. - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-addNewItem.rst b/news/deprecate-addNewItem.rst deleted file mode 100644 index 922d41c9..00000000 --- a/news/deprecate-addNewItem.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added `diffpy.structure.Structure.add_new_atom` in replace of `addNewAtom` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated `diffpy.structure.Structure.addNewAtom` method for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-apps.rst b/news/deprecate-apps.rst deleted file mode 100644 index f9ebb7af..00000000 --- a/news/deprecate-apps.rst +++ /dev/null @@ -1,33 +0,0 @@ -**Added:** - -* Added ``load_structure_file`` method in ``apps/anyeye.py`` -* Added ``convert_structure_file`` method in ``apps/anyeye.py`` -* Added ``watch_structure_file`` method in ``apps/anyeye.py`` -* Added ``clean_up`` method in ``apps/anyeye.py`` -* Added ``parse_formula`` method in ``apps/anyeye.py`` -* Added ``signal_handler`` method in ``apps/anyeye.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``loadStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 -* Deprecated ``convertStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 -* Deprecated ``watchStructureFile`` method in ``apps/anyeye.py`` for removal in version 4.0.0 -* Deprecated ``cleanUp`` method in ``apps/anyeye.py`` for removal in version 4.0.0 -* Deprecated ``parseFormula`` method in ``apps/anyeye.py`` for removal in version 4.0.0 -* Deprecated ``signalHandler`` method in ``apps/anyeye.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-assignUniqueLabels.rst b/news/deprecate-assignUniqueLabels.rst deleted file mode 100644 index cf07ff63..00000000 --- a/news/deprecate-assignUniqueLabels.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added `diffpy.structure.Structure.assign_unique_labels` in replace of `assignUniqueLabels` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated `diffpy.structure.Structure.assignUniqueLabels` for removal in 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-atom.rst b/news/deprecate-atom.rst deleted file mode 100644 index 2ddd8b79..00000000 --- a/news/deprecate-atom.rst +++ /dev/null @@ -1,28 +0,0 @@ -**Added:** - -* Added ``msd_latt`` method in ``atom.py`` -* Added ``msd_cart`` method in ``atom.py`` -* Added ``_get_uij`` method in ``atom.py`` -* Added ``_set_uij`` method in ``atom.py`` - - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``msdLat`` method in ``atom.py`` for removal in version 4.0.0 -* Deprecated ``msdCart`` method in ``atom.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-expansion-utilities-1.rst b/news/deprecate-expansion-utilities-1.rst deleted file mode 100644 index ba3c4b6a..00000000 --- a/news/deprecate-expansion-utilities-1.rst +++ /dev/null @@ -1,27 +0,0 @@ -**Added:** - -* Added ``find_center`` method in ``expansion/shapeutils.py`` -* Added ``make_sphere`` method in ``expansion/makeellipsoid.py`` -* Added ``make_ellipsoid`` method in ``expansion/makeellipsoid.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``findCenter`` method in ``expansion/shapeutils.py`` for removal in version 4.0.0 -* Deprecated ``makeSphere`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 -* Deprecated ``makeEllipsoid`` method in ``expansion/makeellipsoid.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-getLastAtom.rst b/news/deprecate-getLastAtom.rst deleted file mode 100644 index 9f2824ad..00000000 --- a/news/deprecate-getLastAtom.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added `diffpy.structure.Structure.get_last_atom` in replace of `getLastAtom` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated `diffpy.structure.Structure.getLastAtom` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-getParser.rst b/news/deprecate-getParser.rst deleted file mode 100644 index 99e3f33d..00000000 --- a/news/deprecate-getParser.rst +++ /dev/null @@ -1,39 +0,0 @@ -**Added:** - -* Added ``get_parser`` method in ``p_auto.py`` -* Added ``get_parser`` method in ``p_cif.py`` -* Added ``get_parser`` method in ``p_discus.py`` -* Added ``get_parser`` method in ``p_pdb.py`` -* Added ``get_parser`` method in ``p_pdffit.py`` -* Added ``get_parser`` method in ``p_rawxyz.py`` -* Added ``get_parser`` method in ``p_xcfg.py`` -* Added ``get_parser`` method in ``p_xyz.py`` -* Added ``get_parser`` method in ``parsers/__init__.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``getParser`` method in ``p_auto.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_cif.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_discus.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_pdb.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_pdffit.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_rawxyz.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_xcfg.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``p_xyz.py`` for removal in version 4.0.0 -* Deprecated ``getParser`` method in ``parsers/__init__.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-lattice-readstr-method.rst b/news/deprecate-lattice-readstr-method.rst deleted file mode 100644 index 31ff9ff4..00000000 --- a/news/deprecate-lattice-readstr-method.rst +++ /dev/null @@ -1,25 +0,0 @@ -**Added:** - -* Added ``read_structure`` method into ``PDFFitStructure`` class -* Added ``cell_parms`` method into ``Lattice`` class - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``readStr`` method in ``PDFFitStructure`` class for removal in version 4.0.0 -* Deprecated ``abcABG`` method in ``Lattice`` class for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-lattice.rst b/news/deprecate-lattice.rst deleted file mode 100644 index d3ef5438..00000000 --- a/news/deprecate-lattice.rst +++ /dev/null @@ -1,25 +0,0 @@ -**Added:** - -* Added ``set_latt_parms`` method into ``Lattice`` class -* Added ``set_new_latt_base_vec`` method into ``Lattice`` class - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``setLatPar`` method in ``Lattice`` class for removal in version 4.0.0 -* Deprecated ``setLatBase`` method in ``Lattice`` class for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-parsefile.rst b/news/deprecate-parsefile.rst deleted file mode 100644 index 855b4bb2..00000000 --- a/news/deprecate-parsefile.rst +++ /dev/null @@ -1,27 +0,0 @@ -**Added:** - -* Added ``parse_file`` method in ``structureparser.py`` -* Added ``parse_lines`` method in ``p_cif.py`` -* Added ``parse_lines`` method in ``p_auto.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``parse_file`` method in ``structureparser.py`` for removal in version 4.0.0 -* Deprecated ``parse_file`` method in ``p_cif.py`` for removal in version 4.0.0 -* Deprecated ``parse_file`` method in ``p_auto.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-parser-1.rst b/news/deprecate-parser-1.rst deleted file mode 100644 index f6d7b3ff..00000000 --- a/news/deprecate-parser-1.rst +++ /dev/null @@ -1,40 +0,0 @@ -**Added:** - -* Added ``parse_lines`` method in ``p_auto.py`` -* Added ``parse_lines`` method in ``p_cif.py`` -* Added ``parse_lines`` method in ``p_discus.py`` -* Added ``parse_lines`` method in ``p_pdb.py`` -* Added ``parse_lines`` method in ``p_pdffit.py`` -* Added ``parse_lines`` method in ``p_rawxyz.py`` -* Added ``parse_lines`` method in ``p_xcfg.py`` -* Added ``parse_lines`` method in ``p_xyz.py`` -* Added ``parse_lines`` method in ``structureparser.py`` -* Added ``_suppress_cif_parser_output`` method in ``p_cif.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``parseLines`` method in ``p_auto.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_cif.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_discus.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_pdb.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_pdffit.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``p_xyz.py`` for removal in version 4.0.0 -* Deprecated ``parseLines`` method in ``structureparser.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-parser-display.rst b/news/deprecate-parser-display.rst deleted file mode 100644 index 4aaa4e08..00000000 --- a/news/deprecate-parser-display.rst +++ /dev/null @@ -1,31 +0,0 @@ -**Added:** - -* Added ``input_formats`` method in ``parsers/__init__.py`` -* Added ``output_formats`` method in ``parsers/__init__.py`` -* Added ``title_lines`` method in ``p_pdb.py`` -* Added ``cryst1_lines`` method in ``p_pdb.py`` -* Added ``atom_lines`` method in ``p_pdb.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``inputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 -* Deprecated ``outputFormats`` method in ``parsers/__init__.py`` for removal in version 4.0.0 -* Deprecated ``titleLines`` method in ``p_pdb.py`` for removal in version 4.0.0 -* Deprecated ``crystl1Lines`` method in ``p_pdb.py`` for removal in version 4.0.0 -* Deprecated ``atomLines`` method in ``p_pdb.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-private-linkatom.rst b/news/deprecate-private-linkatom.rst deleted file mode 100644 index 860f7b08..00000000 --- a/news/deprecate-private-linkatom.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added ``_link_atom_attribute`` method in ``diffpy.structure.utils`` - -**Changed:** - -* - -**Deprecated:** - -* Derecated ``_linkAtomAttribute`` method in ``diffpy.structure.utils`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-spacegroup.rst b/news/deprecate-spacegroup.rst deleted file mode 100644 index 902e4fdb..00000000 --- a/news/deprecate-spacegroup.rst +++ /dev/null @@ -1,33 +0,0 @@ -**Added:** - -* Added ``get_symop`` method in ``parsers/p_cif.py`` -* Added ``get_space_group`` method in ``spacegroups.py`` -* Added ``find_space_group`` method in ``spacegroups.py`` -* Added ``is_space_group_identifier`` method in ``spacegroups.py`` -* Added ``_hash_symop_list`` method in ``spacegroups.py`` -* Added ``_build_sg_lookup_table`` method in ``spacegroups.py`` -* Added ``_get_sg_hash_lookup_table`` method in ``spacegroups.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``getSymOp`` method in ``parsers/p_cif.py`` for removal in version 4.0.0 -* Deprecated ``GetSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 -* Deprecated ``IsSpaceGroupIdentifier`` method in ``spacegroups.py`` for removal in version 4.0.0 -* Deprecated ``FindSpaceGroup`` method in ``spacegroups.py`` for removal in version 4.0.0 -* Deprecated ``_hashSymOpList`` method in ``spacegroups.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-structure-function.rst b/news/deprecate-structure-function.rst deleted file mode 100644 index 73071f43..00000000 --- a/news/deprecate-structure-function.rst +++ /dev/null @@ -1,27 +0,0 @@ -**Added:** - -* Added ``place_in_lattice`` method to ``Structure`` -* Added ``read_structure`` method to ``Structure`` -* Added ``write_structure`` method to ``Structure`` - -**Changed:** - -* Changed private method ``__emptySharedStructure`` to ``__empty_shared_structure`` - -**Deprecated:** - -* Deprecated ``placeInLattice`` method of ``Structure`` for removal in version 4.0.0 -* Deprecated ``readStr`` method of ``Structure`` for removal in version 4.0.0 -* Deprecated ``writeStr`` method of ``Structure`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-1.rst b/news/deprecate-symmetryutilities-1.rst deleted file mode 100644 index 36cde7fa..00000000 --- a/news/deprecate-symmetryutilities-1.rst +++ /dev/null @@ -1,25 +0,0 @@ -**Added:** - -* Added ``is_space_group_latt_parms`` method in ``symmetryutilities.py`` -* Added ``is_constant_formula`` method in ``symmetryutilities.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``isSpaceGroupLatPar`` method in ``symmetryutilities.py`` for removal in version 4.0.0 -* Deprecated ``isconstantFormula`` method in ``symmetryutilities.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-2.rst b/news/deprecate-symmetryutilities-2.rst deleted file mode 100644 index 4e2d5abe..00000000 --- a/news/deprecate-symmetryutilities-2.rst +++ /dev/null @@ -1,26 +0,0 @@ -**Added:** - -* Added ``position_difference`` method in ``symmetryutilities.py`` -* Added ``nearest_site_index`` method in ``symmetryutilities.py`` -* Added ``_find_invariants`` method in ``symmetryutilities.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``positionDifference`` method in ``symmetryutilities.py`` for removal in version 4.0.0 -* Deprecated ``nearestSiteIndex`` method in ``symmetryutilities.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-3.rst b/news/deprecate-symmetryutilities-3.rst deleted file mode 100644 index 0527f8ba..00000000 --- a/news/deprecate-symmetryutilities-3.rst +++ /dev/null @@ -1,27 +0,0 @@ -**Added:** - -* Added ``equal_positions`` method in ``symmetryutilities.py`` -* Added ``expand_position`` method in ``symmetryutilities.py`` -* Added ``null_space`` method in ``symmetryutilities.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``equalPositions`` method in ``symmetryutilities.py`` for removal in version 4.0.0 -* Deprecated ``expandPosition`` method in ``symmetryutilities.py`` for removal in version 4.0.0 -* Deprecated ``nullSpace`` method in ``symmetryutilities.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-4.rst b/news/deprecate-symmetryutilities-4.rst deleted file mode 100644 index 35d02131..00000000 --- a/news/deprecate-symmetryutilities-4.rst +++ /dev/null @@ -1,28 +0,0 @@ -**Added:** - -* Added ``convert_fp_num_to_signed_rational`` method in ``GeneratorSite`` class -* Added ``_find_null_space`` method in ``GeneratorSite`` class -* Added ``_find_pos_parameters`` method in ``GeneratorSite`` class -* Added ``_find_u_space`` method in ``GeneratorSite`` class -* Added ``_find_u_parameters`` method in ``GeneratorSite`` class -* Added ``_find_eq_uij`` method in ``GeneratorSite`` class - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``signedRatStr`` method in in ``GeneratorSite`` class for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-5.rst b/news/deprecate-symmetryutilities-5.rst deleted file mode 100644 index 8e572454..00000000 --- a/news/deprecate-symmetryutilities-5.rst +++ /dev/null @@ -1,29 +0,0 @@ -**Added:** - -* Added ``position_formula`` method in ``GeneratorSite`` class -* Added ``u_formula`` method in ``GeneratorSite`` class -* Added ``eq_index`` method in ``GeneratorSite`` class -* Added ``prune_formula_dictionary`` method in ``symmetryutilities.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``positionFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 -* Deprecated ``UFormula`` method in ``GeneratorSite`` class for removal in version 4.0.0 -* Deprecated ``eqIndex`` method in ``GeneratorSite`` class for removal in version 4.0.0 -* Deprecated ``pruneFormulaDictionary`` method in ``symmetryutilities.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-6.rst b/news/deprecate-symmetryutilities-6.rst deleted file mode 100644 index b78e0917..00000000 --- a/news/deprecate-symmetryutilities-6.rst +++ /dev/null @@ -1,32 +0,0 @@ -**Added:** - -* Added ``_find_constraints`` method in ``SymmetryConstraints`` class -* Added ``pos_parm_symbols`` method in ``SymmetryConstraints`` class -* Added ``pos_parm_values`` method in ``SymmetryConstraints`` class -* Added ``u_parm_symbols`` method in ``SymmetryConstraints`` class -* Added ``u_parm_values`` method in ``SymmetryConstraints`` class -* Added ``u_formulas`` method in ``SymmetryConstraints`` class - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``posparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``posparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``UparSymbols`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``UparValues`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``UFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-symmetryutilities-7.rst b/news/deprecate-symmetryutilities-7.rst deleted file mode 100644 index e014dac4..00000000 --- a/news/deprecate-symmetryutilities-7.rst +++ /dev/null @@ -1,27 +0,0 @@ -**Added:** - -* Added ``position_formulas`` method in ``SymmetryConstraints`` class -* Added ``position_formulas_pruned`` method in ``SymmetryConstraints`` class -* Added ``u_formulas_pruned`` method in ``SymmetryConstraints`` class - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``positionFormulas`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``positionFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 -* Deprecated ``UFormulasPruned`` method in ``SymmetryConstraints`` class for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-toLine.rst b/news/deprecate-toLine.rst deleted file mode 100644 index ca25c38c..00000000 --- a/news/deprecate-toLine.rst +++ /dev/null @@ -1,38 +0,0 @@ -**Added:** - -* Added ``_parse_cif_data_source`` method in ``p_cif.py`` -* Added ``_parse_cif_block`` method in ``p_cif.py`` -* Added ``to_lines`` method in ``p_cif.py`` -* Added ``to_lines`` method in ``p_pdb.py`` -* Added ``to_lines`` method in ``p_rawxyz.py`` -* Added ``to_lines`` method in ``p_xcfg.py`` -* Added ``to_lines`` method in ``p_xyz.py`` -* Added ``to_lines`` method in ``structureparser.py`` -* Added ``_lines_iterator`` method in ``p_discus.py`` -* Added ``to_lines`` method in ``p_discus.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``toLines`` method in ``p_cif.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``p_pdb.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``p_xyz.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``structureparser.py`` for removal in version 4.0.0 -* Deprecated ``toLines`` method in ``p_discus.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/deprecate-utils.rst b/news/deprecate-utils.rst deleted file mode 100644 index 693b86ca..00000000 --- a/news/deprecate-utils.rst +++ /dev/null @@ -1,39 +0,0 @@ -**Added:** - -* Added ``atom_bare_symbol`` method in ``utils.py`` -* Added ``_get_ordered_formats`` method in ``p_auto.py`` -* Added ``_wrap_parse_method`` method in ``p_auto.py`` -* Added ``_tr_atom_site_u_iso_or_equiv`` method in ``p_cif.py`` -* Added ``_tr_atom_site_b_iso_or_equiv`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_11`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_22`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_33`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_12`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_13`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_u_23`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_11`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_22`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_33`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_12`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_13`` method in ``p_cif.py`` -* Added ``_tr_atom_site_aniso_b_23`` method in ``p_cif.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated ``atomBareSymbol`` method in ``utils.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/documentation-fix.rst b/news/documentation-fix.rst deleted file mode 100644 index 30fe87e3..00000000 --- a/news/documentation-fix.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: documentation fix for diffpy.structure - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/fix-deprecation.rst b/news/fix-deprecation.rst deleted file mode 100644 index 5be83709..00000000 --- a/news/fix-deprecation.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* Fix deprecation for open file for Python 3.14 - -**Security:** - -* diff --git a/news/fix-load-structure.rst b/news/fix-load-structure.rst deleted file mode 100644 index a324ad4f..00000000 --- a/news/fix-load-structure.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added method ``load_structure`` in ``__init__.py`` - -**Changed:** - -* - -**Deprecated:** - -* Deprecated method ``loadStructure`` in ``__init__.py`` for removal in version 4.0.0 - -**Removed:** - -* - -**Fixed:** - -* Fixed ``load_structure`` with successfully loading `Path` object - -**Security:** - -* diff --git a/news/license.rst b/news/license.rst deleted file mode 100644 index 09fe706f..00000000 --- a/news/license.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* No news added: update copyright holders in licesnss - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/skpkg-update.rst b/news/skpkg-update.rst deleted file mode 100644 index a037a121..00000000 --- a/news/skpkg-update.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Support for Python 3.14 - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* Support for Python 3.11 - -**Fixed:** - -* - -**Security:** - -* diff --git a/news/vesta_view.rst b/news/vesta_view.rst deleted file mode 100644 index b8564ee6..00000000 --- a/news/vesta_view.rst +++ /dev/null @@ -1,23 +0,0 @@ -**Added:** - -* Added parser for vesta specific files and viewer for vesta - -**Changed:** - -* - -**Deprecated:** - -* - -**Removed:** - -* - -**Fixed:** - -* - -**Security:** - -* From c5659e9a5b59f969c87cca6853027401d0283a54 Mon Sep 17 00:00:00 2001 From: stevenhua0320 Date: Sun, 29 Mar 2026 13:19:03 -0400 Subject: [PATCH 218/226] chore: fix CI badge in README.rst --- README.rst | 4 ++-- news/CI-badge-fix.rst | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 news/CI-badge-fix.rst diff --git a/README.rst b/README.rst index c1059381..3ce08dfa 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,8 @@ .. |Black| image:: https://img.shields.io/badge/code_style-black-black :target: https://github.com/psf/black -.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov-on-merge-to-main.yml/badge.svg - :target: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov-on-merge-to-main.yml +.. |CI| image:: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov.yml/badge.svg + :target: https://github.com/diffpy/diffpy.structure/actions/workflows/matrix-and-codecov.yml .. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.structure/branch/main/graph/badge.svg :target: https://codecov.io/gh/diffpy/diffpy.structure diff --git a/news/CI-badge-fix.rst b/news/CI-badge-fix.rst new file mode 100644 index 00000000..2df63a8f --- /dev/null +++ b/news/CI-badge-fix.rst @@ -0,0 +1,23 @@ +**Added:** + +* No News Added: fix CI badge and target in README.rst + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From f7f546684bd56eb66c1c9720e23ae4ff83495256 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 2 Apr 2026 11:59:51 -0400 Subject: [PATCH 219/226] rm ase adapter tests --- tests/test_structure.py | 91 ----------------------------------------- 1 file changed, 91 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 0b6fb8e1..5b61f7a2 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -892,97 +892,6 @@ def test_get_lattice_vector_angles(datafile): assert np.allclose(actual_lattice_vector_angles, expected_lattice_vector_angles) -@pytest.mark.parametrize( - "input", - [ - # case: user calls the conversion function on a Structure object that already contains - # a structure - # expected: the structure is wiped clean and replaced with the converted structure - # we use the fixture to create a Structure object that already contains a structure. - "use_diffpy_structure_fixture", - # case: user calls the conversion function on an empty Structure object - # expected: the converted structure is added to the empty Structure object without issue - Structure(), - ], -) -def test_convert_ase_to_diffpy_structure(input, build_ase_atom_object, build_diffpy_structure_object): - """Check convert_ase_to_diffpy_structure()""" - # input: User wants to convert an ASE.Atoms object to a diffpy.structure.Structure object - # expected: All similar data is transferred correctly, - # including chemical symbols, fractional coordinates, and lattice parameters. - - # Create an ASE.Atoms object - ase_zb = build_ase_atom_object - # Create an identical expected diffpy Structure object - expected_structure = build_diffpy_structure_object - - # Create new Structure object and convert ase to diffpy structure. - # Use the string input to determine which type of Structure object to create for the test - if isinstance(input, str): - actual_structure = build_diffpy_structure_object - else: - actual_structure = input - # set the lost_info variable, which gets the attribute of method from ASE.Atoms object, gets the values - # and stores it in a dict. This is used because ASE.Atoms stores more/different - # info that a diffpy.structure object - lost_info_dict = actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info="get_masses") - actual_masses = lost_info_dict["get_masses"] - expected_masses = ase_zb.get_masses() - assert np.allclose(actual_masses, expected_masses) - - # Compare the actual and expected values - expected_lattice_vectors = expected_structure.get_lattice_vectors() - actual_lattice_vectors = actual_structure.get_lattice_vectors() - assert np.allclose(expected_lattice_vectors, actual_lattice_vectors) - - expected_lattice_angle = expected_structure.get_lattice_vector_angles() - actual_lattice_angle = actual_structure.get_lattice_vector_angles() - assert np.allclose(expected_lattice_angle, actual_lattice_angle) - - expected_symbols = expected_structure.get_chemical_symbols() - actual_symbols = actual_structure.get_chemical_symbols() - assert actual_symbols == expected_symbols - - expected_coords = expected_structure.get_fractional_coordinates() - actual_coords = actual_structure.get_fractional_coordinates() - assert np.allclose(actual_coords, expected_coords) - - -def test_convert_ase_to_diffpy_structure_bad_typeerror(): - """Check convert_ase_to_diffpy_structure() with bad input.""" - bad_input = "string" # pass a string instead of ase.Atoms - expected_error_msg = "Input must be an instance of ase.Atoms but got type ." - actual_structure = Structure() - with pytest.raises(TypeError, match=expected_error_msg): - actual_structure.convert_ase_to_diffpy_structure(bad_input) - - -@pytest.mark.parametrize( - "bad_lost_info,error,expected_error_msg", - [ # case: User provides an ASE.Atoms object but requests lost_info that is not an attribute of ASE.Atoms - # expected: A ValueError is raised with a clear error message indicating the requested lost_info - # attribute is invalid. - (["invalid_method"], ValueError, "ASE.Atoms object has no attribute 'invalid_method'"), - # case: User provides an ASE.Atoms object but requests lost_info that is an attribute of ASE.Atoms - # but has not been set yet. - # expected: The error message from ase is raised indicating the specific issue with the - # requested lost_info attribute. - # We set the expected error message to None because this expectation is - # out of our control, but it is good to make sure that we are - # raising the error from ASE. - (["get_magnetic_moments"], RuntimeError, None), - ], -) -def test_convert_ase_to_diffpy_structure_bad_valueerror( - bad_lost_info, error, expected_error_msg, build_ase_atom_object -): - """Check convert_ase_to_diffpy_structure() with bad lost_info.""" - ase_zb = build_ase_atom_object - actual_structure = Structure() - with pytest.raises(error, match=expected_error_msg): - actual_structure.convert_ase_to_diffpy_structure(ase_zb, lost_info=bad_lost_info) - - # ---------------------------------------------------------------------------- @pytest.mark.parametrize( "existing, atype, xyz, expected_len, expected_element, expected_xyz", From c24fd7092f75dcca91098177f5db1a4e9137d63f Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 2 Apr 2026 12:01:53 -0400 Subject: [PATCH 220/226] rm ase adapter function --- src/diffpy/structure/structure.py | 96 ------------------------------- 1 file changed, 96 deletions(-) diff --git a/src/diffpy/structure/structure.py b/src/diffpy/structure/structure.py index cefb9fb4..a33f4643 100644 --- a/src/diffpy/structure/structure.py +++ b/src/diffpy/structure/structure.py @@ -18,7 +18,6 @@ import warnings import numpy -from ase import Atoms as ASEAtoms from diffpy.structure.atom import Atom from diffpy.structure.lattice import Lattice @@ -366,101 +365,6 @@ def get_lattice_vector_angles(self): gamma = self.lattice.angle(a, b) return numpy.array([alpha, beta, gamma]) - def convert_ase_to_diffpy_structure( - self, - ase_atoms: ASEAtoms, - lost_info: list[str] | None = None, - ) -> Structure | tuple[Structure, dict]: # noqa - """Convert ASE `Atoms` object to this `Structure` instance. - - The conversion process involves extracting the lattice parameters, chemical symbols, - and fractional coordinates from the ASE `Atoms` object and populating the corresponding - attributes of this `Structure` instance. The `lattice` attribute is set based on the - cell parameters of the ASE `Atoms` object, and each `Atom` in this `Structure` is created - with the chemical symbol and fractional coordinates extracted from the ASE `Atoms`. - - Parameters - ---------- - ase_structure : ase.Atoms - The ASE `Atoms` object to be converted. - lost_info : str or list of str, optional - The method(s) or attribute(s) to extract from the ASE `Atoms` - object that do not have a direct equivalent in the `Structure` class. - This will be provided in a dictionary format where keys are the - method/attribute name(s) and value(s) are the corresponding data - extracted from the ASE `Atoms` object. - Default is None. See `Examples` for usage. - - Returns - ------- - lost_info : dict, optional - If specified, the dictionary containing any information from the ASE `Atoms` - object that is not currently available in the `Structure` class. - Default behavior is to return `None`. - If `lost_info` is provided, a dictionary containing - any information from the ASE `Atoms` will be returned. - This may include information such as magnetic moments, charge states, - or other ASE-specific properties that do not have a direct equivalent - in the `Structure` class. - - Raises - ------ - TypeError - If the input `ase_structure` is not an instance of `ase.Atoms`. - ValueError - If any of the specified `lost_info` attributes are not present in the ASE `Atoms` object. - - Examples - -------- - An example of converting an `ASE.Atoms` instance to a `Structure` instance, - - .. code-block:: python - from ase import Atoms - from diffpy.structure import Structure - - # Create an ASE Atoms object - ase_atoms = Atoms('H2O', positions=[[0, 0, 0], [0, 0, 1], [1, 0, 0]]) - - # Convert to a diffpy Structure object - structure = Structure() - structure.convert_ase_to_diffpy(ase_atoms) - - - To extract additional information from the ASE `Atoms` object that is not - directly represented in the `Structure` class, such as magnetic moments, - you can specify an attribute or method of `ASE.Atoms` as - a string or list of strings in `lost_info` list. For example, - - .. code-block:: python - lost_info = structure.convert_ase_to_diffpy( - ase_atoms, - lost_info='get_magnetic_moments' - ) - - will return a dictionary with the magnetic moments of the atoms in the ASE `Atoms` object. - """ - # clear structure before populating it with new atoms - del self[:] - if not isinstance(ase_atoms, ASEAtoms): - raise TypeError(f"Input must be an instance of ase.Atoms but got type {type(ase_atoms)}.") - cell = ase_atoms.get_cell() - self.lattice = Lattice(base=numpy.array(cell)) - symbols = ase_atoms.get_chemical_symbols() - scaled_positions = ase_atoms.get_scaled_positions() - for atom_symbol, frac_coord in zip(symbols, scaled_positions): - self.append(Atom(atom_symbol, xyz=frac_coord)) - if lost_info is None: - return - extracted_info = {} - if isinstance(lost_info, str): - lost_info = [lost_info] - for name in lost_info: - if not hasattr(ase_atoms, name): - raise ValueError(f"ASE.Atoms object has no attribute '{name}'.") - attr = getattr(ase_atoms, name) - extracted_info[name] = attr() if callable(attr) else attr - return extracted_info - def assign_unique_labels(self): """Set a unique label string for each `Atom` in this structure. From 30872d9a851106da5cdcc24cc992bd86e2c23c8c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 2 Apr 2026 12:03:19 -0400 Subject: [PATCH 221/226] update news --- news/ase-adapter.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/news/ase-adapter.rst b/news/ase-adapter.rst index 2cf7507a..30b585bd 100644 --- a/news/ase-adapter.rst +++ b/news/ase-adapter.rst @@ -8,7 +8,6 @@ * Added ``Structure.get_cartesian_coordinates()`` method to return the Cartesian coordinates of the sites. * Added ``Structure.get_fractional_coordinates()`` method to return the fractional coordinates of the sites. * Added ``Structure.get_chemical_symbols()`` method to return the chemical symbols of the sites. -* Added ``Structure.convert_ase_to_diffpy_structure()`` method to convert an ASE Atoms object to a DiffPy Structure object. **Changed:** From a018a30f2be37653f692b810a7dd943fde2deb3b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 2 Apr 2026 12:08:08 -0400 Subject: [PATCH 222/226] rm ase from requirements --- requirements/conda.txt | 1 - requirements/pip.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index bb3d289c..4c4ff50e 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,4 +1,3 @@ numpy pycifrw diffpy.utils -ase diff --git a/requirements/pip.txt b/requirements/pip.txt index bb3d289c..4c4ff50e 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,4 +1,3 @@ numpy pycifrw diffpy.utils -ase From 0e5cc9dab6cebd6eea0fd90ae04b9364b1f7c16b Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Thu, 2 Apr 2026 12:11:33 -0400 Subject: [PATCH 223/226] remove ase fixtures --- tests/conftest.py | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index abe71b67..5471acc1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,7 @@ import json from pathlib import Path -import numpy as np import pytest -from ase import Atoms - -from diffpy.structure import Atom, Lattice, Structure @pytest.fixture @@ -31,45 +27,3 @@ def _load(filename): return "tests/testdata/" + filename return _load - - -@pytest.fixture -def build_ase_atom_object(): - """Helper function to build an ASE.Atoms object for testing.""" - a = 5.409 - frac_coords = np.array( - [ - [0.0, 0.0, 0.0], - [0.5, 0.5, 0.5], - [0.25, 0.25, 0.25], - [0.75, 0.75, 0.75], - ] - ) - cart_coords = frac_coords * a - symbols = ["Zn", "Zn", "S", "S"] - ase_zb = Atoms(symbols=symbols, positions=cart_coords, cell=[[a, 0, 0], [0, a, 0], [0, 0, a]], pbc=True) - return ase_zb - - -@pytest.fixture -def build_diffpy_structure_object(): - """Helper function to build a diffpy.structure.Structure object for - testing.""" - a = 5.409 - frac_coords = np.array( - [ - [0.0, 0.0, 0.0], - [0.5, 0.5, 0.5], - [0.25, 0.25, 0.25], - [0.75, 0.75, 0.75], - ] - ) - lattice = Lattice(base=[[a, 0, 0], [0, a, 0], [0, 0, a]]) - atoms = [ - Atom("Zn", frac_coords[0]), - Atom("Zn", frac_coords[1]), - Atom("S", frac_coords[2]), - Atom("S", frac_coords[3]), - ] - diffpy_zb = Structure(atoms=atoms, lattice=lattice) - return diffpy_zb From 6259c383ab7fba5d152a0004abae522846583aad Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 3 Apr 2026 14:09:30 -0400 Subject: [PATCH 224/226] rm np.float64 requirement from test --- tests/test_structure.py | 208 ++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 5b61f7a2..e79a7938 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -734,103 +734,103 @@ def test_get_anisotropic_displacement_parameters(datafile, return_array): else: expected_displacement = { # Iodine - "I_8_11": np.float64(0.025), - "I_8_12": np.float64(0.0), - "I_8_13": np.float64(0.0226), - "I_8_22": np.float64(0.0234), - "I_8_23": np.float64(0.0), - "I_8_33": np.float64(0.0345), - "I_9_11": np.float64(0.025), - "I_9_12": np.float64(0.0), - "I_9_13": np.float64(0.0226), - "I_9_22": np.float64(0.0234), - "I_9_23": np.float64(0.0), - "I_9_33": np.float64(0.0345), - "I_10_11": np.float64(0.025), - "I_10_12": np.float64(0.0), - "I_10_13": np.float64(0.0226), - "I_10_22": np.float64(0.0234), - "I_10_23": np.float64(0.0), - "I_10_33": np.float64(0.0345), - "I_11_11": np.float64(0.025), - "I_11_12": np.float64(0.0), - "I_11_13": np.float64(0.0226), - "I_11_22": np.float64(0.0234), - "I_11_23": np.float64(0.0), - "I_11_33": np.float64(0.0345), - "I_12_11": np.float64(0.0234), - "I_12_12": np.float64(0.0), - "I_12_13": np.float64(0.0138), - "I_12_22": np.float64(0.0295), - "I_12_23": np.float64(0.0), - "I_12_33": np.float64(0.0253), - "I_13_11": np.float64(0.0234), - "I_13_12": np.float64(0.0), - "I_13_13": np.float64(0.0138), - "I_13_22": np.float64(0.0295), - "I_13_23": np.float64(0.0), - "I_13_33": np.float64(0.0253), - "I_14_11": np.float64(0.0234), - "I_14_12": np.float64(0.0), - "I_14_13": np.float64(0.0138), - "I_14_22": np.float64(0.0295), - "I_14_23": np.float64(0.0), - "I_14_33": np.float64(0.0253), - "I_15_11": np.float64(0.0234), - "I_15_12": np.float64(0.0), - "I_15_13": np.float64(0.0138), - "I_15_22": np.float64(0.0295), - "I_15_23": np.float64(0.0), - "I_15_33": np.float64(0.0253), + "I_8_11": 0.025, + "I_8_12": 0.0, + "I_8_13": 0.0226, + "I_8_22": 0.0234, + "I_8_23": 0.0, + "I_8_33": 0.0345, + "I_9_11": 0.025, + "I_9_12": 0.0, + "I_9_13": 0.0226, + "I_9_22": 0.0234, + "I_9_23": 0.0, + "I_9_33": 0.0345, + "I_10_11": 0.025, + "I_10_12": 0.0, + "I_10_13": 0.0226, + "I_10_22": 0.0234, + "I_10_23": 0.0, + "I_10_33": 0.0345, + "I_11_11": 0.025, + "I_11_12": 0.0, + "I_11_13": 0.0226, + "I_11_22": 0.0234, + "I_11_23": 0.0, + "I_11_33": 0.0345, + "I_12_11": 0.0234, + "I_12_12": 0.0, + "I_12_13": 0.0138, + "I_12_22": 0.0295, + "I_12_23": 0.0, + "I_12_33": 0.0253, + "I_13_11": 0.0234, + "I_13_12": 0.0, + "I_13_13": 0.0138, + "I_13_22": 0.0295, + "I_13_23": 0.0, + "I_13_33": 0.0253, + "I_14_11": 0.0234, + "I_14_12": 0.0, + "I_14_13": 0.0138, + "I_14_22": 0.0295, + "I_14_23": 0.0, + "I_14_33": 0.0253, + "I_15_11": 0.0234, + "I_15_12": 0.0, + "I_15_13": 0.0138, + "I_15_22": 0.0295, + "I_15_23": 0.0, + "I_15_33": 0.0253, # Tellurium - "Te_0_11": np.float64(0.0211), - "Te_0_12": np.float64(0.0), - "Te_0_13": np.float64(0.0109), - "Te_0_22": np.float64(0.0195), - "Te_0_23": np.float64(0.0), - "Te_0_33": np.float64(0.016), - "Te_1_11": np.float64(0.0211), - "Te_1_12": np.float64(0.0), - "Te_1_13": np.float64(0.0109), - "Te_1_22": np.float64(0.0195), - "Te_1_23": np.float64(0.0), - "Te_1_33": np.float64(0.016), - "Te_2_11": np.float64(0.0211), - "Te_2_12": np.float64(0.0), - "Te_2_13": np.float64(0.0109), - "Te_2_22": np.float64(0.0195), - "Te_2_23": np.float64(0.0), - "Te_2_33": np.float64(0.016), - "Te_3_11": np.float64(0.0211), - "Te_3_12": np.float64(0.0), - "Te_3_13": np.float64(0.0109), - "Te_3_22": np.float64(0.0195), - "Te_3_23": np.float64(0.0), - "Te_3_33": np.float64(0.016), - "Te_4_11": np.float64(0.0223), - "Te_4_12": np.float64(0.0), - "Te_4_13": np.float64(0.0179), - "Te_4_22": np.float64(0.018), - "Te_4_23": np.float64(0.0), - "Te_4_33": np.float64(0.0254), - "Te_5_11": np.float64(0.0223), - "Te_5_12": np.float64(0.0), - "Te_5_13": np.float64(0.0179), - "Te_5_22": np.float64(0.018), - "Te_5_23": np.float64(0.0), - "Te_5_33": np.float64(0.0254), - "Te_6_11": np.float64(0.0223), - "Te_6_12": np.float64(0.0), - "Te_6_13": np.float64(0.0179), - "Te_6_22": np.float64(0.018), - "Te_6_23": np.float64(0.0), - "Te_6_33": np.float64(0.0254), - "Te_7_11": np.float64(0.0223), - "Te_7_12": np.float64(0.0), - "Te_7_13": np.float64(0.0179), - "Te_7_22": np.float64(0.018), - "Te_7_23": np.float64(0.0), - "Te_7_33": np.float64(0.0254), + "Te_0_11": 0.0211, + "Te_0_12": 0.0, + "Te_0_13": 0.0109, + "Te_0_22": 0.0195, + "Te_0_23": 0.0, + "Te_0_33": 0.016, + "Te_1_11": 0.0211, + "Te_1_12": 0.0, + "Te_1_13": 0.0109, + "Te_1_22": 0.0195, + "Te_1_23": 0.0, + "Te_1_33": 0.016, + "Te_2_11": 0.0211, + "Te_2_12": 0.0, + "Te_2_13": 0.0109, + "Te_2_22": 0.0195, + "Te_2_23": 0.0, + "Te_2_33": 0.016, + "Te_3_11": 0.0211, + "Te_3_12": 0.0, + "Te_3_13": 0.0109, + "Te_3_22": 0.0195, + "Te_3_23": 0.0, + "Te_3_33": 0.016, + "Te_4_11": 0.0223, + "Te_4_12": 0.0, + "Te_4_13": 0.0179, + "Te_4_22": 0.018, + "Te_4_23": 0.0, + "Te_4_33": 0.0254, + "Te_5_11": 0.0223, + "Te_5_12": 0.0, + "Te_5_13": 0.0179, + "Te_5_22": 0.018, + "Te_5_23": 0.0, + "Te_5_33": 0.0254, + "Te_6_11": 0.0223, + "Te_6_12": 0.0, + "Te_6_13": 0.0179, + "Te_6_22": 0.018, + "Te_6_23": 0.0, + "Te_6_33": 0.0254, + "Te_7_11": 0.0223, + "Te_7_12": 0.0, + "Te_7_13": 0.0179, + "Te_7_22": 0.018, + "Te_7_23": 0.0, + "Te_7_33": 0.0254, } assert actual_displacement == expected_displacement @@ -856,14 +856,14 @@ def test_get_isotropic_displacement_parameters(datafile, return_array): assert np.allclose(actual_isotropic_displacement, expected_isotropic_displacement) else: expected_isotropic_displacement = { - "Pb_1_Uiso": np.float64(0.0225566), - "Pb_2_Uiso": np.float64(0.0225566), - "Pb_3_Uiso": np.float64(0.0225566), - "Pb_4_Uiso": np.float64(0.0225566), - "Te_5_Uiso": np.float64(0.0155528), - "Te_6_Uiso": np.float64(0.0155528), - "Te_7_Uiso": np.float64(0.0155528), - "Te_8_Uiso": np.float64(0.0155528), + "Pb_1_Uiso": 0.0225566, + "Pb_2_Uiso": 0.0225566, + "Pb_3_Uiso": 0.0225566, + "Pb_4_Uiso": 0.0225566, + "Te_5_Uiso": 0.0155528, + "Te_6_Uiso": 0.0155528, + "Te_7_Uiso": 0.0155528, + "Te_8_Uiso": 0.0155528, } assert actual_isotropic_displacement == expected_isotropic_displacement From 47b440db4115381e884db67a10bd7afb942c679c Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 3 Apr 2026 14:17:47 -0400 Subject: [PATCH 225/226] add input,expected to tests for adp getters --- tests/test_structure.py | 287 ++++++++++++++++++++-------------------- 1 file changed, 146 insertions(+), 141 deletions(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index e79a7938..223cb2a7 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -707,165 +707,170 @@ def test_get_cartesian_coordinates(datafile): @pytest.mark.parametrize( - "return_array", - [ # case: user wants ADPs as an array + "input,expected", + [ # case: user wants ADPs as an array so they set return_array=True # expected: a 3D array of shape (num_atoms, 3, 3) with the Uij values - True, - # case: user wants ADPs as a dictionary + [ + True, + np.array( + [ + [[0.0211, 0.0, 0.0109], [0.0, 0.0195, 0.0], [0.0109, 0.0, 0.016]], + [[0.0223, 0.0, 0.0179], [0.0, 0.018, 0.0], [0.0179, 0.0, 0.0254]], + [[0.025, 0.0, 0.0226], [0.0, 0.0234, 0.0], [0.0226, 0.0, 0.0345]], + [[0.0234, 0.0, 0.0138], [0.0, 0.0295, 0.0], [0.0138, 0.0, 0.0253]], + ] + ), + ], + # case: user wants ADPs as a dictionary so they set return_array=False (default behavior) # expected: a dictionary with keys like "I_8_11" and values as the corresponding Uij values - False, + [ + False, + { + # Iodine + "I_8_11": 0.025, + "I_8_12": 0.0, + "I_8_13": 0.0226, + "I_8_22": 0.0234, + "I_8_23": 0.0, + "I_8_33": 0.0345, + "I_9_11": 0.025, + "I_9_12": 0.0, + "I_9_13": 0.0226, + "I_9_22": 0.0234, + "I_9_23": 0.0, + "I_9_33": 0.0345, + "I_10_11": 0.025, + "I_10_12": 0.0, + "I_10_13": 0.0226, + "I_10_22": 0.0234, + "I_10_23": 0.0, + "I_10_33": 0.0345, + "I_11_11": 0.025, + "I_11_12": 0.0, + "I_11_13": 0.0226, + "I_11_22": 0.0234, + "I_11_23": 0.0, + "I_11_33": 0.0345, + "I_12_11": 0.0234, + "I_12_12": 0.0, + "I_12_13": 0.0138, + "I_12_22": 0.0295, + "I_12_23": 0.0, + "I_12_33": 0.0253, + "I_13_11": 0.0234, + "I_13_12": 0.0, + "I_13_13": 0.0138, + "I_13_22": 0.0295, + "I_13_23": 0.0, + "I_13_33": 0.0253, + "I_14_11": 0.0234, + "I_14_12": 0.0, + "I_14_13": 0.0138, + "I_14_22": 0.0295, + "I_14_23": 0.0, + "I_14_33": 0.0253, + "I_15_11": 0.0234, + "I_15_12": 0.0, + "I_15_13": 0.0138, + "I_15_22": 0.0295, + "I_15_23": 0.0, + "I_15_33": 0.0253, + # Tellurium + "Te_0_11": 0.0211, + "Te_0_12": 0.0, + "Te_0_13": 0.0109, + "Te_0_22": 0.0195, + "Te_0_23": 0.0, + "Te_0_33": 0.016, + "Te_1_11": 0.0211, + "Te_1_12": 0.0, + "Te_1_13": 0.0109, + "Te_1_22": 0.0195, + "Te_1_23": 0.0, + "Te_1_33": 0.016, + "Te_2_11": 0.0211, + "Te_2_12": 0.0, + "Te_2_13": 0.0109, + "Te_2_22": 0.0195, + "Te_2_23": 0.0, + "Te_2_33": 0.016, + "Te_3_11": 0.0211, + "Te_3_12": 0.0, + "Te_3_13": 0.0109, + "Te_3_22": 0.0195, + "Te_3_23": 0.0, + "Te_3_33": 0.016, + "Te_4_11": 0.0223, + "Te_4_12": 0.0, + "Te_4_13": 0.0179, + "Te_4_22": 0.018, + "Te_4_23": 0.0, + "Te_4_33": 0.0254, + "Te_5_11": 0.0223, + "Te_5_12": 0.0, + "Te_5_13": 0.0179, + "Te_5_22": 0.018, + "Te_5_23": 0.0, + "Te_5_33": 0.0254, + "Te_6_11": 0.0223, + "Te_6_12": 0.0, + "Te_6_13": 0.0179, + "Te_6_22": 0.018, + "Te_6_23": 0.0, + "Te_6_33": 0.0254, + "Te_7_11": 0.0223, + "Te_7_12": 0.0, + "Te_7_13": 0.0179, + "Te_7_22": 0.018, + "Te_7_23": 0.0, + "Te_7_33": 0.0254, + }, + ], ], ) -def test_get_anisotropic_displacement_parameters(datafile, return_array): +def test_get_anisotropic_displacement_parameters(datafile, input, expected): """Check Structure.get_anisotropic_displacement_parameters()""" tei_stru = Structure(filename=datafile("TeI.cif")) - actual_displacement = tei_stru.get_anisotropic_displacement_parameters(return_array=return_array) - if return_array: - expected_one_atom = np.array( - [ - [[0.0211, 0.0, 0.0109], [0.0, 0.0195, 0.0], [0.0109, 0.0, 0.016]], - [[0.0223, 0.0, 0.0179], [0.0, 0.018, 0.0], [0.0179, 0.0, 0.0254]], - [[0.025, 0.0, 0.0226], [0.0, 0.0234, 0.0], [0.0226, 0.0, 0.0345]], - [[0.0234, 0.0, 0.0138], [0.0, 0.0295, 0.0], [0.0138, 0.0, 0.0253]], - ] - ) - expected_displacement = np.repeat(expected_one_atom, 4, axis=0) + actual_displacement = tei_stru.get_anisotropic_displacement_parameters(return_array=input) + if isinstance(expected, np.ndarray): + expected_displacement = np.repeat(expected, 4, axis=0) assert np.allclose(actual_displacement, expected_displacement) - else: - expected_displacement = { - # Iodine - "I_8_11": 0.025, - "I_8_12": 0.0, - "I_8_13": 0.0226, - "I_8_22": 0.0234, - "I_8_23": 0.0, - "I_8_33": 0.0345, - "I_9_11": 0.025, - "I_9_12": 0.0, - "I_9_13": 0.0226, - "I_9_22": 0.0234, - "I_9_23": 0.0, - "I_9_33": 0.0345, - "I_10_11": 0.025, - "I_10_12": 0.0, - "I_10_13": 0.0226, - "I_10_22": 0.0234, - "I_10_23": 0.0, - "I_10_33": 0.0345, - "I_11_11": 0.025, - "I_11_12": 0.0, - "I_11_13": 0.0226, - "I_11_22": 0.0234, - "I_11_23": 0.0, - "I_11_33": 0.0345, - "I_12_11": 0.0234, - "I_12_12": 0.0, - "I_12_13": 0.0138, - "I_12_22": 0.0295, - "I_12_23": 0.0, - "I_12_33": 0.0253, - "I_13_11": 0.0234, - "I_13_12": 0.0, - "I_13_13": 0.0138, - "I_13_22": 0.0295, - "I_13_23": 0.0, - "I_13_33": 0.0253, - "I_14_11": 0.0234, - "I_14_12": 0.0, - "I_14_13": 0.0138, - "I_14_22": 0.0295, - "I_14_23": 0.0, - "I_14_33": 0.0253, - "I_15_11": 0.0234, - "I_15_12": 0.0, - "I_15_13": 0.0138, - "I_15_22": 0.0295, - "I_15_23": 0.0, - "I_15_33": 0.0253, - # Tellurium - "Te_0_11": 0.0211, - "Te_0_12": 0.0, - "Te_0_13": 0.0109, - "Te_0_22": 0.0195, - "Te_0_23": 0.0, - "Te_0_33": 0.016, - "Te_1_11": 0.0211, - "Te_1_12": 0.0, - "Te_1_13": 0.0109, - "Te_1_22": 0.0195, - "Te_1_23": 0.0, - "Te_1_33": 0.016, - "Te_2_11": 0.0211, - "Te_2_12": 0.0, - "Te_2_13": 0.0109, - "Te_2_22": 0.0195, - "Te_2_23": 0.0, - "Te_2_33": 0.016, - "Te_3_11": 0.0211, - "Te_3_12": 0.0, - "Te_3_13": 0.0109, - "Te_3_22": 0.0195, - "Te_3_23": 0.0, - "Te_3_33": 0.016, - "Te_4_11": 0.0223, - "Te_4_12": 0.0, - "Te_4_13": 0.0179, - "Te_4_22": 0.018, - "Te_4_23": 0.0, - "Te_4_33": 0.0254, - "Te_5_11": 0.0223, - "Te_5_12": 0.0, - "Te_5_13": 0.0179, - "Te_5_22": 0.018, - "Te_5_23": 0.0, - "Te_5_33": 0.0254, - "Te_6_11": 0.0223, - "Te_6_12": 0.0, - "Te_6_13": 0.0179, - "Te_6_22": 0.018, - "Te_6_23": 0.0, - "Te_6_33": 0.0254, - "Te_7_11": 0.0223, - "Te_7_12": 0.0, - "Te_7_13": 0.0179, - "Te_7_22": 0.018, - "Te_7_23": 0.0, - "Te_7_33": 0.0254, - } - assert actual_displacement == expected_displacement + if isinstance(expected, dict): + assert actual_displacement == expected @pytest.mark.parametrize( - "return_array", + "input,expected", [ # case: user wants isotropic displacement parameters as an array + # so they set return_array=True # expected: a 1D array of shape (num_atoms,) with the Uiso values - True, + [True, np.array([0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528])], # case: user wants isotropic displacement parameters as a dictionary + # so they set return_array=False (default behavior) # expected: a dictionary with keys like "I_Uiso" and values as the corresponding Uiso values - False, + [ + False, + { + "Pb_1_Uiso": 0.0225566, + "Pb_2_Uiso": 0.0225566, + "Pb_3_Uiso": 0.0225566, + "Pb_4_Uiso": 0.0225566, + "Te_5_Uiso": 0.0155528, + "Te_6_Uiso": 0.0155528, + "Te_7_Uiso": 0.0155528, + "Te_8_Uiso": 0.0155528, + }, + ], ], ) -def test_get_isotropic_displacement_parameters(datafile, return_array): +def test_get_isotropic_displacement_parameters(datafile, input, expected): """Check Structure.get_isotropic_displacement_parameters()""" pbte_stru = Structure(filename=datafile("PbTe.cif")) - actual_isotropic_displacement = pbte_stru.get_isotropic_displacement_parameters(return_array=return_array) - if return_array: - expected_isotropic_displacement = np.array( - [0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528] - ) - assert np.allclose(actual_isotropic_displacement, expected_isotropic_displacement) - else: - expected_isotropic_displacement = { - "Pb_1_Uiso": 0.0225566, - "Pb_2_Uiso": 0.0225566, - "Pb_3_Uiso": 0.0225566, - "Pb_4_Uiso": 0.0225566, - "Te_5_Uiso": 0.0155528, - "Te_6_Uiso": 0.0155528, - "Te_7_Uiso": 0.0155528, - "Te_8_Uiso": 0.0155528, - } - assert actual_isotropic_displacement == expected_isotropic_displacement + actual_isotropic_displacement = pbte_stru.get_isotropic_displacement_parameters(return_array=input) + if isinstance(expected, np.ndarray): + assert np.allclose(actual_isotropic_displacement, expected) + if isinstance(expected, dict): + assert actual_isotropic_displacement == expected def test_get_occupancies(datafile): From 65d27290a978485de1fbe77095ac1b2062214e36 Mon Sep 17 00:00:00 2001 From: Caden Myers Date: Fri, 3 Apr 2026 14:19:36 -0400 Subject: [PATCH 226/226] precommit edits --- tests/test_structure.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_structure.py b/tests/test_structure.py index 223cb2a7..39591bc1 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -844,7 +844,10 @@ def test_get_anisotropic_displacement_parameters(datafile, input, expected): [ # case: user wants isotropic displacement parameters as an array # so they set return_array=True # expected: a 1D array of shape (num_atoms,) with the Uiso values - [True, np.array([0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528])], + [ + True, + np.array([0.0225566, 0.0225566, 0.0225566, 0.0225566, 0.0155528, 0.0155528, 0.0155528, 0.0155528]), + ], # case: user wants isotropic displacement parameters as a dictionary # so they set return_array=False (default behavior) # expected: a dictionary with keys like "I_Uiso" and values as the corresponding Uiso values