QCElemental-0.5.0/000077500000000000000000000000001351361252000136445ustar00rootroot00000000000000QCElemental-0.5.0/.codecov.yml000066400000000000000000000004251351361252000160700ustar00rootroot00000000000000coverage: ignore: - */tests/* - qcelemental/_version.py - setup.py status: patch: false project: default: threshold: 80% comment: layout: "header" require_changes: false branches: null behavior: default flags: null paths: null QCElemental-0.5.0/.gitattributes000066400000000000000000000000451351361252000165360ustar00rootroot00000000000000qcelemental/_version.py export-subst QCElemental-0.5.0/.gitignore000066400000000000000000000025241351361252000156370ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # 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 # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/build/ docs/source/api/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ # project masses.h physconst.h # nist_data nist_data/nist_* # Parsl ipengine.* parsl_scripts/* runinfo/* # Pycharm .idea/ # VSCode .vscode/ QCElemental-0.5.0/.lgtm.yml000066400000000000000000000004321351361252000154070ustar00rootroot00000000000000# Configure LGTM for this package extraction: python: python_setup: version: 3 path_classifiers: library: - versioneer.py # Set Versioneer.py to an external "library" (3rd party code) - devtools/* generated: - nist_data/* - qcelemental/_version.py QCElemental-0.5.0/.travis.yml000066400000000000000000000026011351361252000157540ustar00rootroot00000000000000# After changing this file, check it on: # http://lint.travis-ci.org/ language: python # Run jobs on container-based infrastructure, can be overridden per job dist: trusty matrix: include: - os: linux python: 3.6 env: - PYTHON_VER=3.6 - PROG=MINIMAL - os: linux python: 3.6 env: - PYTHON_VER=3.6 - PROG=FULL - os: linux #python: 3.7 env: - PYTHON_VER=3.7 - PROG=FULL before_install: - uname -a - free -m - df -h - ulimit -a # Setup python environment - source devtools/travis-ci/before_install.sh - python -V install: # Create test environment for package - | if [ $PROG == "MINIMAL" ]; then python devtools/scripts/conda_env.py -n=test -p=$PYTHON_VER devtools/conda-envs/minimal.yaml elif [ $PROG == "FULL" ]; then python devtools/scripts/conda_env.py -n=test -p=$PYTHON_VER devtools/conda-envs/base.yaml else echo "ERROR: No match for PROG ($PROG)." exit 1 fi - source activate test # Build and install package - python setup.py develop --no-deps before_script: - python -V - conda list script: # Get a bit of info first - python -c "import qcelemental; print(qcelemental.__version__)" # Run canonical tests - pytest -v --cov=qcelemental/ qcelemental/ notifications: email: false after_success: - codecov QCElemental-0.5.0/CHANGELOG.md000066400000000000000000000000641351361252000154550ustar00rootroot00000000000000See [changelog in docs](docs/source/changelog.rst). QCElemental-0.5.0/LICENSE000066400000000000000000000030051351361252000146470ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2018, The Molecular Sciences Software Institute All rights reserved. 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 notice, this list of conditions and the following disclaimer. * 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 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. QCElemental-0.5.0/MANIFEST.in000066400000000000000000000003431351361252000154020ustar00rootroot00000000000000recursive-include qcelemental *.py *.json *.md recursive-exclude qcelemental/checkup_data *.py *.md include setup.py include README.md include LICENSE include MANIFEST.in include versioneer.py include qcelemental/_version.py QCElemental-0.5.0/README.md000066400000000000000000000064421351361252000151310ustar00rootroot00000000000000# QCElemental [![Build Status](https://travis-ci.org/MolSSI/QCElemental.svg?branch=master)](https://travis-ci.org/MolSSI/QCElemental) [![codecov](https://codecov.io/gh/MolSSI/QCElemental/branch/master/graph/badge.svg)](https://codecov.io/gh/MolSSI/QCElemental) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/MolSSI/QCElemental.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/MolSSI/QCElemental/context:python) [![Documentation Status](https://readthedocs.org/projects/qcelemental/badge/?version=latest)](https://qcelemental.readthedocs.io/en/latest/?badge=latest) [![Chat on Slack](https://img.shields.io/badge/chat-on_slack-green.svg?longCache=true&style=flat&logo=slack)](https://join.slack.com/t/qcdb/shared_invite/enQtNDIzNTQ2OTExODk0LWM3OTgxN2ExYTlkMTlkZjA0OTExZDlmNGRlY2M4NWJlNDlkZGQyYWUxOTJmMzc3M2VlYzZjMjgxMDRkYzFmOTE) ![python](https://img.shields.io/badge/python-3.6+-blue.svg) QCElemental is a resource module for quantum chemistry containing physical constants and periodic table data from NIST and molecule handlers. Periodic Table and Physical Constants data are pulled from NIST srd144 and srd121, respectively ([details](nist_data/README.md)) in a renewable manner (class around NIST-published JSON file). This project also contains a generator, validator, and translator for [Molecule QCSchema](https://molssi-qc-schema.readthedocs.io/en/latest/auto_topology.html). ### Periodic Table A variety of periodic table quantities are available using virtually any alias: ```python >>> import qcelemental as qcel >>> qcel.periodictable.to_E('KRYPTON') 'Kr' >>> qcel.periodictable.to_element(36) 'Krypton' >>> qcel.periodictable.to_Z('kr84') 36 >>> qcel.periodictable.to_A('Kr') 84 >>> qcel.periodictable.to_A('D') 2 >>> qcel.periodictable.to_mass('kr', return_decimal=True) Decimal('83.9114977282') >>> qcel.periodictable.to_mass('kr84') 83.9114977282 >>> qcel.periodictable.to_mass('Kr86') 85.9106106269 ``` ### Physical Constants Physical constants can be acquired directly from the [NIST CODATA](https://physics.nist.gov/cuu/Constants/Table/allascii.txt): ```python >>> import qcelemental as qcel >>> qcel.constants.Hartree_energy_in_eV 27.21138602 >>> qcel.constants.get('hartree ENERGY in ev') 27.21138602 >>> pc = qcel.constants.get('hartree ENERGY in ev', return_tuple=True) >>> pc.lbl 'Hartree energy in eV' >>> pc.data Decimal('27.21138602') >>> pc.units 'eV' >>> pc.comment 'uncertainty=0.000 000 17' ``` Alternatively, with the use of the [Pint unit conversion package](https://pint.readthedocs.io/en/latest/), arbitrary conversion factors can be obtained: ```python >>> qcel.constants.conversion_factor("bohr", "miles") 3.2881547429884475e-14 ``` ### Covalent Radii Covalent radii are accessible for most of the periodic table from [Alvarez, Dalton Transactions (2008) doi:10.1039/b801115j](https://doi.org/10.1039/b801115j). ```python >>> import qcelemental as qcel >>> qcel.covalentradii.get('I') 2.626719314386381 >>> qcel.covalentradii.get('I', units='angstrom') 1.39 >>> qcel.covalentradii.get(116) Traceback (most recent call last): ... qcelemental.exceptions.DataUnavailableError: ('covalent radius', 'Lv') >>> qcel.covalentradii.get(116, missing=4.0) 4.0 >>> qcel.covalentradii.get('iodine', return_tuple=True).to_dict() {'label': 'I', 'units': 'angstrom', 'data': Decimal('1.39')} ``` QCElemental-0.5.0/devtools/000077500000000000000000000000001351361252000155035ustar00rootroot00000000000000QCElemental-0.5.0/devtools/README.md000066400000000000000000000045011351361252000167620ustar00rootroot00000000000000# Development, testing, and deployment tools This directory contains a collection of tools for running Continuous Integration (CI) tests, conda installation, and other development tools not directly related to the coding process. ## Manifest ### Continuous Integration You should test your code, but do not feel compelled to use these specific programs. You also may not need Unix and Windows testing if you only plan to deploy on specific platforms. These are just to help you get started * `travis-ci`: Linux and OSX based testing through [Travis-CI](https://about.travis-ci.com/) * `install.sh`: Pip/Miniconda installation script for Travis * `appveyor`: Windows based testing through [AppVeyor](https://www.appveyor.com/) * `install_conda.ps1` Powershell installation script of Conda components ## How to contribute changes - Clone the repository if you have write access to the main repo, fork the repository if you are a collaborator. - Make a new branch with `git checkout -b {your branch name}` - Make changes and test your code - Push the branch to the repo (either the main or your fork) with `git push -u origin {your branch name}` * Note that `origin` is the default name assigned to the remote, yours may be different - Make a PR on GitHub with your changes - We'll review the changes and get your code into the repo after lively discussion! ## Checklist for updates - [ ] Make sure there is an/are issue(s) opened for your specific update - [ ] Create the PR, referencing the issue - [ ] Debug the PR as needed until tests pass - [ ] Tag the final, debugged version * `git tag -a X.Y.Z [latest pushed commit] && git push --follow-tags` - [ ] Get the PR merged in ## Versioneer Auto-version [Versioneer](https://github.com/warner/python-versioneer) will automatically infer what version is installed by looking at the `git` tags and how many commits ahead this version is. The format follows [PEP 440](https://www.python.org/dev/peps/pep-0440/) and has the regular expression of: ```regexp \d+.\d+.\d+(?\+\d+-[a-z0-9]+) ``` If the version of this commit is the same as a `git` tag, the installed version is the same as the tag, e.g. `qcfractal-0.1.2`, otherwise it will be appended with `+X` where `X` is the number of commits ahead from the last tag, and then `-YYYYYY` where the `Y`'s are replaced with the `git` commit hash. QCElemental-0.5.0/devtools/conda-envs/000077500000000000000000000000001351361252000175405ustar00rootroot00000000000000QCElemental-0.5.0/devtools/conda-envs/README.md000066400000000000000000000021501351361252000210150ustar00rootroot00000000000000# QCElemental Pre-built Conda Environments The QCElemental program has few requirements on its own `meta.yaml` file, however, you may want to emulate the server side of things on your own. To help make that possible, we have provided the various YAML files here which can be used to quickly and mostly automatically build a working environment for to emulate the server. These use the `conda env create` commands (examples below) instead of the more common `conda create` (the commands are slightly different as of writting, circa Conda 4.3), so note the difference in commands. ## Requirements to use Environments 1. `git` 2. `conda` 3. `conda` installed `pip` (pretty much always available unless you are in some custom Python-less Conda environment such as an `R`-based env.) 4. Network access ## Setup/Install Run the following command to configure a new environment with the replacements: * `{name}`: Replace with whatever you want to call the new env * `{file}`: Replace with target file ```bash conda env create -n {name} -f {file} ``` To access the new environment: ```bash conda activate {name} ``` QCElemental-0.5.0/devtools/conda-envs/base.yaml000066400000000000000000000005101351361252000213320ustar00rootroot00000000000000name: test channels: - defaults - conda-forge dependencies: # Base depends - numpy - nomkl - python - pint - pydantic>=0.30.1 # Optional depends - networkx - py3dmol # Testing - pytest>=4.0.0 - pytest-cov - codecov - scipy # tests an aspect of a helper fn not used by qcel functionality QCElemental-0.5.0/devtools/conda-envs/minimal.yaml000066400000000000000000000003141351361252000220500ustar00rootroot00000000000000name: test channels: - defaults - conda-forge dependencies: # Base depends - numpy - nomkl - python - pint - pydantic>=0.30.1 # Testing - pytest>=4.0.0 - pytest-cov - codecov QCElemental-0.5.0/devtools/scripts/000077500000000000000000000000001351361252000171725ustar00rootroot00000000000000QCElemental-0.5.0/devtools/scripts/conda_env.py000066400000000000000000000021361351361252000215020ustar00rootroot00000000000000import argparse import os import shutil import subprocess as sp # Args parser = argparse.ArgumentParser(description='Creates a conda environment from file for a given Python version.') parser.add_argument('-n', '--name', type=str, nargs=1, help='The name of the created Python environment') parser.add_argument('-p', '--python', type=str, nargs=1, help='The version of the created Python environment') parser.add_argument('conda_file', nargs='*', help='The file for the created Python environment') args = parser.parse_args() with open(args.conda_file[0], "r") as handle: script = handle.read() tmp_file = "tmp_env.yaml" script = script.replace("- python", "- python {}*".format(args.python[0])) with open(tmp_file, "w") as handle: handle.write(script) conda_path = shutil.which("conda") print("CONDA ENV NAME {}".format(args.name[0])) print("PYTHON VERSION {}".format(args.python[0])) print("CONDA FILE NAME {}".format(args.conda_file[0])) print("CONDA path {}".format(conda_path)) sp.call("{} env create -n {} -f {}".format(conda_path, args.name[0], tmp_file), shell=True) os.unlink(tmp_file) QCElemental-0.5.0/devtools/travis-ci/000077500000000000000000000000001351361252000174045ustar00rootroot00000000000000QCElemental-0.5.0/devtools/travis-ci/before_install.sh000077500000000000000000000016501351361252000227350ustar00rootroot00000000000000# Temporarily change directory to $HOME to install software pushd . cd $HOME # Install Miniconda if [ "$TRAVIS_OS_NAME" == "osx" ]; then # Make OSX md5 mimic md5sum from linux, alias does not work md5sum () { command md5 -r "$@" } MINICONDA=Miniconda3-latest-MacOSX-x86_64.sh else MINICONDA=Miniconda3-latest-Linux-x86_64.sh fi MINICONDA_HOME=$HOME/miniconda MINICONDA_MD5=$(curl -s https://repo.continuum.io/miniconda/ | grep -A3 $MINICONDA | sed -n '4p' | sed -n 's/ *\(.*\)<\/td> */\1/p') wget -q https://repo.continuum.io/miniconda/$MINICONDA if [[ $MINICONDA_MD5 != $(md5sum $MINICONDA | cut -d ' ' -f 1) ]]; then echo "Miniconda MD5 mismatch" exit 1 fi bash $MINICONDA -b -p $MINICONDA_HOME # Configure miniconda export PIP_ARGS="-U" export PATH=$MINICONDA_HOME/bin:$PATH conda config --set always_yes yes --set changeps1 no conda update --q conda # Restore original directory popd QCElemental-0.5.0/docs/000077500000000000000000000000001351361252000145745ustar00rootroot00000000000000QCElemental-0.5.0/docs/Makefile000066400000000000000000000011451351361252000162350ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = qcelemental SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) QCElemental-0.5.0/docs/README.md000066400000000000000000000010211351361252000160450ustar00rootroot00000000000000# Compiling QCFractal's Documentation The docs for this project are built with Sphinx. To compile the docs, first ensure that Sphinx and the ReadTheDocs theme are installed. ``` conda install sphinx sphinx_rtd_theme ``` Once installed, you can use the Makefile in this directory to compile static HTML pages by ``` make html ``` The compiled docs will be in the _build directory and can be viewed by opening index.html (which may itself be inside a directory called html/ depending on what version of Sphinx is installed). QCElemental-0.5.0/docs/requirements.yml000066400000000000000000000004631351361252000200450ustar00rootroot00000000000000name: qcelemental-docs channels: - defaults - conda-forge dependencies: - python=3 - numpy - pydantic - pint - sphinx - sphinx_rtd_theme - sphinx-automodapi - graphviz - pip: - git+git://github.com/MolSSI/qcarchive-sphinx-theme#egg=qcarchive_sphinx_theme QCElemental-0.5.0/docs/source/000077500000000000000000000000001351361252000160745ustar00rootroot00000000000000QCElemental-0.5.0/docs/source/api.rst000066400000000000000000000005251351361252000174010ustar00rootroot00000000000000=============== QCElemental API =============== .. automodapi:: qcelemental :include-all-objects: :skip: covalentradii .. automodapi:: qcelemental.periodic_table :skip: NotAnElementError :skip: Decimal .. automodapi:: qcelemental.physical_constants .. automodapi:: qcelemental.molparse .. automodapi:: qcelemental.testing QCElemental-0.5.0/docs/source/changelog.rst000066400000000000000000000315061351361252000205620ustar00rootroot00000000000000Changelog ========= .. X.Y.0 / 2019-MM-DD .. ------------------ .. .. New Features .. ++++++++++++ .. .. Enhancements .. ++++++++++++ .. .. Bug Fixes .. +++++++++ 0.5.0 / 2019-07-16 ------------------ Enhancements ++++++++++++ - (:pr:`76`) Adds a built-in ``Molecule.to_file`` function for easy serialization into ``.numpy``, ``.json``, ``.xyz``, ``.psimol``, and ``.psi4`` file formats. Bug Fixes +++++++++ - (:pr:`74`) Atom and fragment ordering are preserved when invoking ``get_fragment``. 0.4.2 / 2019-06-13 ------------------ New Features ++++++++++++ - (:pr:`70`, :pr:`72`) ``molparse.to_string`` Molpro dtype developed. 0.4.1 / 2019-05-31 ------------------ New Features ++++++++++++ Enhancements ++++++++++++ - (:pr:`68`) ``molparse.to_string`` learned parameter ``return_data`` that contains aspects of the ``models.Molecule`` not expressible in the string. Implemented for dtypes xyz, cfour, psi4. - (:pr:`68`) ``Datum`` gained an attribute ``numeric`` that reflects whether arithmetic on ``data`` is valid. ``Datum``\ s that aren't numeric can now be created by initializing with ``numeric=False``. Bug Fixes +++++++++ - (:pr:`66`) Fix tests when `networkx` not installed. - (:pr:`67`) Fix "unsupported format string passed to numpy.ndarray.__format__" on Mac for ``testing.compare_values``. 0.4.0 / 2019-05-13 ------------------ New Features ++++++++++++ - (:pr:`51`) Changes ``models.Molecule`` connectivity to default to `None` rather than an empty list. **WARNING** this change alters the hashes produced from the ``Molecule.get_hash`` functionality. - (:pr:`52`, :pr:`53`) ``models.Molecule`` learned ``nuclear_repulsion_energy``, ``nelectrons``, and ``to_string`` functions. - (:pr:`54`) ``models.ResultProperties`` supports CCSD and CCSD(T) properties. - (:pr:`56`) Algorithms Kabsch ``molutil.kabsch_align``, Hungarian ``util.linear_sum_assignment``, and Uno ``util.uno`` added. Utilities to generate random 3D rotations ``util.random_rotation_matrix`` and reindex a NumPy array into smaller blocks ``util.blockwise_expand`` added. - (:pr:`56`) Molecular alignment taking into account displacement, rotation, atom exchange, and mirror symmetry for superimposable and differing geometries was added in ``molutil.B787`` (basis NumPy function) and ``models.Molecule.align`` (far more convenient). Suitable for QM-sized molecules. Requires addition package ``networkx``. - (:pr:`58`) ``utils`` learned ``which_import`` and ``which`` that provide a path or boolean result for locating modules or commands, respectively. These were migrated from QCEngine along with ``safe_version`` and ``parse_version`` to colocate the import utilities. - (:pr:`61`) Add molecular visualization to the ``models.Molecule`` object through the optional 3dMol.js framework. - (:pr:`65`) ``testing.compare_molrecs`` learned parameter ``relative_geoms='align'`` that lets Molecules pass if geometries within a translation and rotation of each other. - (:pr:`65`) ``testing.compare_recursive`` learned parameter ``forgive`` that is a list of paths that may differ without failing the comparison. Enhancements ++++++++++++ - (:pr:`52`, :pr:`53`) ``molparse.to_string`` NWChem and GAMESS dtypes developed. - (:pr:`57`) ``molparse.to_string`` learned ``dtype='terachem'`` for writing the separate XYZ file required by TeraChem. Angstroms or Bohr allowed, though the latter requires extra in input file. - (:pr:`60`) ``util.which`` added the Python interpreter path to the default search ``$PATH``. - (:pr:`62`) Added ``*`` to parameter list of many functions requiring subsequent to be keyword only. Code relying heavily on positional arguments may get broken. - (:pr:`63`) ``util.which`` learned parameter ``env`` to use an alternate search ``$PATH``. - (:pr:`63`) ``util.which`` and ``util.which_import`` learned parameters ``raise_error`` and ``raise_msg`` which raises ``ModuleNotFoundError`` (for both functions) when not located. It error will have a generic error message which can be extended by ``raise_msg``. It is strongly encouraged to add specific remedies (like how to install) through this parameter. This is the third exit pattern possible from the "which" functions, of which path/None is the default, True/error happens when ``raise_error=True``, and True/False happens otherwise when ``return_bool=True``. - (:pr:`65`) Testing functions ``compare``, ``compare_values``, ``compare_recursive`` learned parameter ``return_handler`` that lets other printing, logging, and pass/fail behavior to be interjected. Bug Fixes +++++++++ - (:pr:`63`) ``util.which`` uses ``os.pathsep`` rather than Linux-focused ``:``. - (:pr:`65`) Fixed some minor printing and tolerance errors in molecule alignment. - (:pr:`65`) ``testing.compare_recursive`` stopped doing ``atol=10**-atol`` for ``atol>=1``, bringing it in line with other compare functions. 0.3.3 / 2019-03-12 ------------------ Enhancements ++++++++++++ - (:pr:`49`) Precompute some mass number and mass lookups and store on ``qcel.periodic_table``. Also move static ``re.compile`` expressions out of fns on to module. Mol validation .127s --> .005s. 0.3.2 / 2019-03-11 ------------------ New Features ++++++++++++ - (:pr:`47`) ``models.DriverEnum`` now has a ``derivative_int`` function to return 1 for ``gradient``, etc., for easy math. ``properties`` returns 0. - (:pr:`47`) Optional ``fix_symmetry`` field in qcschema_molecule was missing from ``models.Molecule`` so Pydantic got mad at Psi4. Now calmed. Enhancements ++++++++++++ - (:pr:`48`) If Molecule object has passed through molparse validation because it was created with a molparse constructor (e.g., ``from_string``), save some time by not passing it through again at ``model.Molecule`` creation time. Bug Fixes +++++++++ - (:pr:`48`) Fixed a ``Molecule.get_fragment`` bug where ghosted fragments still asserted charge/multiplicity to the validator, which was rightly confused. 0.3.1 / 2019-03-07 ------------------ Enhancements ++++++++++++ - (:pr:`37`) Documentation now pulls from the custom QC Archive Sphinx Theme, but can fall back to the standard RTD theme. This allows all docs across QCA to appear consistent with each other. - (:pr:`41`) Conda-build recipe removed to avoid possible confusion for everyone who isn't a Conda-Forge recipe maintainer. Tests now rely on the ``conda env`` setups. - (:pr:`44`) Molecule objects are now always validated against a more rigorous model and fragment multiplicities are fixed at the correct times, even when no multiplicities are provided. Molecule defaults to ``dtype=2``. Bug Fixes +++++++++ - (:pr:`39`) Fixed ``setup.py`` to call ``pytest`` instead of ``unittest`` when running tests on install - (:pr:`41`) Pinned a minimum Pytest version to make sure errors are not because of too old of a pytest version 0.3.0 / 2019-02-27 ------------------ New Features ++++++++++++ - (:pr:`33`) ``molparse.to_schema`` recognizes ``dtype=2`` in keeping with GH:MolSSI/QCSchema#60 with internal ``schema_name=qcschema_molecule`` and ``schema_version=2`` fields. ``molparse.from_schema`` recognizes external fields (existing functionality), internal fields (dtype=2), and mixed. - (:pr:`33`) Pydantic molecule model now contains schema_name and schema_version=2 information. - (:pr:`35`) Models now have an ``extra`` field for extra attributes, no additional base keys are allowed. Enhancements ++++++++++++ - (:pr:`34`) Converts ``qcel.Datum`` to Pydantic model. Changes: (a) comment, doi, glossary fields must be accessed by keyword, (b) ``to_dict()`` becomes ``dict()`` and instead of only label, units, data fields in dict, now comment, doi, glossary present _if_ non-default, (c) complex values no longer list-ified by ``to_dict()``. - (:pr:`36`) Changelog and Models documentation. Bug Fixes +++++++++ 0.2.6 / 2019-02-18 ------------------ Bug Fixes +++++++++ - (:pr:`32`) Updates compliance with Pydantic v0.20. 0.2.5 / 2019-02-13 ------------------ Enhancements ++++++++++++ - (:pr:`31`) Lints the code base preparing for a release and minor test improvements. Bug Fixes +++++++++ - (:pr:`30`) Fixes ``dihedral`` measurement code for incorrect phase in certain quadrants. 0.2.4 / 2019-02-08 ------------------ New Features ++++++++++++ - (:pr:`27`) Adds a new ``measure`` feature to Molecule for distances, angles, and dihedrals. - (:pr:`25`) Adds a new ``testing`` module which contains testing routines for arrays, dictionaries, and molecules. Enhancements ++++++++++++ - (:pr:`28`) Reduces loading time from ~1 second to 200 ms by delaying ``pint`` import and ensuring git tags are only computed once. 0.2.3 / 2019-01-29 ------------------ Enhancements ++++++++++++ - (:pr:`24`) Update models to be compatible with QCFractal and MongoDB objects in the QCArchive Ecosystem. Also enhances the ``Molecule`` model's ``json`` function to accept ``as_dict`` keyword, permitting a return as a dictionary of Pydantic-serialized python (primitive) objects, instead of a string. 0.2.2 / 2019-01-28 ------------------ Bug Fixes +++++++++ - (:pr:`21`) Molparse's ``from_schema`` method now correctly parses the new ``qcschema_X`` strings for schema names. - (:pr:`23`) Pydantic model serializations now correctly handle Numpy Array objects in nested ``BaseModels``. Model serialization testing added to catch these in the future. 0.2.1 / 2019-01-27 ------------------ - (:pr:`20`) Moves several Molecule parsing functions to the molparse module. 0.2.0 / 2019-01-25 ------------------ - now requires Python 3.6+ - now requires Pydantic New Features ++++++++++++ - (:pr:`14`, :pr:`16`, :pr:`17`) Added new Pydantic models for Molecules, Results, and Optimizations to make common objects used in the QCArchive project all exist in one central, always imported module. Enhancements ++++++++++++ - (:pr:`13`) Function ``util.unnp`` that recursively list-ifies ndarray in a dict now handles lists and flattens. 0.1.3 / 2018-12-14 ------------------ New Features ++++++++++++ - (:pr:`12`) Adds "connectivity" validation and storage consistent with QCSchema. Enhancements ++++++++++++ - (:pr:`12`) Adds single dictionary provenance consistent with `QCSchema `_ rather than previous list o'dicts. 0.1.2 / 2018-11-3 ----------------- New Features ++++++++++++ - (:pr:`10`) Adds covalent radii data available through ``covalentradii.get(atom)`` function. - (:pr:`10`) Adds ``to_units(unit)`` to ``Datum`` class to access the data in non-native units. - (:pr:`10`) Adds ``periodictable.to_period(atom)`` and ``to_group(atom)`` functions to address periodic table. 0.1.1 / 2018-10-30 ------------------ New Features ++++++++++++ - (:pr:`7`, :pr:`9`) Adds "comment" and "provenance" fields to internal repr to better match QCSchema. - (:pr:`7`) Adds provenance stamp to ``from_string``, ``from_arrays``, ``from_schema`` functions. Enhancements ++++++++++++ - (:pr:`7`) Adds outer schema_name/schema_version to ``to_schema(..., dtype=1)`` output so is inverse to ``from_schema``. Bug Fixes +++++++++ - (:pr:`8`) Tests pass for installed module now that comparison tests are xfail. 0.1.0a / 2018-10-24 ------------------- This is the first alpha release of QCElemental containing the primary three components. New Features ++++++++++++ - (:pr:`6`) Updated molparse to write new Molecule QCSchema fields in keeping with GH:MolSSI/QCSchema#44 - Periodic Table data from NIST SRD144 (c. pre-2015?) collected into ``qcelemental.periodictable`` instance, with accessors ``to_Z``, ``to_element``, ``to_E``, ``to_mass``, ``to_A`` (and redundant accessors ``to_mass_number``, ``to_atomic_number``, ``to_symbol``, ``to_name``) in ``float`` and ``Decimal`` formats. Also includes functionality to write a corresponding "C" header. - Physical Constants data from NIST SRD121 (CODATA 2014) collected into ``qcelemental.constants`` instance, with access through ``qcelemental.constants.Faraday_constant`` (exact capitalization; ``float`` result) or ``get`` (free capitalization; ``float`` or ``Decimal`` result). Also includes functionality to write a corresponding "C" header. - ``molparse`` submodule where ``from_string``, ``from_array``, ``from_schema`` constructors parse and rearrange (if necessary) and validate molecule topology inputs from the QC and EFP domains into a QCSchema-like data structure. Current deficiencies from QCSchema are non-contiguous fragments and "provenance" fields. Accessors ``to_string`` and ``to_schema`` are highly customizable. - A `pint `_ context has been built around the NIST physical constants data so that ``qcelemental.constants.conversion_factor(from_unit, to_unit)`` uses the QCElemental values in its conversions. Resulting ``float`` is within uncertainty range of NIST constants but won't be exact for conversions involving multiple fundamental dimensions or ``wavelength -> energy != 1 / (energy -> wavelength)``. QCElemental-0.5.0/docs/source/community.rst000066400000000000000000000034751351361252000206630ustar00rootroot00000000000000Community ========= The QCArchive is an open community sponsored by `The Molecular Sciences Software Institute `_. However, this is a community-driven project which requires feature requests, user feedback, and code support. There are a variety of ways to help support the QCArchive project as seen below. Discussion ---------- - QCArchive Slack is a great place to get feedback and advice from the community. Click `here `_ to get started. - The QCArchive GitHub repositories contain future roadmaps, current code updates, and a list of issues that are being worked and provide an excellent overview of the development status of the project. See the following links: - `QCSchema `_ - `QCElemental `_ - `QCEngine `_ - `QCFractal `_ Work with us! ------------- The QCArchive project is actively looking for early collaborations to use our tools, help us shake out the bugs, and be evangelists within the computational molecular science community for this code ecosystem. In return you will receive the following benefits: - Work directly with a MolSSI Software Scientist who will discuss your problem and provide ideas. - Develop the requirements and potential solutions for your use case within the QCArchive ecosystem. - Setup monthly meetings to ensure your project stays on track. - Highlight your project within the QCArchive ecosystem. If you are interested in working with us, please send an email to `QCArchive@molssi.org `_ and we will set up a meeting to discuss specifics. QCElemental-0.5.0/docs/source/conf.py000066400000000000000000000145321351361252000174000ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # 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 datetime import os import sys sys.path.insert(0, os.path.abspath('../../')) import qcelemental # -- Project information ----------------------------------------------------- project = 'QCElemental' copyright = f'2018-{datetime.datetime.today().year}, The Molecular Sciences Software Institute' author = 'The QCArchive Development Team' # The short X.Y version version = qcelemental.__version__ # The full version, including alpha/beta/rc tags release = qcelemental.__version__ # -- 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 = [ # from Sphinx 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinx.ext.extlinks', 'sphinx.ext.graphviz', 'sphinx.ext.autosummary', 'sphinx.ext.napoleon', 'sphinx.ext.graphviz', # from Astropy 'sphinx_automodapi.automodapi', 'sphinx_automodapi.automodsumm', #'sphinx_automodapi.smart_resolver', ] autosummary_generate = True automodapi_toctreedirnm = 'api' #numpydoc_show_class_members = False #automodsumm_inherited_members = True # 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' # The master toctree document. master_doc = 'index' # 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 # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'default' # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # try: import qcarchive_sphinx_theme html_theme = 'qcarchive_sphinx_theme' except ModuleNotFoundError: 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 = {} # 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'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'qcelementaldoc' # -- 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, 'QCElemental.tex', 'QCElemental Documentation', author, '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, 'qcelemental', 'QCElemental Documentation', [author], 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, 'QCElemental', 'QCElemental Documentation', author, 'QCElemental', 'One line description of project.', 'Miscellaneous'), ] # -- Extension configuration ------------------------------------------------- extlinks = { 'issue': ('https://github.com/MolSSI/QCElemental/issues/%s', 'GH#'), 'pr': ('https://github.com/MolSSI/QCElemental/pull/%s', 'GH#') } # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'python': ('https://docs.python.org/3.7', None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference/', None), 'matplotlib': ('https://matplotlib.org/', None), } # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True QCElemental-0.5.0/docs/source/index.rst000066400000000000000000000046331351361252000177430ustar00rootroot00000000000000.. qcelemental documentation master file, created by sphinx-quickstart on Wed May 30 19:16:00 2018. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. =========== QCElemental =========== *QCElemental is a resource module for quantum chemistry containing physical constants and periodic table data from NIST and molecule handlers.* Physical Constants ------------------ Physical constants can be acquired directly from the NIST CODATA: .. code-block:: python >>> qcel.constants.get("hartree energy in ev") 27.21138602 Alternatively, with the use of the Pint unit conversion package, arbitrary conversion factors can be obtained: .. code-block:: python >>> qcel.constants.conversion_factor("bohr", "miles") 3.2881547429884475e-14 Periodic Table Data ------------------- A variety of periodic table quantities are available using virtually any alias: .. code-block:: python >>> qcel.periodictable.to_mass("Ne") 19.9924401762 >>> qcel.periodictable.to_mass(10) 19.9924401762 Molecule Handlers ----------------- Molecules can be translated to/from the `MolSSI QCSchema `_ format or quantum chemistry program specific input specifications such as NWChem, Psi4, and CFour. In addition, databases such as PubChem can be searched: .. code-block:: python >>> qcel.molparse.from_string("pubchem:benzene") Searching PubChem database for benzene (single best match returned) Found 1 result(s) {"geometry": ...} ======== Index ----- **Getting Started** * :doc:`install` * :doc:`community` .. toctree:: :maxdepth: 1 :hidden: :caption: Getting Started install community **User Interface** * :doc:`physconst` * :doc:`periodic_table` .. toctree:: :maxdepth: 1 :hidden: :caption: User Interface physconst periodic_table **QCSchema Models** Implementation descriptions of QCSchema objects in Python. * :doc:`models` * :doc:`molecule` .. toctree:: :maxdepth: 1 :hidden: :caption: QCSchema Models models molecule **Developer Documentation** Contains in-depth developer documentation and API references. * :doc:`api` * :doc:`changelog` .. toctree:: :maxdepth: 2 :caption: Developer Documentation :hidden: api changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` QCElemental-0.5.0/docs/source/install.rst000066400000000000000000000026701351361252000203010ustar00rootroot00000000000000Install QCElemental =================== You can install qcelemental with ``conda``, with ``pip``, or by installing from source. Conda ----- You can update qcelemental using `conda `_: .. code-block:: console >>> conda install qcelemental -c conda-forge This installs QCElemental and its dependancies. The qcelemental package is maintained on the `conda-forge channel `_. Pip --- To install QCElemental with ``pip`` there are a few options, depending on which dependencies you would like to keep up to date: .. code-block:: console >>> pip install qcelemental Install from Source ------------------- To install QCElemental from source, clone the repository from `github `_: .. code-block:: console >>> git clone https://github.com/MolSSI/QCElemental.git >>> cd QCElemental >>> python setup.py install or use ``pip`` for a local install: .. code-block:: console >>> pip install -e . Testing ------- QCElemental can be tested using the ``pytest`` package which can be installed via Conda as well: .. code-block:: console >>> conda install pytest -c conda-forge Once ``pytest`` is installed QCElemental's testing suite can be run by: .. code-block:: console >>> pytest --pyargs qcelemental QCElemental can also be tested from source with: .. code-block:: console >>> cd QCElemental >>> pytest QCElemental-0.5.0/docs/source/models.rst000066400000000000000000000050531351361252000201140ustar00rootroot00000000000000Overview ======== Python implementations of the `MolSSI QCSchema `_ are available within QCElemental. These models use `Pydantic `_ as their base to provide serialization, validation, and manipluation. Basics -------- Model creation occurs with a ``kwargs`` constructor as shown by equivalent operations below: .. code-block:: python >>> mol = qcel.models.Molecule(symbols=["He"], geometry=[0, 0, 0]) >>> mol = qcel.models.Molecule(**{"symbols":["He"], "geometry": [0, 0, 0]}) A list of all available fields can be found by querying the ``fields`` attribute: .. code-block:: python >>> mol.fields.keys() dict_keys(['symbols', 'geometry', ..., 'id', 'extras']) These attributes can be accessed as shown: .. code-block:: python >>> mol.symbols ['He'] Note that these models are typically immutable: .. code-block:: python >>> mol.symbols = ["Ne"] TypeError: "Molecule" is immutable and does not support item assignment To update or alter a model the ``copy`` command can be used with the ``update`` kwargs: .. code-block:: python >>> mol.copy(update={"symbols": ["Ne"]}) < Geometry (in Angstrom), charge = 0.0, multiplicity = 1: Center X Y Z ------------ ----------------- ----------------- ----------------- Ne 0.000000000000 0.000000000000 0.000000000000 > Serialization ------------- All models can be serialized back to their dictionary counterparts through the ``dict`` function: .. code-block:: python >>> mol.dict() {'symbols': ['He'], 'geometry': array([[0., 0., 0.]])} JSON representations are supported out of the box for all models: .. code-block:: python >>> mol.json() '{"symbols": ["He"], "geometry": [0.0, 0.0, 0.0]}' Raw JSON can also be parsed back into a model: .. code-block:: python >>> mol.parse_raw(mol.json()) < Geometry (in Angstrom), charge = 0.0, multiplicity = 1: Center X Y Z ------------ ----------------- ----------------- ----------------- He 0.000000000000 0.000000000000 0.000000000000 > The standard ``dict`` operation returns all internal representations which may be classes or other complex structures. To return a JSON-like dictionary the ``json_dict`` function can be used: .. code-block:: python >>> mol.json_dict() {'symbols': ['He'], 'geometry': [0.0, 0.0, 0.0]} QCElemental-0.5.0/docs/source/molecule.rst000066400000000000000000000073221351361252000204370ustar00rootroot00000000000000Molecule Model ============== A Python implementations of the `MolSSI QCSchema `_ ``Molecule`` object. A "Molecule" many definitions of ``Molecule`` depending on the domain; this particular ``Molecule`` is an immutable 3D Cartesian representation with support for quantum chemistry constructs. Creation --------- A Molecule can be created using the normal kwargs fashion as shown below: .. code-block:: python >>> mol = qcel.models.Molecule(**{"symbols":["He"], "geometry": [0, 0, 0]}) In addition, there is the ``from_data`` attribute to create a molecule from standard strings: .. code-block:: python >>> mol = qcel.models.Molecule.from_data("He 0 0 0") >>> mol < Geometry (in Angstrom), charge = 0.0, multiplicity = 1: Center X Y Z ------------ ----------------- ----------------- ----------------- He 0.000000000000 0.000000000000 0.000000000000 > Identifiers ----------- A number of unique identifiers are automatically created for each molecule. Additional implementation such as InChI and SMILES are actively being looked into. Molecular Hash ++++++++++++++ A molecule hash is automatically created to allow each molecule to be uniquely identified. The following keys are used to generate the hash: - ``symbols`` - ``masses`` (1.e-6 tolerance) - ``molecular_charge`` (1.e-4 tolerance) - ``molecular_multiplicity`` - ``real`` - ``geometry`` (1.e-8 tolerance) - ``fragments`` - ``fragment_charges`` (1.e-4 tolerance) - ``fragment_multiplicities`` - ``connectivity`` Hashes can be acquired from any molecule object and a ``FractalServer`` automatically generates canonical hashes when a molecule is added to the database. .. code-block:: python >>> mol = qcel.models.Molecule(**{"symbols": ["He", "He"], "geometry": [0, 0, -3, 0, 0, 3]}) >>> mol.get_hash() '84872f975d19aafa62b188b40fbadaf26a3b1f84' Molecular Formula +++++++++++++++++ The molecular formula is also available sorted in alphabetical order with title case symbol names. Any symbol with a count of one does not have a number associated with it. .. code-block:: python >>> mol.get_molecular_formula() 'He2' Fragments --------- A Molecule with fragments can be created either using the ``--`` separators in the ``from_data`` function or by passing explicit fragments in the ``Molecule`` constructor: .. code-block:: python >>> mol = qcel.models.Molecule.from_data( >>> """ >>> Ne 0.000000 0.000000 0.000000 >>> -- >>> Ne 3.100000 0.000000 0.000000 >>> """) >>> mol = qcel.models.Molecule( >>> geometry=[0, 0, 0, 3.1, 0, 0], >>> symbols=["Ne", "Ne"], >>> fragments=[[0], [1]] >>> ) Fragments from a molecule containing fragment information can be aquired by: .. code-block:: python >>> mol.get_fragment(0) < Geometry (in Angstrom), charge = 0.0, multiplicity = 1: Center X Y Z ------------ ----------------- ----------------- ----------------- Ne 0.000000000000 0.000000000000 0.000000000000 > Obtaining fragments with ghost atoms is also supported: .. code-block:: python >>> mol.get_fragment(0, 1) < Geometry (in Angstrom), charge = 0.0, multiplicity = 1: Center X Y Z ------------ ----------------- ----------------- ----------------- Ne 0.000000000000 0.000000000000 0.000000000000 Ne (Gh) 3.100000000572 0.000000000000 0.000000000000 > QCElemental-0.5.0/docs/source/periodic_table.rst000066400000000000000000000032011351361252000215670ustar00rootroot00000000000000Periodic Table ============== Full access to the periodic table is also available within QCElemental. This includes mass, atomic number, symbol, and name information. Data is indexed many ways so that many possible aliases can lead to a single quantity. For example, to obtain the mass (in a.m.u) of of Carbon atomic number, symbol, isotope symbol, and name can all be passed: .. code-block:: python >>> qcel.periodictable.to_mass(6) 12.0 >>> qcel.periodictable.to_mass("C") 12.0 >>> qcel.periodictable.to_mass("C12") 12.0 >>> qcel.periodictable.to_mass("Carbon") 12.0 A variety of infomation can be accessed in this manner. Taking 'Carbon' as an example for mass information: .. code-block:: python >>> qcel.periodictable.to_mass("Carbon") 12.0 >>> qcel.periodictable.to_mass_number("Carbon") 12 >>> qcel.periodictable.to_atomic_number("Carbon") 6 Symbol information: .. code-block:: python >>> qcel.periodictable.to_symbol("Carbon") 'C' >>> qcel.periodictable.to_name("Carbon") 'Carbon' Table position information: >>> qcel.periodictable.to_period("Carbon") 2 >>> qcel.periodictable.to_group("Carbon") 14 API --- .. currentmodule:: qcelemental.periodictable Top level user functions: .. autosummary:: to_mass to_mass_number to_atomic_number to_symbol to_name to_period to_group Function Definitions -------------------- .. autofunction:: to_mass .. autofunction:: to_mass_number .. autofunction:: to_atomic_number .. autofunction:: to_symbol .. autofunction:: to_name .. autofunction:: to_period .. autofunction:: to_group QCElemental-0.5.0/docs/source/physconst.rst000066400000000000000000000074051351361252000206660ustar00rootroot00000000000000Physical Constants ================== NIST Physical constants are available from QCElemental with arbitrary conversion factors using the `pint `_ package. The current default physical constants come from the `NIST CODATA 2014 `_. Conversion Factors ------------------ Conversion factors are available for any valid conversion: .. code-block:: python >>> qcel.constants.conversion_factor("nanometer", "angstrom") 10.0 >>> qcel.constants.conversion_factor("eV / nanometer ** 2", "hartree / angstrom ** 2") 0.00036749322481535707 .. warning:: QCElemental is explicit: ``kcal`` is quite different from ``kcal / mol``. Be careful of common shorthands. .. code-block:: python >>> qcel.constants.conversion_factor("kcal", "eV") 2.611447418269555e+22 >>> qcel.constants.conversion_factor("kcal / mol", "eV") 0.043364103900593226 Quantities ----------- QCElemental supports the ``pint`` "values with units" Quantity objects: .. code-block:: python >>> q = qcel.constants.Quantity("5 kcal / mol") >>> q >>> q.magnitude 5.0 >>> q.dimensionality These objects are often used for code that has many different units to make the requisite bookkeeping nearly effortless. In addition, these objects have NumPy and Pandas support built-in: .. code-block:: python >>> import numpy as np >>> a = qcel.constants.Quantity("kcal") * np.arange(4) >>> a An example of array manipulation using a NumPy array with a ``pint`` quantity: >>> a * qcel.constants.Quantity("eV") >>> a.to("eV") NIST CODATA ----------- The exact values from the NIST CODATA can be queried explicitly: .. code-block:: python >>> qcel.constants.get("hartree energy in ev") 27.21138602 The complete NIST CODATA record is held and can be obtained via the Python- API. The following example shows how to obtain a comprehensive overview of the individual CODATA record: .. code-block:: python >>> datum = qcel.constants.get("hartree energy in ev", return_tuple=True) >>> datum <---------------------------------------- Datum Hartree energy in eV ---------------------------------------- Data: 27.21138602 Units: [eV] doi: 10.18434/T4WW24 Comment: uncertainty=0.000 000 17 Glossary: ----------------------------------------> Each of these quantities is API accessible: .. code-block:: python >>> datum.doi '10.18434/T4WW24' >>> datum.comment 'uncertainty=0.000 000 17' Contexts -------- Physical constants are continuously refined over time as experimental precision increases or redefinition occurs. To prepare for future changes, physical constants are contained in contexts. The ``qcel.constants`` context will be updated over time to the latest NIST data. To "pin" a context version, a specific context can be created like so: .. code-block:: python >>> context = qcel.PhysicalConstantsContext("CODATA2014") >>> context.conversion_factor("hartree", "eV") 27.21138601949571 Currently only ``CODATA2014`` is available. API --- .. currentmodule:: qcelemental.constants Top level user functions: .. autosummary:: conversion_factor get Quantity string_representation Function Definitions -------------------- .. autofunction:: conversion_factor .. autofunction:: get .. autofunction:: Quantity .. autofunction:: string_representation QCElemental-0.5.0/nist_data/000077500000000000000000000000001351361252000156125ustar00rootroot00000000000000QCElemental-0.5.0/nist_data/README.md000066400000000000000000000030151351361252000170700ustar00rootroot00000000000000# Sources * [srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json](srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json) from https://nist.gov/srd/srd_data//srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json downloaded 30 Aug 2018. A related website is https://www.nist.gov/pml/atomic-weights-and-isotopic-compositions-relative-atomic-masses * [element_names.py](element_names.py) from https://www.nist.gov/pml/periodic-table-elements `NIST SP 966 (July 2018)` downloaded 30 Aug 2018 * [longest_lived_isotope_for_unstable_elements.py](longest_lived_isotope_for_unstable_elements.py) from https://www.nist.gov/pml/periodic-table-elements `NIST SP 966 (July 2018)` downloaded 30 Aug 2018 * [srd121_nist-codata-fundamental-physical-constants-2014.json](srd121_nist-codata-fundamental-physical-constants-2014.json) (CODATA 2014) from https://nist.gov/srd/srd_data//srd121_allascii_2014.json downloaded 1 Sep 2018 off https://catalog.data.gov/dataset/nist-codata-fundamental-physical-constants-srd-121. * [srd121_nist-codata-fundamental-physical-constants-2014-metadata.json](srd121_nist-codata-fundamental-physical-constants-2014-metadata.json) (metadata for CODATA 2014) from https://catalog.data.gov/harvest/object/14b5729a-4814-409b-8e0a-cd733f06b850 downloaded 2 Sep 2018 off https://catalog.data.gov/dataset/nist-codata-fundamental-physical-constants-srd-121. If anyone finds a JSON/XML/YAML file for the 2nd & 3rd items from NIST or IUPAC, that would be preferable. Or an update to anything. QCElemental-0.5.0/nist_data/build_period_table.py000066400000000000000000000161031351361252000217750ustar00rootroot00000000000000""" This file will generate a JSON blob usable by QCElemental for physical constants """ import json import datetime import requests from yapf.yapflib.yapf_api import FormatCode import re from decimal import Decimal # from https://www.nist.gov/pml/periodic-table-elements on 30 Aug 2018 # NIST SP 966 (July 2018) element_names = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium', 'Boron', 'Carbon', 'Nitrogen', 'Oxygen', 'Fluorine', 'Neon', 'Sodium', 'Magnesium', 'Aluminum', 'Silicon', 'Phosphorus', 'Sulfur', 'Chlorine', 'Argon', 'Potassium', 'Calcium', 'Scandium', 'Titanium', 'Vanadium', 'Chromium', 'Manganese', 'Iron', 'Cobalt', 'Nickel', 'Copper', 'Zinc', 'Gallium', 'Germanium', 'Arsenic', 'Selenium', 'Bromine', 'Krypton', 'Rubidium', 'Strontium', 'Yttrium', 'Zirconium', 'Niobium', 'Molybdenum', 'Technetium', 'Ruthenium', 'Rhodium', 'Palladium', 'Silver', 'Cadmium', 'Indium', 'Tin', 'Antimony', 'Tellurium', 'Iodine', 'Xenon', 'Cesium', 'Barium', 'Lanthanum', 'Cerium', 'Praseodymium', 'Neodymium', 'Promethium', 'Samarium', 'Europium', 'Gadolinium', 'Terbium', 'Dysprosium', 'Holmium', 'Erbium', 'Thulium', 'Ytterbium', 'Lutetium', 'Hafnium', 'Tantalum', 'Tungsten', 'Rhenium', 'Osmium', 'Iridium', 'Platinum', 'Gold', 'Mercury', 'Thallium', 'Lead', 'Bismuth', 'Polonium', 'Astatine', 'Radon', 'Francium', 'Radium', 'Actinium', 'Thorium', 'Protactinium', 'Uranium', 'Neptunium', 'Plutonium', 'Americium', 'Curium', 'Berkelium', 'Californium', 'Einsteinium', 'Fermium', 'Mendelevium', 'Nobelium', 'Lawrencium', 'Rutherfordium', 'Dubnium', 'Seaborgium', 'Bohrium', 'Hassium', 'Meitnerium', 'Darmstadtium', 'Roentgenium', 'Copernicium', 'Nihonium', 'Flerovium', 'Moscovium', 'Livermorium', 'Tennessine', 'Oganesson', ] # from https://www.nist.gov/pml/periodic-table-elements on 30 Aug 2018 # NIST SP 966 (July 2018) longest_lived_isotope_for_unstable_elements = { 'Tc': 98, 'Pm': 145, 'Po': 209, 'At': 210, 'Rn': 222, 'Fr': 223, 'Ra': 226, 'Ac': 227, 'Np': 237, 'Pu': 244, 'Am': 243, 'Cm': 247, 'Bk': 247, 'Cf': 251, 'Es': 252, 'Fm': 257, 'Md': 258, 'No': 259, 'Lr': 266, 'Rf': 267, 'Db': 268, 'Sg': 271, 'Bh': 270, 'Hs': 269, 'Mt': 278, 'Ds': 281, 'Rg': 282, 'Cn': 285, 'Nh': 286, 'Fl': 289, 'Mc': 289, 'Lv': 293, 'Ts': 294, 'Og': 294, } data_url = "https://nist.gov/srd/srd_data//srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json" title = "Atomic Weights and Isotopic Compositions with Relative Atomic Masses - SRD144" date_modified = "2011-01-14" year = date_modified.split('-')[0] doi = "10.1351/PAC-REP-10-06-02" url = data_url access_date = str(datetime.datetime.utcnow()) atomic_weights_data = requests.get(url).json() output = ''' """ This is a automatically generated file from the {0} NIST atomic weights. Title: {1} Date: {2} DOI: {3} URL: {4} Access Date: {5} UTC File Authors: QCElemental Authors """ '''.format(year, title, date_modified, doi, url, access_date) atomic_weights_json = { "title": title, "date": date_modified, "doi": doi, "url": url, "access_data": access_date} # length number of elements Z = [0] # , 1, 2, ... E = ['X'] # , H, He, ... name = ['Dummy'] # , Hydrogen, Helium, ... # length number of elements plus number of isotopes _EE = ['X', 'X'] # , H, H, H, ..., He, He, He, ... EA = ['X', 'X0'] # , H, H1, H2, ..., He, He3, He4, ... A = [0, 0] # , 1, 1, 2, ..., 4, 3, 4, ... masses = ["0", "0"] # , 1.0078, 1.0078, 2.014, ..., 4.0026, 3.016, 4.0026, ...V uncertain_value = re.compile(r"""(?P[\d.]+)(?P\([\d#]+\))?""") aliases = {'D': 'H2', 'T': 'H3'} newnames = {'Uut': 'Nh', 'Uup': 'Mc', 'Uus': 'Ts'} for delem in atomic_weights_data['data']: symbol = delem['Atomic Symbol'] delem['Atomic Symbol'] = newnames.get(symbol, symbol) for diso in delem['isotopes']: symbol = diso['Atomic Symbol'] diso['Atomic Symbol'] = newnames.get(symbol, symbol) # element loop for delem in atomic_weights_data['data']: mass_of_most_common_isotope = None mass_number_of_most_common_isotope = None max_isotopic_contribution = 0.0 # isotope loop for diso in delem['isotopes']: mobj = re.match(uncertain_value, diso['Relative Atomic Mass']) if mobj: mass = mobj.group('value') else: raise ValueError('Trouble parsing mass string ({}) for element ({})'.format( diso['Relative Atomic Mass'], diso['Atomic Symbol'])) a = int(diso['Mass Number']) if diso['Atomic Symbol'] in aliases: _EE.append('H') EA.append(aliases[diso['Atomic Symbol']]) A.append(a) masses.append(mass) _EE.append('H') EA.append(diso['Atomic Symbol']) A.append(a) masses.append(mass) else: _EE.append(diso['Atomic Symbol']) EA.append(diso['Atomic Symbol'] + diso['Mass Number']) A.append(a) masses.append(mass) if 'Isotopic Composition' in diso: mobj = re.match(uncertain_value, diso['Isotopic Composition']) if mobj: if float(mobj.group('value')) > max_isotopic_contribution: mass_of_most_common_isotope = mass mass_number_of_most_common_isotope = a max_isotopic_contribution = float(mobj.group('value')) # Source atomic_weights_and_isotopic_compositions_for_all_elements deals with isotopic composition of # stable elements. For unstable elements, need another source for the longest-lived isotope. if mass_of_most_common_isotope is None: mass_number_of_most_common_isotope = longest_lived_isotope_for_unstable_elements[diso['Atomic Symbol']] eliso = delem['Atomic Symbol'] + str(mass_number_of_most_common_isotope) mass_of_most_common_isotope = masses[EA.index(eliso)] _EE.append(delem['Atomic Symbol']) EA.append(delem['Atomic Symbol']) A.append(mass_number_of_most_common_isotope) masses.append(mass_of_most_common_isotope) z = int(delem['Atomic Number']) Z.append(z) E.append(delem['Atomic Symbol']) name.append(element_names[z - 1].capitalize()) atomic_weights_json["Z"] = Z atomic_weights_json["E"] = E atomic_weights_json["name"] = name atomic_weights_json["_EE"] = _EE atomic_weights_json["EA"] = EA atomic_weights_json["A"] = A atomic_weights_json["mass"] = masses output += "nist_{}_atomic_weights = {}".format(year, json.dumps(atomic_weights_json)) # output = FormatCode(output)[0] fn = "nist_{}_atomic_weights.py".format(year) with open(fn, "w") as handle: handle.write(output) QCElemental-0.5.0/nist_data/build_physical_constants.py000066400000000000000000000031721351361252000232560ustar00rootroot00000000000000""" This file will generate a JSON blob usable by QCElemental for physical constants """ import json import datetime import requests from yapf.yapflib.yapf_api import FormatCode metadata_file = "srd121_nist-codata-fundamental-physical-constants-2014-metadata.json" with open(metadata_file, "r") as handle: metadata = json.load(handle) title = metadata["title"] date_modified = metadata["modified"] year = metadata["modified"].split('-')[0] doi = metadata['distribution'][-1]['accessURL'].strip('https://dx.doi.org/') url = metadata['distribution'][0]['downloadURL'] access_date = str(datetime.datetime.utcnow()) year = date_modified.split('-')[0] constants = requests.get(url).json() output = ''' """ This is a automatically generated file from the {0} NIST fundamental constants. Title: {1} Date: {2} DOI: {3} URL: {4} Access Date: {5} UTC File Authors: QCElemental Authors """ '''.format(year, title, date_modified, doi, url, access_date) constants_json = { "title": title, "date": date_modified, "doi": doi, "url": url, "access_data": access_date, "constants": {}} for pc in constants['constant']: value = pc['Value'].strip() uncertainty = pc['Uncertainty'] if uncertainty == '(exact)': value = value.replace('...', '') constants_json["constants"][pc["Quantity "].lower()] = { "quantity": pc["Quantity "], "unit": pc["Unit"], "value": value.replace(" ", ""), 'uncertainty': uncertainty } output += "nist_{}_codata = {}".format(year, constants_json) output = FormatCode(output) fn = "nist_{}_codata.py".format(year) with open(fn, "w") as handle: handle.write(output[0]) QCElemental-0.5.0/nist_data/srd121_nist-codata-fundamental-physical-constants-2014.json000066400000000000000000001503001351361252000305120ustar00rootroot00000000000000{ "constant": [ { "Quantity ": "{220} lattice spacing of silicon", "Value": "192.015 5714 e-12", "Uncertainty": "0.000 0032 e-12", "Unit": "m" }, { "Quantity ": "alpha particle-electron mass ratio", "Value": "7294.299 541 36", "Uncertainty": "0.000 000 24", "Unit": "" }, { "Quantity ": "alpha particle mass", "Value": "6.644 657 230 e-27", "Uncertainty": "0.000 000 082 e-27", "Unit": "kg" }, { "Quantity ": "alpha particle mass energy equivalent", "Value": "5.971 920 097 e-10", "Uncertainty": "0.000 000 073 e-10", "Unit": "J" }, { "Quantity ": "alpha particle mass energy equivalent in MeV", "Value": "3727.379 378", "Uncertainty": "0.000 023", "Unit": "MeV" }, { "Quantity ": "alpha particle mass in u", "Value": "4.001 506 179 127", "Uncertainty": "0.000 000 000 063", "Unit": "u" }, { "Quantity ": "alpha particle molar mass", "Value": "4.001 506 179 127 e-3", "Uncertainty": "0.000 000 000 063 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "alpha particle-proton mass ratio", "Value": "3.972 599 689 07", "Uncertainty": "0.000 000 000 36", "Unit": "" }, { "Quantity ": "Angstrom star", "Value": "1.000 014 95 e-10", "Uncertainty": "0.000 000 90 e-10", "Unit": "m" }, { "Quantity ": "atomic mass constant", "Value": "1.660 539 040 e-27", "Uncertainty": "0.000 000 020 e-27", "Unit": "kg" }, { "Quantity ": "atomic mass constant energy equivalent", "Value": "1.492 418 062 e-10", "Uncertainty": "0.000 000 018 e-10", "Unit": "J" }, { "Quantity ": "atomic mass constant energy equivalent in MeV", "Value": "931.494 0954", "Uncertainty": "0.000 0057", "Unit": "MeV" }, { "Quantity ": "atomic mass unit-electron volt relationship", "Value": "931.494 0954 e6", "Uncertainty": "0.000 0057 e6", "Unit": "eV" }, { "Quantity ": "atomic mass unit-hartree relationship", "Value": "3.423 177 6902 e7", "Uncertainty": "0.000 000 0016 e7", "Unit": "E_h" }, { "Quantity ": "atomic mass unit-hertz relationship", "Value": "2.252 342 7206 e23", "Uncertainty": "0.000 000 0010 e23", "Unit": "Hz" }, { "Quantity ": "atomic mass unit-inverse meter relationship", "Value": "7.513 006 6166 e14", "Uncertainty": "0.000 000 0034 e14", "Unit": "m^{-1}" }, { "Quantity ": "atomic mass unit-joule relationship", "Value": "1.492 418 062 e-10", "Uncertainty": "0.000 000 018 e-10", "Unit": "J" }, { "Quantity ": "atomic mass unit-kelvin relationship", "Value": "1.080 954 38 e13", "Uncertainty": "0.000 000 62 e13", "Unit": "K" }, { "Quantity ": "atomic mass unit-kilogram relationship", "Value": "1.660 539 040 e-27", "Uncertainty": "0.000 000 020 e-27", "Unit": "kg" }, { "Quantity ": "atomic unit of 1st hyperpolarizability", "Value": "3.206 361 329 e-53", "Uncertainty": "0.000 000 020 e-53", "Unit": "C^3 m^3 J^{-2}" }, { "Quantity ": "atomic unit of 2nd hyperpolarizability", "Value": "6.235 380 085 e-65", "Uncertainty": "0.000 000 077 e-65", "Unit": "C^4 m^4 J^{-3}" }, { "Quantity ": "atomic unit of action", "Value": "1.054 571 800 e-34", "Uncertainty": "0.000 000 013 e-34", "Unit": "J s" }, { "Quantity ": "atomic unit of charge", "Value": "1.602 176 6208 e-19", "Uncertainty": "0.000 000 0098 e-19", "Unit": "C" }, { "Quantity ": "atomic unit of charge density", "Value": "1.081 202 3770 e12", "Uncertainty": "0.000 000 0067 e12", "Unit": "C m^{-3}" }, { "Quantity ": "atomic unit of current", "Value": "6.623 618 183 e-3", "Uncertainty": "0.000 000 041 e-3", "Unit": "A" }, { "Quantity ": "atomic unit of electric dipole mom.", "Value": "8.478 353 552 e-30", "Uncertainty": "0.000 000 052 e-30", "Unit": "C m" }, { "Quantity ": "atomic unit of electric field", "Value": "5.142 206 707 e11", "Uncertainty": "0.000 000 032 e11", "Unit": "V m^{-1}" }, { "Quantity ": "atomic unit of electric field gradient", "Value": "9.717 362 356 e21", "Uncertainty": "0.000 000 060 e21", "Unit": "V m^{-2}" }, { "Quantity ": "atomic unit of electric polarizability", "Value": "1.648 777 2731 e-41", "Uncertainty": "0.000 000 0011 e-41", "Unit": "C^2 m^2 J^{-1}" }, { "Quantity ": "atomic unit of electric potential", "Value": "27.211 386 02", "Uncertainty": "0.000 000 17", "Unit": "V" }, { "Quantity ": "atomic unit of electric quadrupole mom.", "Value": "4.486 551 484 e-40", "Uncertainty": "0.000 000 028 e-40", "Unit": "C m^2" }, { "Quantity ": "atomic unit of energy", "Value": "4.359 744 650 e-18", "Uncertainty": "0.000 000 054 e-18", "Unit": "J" }, { "Quantity ": "atomic unit of force", "Value": "8.238 723 36 e-8", "Uncertainty": "0.000 000 10 e-8", "Unit": "N" }, { "Quantity ": "atomic unit of length", "Value": "0.529 177 210 67 e-10", "Uncertainty": "0.000 000 000 12 e-10", "Unit": "m" }, { "Quantity ": "atomic unit of mag. dipole mom.", "Value": "1.854 801 999 e-23", "Uncertainty": "0.000 000 011 e-23", "Unit": "J T^{-1}" }, { "Quantity ": "atomic unit of mag. flux density", "Value": "2.350 517 550 e5", "Uncertainty": "0.000 000 014 e5", "Unit": "T" }, { "Quantity ": "atomic unit of magnetizability", "Value": "7.891 036 5886 e-29", "Uncertainty": "0.000 000 0090 e-29", "Unit": "J T^{-2}" }, { "Quantity ": "atomic unit of mass", "Value": "9.109 383 56 e-31", "Uncertainty": "0.000 000 11 e-31", "Unit": "kg" }, { "Quantity ": "atomic unit of mom.um", "Value": "1.992 851 882 e-24", "Uncertainty": "0.000 000 024 e-24", "Unit": "kg m s^{-1}" }, { "Quantity ": "atomic unit of permittivity", "Value": "1.112 650 056... e-10", "Uncertainty": "(exact)", "Unit": "F m^{-1}" }, { "Quantity ": "atomic unit of time", "Value": "2.418 884 326 509 e-17", "Uncertainty": "0.000 000 000 014 e-17", "Unit": "s" }, { "Quantity ": "atomic unit of velocity", "Value": "2.187 691 262 77 e6", "Uncertainty": "0.000 000 000 50 e6", "Unit": "m s^{-1}" }, { "Quantity ": "Avogadro constant", "Value": "6.022 140 857 e23", "Uncertainty": "0.000 000 074 e23", "Unit": "mol^{-1}" }, { "Quantity ": "Bohr magneton", "Value": "927.400 9994 e-26", "Uncertainty": "0.000 0057 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "Bohr magneton in eV/T", "Value": "5.788 381 8012 e-5", "Uncertainty": "0.000 000 0026 e-5", "Unit": "eV T^{-1}" }, { "Quantity ": "Bohr magneton in Hz/T", "Value": "13.996 245 042 e9", "Uncertainty": "0.000 000 086 e9", "Unit": "Hz T^{-1}" }, { "Quantity ": "Bohr magneton in inverse meters per tesla", "Value": "46.686 448 14", "Uncertainty": "0.000 000 29", "Unit": "m^{-1} T^{-1}" }, { "Quantity ": "Bohr magneton in K/T", "Value": "0.671 714 05", "Uncertainty": "0.000 000 39", "Unit": "K T^{-1}" }, { "Quantity ": "Bohr radius", "Value": "0.529 177 210 67 e-10", "Uncertainty": "0.000 000 000 12 e-10", "Unit": "m" }, { "Quantity ": "Boltzmann constant", "Value": "1.380 648 52 e-23", "Uncertainty": "0.000 000 79 e-23", "Unit": "J K^{-1}" }, { "Quantity ": "Boltzmann constant in eV/K", "Value": "8.617 3303 e-5", "Uncertainty": "0.000 0050 e-5", "Unit": "eV K^{-1}" }, { "Quantity ": "Boltzmann constant in Hz/K", "Value": "2.083 6612 e10", "Uncertainty": "0.000 0012 e10", "Unit": "Hz K^{-1}" }, { "Quantity ": "Boltzmann constant in inverse meters per kelvin", "Value": "69.503 457", "Uncertainty": "0.000 040", "Unit": "m^{-1} K^{-1}" }, { "Quantity ": "characteristic impedance of vacuum", "Value": "376.730 313 461...", "Uncertainty": "(exact)", "Unit": "ohm" }, { "Quantity ": "classical electron radius", "Value": "2.817 940 3227 e-15", "Uncertainty": "0.000 000 0019 e-15", "Unit": "m" }, { "Quantity ": "Compton wavelength", "Value": "2.426 310 2367 e-12", "Uncertainty": "0.000 000 0011 e-12", "Unit": "m" }, { "Quantity ": "Compton wavelength over 2 pi", "Value": "386.159 267 64 e-15", "Uncertainty": "0.000 000 18 e-15", "Unit": "m" }, { "Quantity ": "conductance quantum", "Value": "7.748 091 7310 e-5", "Uncertainty": "0.000 000 0018 e-5", "Unit": "S" }, { "Quantity ": "conventional value of Josephson constant", "Value": "483 597.9 e9", "Uncertainty": "(exact)", "Unit": "Hz V^{-1}" }, { "Quantity ": "conventional value of von Klitzing constant", "Value": "25 812.807", "Uncertainty": "(exact)", "Unit": "ohm" }, { "Quantity ": "Cu x unit", "Value": "1.002 076 97 e-13", "Uncertainty": "0.000 000 28 e-13", "Unit": "m" }, { "Quantity ": "deuteron-electron mag. mom. ratio", "Value": "-4.664 345 535 e-4", "Uncertainty": "0.000 000 026 e-4", "Unit": "" }, { "Quantity ": "deuteron-electron mass ratio", "Value": "3670.482 967 85", "Uncertainty": "0.000 000 13", "Unit": "" }, { "Quantity ": "deuteron g factor", "Value": "0.857 438 2311", "Uncertainty": "0.000 000 0048", "Unit": "" }, { "Quantity ": "deuteron mag. mom.", "Value": "0.433 073 5040 e-26", "Uncertainty": "0.000 000 0036 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "deuteron mag. mom. to Bohr magneton ratio", "Value": "0.466 975 4554 e-3", "Uncertainty": "0.000 000 0026 e-3", "Unit": "" }, { "Quantity ": "deuteron mag. mom. to nuclear magneton ratio", "Value": "0.857 438 2311", "Uncertainty": "0.000 000 0048", "Unit": "" }, { "Quantity ": "deuteron mass", "Value": "3.343 583 719 e-27", "Uncertainty": "0.000 000 041 e-27", "Unit": "kg" }, { "Quantity ": "deuteron mass energy equivalent", "Value": "3.005 063 183 e-10", "Uncertainty": "0.000 000 037 e-10", "Unit": "J" }, { "Quantity ": "deuteron mass energy equivalent in MeV", "Value": "1875.612 928", "Uncertainty": "0.000 012", "Unit": "MeV" }, { "Quantity ": "deuteron mass in u", "Value": "2.013 553 212 745", "Uncertainty": "0.000 000 000 040", "Unit": "u" }, { "Quantity ": "deuteron molar mass", "Value": "2.013 553 212 745 e-3", "Uncertainty": "0.000 000 000 040 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "deuteron-neutron mag. mom. ratio", "Value": "-0.448 206 52", "Uncertainty": "0.000 000 11", "Unit": "" }, { "Quantity ": "deuteron-proton mag. mom. ratio", "Value": "0.307 012 2077", "Uncertainty": "0.000 000 0015", "Unit": "" }, { "Quantity ": "deuteron-proton mass ratio", "Value": "1.999 007 500 87", "Uncertainty": "0.000 000 000 19", "Unit": "" }, { "Quantity ": "deuteron rms charge radius", "Value": "2.1413 e-15", "Uncertainty": "0.0025 e-15", "Unit": "m" }, { "Quantity ": "electric constant", "Value": "8.854 187 817... e-12", "Uncertainty": "(exact)", "Unit": "F m^{-1}" }, { "Quantity ": "electron charge to mass quotient", "Value": "-1.758 820 024 e11", "Uncertainty": "0.000 000 011 e11", "Unit": "C kg^{-1}" }, { "Quantity ": "electron-deuteron mag. mom. ratio", "Value": "-2143.923 499", "Uncertainty": "0.000 012", "Unit": "" }, { "Quantity ": "electron-deuteron mass ratio", "Value": "2.724 437 107 484 e-4", "Uncertainty": "0.000 000 000 096 e-4", "Unit": "" }, { "Quantity ": "electron g factor", "Value": "-2.002 319 304 361 82", "Uncertainty": "0.000 000 000 000 52", "Unit": "" }, { "Quantity ": "electron gyromag. ratio", "Value": "1.760 859 644 e11", "Uncertainty": "0.000 000 011 e11", "Unit": "s^{-1} T^{-1}" }, { "Quantity ": "electron gyromag. ratio over 2 pi", "Value": "28 024.951 64", "Uncertainty": "0.000 17", "Unit": "MHz T^{-1}" }, { "Quantity ": "electron-helion mass ratio", "Value": "1.819 543 074 854 e-4", "Uncertainty": "0.000 000 000 088 e-4", "Unit": "" }, { "Quantity ": "electron mag. mom.", "Value": "-928.476 4620 e-26", "Uncertainty": "0.000 0057 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "electron mag. mom. anomaly", "Value": "1.159 652 180 91 e-3", "Uncertainty": "0.000 000 000 26 e-3", "Unit": "" }, { "Quantity ": "electron mag. mom. to Bohr magneton ratio", "Value": "-1.001 159 652 180 91", "Uncertainty": "0.000 000 000 000 26", "Unit": "" }, { "Quantity ": "electron mag. mom. to nuclear magneton ratio", "Value": "-1838.281 972 34", "Uncertainty": "0.000 000 17", "Unit": "" }, { "Quantity ": "electron mass", "Value": "9.109 383 56 e-31", "Uncertainty": "0.000 000 11 e-31", "Unit": "kg" }, { "Quantity ": "electron mass energy equivalent", "Value": "8.187 105 65 e-14", "Uncertainty": "0.000 000 10 e-14", "Unit": "J" }, { "Quantity ": "electron mass energy equivalent in MeV", "Value": "0.510 998 9461", "Uncertainty": "0.000 000 0031", "Unit": "MeV" }, { "Quantity ": "electron mass in u", "Value": "5.485 799 090 70 e-4", "Uncertainty": "0.000 000 000 16 e-4", "Unit": "u" }, { "Quantity ": "electron molar mass", "Value": "5.485 799 090 70 e-7", "Uncertainty": "0.000 000 000 16 e-7", "Unit": "kg mol^{-1}" }, { "Quantity ": "electron-muon mag. mom. ratio", "Value": "206.766 9880", "Uncertainty": "0.000 0046", "Unit": "" }, { "Quantity ": "electron-muon mass ratio", "Value": "4.836 331 70 e-3", "Uncertainty": "0.000 000 11 e-3", "Unit": "" }, { "Quantity ": "electron-neutron mag. mom. ratio", "Value": "960.920 50", "Uncertainty": "0.000 23", "Unit": "" }, { "Quantity ": "electron-neutron mass ratio", "Value": "5.438 673 4428 e-4", "Uncertainty": "0.000 000 0027 e-4", "Unit": "" }, { "Quantity ": "electron-proton mag. mom. ratio", "Value": "-658.210 6866", "Uncertainty": "0.000 0020", "Unit": "" }, { "Quantity ": "electron-proton mass ratio", "Value": "5.446 170 213 52 e-4", "Uncertainty": "0.000 000 000 52 e-4", "Unit": "" }, { "Quantity ": "electron-tau mass ratio", "Value": "2.875 92 e-4", "Uncertainty": "0.000 26 e-4", "Unit": "" }, { "Quantity ": "electron to alpha particle mass ratio", "Value": "1.370 933 554 798 e-4", "Uncertainty": "0.000 000 000 045 e-4", "Unit": "" }, { "Quantity ": "electron to shielded helion mag. mom. ratio", "Value": "864.058 257", "Uncertainty": "0.000 010", "Unit": "" }, { "Quantity ": "electron to shielded proton mag. mom. ratio", "Value": "-658.227 5971", "Uncertainty": "0.000 0072", "Unit": "" }, { "Quantity ": "electron-triton mass ratio", "Value": "1.819 200 062 203 e-4", "Uncertainty": "0.000 000 000 084 e-4", "Unit": "" }, { "Quantity ": "electron volt", "Value": "1.602 176 6208 e-19", "Uncertainty": "0.000 000 0098 e-19", "Unit": "J" }, { "Quantity ": "electron volt-atomic mass unit relationship", "Value": "1.073 544 1105 e-9", "Uncertainty": "0.000 000 0066 e-9", "Unit": "u" }, { "Quantity ": "electron volt-hartree relationship", "Value": "3.674 932 248 e-2", "Uncertainty": "0.000 000 023 e-2", "Unit": "E_h" }, { "Quantity ": "electron volt-hertz relationship", "Value": "2.417 989 262 e14", "Uncertainty": "0.000 000 015 e14", "Unit": "Hz" }, { "Quantity ": "electron volt-inverse meter relationship", "Value": "8.065 544 005 e5", "Uncertainty": "0.000 000 050 e5", "Unit": "m^{-1}" }, { "Quantity ": "electron volt-joule relationship", "Value": "1.602 176 6208 e-19", "Uncertainty": "0.000 000 0098 e-19", "Unit": "J" }, { "Quantity ": "electron volt-kelvin relationship", "Value": "1.160 452 21 e4", "Uncertainty": "0.000 000 67 e4", "Unit": "K" }, { "Quantity ": "electron volt-kilogram relationship", "Value": "1.782 661 907 e-36", "Uncertainty": "0.000 000 011 e-36", "Unit": "kg" }, { "Quantity ": "elementary charge", "Value": "1.602 176 6208 e-19", "Uncertainty": "0.000 000 0098 e-19", "Unit": "C" }, { "Quantity ": "elementary charge over h", "Value": "2.417 989 262 e14", "Uncertainty": "0.000 000 015 e14", "Unit": "A J^{-1}" }, { "Quantity ": "Faraday constant", "Value": "96 485.332 89", "Uncertainty": "0.000 59", "Unit": "C mol^{-1}" }, { "Quantity ": "Faraday constant for conventional electric current", "Value": "96 485.3251", "Uncertainty": "0.0012", "Unit": "C_{90} mol^{-1}" }, { "Quantity ": "Fermi coupling constant", "Value": "1.166 3787 e-5", "Uncertainty": "0.000 0006 e-5", "Unit": "GeV^{-2}" }, { "Quantity ": "fine-structure constant", "Value": "7.297 352 5664 e-3", "Uncertainty": "0.000 000 0017 e-3", "Unit": "" }, { "Quantity ": "first radiation constant", "Value": "3.741 771 790 e-16", "Uncertainty": "0.000 000 046 e-16", "Unit": "W m^2" }, { "Quantity ": "first radiation constant for spectral radiance", "Value": "1.191 042 953 e-16", "Uncertainty": "0.000 000 015 e-16", "Unit": "W m^2 sr^{-1}" }, { "Quantity ": "hartree-atomic mass unit relationship", "Value": "2.921 262 3197 e-8", "Uncertainty": "0.000 000 0013 e-8", "Unit": "u" }, { "Quantity ": "hartree-electron volt relationship", "Value": "27.211 386 02", "Uncertainty": "0.000 000 17", "Unit": "eV" }, { "Quantity ": "Hartree energy", "Value": "4.359 744 650 e-18", "Uncertainty": "0.000 000 054 e-18", "Unit": "J" }, { "Quantity ": "Hartree energy in eV", "Value": "27.211 386 02", "Uncertainty": "0.000 000 17", "Unit": "eV" }, { "Quantity ": "hartree-hertz relationship", "Value": "6.579 683 920 711 e15", "Uncertainty": "0.000 000 000 039 e15", "Unit": "Hz" }, { "Quantity ": "hartree-inverse meter relationship", "Value": "2.194 746 313 702 e7", "Uncertainty": "0.000 000 000 013 e7", "Unit": "m^{-1}" }, { "Quantity ": "hartree-joule relationship", "Value": "4.359 744 650 e-18", "Uncertainty": "0.000 000 054 e-18", "Unit": "J" }, { "Quantity ": "hartree-kelvin relationship", "Value": "3.157 7513 e5", "Uncertainty": "0.000 0018 e5", "Unit": "K" }, { "Quantity ": "hartree-kilogram relationship", "Value": "4.850 870 129 e-35", "Uncertainty": "0.000 000 060 e-35", "Unit": "kg" }, { "Quantity ": "helion-electron mass ratio", "Value": "5495.885 279 22", "Uncertainty": "0.000 000 27", "Unit": "" }, { "Quantity ": "helion g factor", "Value": "-4.255 250 616", "Uncertainty": "0.000 000 050", "Unit": "" }, { "Quantity ": "helion mag. mom.", "Value": "-1.074 617 522 e-26", "Uncertainty": "0.000 000 014 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "helion mag. mom. to Bohr magneton ratio", "Value": "-1.158 740 958 e-3", "Uncertainty": "0.000 000 014 e-3", "Unit": "" }, { "Quantity ": "helion mag. mom. to nuclear magneton ratio", "Value": "-2.127 625 308", "Uncertainty": "0.000 000 025", "Unit": "" }, { "Quantity ": "helion mass", "Value": "5.006 412 700 e-27", "Uncertainty": "0.000 000 062 e-27", "Unit": "kg" }, { "Quantity ": "helion mass energy equivalent", "Value": "4.499 539 341 e-10", "Uncertainty": "0.000 000 055 e-10", "Unit": "J" }, { "Quantity ": "helion mass energy equivalent in MeV", "Value": "2808.391 586", "Uncertainty": "0.000 017", "Unit": "MeV" }, { "Quantity ": "helion mass in u", "Value": "3.014 932 246 73", "Uncertainty": "0.000 000 000 12", "Unit": "u" }, { "Quantity ": "helion molar mass", "Value": "3.014 932 246 73 e-3", "Uncertainty": "0.000 000 000 12 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "helion-proton mass ratio", "Value": "2.993 152 670 46", "Uncertainty": "0.000 000 000 29", "Unit": "" }, { "Quantity ": "hertz-atomic mass unit relationship", "Value": "4.439 821 6616 e-24", "Uncertainty": "0.000 000 0020 e-24", "Unit": "u" }, { "Quantity ": "hertz-electron volt relationship", "Value": "4.135 667 662 e-15", "Uncertainty": "0.000 000 025 e-15", "Unit": "eV" }, { "Quantity ": "hertz-hartree relationship", "Value": "1.519 829 846 0088 e-16", "Uncertainty": "0.000 000 000 0090 e-16", "Unit": "E_h" }, { "Quantity ": "hertz-inverse meter relationship", "Value": "3.335 640 951... e-9", "Uncertainty": "(exact)", "Unit": "m^{-1}" }, { "Quantity ": "hertz-joule relationship", "Value": "6.626 070 040 e-34", "Uncertainty": "0.000 000 081 e-34", "Unit": "J" }, { "Quantity ": "hertz-kelvin relationship", "Value": "4.799 2447 e-11", "Uncertainty": "0.000 0028 e-11", "Unit": "K" }, { "Quantity ": "hertz-kilogram relationship", "Value": "7.372 497 201 e-51", "Uncertainty": "0.000 000 091 e-51", "Unit": "kg" }, { "Quantity ": "inverse fine-structure constant", "Value": "137.035 999 139", "Uncertainty": "0.000 000 031", "Unit": "" }, { "Quantity ": "inverse meter-atomic mass unit relationship", "Value": "1.331 025 049 00 e-15", "Uncertainty": "0.000 000 000 61 e-15", "Unit": "u" }, { "Quantity ": "inverse meter-electron volt relationship", "Value": "1.239 841 9739 e-6", "Uncertainty": "0.000 000 0076 e-6", "Unit": "eV" }, { "Quantity ": "inverse meter-hartree relationship", "Value": "4.556 335 252 767 e-8", "Uncertainty": "0.000 000 000 027 e-8", "Unit": "E_h" }, { "Quantity ": "inverse meter-hertz relationship", "Value": "299 792 458", "Uncertainty": "(exact)", "Unit": "Hz" }, { "Quantity ": "inverse meter-joule relationship", "Value": "1.986 445 824 e-25", "Uncertainty": "0.000 000 024 e-25", "Unit": "J" }, { "Quantity ": "inverse meter-kelvin relationship", "Value": "1.438 777 36 e-2", "Uncertainty": "0.000 000 83 e-2", "Unit": "K" }, { "Quantity ": "inverse meter-kilogram relationship", "Value": "2.210 219 057 e-42", "Uncertainty": "0.000 000 027 e-42", "Unit": "kg" }, { "Quantity ": "inverse of conductance quantum", "Value": "12 906.403 7278", "Uncertainty": "0.000 0029", "Unit": "ohm" }, { "Quantity ": "Josephson constant", "Value": "483 597.8525 e9", "Uncertainty": "0.0030 e9", "Unit": "Hz V^{-1}" }, { "Quantity ": "joule-atomic mass unit relationship", "Value": "6.700 535 363 e9", "Uncertainty": "0.000 000 082 e9", "Unit": "u" }, { "Quantity ": "joule-electron volt relationship", "Value": "6.241 509 126 e18", "Uncertainty": "0.000 000 038 e18", "Unit": "eV" }, { "Quantity ": "joule-hartree relationship", "Value": "2.293 712 317 e17", "Uncertainty": "0.000 000 028 e17", "Unit": "E_h" }, { "Quantity ": "joule-hertz relationship", "Value": "1.509 190 205 e33", "Uncertainty": "0.000 000 019 e33", "Unit": "Hz" }, { "Quantity ": "joule-inverse meter relationship", "Value": "5.034 116 651 e24", "Uncertainty": "0.000 000 062 e24", "Unit": "m^{-1}" }, { "Quantity ": "joule-kelvin relationship", "Value": "7.242 9731 e22", "Uncertainty": "0.000 0042 e22", "Unit": "K" }, { "Quantity ": "joule-kilogram relationship", "Value": "1.112 650 056... e-17", "Uncertainty": "(exact)", "Unit": "kg" }, { "Quantity ": "kelvin-atomic mass unit relationship", "Value": "9.251 0842 e-14", "Uncertainty": "0.000 0053 e-14", "Unit": "u" }, { "Quantity ": "kelvin-electron volt relationship", "Value": "8.617 3303 e-5", "Uncertainty": "0.000 0050 e-5", "Unit": "eV" }, { "Quantity ": "kelvin-hartree relationship", "Value": "3.166 8105 e-6", "Uncertainty": "0.000 0018 e-6", "Unit": "E_h" }, { "Quantity ": "kelvin-hertz relationship", "Value": "2.083 6612 e10", "Uncertainty": "0.000 0012 e10", "Unit": "Hz" }, { "Quantity ": "kelvin-inverse meter relationship", "Value": "69.503 457", "Uncertainty": "0.000 040", "Unit": "m^{-1}" }, { "Quantity ": "kelvin-joule relationship", "Value": "1.380 648 52 e-23", "Uncertainty": "0.000 000 79 e-23", "Unit": "J" }, { "Quantity ": "kelvin-kilogram relationship", "Value": "1.536 178 65 e-40", "Uncertainty": "0.000 000 88 e-40", "Unit": "kg" }, { "Quantity ": "kilogram-atomic mass unit relationship", "Value": "6.022 140 857 e26", "Uncertainty": "0.000 000 074 e26", "Unit": "u" }, { "Quantity ": "kilogram-electron volt relationship", "Value": "5.609 588 650 e35", "Uncertainty": "0.000 000 034 e35", "Unit": "eV" }, { "Quantity ": "kilogram-hartree relationship", "Value": "2.061 485 823 e34", "Uncertainty": "0.000 000 025 e34", "Unit": "E_h" }, { "Quantity ": "kilogram-hertz relationship", "Value": "1.356 392 512 e50", "Uncertainty": "0.000 000 017 e50", "Unit": "Hz" }, { "Quantity ": "kilogram-inverse meter relationship", "Value": "4.524 438 411 e41", "Uncertainty": "0.000 000 056 e41", "Unit": "m^{-1}" }, { "Quantity ": "kilogram-joule relationship", "Value": "8.987 551 787... e16", "Uncertainty": "(exact)", "Unit": "J" }, { "Quantity ": "kilogram-kelvin relationship", "Value": "6.509 6595 e39", "Uncertainty": "0.000 0037 e39", "Unit": "K" }, { "Quantity ": "lattice parameter of silicon", "Value": "543.102 0504 e-12", "Uncertainty": "0.000 0089 e-12", "Unit": "m" }, { "Quantity ": "Loschmidt constant (273.15 K, 100 kPa)", "Value": "2.651 6467 e25", "Uncertainty": "0.000 0015 e25", "Unit": "m^{-3}" }, { "Quantity ": "Loschmidt constant (273.15 K, 101.325 kPa)", "Value": "2.686 7811 e25", "Uncertainty": "0.000 0015 e25", "Unit": "m^{-3}" }, { "Quantity ": "mag. constant", "Value": "12.566 370 614... e-7", "Uncertainty": "(exact)", "Unit": "N A^{-2}" }, { "Quantity ": "mag. flux quantum", "Value": "2.067 833 831 e-15", "Uncertainty": "0.000 000 013 e-15", "Unit": "Wb" }, { "Quantity ": "molar gas constant", "Value": "8.314 4598", "Uncertainty": "0.000 0048", "Unit": "J mol^{-1} K^{-1}" }, { "Quantity ": "molar mass constant", "Value": "1 e-3", "Uncertainty": "(exact)", "Unit": "kg mol^{-1}" }, { "Quantity ": "molar mass of carbon-12", "Value": "12 e-3", "Uncertainty": "(exact)", "Unit": "kg mol^{-1}" }, { "Quantity ": "molar Planck constant", "Value": "3.990 312 7110 e-10", "Uncertainty": "0.000 000 0018 e-10", "Unit": "J s mol^{-1}" }, { "Quantity ": "molar Planck constant times c", "Value": "0.119 626 565 582", "Uncertainty": "0.000 000 000 054", "Unit": "J m mol^{-1}" }, { "Quantity ": "molar volume of ideal gas (273.15 K, 100 kPa)", "Value": "22.710 947 e-3", "Uncertainty": "0.000 013 e-3", "Unit": "m^3 mol^{-1}" }, { "Quantity ": "molar volume of ideal gas (273.15 K, 101.325 kPa)", "Value": "22.413 962 e-3", "Uncertainty": "0.000 013 e-3", "Unit": "m^3 mol^{-1}" }, { "Quantity ": "molar volume of silicon", "Value": "12.058 832 14 e-6", "Uncertainty": "0.000 000 61 e-6", "Unit": "m^3 mol^{-1}" }, { "Quantity ": "Mo x unit", "Value": "1.002 099 52 e-13", "Uncertainty": "0.000 000 53 e-13", "Unit": "m" }, { "Quantity ": "muon Compton wavelength", "Value": "11.734 441 11 e-15", "Uncertainty": "0.000 000 26 e-15", "Unit": "m" }, { "Quantity ": "muon Compton wavelength over 2 pi", "Value": "1.867 594 308 e-15", "Uncertainty": "0.000 000 042 e-15", "Unit": "m" }, { "Quantity ": "muon-electron mass ratio", "Value": "206.768 2826", "Uncertainty": "0.000 0046", "Unit": "" }, { "Quantity ": "muon g factor", "Value": "-2.002 331 8418", "Uncertainty": "0.000 000 0013", "Unit": "" }, { "Quantity ": "muon mag. mom.", "Value": "-4.490 448 26 e-26", "Uncertainty": "0.000 000 10 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "muon mag. mom. anomaly", "Value": "1.165 920 89 e-3", "Uncertainty": "0.000 000 63 e-3", "Unit": "" }, { "Quantity ": "muon mag. mom. to Bohr magneton ratio", "Value": "-4.841 970 48 e-3", "Uncertainty": "0.000 000 11 e-3", "Unit": "" }, { "Quantity ": "muon mag. mom. to nuclear magneton ratio", "Value": "-8.890 597 05", "Uncertainty": "0.000 000 20", "Unit": "" }, { "Quantity ": "muon mass", "Value": "1.883 531 594 e-28", "Uncertainty": "0.000 000 048 e-28", "Unit": "kg" }, { "Quantity ": "muon mass energy equivalent", "Value": "1.692 833 774 e-11", "Uncertainty": "0.000 000 043 e-11", "Unit": "J" }, { "Quantity ": "muon mass energy equivalent in MeV", "Value": "105.658 3745", "Uncertainty": "0.000 0024", "Unit": "MeV" }, { "Quantity ": "muon mass in u", "Value": "0.113 428 9257", "Uncertainty": "0.000 000 0025", "Unit": "u" }, { "Quantity ": "muon molar mass", "Value": "0.113 428 9257 e-3", "Uncertainty": "0.000 000 0025 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "muon-neutron mass ratio", "Value": "0.112 454 5167", "Uncertainty": "0.000 000 0025", "Unit": "" }, { "Quantity ": "muon-proton mag. mom. ratio", "Value": "-3.183 345 142", "Uncertainty": "0.000 000 071", "Unit": "" }, { "Quantity ": "muon-proton mass ratio", "Value": "0.112 609 5262", "Uncertainty": "0.000 000 0025", "Unit": "" }, { "Quantity ": "muon-tau mass ratio", "Value": "5.946 49 e-2", "Uncertainty": "0.000 54 e-2", "Unit": "" }, { "Quantity ": "natural unit of action", "Value": "1.054 571 800 e-34", "Uncertainty": "0.000 000 013 e-34", "Unit": "J s" }, { "Quantity ": "natural unit of action in eV s", "Value": "6.582 119 514 e-16", "Uncertainty": "0.000 000 040 e-16", "Unit": "eV s" }, { "Quantity ": "natural unit of energy", "Value": "8.187 105 65 e-14", "Uncertainty": "0.000 000 10 e-14", "Unit": "J" }, { "Quantity ": "natural unit of energy in MeV", "Value": "0.510 998 9461", "Uncertainty": "0.000 000 0031", "Unit": "MeV" }, { "Quantity ": "natural unit of length", "Value": "386.159 267 64 e-15", "Uncertainty": "0.000 000 18 e-15", "Unit": "m" }, { "Quantity ": "natural unit of mass", "Value": "9.109 383 56 e-31", "Uncertainty": "0.000 000 11 e-31", "Unit": "kg" }, { "Quantity ": "natural unit of mom.um", "Value": "2.730 924 488 e-22", "Uncertainty": "0.000 000 034 e-22", "Unit": "kg m s^{-1}" }, { "Quantity ": "natural unit of mom.um in MeV/c", "Value": "0.510 998 9461", "Uncertainty": "0.000 000 0031", "Unit": "MeV/c" }, { "Quantity ": "natural unit of time", "Value": "1.288 088 667 12 e-21", "Uncertainty": "0.000 000 000 58 e-21", "Unit": "s" }, { "Quantity ": "natural unit of velocity", "Value": "299 792 458", "Uncertainty": "(exact)", "Unit": "m s^{-1}" }, { "Quantity ": "neutron Compton wavelength", "Value": "1.319 590 904 81 e-15", "Uncertainty": "0.000 000 000 88 e-15", "Unit": "m" }, { "Quantity ": "neutron Compton wavelength over 2 pi", "Value": "0.210 019 415 36 e-15", "Uncertainty": "0.000 000 000 14 e-15", "Unit": "m" }, { "Quantity ": "neutron-electron mag. mom. ratio", "Value": "1.040 668 82 e-3", "Uncertainty": "0.000 000 25 e-3", "Unit": "" }, { "Quantity ": "neutron-electron mass ratio", "Value": "1838.683 661 58", "Uncertainty": "0.000 000 90", "Unit": "" }, { "Quantity ": "neutron g factor", "Value": "-3.826 085 45", "Uncertainty": "0.000 000 90", "Unit": "" }, { "Quantity ": "neutron gyromag. ratio", "Value": "1.832 471 72 e8", "Uncertainty": "0.000 000 43 e8", "Unit": "s^{-1} T^{-1}" }, { "Quantity ": "neutron gyromag. ratio over 2 pi", "Value": "29.164 6933", "Uncertainty": "0.000 0069", "Unit": "MHz T^{-1}" }, { "Quantity ": "neutron mag. mom.", "Value": "-0.966 236 50 e-26", "Uncertainty": "0.000 000 23 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "neutron mag. mom. to Bohr magneton ratio", "Value": "-1.041 875 63 e-3", "Uncertainty": "0.000 000 25 e-3", "Unit": "" }, { "Quantity ": "neutron mag. mom. to nuclear magneton ratio", "Value": "-1.913 042 73", "Uncertainty": "0.000 000 45", "Unit": "" }, { "Quantity ": "neutron mass", "Value": "1.674 927 471 e-27", "Uncertainty": "0.000 000 021 e-27", "Unit": "kg" }, { "Quantity ": "neutron mass energy equivalent", "Value": "1.505 349 739 e-10", "Uncertainty": "0.000 000 019 e-10", "Unit": "J" }, { "Quantity ": "neutron mass energy equivalent in MeV", "Value": "939.565 4133", "Uncertainty": "0.000 0058", "Unit": "MeV" }, { "Quantity ": "neutron mass in u", "Value": "1.008 664 915 88", "Uncertainty": "0.000 000 000 49", "Unit": "u" }, { "Quantity ": "neutron molar mass", "Value": "1.008 664 915 88 e-3", "Uncertainty": "0.000 000 000 49 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "neutron-muon mass ratio", "Value": "8.892 484 08", "Uncertainty": "0.000 000 20", "Unit": "" }, { "Quantity ": "neutron-proton mag. mom. ratio", "Value": "-0.684 979 34", "Uncertainty": "0.000 000 16", "Unit": "" }, { "Quantity ": "neutron-proton mass difference", "Value": "2.305 573 77 e-30", "Uncertainty": "0.000 000 85 e-30", "Unit": "" }, { "Quantity ": "neutron-proton mass difference energy equivalent", "Value": "2.072 146 37 e-13", "Uncertainty": "0.000 000 76 e-13", "Unit": "" }, { "Quantity ": "neutron-proton mass difference energy equivalent in MeV", "Value": "1.293 332 05", "Uncertainty": "0.000 000 48", "Unit": "" }, { "Quantity ": "neutron-proton mass difference in u", "Value": "0.001 388 449 00", "Uncertainty": "0.000 000 000 51", "Unit": "" }, { "Quantity ": "neutron-proton mass ratio", "Value": "1.001 378 418 98", "Uncertainty": "0.000 000 000 51", "Unit": "" }, { "Quantity ": "neutron-tau mass ratio", "Value": "0.528 790", "Uncertainty": "0.000 048", "Unit": "" }, { "Quantity ": "neutron to shielded proton mag. mom. ratio", "Value": "-0.684 996 94", "Uncertainty": "0.000 000 16", "Unit": "" }, { "Quantity ": "Newtonian constant of gravitation", "Value": "6.674 08 e-11", "Uncertainty": "0.000 31 e-11", "Unit": "m^3 kg^{-1} s^{-2}" }, { "Quantity ": "Newtonian constant of gravitation over h-bar c", "Value": "6.708 61 e-39", "Uncertainty": "0.000 31 e-39", "Unit": "(GeV/c^2)^-2" }, { "Quantity ": "nuclear magneton", "Value": "5.050 783 699 e-27", "Uncertainty": "0.000 000 031 e-27", "Unit": "J T^{-1}" }, { "Quantity ": "nuclear magneton in eV/T", "Value": "3.152 451 2550 e-8", "Uncertainty": "0.000 000 0015 e-8", "Unit": "eV T^{-1}" }, { "Quantity ": "nuclear magneton in inverse meters per tesla", "Value": "2.542 623 432 e-2", "Uncertainty": "0.000 000 016 e-2", "Unit": "m^{-1} T^{-1}" }, { "Quantity ": "nuclear magneton in K/T", "Value": "3.658 2690 e-4", "Uncertainty": "0.000 0021 e-4", "Unit": "K T^{-1}" }, { "Quantity ": "nuclear magneton in MHz/T", "Value": "7.622 593 285", "Uncertainty": "0.000 000 047", "Unit": "MHz T^{-1}" }, { "Quantity ": "Planck constant", "Value": "6.626 070 040 e-34", "Uncertainty": "0.000 000 081 e-34", "Unit": "J s" }, { "Quantity ": "Planck constant in eV s", "Value": "4.135 667 662 e-15", "Uncertainty": "0.000 000 025 e-15", "Unit": "eV s" }, { "Quantity ": "Planck constant over 2 pi", "Value": "1.054 571 800 e-34", "Uncertainty": "0.000 000 013 e-34", "Unit": "J s" }, { "Quantity ": "Planck constant over 2 pi in eV s", "Value": "6.582 119 514 e-16", "Uncertainty": "0.000 000 040 e-16", "Unit": "eV s" }, { "Quantity ": "Planck constant over 2 pi times c in MeV fm", "Value": "197.326 9788", "Uncertainty": "0.000 0012", "Unit": "MeV fm" }, { "Quantity ": "Planck length", "Value": "1.616 229 e-35", "Uncertainty": "0.000 038 e-35", "Unit": "m" }, { "Quantity ": "Planck mass", "Value": "2.176 470 e-8", "Uncertainty": "0.000 051 e-8", "Unit": "kg" }, { "Quantity ": "Planck mass energy equivalent in GeV", "Value": "1.220 910 e19", "Uncertainty": "0.000 029 e19", "Unit": "GeV" }, { "Quantity ": "Planck temperature", "Value": "1.416 808 e32", "Uncertainty": "0.000 033 e32", "Unit": "K" }, { "Quantity ": "Planck time", "Value": "5.391 16 e-44", "Uncertainty": "0.000 13 e-44", "Unit": "s" }, { "Quantity ": "proton charge to mass quotient", "Value": "9.578 833 226 e7", "Uncertainty": "0.000 000 059 e7", "Unit": "C kg^{-1}" }, { "Quantity ": "proton Compton wavelength", "Value": "1.321 409 853 96 e-15", "Uncertainty": "0.000 000 000 61 e-15", "Unit": "m" }, { "Quantity ": "proton Compton wavelength over 2 pi", "Value": "0.210 308 910 109 e-15", "Uncertainty": "0.000 000 000 097 e-15", "Unit": "m" }, { "Quantity ": "proton-electron mass ratio", "Value": "1836.152 673 89", "Uncertainty": "0.000 000 17", "Unit": "" }, { "Quantity ": "proton g factor", "Value": "5.585 694 702", "Uncertainty": "0.000 000 017", "Unit": "" }, { "Quantity ": "proton gyromag. ratio", "Value": "2.675 221 900 e8", "Uncertainty": "0.000 000 018 e8", "Unit": "s^{-1} T^{-1}" }, { "Quantity ": "proton gyromag. ratio over 2 pi", "Value": "42.577 478 92", "Uncertainty": "0.000 000 29", "Unit": "MHz T^{-1}" }, { "Quantity ": "proton mag. mom.", "Value": "1.410 606 7873 e-26", "Uncertainty": "0.000 000 0097 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "proton mag. mom. to Bohr magneton ratio", "Value": "1.521 032 2053 e-3", "Uncertainty": "0.000 000 0046 e-3", "Unit": "" }, { "Quantity ": "proton mag. mom. to nuclear magneton ratio", "Value": "2.792 847 3508", "Uncertainty": "0.000 000 0085", "Unit": "" }, { "Quantity ": "proton mag. shielding correction", "Value": "25.691 e-6", "Uncertainty": "0.011 e-6", "Unit": "" }, { "Quantity ": "proton mass", "Value": "1.672 621 898 e-27", "Uncertainty": "0.000 000 021 e-27", "Unit": "kg" }, { "Quantity ": "proton mass energy equivalent", "Value": "1.503 277 593 e-10", "Uncertainty": "0.000 000 018 e-10", "Unit": "J" }, { "Quantity ": "proton mass energy equivalent in MeV", "Value": "938.272 0813", "Uncertainty": "0.000 0058", "Unit": "MeV" }, { "Quantity ": "proton mass in u", "Value": "1.007 276 466 879", "Uncertainty": "0.000 000 000 091", "Unit": "u" }, { "Quantity ": "proton molar mass", "Value": "1.007 276 466 879 e-3", "Uncertainty": "0.000 000 000 091 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "proton-muon mass ratio", "Value": "8.880 243 38", "Uncertainty": "0.000 000 20", "Unit": "" }, { "Quantity ": "proton-neutron mag. mom. ratio", "Value": "-1.459 898 05", "Uncertainty": "0.000 000 34", "Unit": "" }, { "Quantity ": "proton-neutron mass ratio", "Value": "0.998 623 478 44", "Uncertainty": "0.000 000 000 51", "Unit": "" }, { "Quantity ": "proton rms charge radius", "Value": "0.8751 e-15", "Uncertainty": "0.0061 e-15", "Unit": "m" }, { "Quantity ": "proton-tau mass ratio", "Value": "0.528 063", "Uncertainty": "0.000 048", "Unit": "" }, { "Quantity ": "quantum of circulation", "Value": "3.636 947 5486 e-4", "Uncertainty": "0.000 000 0017 e-4", "Unit": "m^2 s^{-1}" }, { "Quantity ": "quantum of circulation times 2", "Value": "7.273 895 0972 e-4", "Uncertainty": "0.000 000 0033 e-4", "Unit": "m^2 s^{-1}" }, { "Quantity ": "Rydberg constant", "Value": "10 973 731.568 508", "Uncertainty": "0.000 065", "Unit": "m^{-1}" }, { "Quantity ": "Rydberg constant times c in Hz", "Value": "3.289 841 960 355 e15", "Uncertainty": "0.000 000 000 019 e15", "Unit": "Hz" }, { "Quantity ": "Rydberg constant times hc in eV", "Value": "13.605 693 009", "Uncertainty": "0.000 000 084", "Unit": "eV" }, { "Quantity ": "Rydberg constant times hc in J", "Value": "2.179 872 325 e-18", "Uncertainty": "0.000 000 027 e-18", "Unit": "J" }, { "Quantity ": "Sackur-Tetrode constant (1 K, 100 kPa)", "Value": "-1.151 7084", "Uncertainty": "0.000 0014", "Unit": "" }, { "Quantity ": "Sackur-Tetrode constant (1 K, 101.325 kPa)", "Value": "-1.164 8714", "Uncertainty": "0.000 0014", "Unit": "" }, { "Quantity ": "second radiation constant", "Value": "1.438 777 36 e-2", "Uncertainty": "0.000 000 83 e-2", "Unit": "m K" }, { "Quantity ": "shielded helion gyromag. ratio", "Value": "2.037 894 585 e8", "Uncertainty": "0.000 000 027 e8", "Unit": "s^{-1} T^{-1}" }, { "Quantity ": "shielded helion gyromag. ratio over 2 pi", "Value": "32.434 099 66", "Uncertainty": "0.000 000 43", "Unit": "MHz T^{-1}" }, { "Quantity ": "shielded helion mag. mom.", "Value": "-1.074 553 080 e-26", "Uncertainty": "0.000 000 014 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "shielded helion mag. mom. to Bohr magneton ratio", "Value": "-1.158 671 471 e-3", "Uncertainty": "0.000 000 014 e-3", "Unit": "" }, { "Quantity ": "shielded helion mag. mom. to nuclear magneton ratio", "Value": "-2.127 497 720", "Uncertainty": "0.000 000 025", "Unit": "" }, { "Quantity ": "shielded helion to proton mag. mom. ratio", "Value": "-0.761 766 5603", "Uncertainty": "0.000 000 0092", "Unit": "" }, { "Quantity ": "shielded helion to shielded proton mag. mom. ratio", "Value": "-0.761 786 1313", "Uncertainty": "0.000 000 0033", "Unit": "" }, { "Quantity ": "shielded proton gyromag. ratio", "Value": "2.675 153 171 e8", "Uncertainty": "0.000 000 033 e8", "Unit": "s^{-1} T^{-1}" }, { "Quantity ": "shielded proton gyromag. ratio over 2 pi", "Value": "42.576 385 07", "Uncertainty": "0.000 000 53", "Unit": "MHz T^{-1}" }, { "Quantity ": "shielded proton mag. mom.", "Value": "1.410 570 547 e-26", "Uncertainty": "0.000 000 018 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "shielded proton mag. mom. to Bohr magneton ratio", "Value": "1.520 993 128 e-3", "Uncertainty": "0.000 000 017 e-3", "Unit": "" }, { "Quantity ": "shielded proton mag. mom. to nuclear magneton ratio", "Value": "2.792 775 600", "Uncertainty": "0.000 000 030", "Unit": "" }, { "Quantity ": "speed of light in vacuum", "Value": "299 792 458", "Uncertainty": "(exact)", "Unit": "m s^{-1}" }, { "Quantity ": "standard acceleration of gravity", "Value": "9.806 65", "Uncertainty": "(exact)", "Unit": "m s^{-2}" }, { "Quantity ": "standard atmosphere", "Value": "101 325", "Uncertainty": "(exact)", "Unit": "Pa" }, { "Quantity ": "standard-state pressure", "Value": "100 000", "Uncertainty": "(exact)", "Unit": "Pa" }, { "Quantity ": "Stefan-Boltzmann constant", "Value": "5.670 367 e-8", "Uncertainty": "0.000 013 e-8", "Unit": "W m^{-2} K^{-4}" }, { "Quantity ": "tau Compton wavelength", "Value": "0.697 787 e-15", "Uncertainty": "0.000 063 e-15", "Unit": "m" }, { "Quantity ": "tau Compton wavelength over 2 pi", "Value": "0.111 056 e-15", "Uncertainty": "0.000 010 e-15", "Unit": "m" }, { "Quantity ": "tau-electron mass ratio", "Value": "3477.15", "Uncertainty": "0.31", "Unit": "" }, { "Quantity ": "tau mass", "Value": "3.167 47 e-27", "Uncertainty": "0.000 29 e-27", "Unit": "kg" }, { "Quantity ": "tau mass energy equivalent", "Value": "2.846 78 e-10", "Uncertainty": "0.000 26 e-10", "Unit": "J" }, { "Quantity ": "tau mass energy equivalent in MeV", "Value": "1776.82", "Uncertainty": "0.16", "Unit": "MeV" }, { "Quantity ": "tau mass in u", "Value": "1.907 49", "Uncertainty": "0.000 17", "Unit": "u" }, { "Quantity ": "tau molar mass", "Value": "1.907 49 e-3", "Uncertainty": "0.000 17 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "tau-muon mass ratio", "Value": "16.8167", "Uncertainty": "0.0015", "Unit": "" }, { "Quantity ": "tau-neutron mass ratio", "Value": "1.891 11", "Uncertainty": "0.000 17", "Unit": "" }, { "Quantity ": "tau-proton mass ratio", "Value": "1.893 72", "Uncertainty": "0.000 17", "Unit": "" }, { "Quantity ": "Thomson cross section", "Value": "0.665 245 871 58 e-28", "Uncertainty": "0.000 000 000 91 e-28", "Unit": "m^2" }, { "Quantity ": "triton-electron mass ratio", "Value": "5496.921 535 88", "Uncertainty": "0.000 000 26", "Unit": "" }, { "Quantity ": "triton g factor", "Value": "5.957 924 920", "Uncertainty": "0.000 000 028", "Unit": "" }, { "Quantity ": "triton mag. mom.", "Value": "1.504 609 503 e-26", "Uncertainty": "0.000 000 012 e-26", "Unit": "J T^{-1}" }, { "Quantity ": "triton mag. mom. to Bohr magneton ratio", "Value": "1.622 393 6616 e-3", "Uncertainty": "0.000 000 0076 e-3", "Unit": "" }, { "Quantity ": "triton mag. mom. to nuclear magneton ratio", "Value": "2.978 962 460", "Uncertainty": "0.000 000 014", "Unit": "" }, { "Quantity ": "triton mass", "Value": "5.007 356 665 e-27", "Uncertainty": "0.000 000 062 e-27", "Unit": "kg" }, { "Quantity ": "triton mass energy equivalent", "Value": "4.500 387 735 e-10", "Uncertainty": "0.000 000 055 e-10", "Unit": "J" }, { "Quantity ": "triton mass energy equivalent in MeV", "Value": "2808.921 112", "Uncertainty": "0.000 017", "Unit": "MeV" }, { "Quantity ": "triton mass in u", "Value": "3.015 500 716 32", "Uncertainty": "0.000 000 000 11", "Unit": "u" }, { "Quantity ": "triton molar mass", "Value": "3.015 500 716 32 e-3", "Uncertainty": "0.000 000 000 11 e-3", "Unit": "kg mol^{-1}" }, { "Quantity ": "triton-proton mass ratio", "Value": "2.993 717 033 48", "Uncertainty": "0.000 000 000 22", "Unit": "" }, { "Quantity ": "unified atomic mass unit", "Value": "1.660 539 040 e-27", "Uncertainty": "0.000 000 020 e-27", "Unit": "kg" }, { "Quantity ": "von Klitzing constant", "Value": "25 812.807 4555", "Uncertainty": "0.000 0059", "Unit": "ohm" }, { "Quantity ": "weak mixing angle", "Value": "0.2223", "Uncertainty": "0.0021", "Unit": "" }, { "Quantity ": "Wien frequency displacement law constant", "Value": "5.878 9238 e10", "Uncertainty": "0.000 0034 e10", "Unit": "Hz K^{-1}" }, { "Quantity ": "Wien wavelength displacement law constant", "Value": "2.897 7729 e-3", "Uncertainty": "0.000 0017 e-3", "Unit": "m K" } ] } QCElemental-0.5.0/nist_data/srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json000066400000000000000000016714221351361252000332640ustar00rootroot00000000000000{ "data": [ { "Atomic Symbol": "H", "Atomic Number": "1", "isotopes": [ { "Atomic Symbol": "H", "Mass Number": "1", "Isotopic Composition": "0.999885(70)", "Relative Atomic Mass": "1.00782503223(9)" }, { "Atomic Symbol": "D", "Mass Number": "2", "Isotopic Composition": "0.000115(70)", "Relative Atomic Mass": "2.01410177812(12)" }, { "Atomic Symbol": "T", "Mass Number": "3", "Relative Atomic Mass": "3.0160492779(24)" }, { "Atomic Symbol": "H", "Mass Number": "4", "Relative Atomic Mass": "4.02643(11)" }, { "Atomic Symbol": "H", "Mass Number": "5", "Relative Atomic Mass": "5.035311(96)" }, { "Atomic Symbol": "H", "Mass Number": "6", "Relative Atomic Mass": "6.04496(27)" }, { "Atomic Symbol": "H", "Mass Number": "7", "Relative Atomic Mass": "7.0527(11#)" } ], "Notes": "m", "Standard Atomic Weight": "[1.00784,1.00811]" }, { "Atomic Symbol": "He", "Atomic Number": "2", "isotopes": [ { "Atomic Symbol": "He", "Mass Number": "3", "Isotopic Composition": "0.00000134(3)", "Relative Atomic Mass": "3.0160293201(25)" }, { "Atomic Symbol": "He", "Mass Number": "4", "Isotopic Composition": "0.99999866(3)", "Relative Atomic Mass": "4.00260325413(6)" }, { "Atomic Symbol": "He", "Mass Number": "5", "Relative Atomic Mass": "5.012057(21)" }, { "Atomic Symbol": "He", "Mass Number": "6", "Relative Atomic Mass": "6.018885891(57)" }, { "Atomic Symbol": "He", "Mass Number": "7", "Relative Atomic Mass": "7.0279907(81)" }, { "Atomic Symbol": "He", "Mass Number": "8", "Relative Atomic Mass": "8.033934390(95)" }, { "Atomic Symbol": "He", "Mass Number": "9", "Relative Atomic Mass": "9.043946(50)" }, { "Atomic Symbol": "He", "Mass Number": "10", "Relative Atomic Mass": "10.05279(11)" } ], "Notes": "g,r", "Standard Atomic Weight": "4.002602(2)" }, { "Atomic Symbol": "Li", "Atomic Number": "3", "isotopes": [ { "Atomic Symbol": "Li", "Mass Number": "3", "Relative Atomic Mass": "3.0308(21#)" }, { "Atomic Symbol": "Li", "Mass Number": "4", "Relative Atomic Mass": "4.02719(23)" }, { "Atomic Symbol": "Li", "Mass Number": "5", "Relative Atomic Mass": "5.012538(54)" }, { "Atomic Symbol": "Li", "Mass Number": "6", "Isotopic Composition": "0.0759(4)", "Relative Atomic Mass": "6.0151228874(16)" }, { "Atomic Symbol": "Li", "Mass Number": "7", "Isotopic Composition": "0.9241(4)", "Relative Atomic Mass": "7.0160034366(45)" }, { "Atomic Symbol": "Li", "Mass Number": "8", "Relative Atomic Mass": "8.022486246(50)" }, { "Atomic Symbol": "Li", "Mass Number": "9", "Relative Atomic Mass": "9.02679019(20)" }, { "Atomic Symbol": "Li", "Mass Number": "10", "Relative Atomic Mass": "10.035483(14)" }, { "Atomic Symbol": "Li", "Mass Number": "11", "Relative Atomic Mass": "11.04372358(66)" }, { "Atomic Symbol": "Li", "Mass Number": "12", "Relative Atomic Mass": "12.052517(16)" }, { "Atomic Symbol": "Li", "Mass Number": "13", "Relative Atomic Mass": "13.06263(38)" } ], "Notes": "m", "Standard Atomic Weight": "[6.938,6.997]" }, { "Atomic Symbol": "Be", "Atomic Number": "4", "isotopes": [ { "Atomic Symbol": "Be", "Mass Number": "5", "Relative Atomic Mass": "5.0399(22#)" }, { "Atomic Symbol": "Be", "Mass Number": "6", "Relative Atomic Mass": "6.0197264(58)" }, { "Atomic Symbol": "Be", "Mass Number": "7", "Relative Atomic Mass": "7.016928717(76)" }, { "Atomic Symbol": "Be", "Mass Number": "8", "Relative Atomic Mass": "8.005305102(37)" }, { "Atomic Symbol": "Be", "Mass Number": "9", "Isotopic Composition": "1", "Relative Atomic Mass": "9.012183065(82)" }, { "Atomic Symbol": "Be", "Mass Number": "10", "Relative Atomic Mass": "10.013534695(86)" }, { "Atomic Symbol": "Be", "Mass Number": "11", "Relative Atomic Mass": "11.02166108(26)" }, { "Atomic Symbol": "Be", "Mass Number": "12", "Relative Atomic Mass": "12.0269221(20)" }, { "Atomic Symbol": "Be", "Mass Number": "13", "Relative Atomic Mass": "13.036135(11)" }, { "Atomic Symbol": "Be", "Mass Number": "14", "Relative Atomic Mass": "14.04289(14)" }, { "Atomic Symbol": "Be", "Mass Number": "15", "Relative Atomic Mass": "15.05342(43#)" }, { "Atomic Symbol": "Be", "Mass Number": "16", "Relative Atomic Mass": "16.06167(18)" } ], "Standard Atomic Weight": "9.0121831(5)" }, { "Atomic Symbol": "B", "Atomic Number": "5", "isotopes": [ { "Atomic Symbol": "B", "Mass Number": "6", "Relative Atomic Mass": "6.0508(22#)" }, { "Atomic Symbol": "B", "Mass Number": "7", "Relative Atomic Mass": "7.029712(27)" }, { "Atomic Symbol": "B", "Mass Number": "8", "Relative Atomic Mass": "8.0246073(11)" }, { "Atomic Symbol": "B", "Mass Number": "9", "Relative Atomic Mass": "9.01332965(97)" }, { "Atomic Symbol": "B", "Mass Number": "10", "Isotopic Composition": "0.199(7)", "Relative Atomic Mass": "10.01293695(41)" }, { "Atomic Symbol": "B", "Mass Number": "11", "Isotopic Composition": "0.801(7)", "Relative Atomic Mass": "11.00930536(45)" }, { "Atomic Symbol": "B", "Mass Number": "12", "Relative Atomic Mass": "12.0143527(14)" }, { "Atomic Symbol": "B", "Mass Number": "13", "Relative Atomic Mass": "13.0177802(12)" }, { "Atomic Symbol": "B", "Mass Number": "14", "Relative Atomic Mass": "14.025404(23)" }, { "Atomic Symbol": "B", "Mass Number": "15", "Relative Atomic Mass": "15.031088(23)" }, { "Atomic Symbol": "B", "Mass Number": "16", "Relative Atomic Mass": "16.039842(26)" }, { "Atomic Symbol": "B", "Mass Number": "17", "Relative Atomic Mass": "17.04699(18)" }, { "Atomic Symbol": "B", "Mass Number": "18", "Relative Atomic Mass": "18.05566(18)" }, { "Atomic Symbol": "B", "Mass Number": "19", "Relative Atomic Mass": "19.06310(43#)" }, { "Atomic Symbol": "B", "Mass Number": "20", "Relative Atomic Mass": "20.07207(75#)" }, { "Atomic Symbol": "B", "Mass Number": "21", "Relative Atomic Mass": "21.08129(97#)" } ], "Notes": "m", "Standard Atomic Weight": "[10.806,10.821]" }, { "Atomic Symbol": "C", "Atomic Number": "6", "isotopes": [ { "Atomic Symbol": "C", "Mass Number": "8", "Relative Atomic Mass": "8.037643(20)" }, { "Atomic Symbol": "C", "Mass Number": "9", "Relative Atomic Mass": "9.0310372(23)" }, { "Atomic Symbol": "C", "Mass Number": "10", "Relative Atomic Mass": "10.01685331(42)" }, { "Atomic Symbol": "C", "Mass Number": "11", "Relative Atomic Mass": "11.0114336(10)" }, { "Atomic Symbol": "C", "Mass Number": "12", "Isotopic Composition": "0.9893(8)", "Relative Atomic Mass": "12.0000000(00)" }, { "Atomic Symbol": "C", "Mass Number": "13", "Isotopic Composition": "0.0107(8)", "Relative Atomic Mass": "13.00335483507(23)" }, { "Atomic Symbol": "C", "Mass Number": "14", "Relative Atomic Mass": "14.0032419884(40)" }, { "Atomic Symbol": "C", "Mass Number": "15", "Relative Atomic Mass": "15.01059926(86)" }, { "Atomic Symbol": "C", "Mass Number": "16", "Relative Atomic Mass": "16.0147013(38)" }, { "Atomic Symbol": "C", "Mass Number": "17", "Relative Atomic Mass": "17.022577(19)" }, { "Atomic Symbol": "C", "Mass Number": "18", "Relative Atomic Mass": "18.026751(32)" }, { "Atomic Symbol": "C", "Mass Number": "19", "Relative Atomic Mass": "19.03480(11)" }, { "Atomic Symbol": "C", "Mass Number": "20", "Relative Atomic Mass": "20.04032(26)" }, { "Atomic Symbol": "C", "Mass Number": "21", "Relative Atomic Mass": "21.04900(43#)" }, { "Atomic Symbol": "C", "Mass Number": "22", "Relative Atomic Mass": "22.05753(26)" }, { "Atomic Symbol": "C", "Mass Number": "23", "Relative Atomic Mass": "23.0689(11#)" } ], "Standard Atomic Weight": "[12.0096,12.0116]" }, { "Atomic Symbol": "N", "Atomic Number": "7", "isotopes": [ { "Atomic Symbol": "N", "Mass Number": "10", "Relative Atomic Mass": "10.04165(43)" }, { "Atomic Symbol": "N", "Mass Number": "11", "Relative Atomic Mass": "11.026091(50)" }, { "Atomic Symbol": "N", "Mass Number": "12", "Relative Atomic Mass": "12.0186132(11)" }, { "Atomic Symbol": "N", "Mass Number": "13", "Relative Atomic Mass": "13.00573861(29)" }, { "Atomic Symbol": "N", "Mass Number": "14", "Isotopic Composition": "0.99636(20)", "Relative Atomic Mass": "14.00307400443(20)" }, { "Atomic Symbol": "N", "Mass Number": "15", "Isotopic Composition": "0.00364(20)", "Relative Atomic Mass": "15.00010889888(64)" }, { "Atomic Symbol": "N", "Mass Number": "16", "Relative Atomic Mass": "16.0061019(25)" }, { "Atomic Symbol": "N", "Mass Number": "17", "Relative Atomic Mass": "17.008449(16)" }, { "Atomic Symbol": "N", "Mass Number": "18", "Relative Atomic Mass": "18.014078(20)" }, { "Atomic Symbol": "N", "Mass Number": "19", "Relative Atomic Mass": "19.017022(18)" }, { "Atomic Symbol": "N", "Mass Number": "20", "Relative Atomic Mass": "20.023366(60)" }, { "Atomic Symbol": "N", "Mass Number": "21", "Relative Atomic Mass": "21.02711(10)" }, { "Atomic Symbol": "N", "Mass Number": "22", "Relative Atomic Mass": "22.03439(21)" }, { "Atomic Symbol": "N", "Mass Number": "23", "Relative Atomic Mass": "23.04114(32#)" }, { "Atomic Symbol": "N", "Mass Number": "24", "Relative Atomic Mass": "24.05039(43#)" }, { "Atomic Symbol": "N", "Mass Number": "25", "Relative Atomic Mass": "25.06010(54#)" } ], "Standard Atomic Weight": "[14.00643,14.00728]" }, { "Atomic Symbol": "O", "Atomic Number": "8", "isotopes": [ { "Atomic Symbol": "O", "Mass Number": "12", "Relative Atomic Mass": "12.034262(26)" }, { "Atomic Symbol": "O", "Mass Number": "13", "Relative Atomic Mass": "13.024815(10)" }, { "Atomic Symbol": "O", "Mass Number": "14", "Relative Atomic Mass": "14.00859636(12)" }, { "Atomic Symbol": "O", "Mass Number": "15", "Relative Atomic Mass": "15.00306562(53)" }, { "Atomic Symbol": "O", "Mass Number": "16", "Isotopic Composition": "0.99757(16)", "Relative Atomic Mass": "15.99491461957(17)" }, { "Atomic Symbol": "O", "Mass Number": "17", "Isotopic Composition": "0.00038(1)", "Relative Atomic Mass": "16.99913175650(69)" }, { "Atomic Symbol": "O", "Mass Number": "18", "Isotopic Composition": "0.00205(14)", "Relative Atomic Mass": "17.99915961286(76)" }, { "Atomic Symbol": "O", "Mass Number": "19", "Relative Atomic Mass": "19.0035780(28)" }, { "Atomic Symbol": "O", "Mass Number": "20", "Relative Atomic Mass": "20.00407535(95)" }, { "Atomic Symbol": "O", "Mass Number": "21", "Relative Atomic Mass": "21.008655(13)" }, { "Atomic Symbol": "O", "Mass Number": "22", "Relative Atomic Mass": "22.009966(61)" }, { "Atomic Symbol": "O", "Mass Number": "23", "Relative Atomic Mass": "23.015696(97)" }, { "Atomic Symbol": "O", "Mass Number": "24", "Relative Atomic Mass": "24.01986(12)" }, { "Atomic Symbol": "O", "Mass Number": "25", "Relative Atomic Mass": "25.02936(12)" }, { "Atomic Symbol": "O", "Mass Number": "26", "Relative Atomic Mass": "26.03729(17)" }, { "Atomic Symbol": "O", "Mass Number": "27", "Relative Atomic Mass": "27.04772(54#)" }, { "Atomic Symbol": "O", "Mass Number": "28", "Relative Atomic Mass": "28.05591(75#)" } ], "Standard Atomic Weight": "[15.99903,15.99977]" }, { "Atomic Symbol": "F", "Atomic Number": "9", "isotopes": [ { "Atomic Symbol": "F", "Mass Number": "14", "Relative Atomic Mass": "14.034315(44)" }, { "Atomic Symbol": "F", "Mass Number": "15", "Relative Atomic Mass": "15.018043(67)" }, { "Atomic Symbol": "F", "Mass Number": "16", "Relative Atomic Mass": "16.0114657(89)" }, { "Atomic Symbol": "F", "Mass Number": "17", "Relative Atomic Mass": "17.00209524(27)" }, { "Atomic Symbol": "F", "Mass Number": "18", "Relative Atomic Mass": "18.00093733(50)" }, { "Atomic Symbol": "F", "Mass Number": "19", "Isotopic Composition": "1", "Relative Atomic Mass": "18.99840316273(92)" }, { "Atomic Symbol": "F", "Mass Number": "20", "Relative Atomic Mass": "19.999981252(31)" }, { "Atomic Symbol": "F", "Mass Number": "21", "Relative Atomic Mass": "20.9999489(19)" }, { "Atomic Symbol": "F", "Mass Number": "22", "Relative Atomic Mass": "22.002999(13)" }, { "Atomic Symbol": "F", "Mass Number": "23", "Relative Atomic Mass": "23.003557(54)" }, { "Atomic Symbol": "F", "Mass Number": "24", "Relative Atomic Mass": "24.008115(78)" }, { "Atomic Symbol": "F", "Mass Number": "25", "Relative Atomic Mass": "25.012199(81)" }, { "Atomic Symbol": "F", "Mass Number": "26", "Relative Atomic Mass": "26.020038(83)" }, { "Atomic Symbol": "F", "Mass Number": "27", "Relative Atomic Mass": "27.02644(20)" }, { "Atomic Symbol": "F", "Mass Number": "28", "Relative Atomic Mass": "28.03534(21)" }, { "Atomic Symbol": "F", "Mass Number": "29", "Relative Atomic Mass": "29.04254(54#)" }, { "Atomic Symbol": "F", "Mass Number": "30", "Relative Atomic Mass": "30.05165(64#)" }, { "Atomic Symbol": "F", "Mass Number": "31", "Relative Atomic Mass": "31.05971(56#)" } ], "Standard Atomic Weight": "18.998403163(6)" }, { "Atomic Symbol": "Ne", "Atomic Number": "10", "isotopes": [ { "Atomic Symbol": "Ne", "Mass Number": "16", "Relative Atomic Mass": "16.025750(22)" }, { "Atomic Symbol": "Ne", "Mass Number": "17", "Relative Atomic Mass": "17.01771396(38)" }, { "Atomic Symbol": "Ne", "Mass Number": "18", "Relative Atomic Mass": "18.00570870(39)" }, { "Atomic Symbol": "Ne", "Mass Number": "19", "Relative Atomic Mass": "19.00188091(17)" }, { "Atomic Symbol": "Ne", "Mass Number": "20", "Isotopic Composition": "0.9048(3)", "Relative Atomic Mass": "19.9924401762(17)" }, { "Atomic Symbol": "Ne", "Mass Number": "21", "Isotopic Composition": "0.0027(1)", "Relative Atomic Mass": "20.993846685(41)" }, { "Atomic Symbol": "Ne", "Mass Number": "22", "Isotopic Composition": "0.0925(3)", "Relative Atomic Mass": "21.991385114(18)" }, { "Atomic Symbol": "Ne", "Mass Number": "23", "Relative Atomic Mass": "22.99446691(11)" }, { "Atomic Symbol": "Ne", "Mass Number": "24", "Relative Atomic Mass": "23.99361065(55)" }, { "Atomic Symbol": "Ne", "Mass Number": "25", "Relative Atomic Mass": "24.997789(48)" }, { "Atomic Symbol": "Ne", "Mass Number": "26", "Relative Atomic Mass": "26.000515(20)" }, { "Atomic Symbol": "Ne", "Mass Number": "27", "Relative Atomic Mass": "27.007553(70)" }, { "Atomic Symbol": "Ne", "Mass Number": "28", "Relative Atomic Mass": "28.01212(10)" }, { "Atomic Symbol": "Ne", "Mass Number": "29", "Relative Atomic Mass": "29.01975(11)" }, { "Atomic Symbol": "Ne", "Mass Number": "30", "Relative Atomic Mass": "30.02473(30)" }, { "Atomic Symbol": "Ne", "Mass Number": "31", "Relative Atomic Mass": "31.0331(17)" }, { "Atomic Symbol": "Ne", "Mass Number": "32", "Relative Atomic Mass": "32.03972(54#)" }, { "Atomic Symbol": "Ne", "Mass Number": "33", "Relative Atomic Mass": "33.04938(64#)" }, { "Atomic Symbol": "Ne", "Mass Number": "34", "Relative Atomic Mass": "34.05673(55#)" } ], "Notes": "g,m", "Standard Atomic Weight": "20.1797(6)" }, { "Atomic Symbol": "Na", "Atomic Number": "11", "isotopes": [ { "Atomic Symbol": "Na", "Mass Number": "18", "Relative Atomic Mass": "18.02688(12)" }, { "Atomic Symbol": "Na", "Mass Number": "19", "Relative Atomic Mass": "19.013880(11)" }, { "Atomic Symbol": "Na", "Mass Number": "20", "Relative Atomic Mass": "20.0073544(12)" }, { "Atomic Symbol": "Na", "Mass Number": "21", "Relative Atomic Mass": "20.99765469(30)" }, { "Atomic Symbol": "Na", "Mass Number": "22", "Relative Atomic Mass": "21.99443741(18)" }, { "Atomic Symbol": "Na", "Mass Number": "23", "Isotopic Composition": "1", "Relative Atomic Mass": "22.9897692820(19)" }, { "Atomic Symbol": "Na", "Mass Number": "24", "Relative Atomic Mass": "23.990962950(38)" }, { "Atomic Symbol": "Na", "Mass Number": "25", "Relative Atomic Mass": "24.9899540(13)" }, { "Atomic Symbol": "Na", "Mass Number": "26", "Relative Atomic Mass": "25.9926346(38)" }, { "Atomic Symbol": "Na", "Mass Number": "27", "Relative Atomic Mass": "26.9940765(40)" }, { "Atomic Symbol": "Na", "Mass Number": "28", "Relative Atomic Mass": "27.998939(11)" }, { "Atomic Symbol": "Na", "Mass Number": "29", "Relative Atomic Mass": "29.0028771(79)" }, { "Atomic Symbol": "Na", "Mass Number": "30", "Relative Atomic Mass": "30.0090979(51)" }, { "Atomic Symbol": "Na", "Mass Number": "31", "Relative Atomic Mass": "31.013163(25)" }, { "Atomic Symbol": "Na", "Mass Number": "32", "Relative Atomic Mass": "32.02019(13)" }, { "Atomic Symbol": "Na", "Mass Number": "33", "Relative Atomic Mass": "33.02573(64#)" }, { "Atomic Symbol": "Na", "Mass Number": "34", "Relative Atomic Mass": "34.03359(54#)" }, { "Atomic Symbol": "Na", "Mass Number": "35", "Relative Atomic Mass": "35.04062(63#)" }, { "Atomic Symbol": "Na", "Mass Number": "36", "Relative Atomic Mass": "36.04929(64#)" }, { "Atomic Symbol": "Na", "Mass Number": "37", "Relative Atomic Mass": "37.05705(65#)" } ], "Standard Atomic Weight": "22.98976928(2)" }, { "Atomic Symbol": "Mg", "Atomic Number": "12", "isotopes": [ { "Atomic Symbol": "Mg", "Mass Number": "19", "Relative Atomic Mass": "19.034169(54)" }, { "Atomic Symbol": "Mg", "Mass Number": "20", "Relative Atomic Mass": "20.018850(29)" }, { "Atomic Symbol": "Mg", "Mass Number": "21", "Relative Atomic Mass": "21.011716(18)" }, { "Atomic Symbol": "Mg", "Mass Number": "22", "Relative Atomic Mass": "21.99957065(34)" }, { "Atomic Symbol": "Mg", "Mass Number": "23", "Relative Atomic Mass": "22.99412421(74)" }, { "Atomic Symbol": "Mg", "Mass Number": "24", "Isotopic Composition": "0.7899(4)", "Relative Atomic Mass": "23.985041697(14)" }, { "Atomic Symbol": "Mg", "Mass Number": "25", "Isotopic Composition": "0.1000(1)", "Relative Atomic Mass": "24.985836976(50)" }, { "Atomic Symbol": "Mg", "Mass Number": "26", "Isotopic Composition": "0.1101(3)", "Relative Atomic Mass": "25.982592968(31)" }, { "Atomic Symbol": "Mg", "Mass Number": "27", "Relative Atomic Mass": "26.984340624(53)" }, { "Atomic Symbol": "Mg", "Mass Number": "28", "Relative Atomic Mass": "27.9838767(22)" }, { "Atomic Symbol": "Mg", "Mass Number": "29", "Relative Atomic Mass": "28.988617(12)" }, { "Atomic Symbol": "Mg", "Mass Number": "30", "Relative Atomic Mass": "29.9904629(37)" }, { "Atomic Symbol": "Mg", "Mass Number": "31", "Relative Atomic Mass": "30.9966480(33)" }, { "Atomic Symbol": "Mg", "Mass Number": "32", "Relative Atomic Mass": "31.9991102(34)" }, { "Atomic Symbol": "Mg", "Mass Number": "33", "Relative Atomic Mass": "33.0053271(31)" }, { "Atomic Symbol": "Mg", "Mass Number": "34", "Relative Atomic Mass": "34.008935(31)" }, { "Atomic Symbol": "Mg", "Mass Number": "35", "Relative Atomic Mass": "35.01679(19)" }, { "Atomic Symbol": "Mg", "Mass Number": "36", "Relative Atomic Mass": "36.02188(49)" }, { "Atomic Symbol": "Mg", "Mass Number": "37", "Relative Atomic Mass": "37.03037(54#)" }, { "Atomic Symbol": "Mg", "Mass Number": "38", "Relative Atomic Mass": "38.03658(54#)" }, { "Atomic Symbol": "Mg", "Mass Number": "39", "Relative Atomic Mass": "39.04538(55#)" }, { "Atomic Symbol": "Mg", "Mass Number": "40", "Relative Atomic Mass": "40.05218(64#)" } ], "Standard Atomic Weight": "[24.304,24.307]" }, { "Atomic Symbol": "Al", "Atomic Number": "13", "isotopes": [ { "Atomic Symbol": "Al", "Mass Number": "21", "Relative Atomic Mass": "21.02897(43#)" }, { "Atomic Symbol": "Al", "Mass Number": "22", "Relative Atomic Mass": "22.01954(43#)" }, { "Atomic Symbol": "Al", "Mass Number": "23", "Relative Atomic Mass": "23.00724435(37)" }, { "Atomic Symbol": "Al", "Mass Number": "24", "Relative Atomic Mass": "23.9999489(12)" }, { "Atomic Symbol": "Al", "Mass Number": "25", "Relative Atomic Mass": "24.99042810(51)" }, { "Atomic Symbol": "Al", "Mass Number": "26", "Relative Atomic Mass": "25.986891904(69)" }, { "Atomic Symbol": "Al", "Mass Number": "27", "Isotopic Composition": "1", "Relative Atomic Mass": "26.98153853(11)" }, { "Atomic Symbol": "Al", "Mass Number": "28", "Relative Atomic Mass": "27.98191021(13)" }, { "Atomic Symbol": "Al", "Mass Number": "29", "Relative Atomic Mass": "28.9804565(10)" }, { "Atomic Symbol": "Al", "Mass Number": "30", "Relative Atomic Mass": "29.982960(15)" }, { "Atomic Symbol": "Al", "Mass Number": "31", "Relative Atomic Mass": "30.983945(22)" }, { "Atomic Symbol": "Al", "Mass Number": "32", "Relative Atomic Mass": "31.988085(13)" }, { "Atomic Symbol": "Al", "Mass Number": "33", "Relative Atomic Mass": "32.990909(81)" }, { "Atomic Symbol": "Al", "Mass Number": "34", "Relative Atomic Mass": "33.996705(74)" }, { "Atomic Symbol": "Al", "Mass Number": "35", "Relative Atomic Mass": "34.999764(75)" }, { "Atomic Symbol": "Al", "Mass Number": "36", "Relative Atomic Mass": "36.00639(11)" }, { "Atomic Symbol": "Al", "Mass Number": "37", "Relative Atomic Mass": "37.01053(13)" }, { "Atomic Symbol": "Al", "Mass Number": "38", "Relative Atomic Mass": "38.01740(27)" }, { "Atomic Symbol": "Al", "Mass Number": "39", "Relative Atomic Mass": "39.02254(54#)" }, { "Atomic Symbol": "Al", "Mass Number": "40", "Relative Atomic Mass": "40.03003(54#)" }, { "Atomic Symbol": "Al", "Mass Number": "41", "Relative Atomic Mass": "41.03638(64#)" }, { "Atomic Symbol": "Al", "Mass Number": "42", "Relative Atomic Mass": "42.04384(64#)" }, { "Atomic Symbol": "Al", "Mass Number": "43", "Relative Atomic Mass": "43.05147(75#)" } ], "Standard Atomic Weight": "26.9815385(7)" }, { "Atomic Symbol": "Si", "Atomic Number": "14", "isotopes": [ { "Atomic Symbol": "Si", "Mass Number": "22", "Relative Atomic Mass": "22.03579(54#)" }, { "Atomic Symbol": "Si", "Mass Number": "23", "Relative Atomic Mass": "23.02544(54#)" }, { "Atomic Symbol": "Si", "Mass Number": "24", "Relative Atomic Mass": "24.011535(21)" }, { "Atomic Symbol": "Si", "Mass Number": "25", "Relative Atomic Mass": "25.004109(11)" }, { "Atomic Symbol": "Si", "Mass Number": "26", "Relative Atomic Mass": "25.99233384(11)" }, { "Atomic Symbol": "Si", "Mass Number": "27", "Relative Atomic Mass": "26.98670481(15)" }, { "Atomic Symbol": "Si", "Mass Number": "28", "Isotopic Composition": "0.92223(19)", "Relative Atomic Mass": "27.97692653465(44)" }, { "Atomic Symbol": "Si", "Mass Number": "29", "Isotopic Composition": "0.04685(8)", "Relative Atomic Mass": "28.97649466490(52)" }, { "Atomic Symbol": "Si", "Mass Number": "30", "Isotopic Composition": "0.03092(11)", "Relative Atomic Mass": "29.973770136(23)" }, { "Atomic Symbol": "Si", "Mass Number": "31", "Relative Atomic Mass": "30.975363194(46)" }, { "Atomic Symbol": "Si", "Mass Number": "32", "Relative Atomic Mass": "31.97415154(32)" }, { "Atomic Symbol": "Si", "Mass Number": "33", "Relative Atomic Mass": "32.97797696(75)" }, { "Atomic Symbol": "Si", "Mass Number": "34", "Relative Atomic Mass": "33.978576(15)" }, { "Atomic Symbol": "Si", "Mass Number": "35", "Relative Atomic Mass": "34.984583(41)" }, { "Atomic Symbol": "Si", "Mass Number": "36", "Relative Atomic Mass": "35.986695(77)" }, { "Atomic Symbol": "Si", "Mass Number": "37", "Relative Atomic Mass": "36.992921(89)" }, { "Atomic Symbol": "Si", "Mass Number": "38", "Relative Atomic Mass": "37.995523(75)" }, { "Atomic Symbol": "Si", "Mass Number": "39", "Relative Atomic Mass": "39.002491(97)" }, { "Atomic Symbol": "Si", "Mass Number": "40", "Relative Atomic Mass": "40.00583(25)" }, { "Atomic Symbol": "Si", "Mass Number": "41", "Relative Atomic Mass": "41.01301(40)" }, { "Atomic Symbol": "Si", "Mass Number": "42", "Relative Atomic Mass": "42.01778(54#)" }, { "Atomic Symbol": "Si", "Mass Number": "43", "Relative Atomic Mass": "43.02480(64#)" }, { "Atomic Symbol": "Si", "Mass Number": "44", "Relative Atomic Mass": "44.03061(64#)" }, { "Atomic Symbol": "Si", "Mass Number": "45", "Relative Atomic Mass": "45.03995(75#)" } ], "Standard Atomic Weight": "[28.084,28.086]" }, { "Atomic Symbol": "P", "Atomic Number": "15", "isotopes": [ { "Atomic Symbol": "P", "Mass Number": "24", "Relative Atomic Mass": "24.03577(54#)" }, { "Atomic Symbol": "P", "Mass Number": "25", "Relative Atomic Mass": "25.02119(43#)" }, { "Atomic Symbol": "P", "Mass Number": "26", "Relative Atomic Mass": "26.01178(21#)" }, { "Atomic Symbol": "P", "Mass Number": "27", "Relative Atomic Mass": "26.999224(28)" }, { "Atomic Symbol": "P", "Mass Number": "28", "Relative Atomic Mass": "27.9923266(12)" }, { "Atomic Symbol": "P", "Mass Number": "29", "Relative Atomic Mass": "28.98180079(60)" }, { "Atomic Symbol": "P", "Mass Number": "30", "Relative Atomic Mass": "29.97831375(34)" }, { "Atomic Symbol": "P", "Mass Number": "31", "Isotopic Composition": "1", "Relative Atomic Mass": "30.97376199842(70)" }, { "Atomic Symbol": "P", "Mass Number": "32", "Relative Atomic Mass": "31.973907643(42)" }, { "Atomic Symbol": "P", "Mass Number": "33", "Relative Atomic Mass": "32.9717257(12)" }, { "Atomic Symbol": "P", "Mass Number": "34", "Relative Atomic Mass": "33.97364589(87)" }, { "Atomic Symbol": "P", "Mass Number": "35", "Relative Atomic Mass": "34.9733141(20)" }, { "Atomic Symbol": "P", "Mass Number": "36", "Relative Atomic Mass": "35.978260(14)" }, { "Atomic Symbol": "P", "Mass Number": "37", "Relative Atomic Mass": "36.979607(41)" }, { "Atomic Symbol": "P", "Mass Number": "38", "Relative Atomic Mass": "37.984252(93)" }, { "Atomic Symbol": "P", "Mass Number": "39", "Relative Atomic Mass": "38.986227(98)" }, { "Atomic Symbol": "P", "Mass Number": "40", "Relative Atomic Mass": "39.99133(12)" }, { "Atomic Symbol": "P", "Mass Number": "41", "Relative Atomic Mass": "40.994654(86)" }, { "Atomic Symbol": "P", "Mass Number": "42", "Relative Atomic Mass": "42.00108(23)" }, { "Atomic Symbol": "P", "Mass Number": "43", "Relative Atomic Mass": "43.00502(40)" }, { "Atomic Symbol": "P", "Mass Number": "44", "Relative Atomic Mass": "44.01121(54#)" }, { "Atomic Symbol": "P", "Mass Number": "45", "Relative Atomic Mass": "45.01645(64#)" }, { "Atomic Symbol": "P", "Mass Number": "46", "Relative Atomic Mass": "46.02446(75#)" }, { "Atomic Symbol": "P", "Mass Number": "47", "Relative Atomic Mass": "47.03139(86#)" } ], "Standard Atomic Weight": "30.973761998(5)" }, { "Atomic Symbol": "S", "Atomic Number": "16", "isotopes": [ { "Atomic Symbol": "S", "Mass Number": "26", "Relative Atomic Mass": "26.02907(64#)" }, { "Atomic Symbol": "S", "Mass Number": "27", "Relative Atomic Mass": "27.01828(43#)" }, { "Atomic Symbol": "S", "Mass Number": "28", "Relative Atomic Mass": "28.00437(17)" }, { "Atomic Symbol": "S", "Mass Number": "29", "Relative Atomic Mass": "28.996611(54)" }, { "Atomic Symbol": "S", "Mass Number": "30", "Relative Atomic Mass": "29.98490703(40)" }, { "Atomic Symbol": "S", "Mass Number": "31", "Relative Atomic Mass": "30.97955701(25)" }, { "Atomic Symbol": "S", "Mass Number": "32", "Isotopic Composition": "0.9499(26)", "Relative Atomic Mass": "31.9720711744(14)" }, { "Atomic Symbol": "S", "Mass Number": "33", "Isotopic Composition": "0.0075(2)", "Relative Atomic Mass": "32.9714589098(15)" }, { "Atomic Symbol": "S", "Mass Number": "34", "Isotopic Composition": "0.0425(24)", "Relative Atomic Mass": "33.967867004(47)" }, { "Atomic Symbol": "S", "Mass Number": "35", "Relative Atomic Mass": "34.969032310(43)" }, { "Atomic Symbol": "S", "Mass Number": "36", "Isotopic Composition": "0.0001(1)", "Relative Atomic Mass": "35.96708071(20)" }, { "Atomic Symbol": "S", "Mass Number": "37", "Relative Atomic Mass": "36.97112551(21)" }, { "Atomic Symbol": "S", "Mass Number": "38", "Relative Atomic Mass": "37.9711633(77)" }, { "Atomic Symbol": "S", "Mass Number": "39", "Relative Atomic Mass": "38.975134(54)" }, { "Atomic Symbol": "S", "Mass Number": "40", "Relative Atomic Mass": "39.9754826(43)" }, { "Atomic Symbol": "S", "Mass Number": "41", "Relative Atomic Mass": "40.9795935(44)" }, { "Atomic Symbol": "S", "Mass Number": "42", "Relative Atomic Mass": "41.9810651(30)" }, { "Atomic Symbol": "S", "Mass Number": "43", "Relative Atomic Mass": "42.9869076(53)" }, { "Atomic Symbol": "S", "Mass Number": "44", "Relative Atomic Mass": "43.9901188(56)" }, { "Atomic Symbol": "S", "Mass Number": "45", "Relative Atomic Mass": "44.99572(74)" }, { "Atomic Symbol": "S", "Mass Number": "46", "Relative Atomic Mass": "46.00004(54#)" }, { "Atomic Symbol": "S", "Mass Number": "47", "Relative Atomic Mass": "47.00795(54#)" }, { "Atomic Symbol": "S", "Mass Number": "48", "Relative Atomic Mass": "48.01370(64#)" }, { "Atomic Symbol": "S", "Mass Number": "49", "Relative Atomic Mass": "49.02276(72#)" } ], "Standard Atomic Weight": "[32.059,32.076]" }, { "Atomic Symbol": "Cl", "Atomic Number": "17", "isotopes": [ { "Atomic Symbol": "Cl", "Mass Number": "28", "Relative Atomic Mass": "28.02954(64#)" }, { "Atomic Symbol": "Cl", "Mass Number": "29", "Relative Atomic Mass": "29.01478(43#)" }, { "Atomic Symbol": "Cl", "Mass Number": "30", "Relative Atomic Mass": "30.00477(21#)" }, { "Atomic Symbol": "Cl", "Mass Number": "31", "Relative Atomic Mass": "30.992414(54)" }, { "Atomic Symbol": "Cl", "Mass Number": "32", "Relative Atomic Mass": "31.98568464(60)" }, { "Atomic Symbol": "Cl", "Mass Number": "33", "Relative Atomic Mass": "32.97745199(42)" }, { "Atomic Symbol": "Cl", "Mass Number": "34", "Relative Atomic Mass": "33.973762485(52)" }, { "Atomic Symbol": "Cl", "Mass Number": "35", "Isotopic Composition": "0.7576(10)", "Relative Atomic Mass": "34.968852682(37)" }, { "Atomic Symbol": "Cl", "Mass Number": "36", "Relative Atomic Mass": "35.968306809(38)" }, { "Atomic Symbol": "Cl", "Mass Number": "37", "Isotopic Composition": "0.2424(10)", "Relative Atomic Mass": "36.965902602(55)" }, { "Atomic Symbol": "Cl", "Mass Number": "38", "Relative Atomic Mass": "37.96801044(11)" }, { "Atomic Symbol": "Cl", "Mass Number": "39", "Relative Atomic Mass": "38.9680082(19)" }, { "Atomic Symbol": "Cl", "Mass Number": "40", "Relative Atomic Mass": "39.970415(34)" }, { "Atomic Symbol": "Cl", "Mass Number": "41", "Relative Atomic Mass": "40.970685(74)" }, { "Atomic Symbol": "Cl", "Mass Number": "42", "Relative Atomic Mass": "41.97325(15)" }, { "Atomic Symbol": "Cl", "Mass Number": "43", "Relative Atomic Mass": "42.97389(10)" }, { "Atomic Symbol": "Cl", "Mass Number": "44", "Relative Atomic Mass": "43.97787(20)" }, { "Atomic Symbol": "Cl", "Mass Number": "45", "Relative Atomic Mass": "44.98029(11)" }, { "Atomic Symbol": "Cl", "Mass Number": "46", "Relative Atomic Mass": "45.98517(17)" }, { "Atomic Symbol": "Cl", "Mass Number": "47", "Relative Atomic Mass": "46.98916(43#)" }, { "Atomic Symbol": "Cl", "Mass Number": "48", "Relative Atomic Mass": "47.99564(54#)" }, { "Atomic Symbol": "Cl", "Mass Number": "49", "Relative Atomic Mass": "49.00123(64#)" }, { "Atomic Symbol": "Cl", "Mass Number": "50", "Relative Atomic Mass": "50.00905(64#)" }, { "Atomic Symbol": "Cl", "Mass Number": "51", "Relative Atomic Mass": "51.01554(75#)" } ], "Notes": "m", "Standard Atomic Weight": "[35.446,35.457]" }, { "Atomic Symbol": "Ar", "Atomic Number": "18", "isotopes": [ { "Atomic Symbol": "Ar", "Mass Number": "30", "Relative Atomic Mass": "30.02307(54#)" }, { "Atomic Symbol": "Ar", "Mass Number": "31", "Relative Atomic Mass": "31.01212(22#)" }, { "Atomic Symbol": "Ar", "Mass Number": "32", "Relative Atomic Mass": "31.9976378(19)" }, { "Atomic Symbol": "Ar", "Mass Number": "33", "Relative Atomic Mass": "32.98992555(43)" }, { "Atomic Symbol": "Ar", "Mass Number": "34", "Relative Atomic Mass": "33.980270090(83)" }, { "Atomic Symbol": "Ar", "Mass Number": "35", "Relative Atomic Mass": "34.97525759(80)" }, { "Atomic Symbol": "Ar", "Mass Number": "36", "Isotopic Composition": "0.003336(21)", "Relative Atomic Mass": "35.967545105(28)" }, { "Atomic Symbol": "Ar", "Mass Number": "37", "Relative Atomic Mass": "36.96677633(22)" }, { "Atomic Symbol": "Ar", "Mass Number": "38", "Isotopic Composition": "0.000629(7)", "Relative Atomic Mass": "37.96273211(21)" }, { "Atomic Symbol": "Ar", "Mass Number": "39", "Relative Atomic Mass": "38.9643130(54)" }, { "Atomic Symbol": "Ar", "Mass Number": "40", "Isotopic Composition": "0.996035(25)", "Relative Atomic Mass": "39.9623831237(24)" }, { "Atomic Symbol": "Ar", "Mass Number": "41", "Relative Atomic Mass": "40.96450057(37)" }, { "Atomic Symbol": "Ar", "Mass Number": "42", "Relative Atomic Mass": "41.9630457(62)" }, { "Atomic Symbol": "Ar", "Mass Number": "43", "Relative Atomic Mass": "42.9656361(57)" }, { "Atomic Symbol": "Ar", "Mass Number": "44", "Relative Atomic Mass": "43.9649238(17)" }, { "Atomic Symbol": "Ar", "Mass Number": "45", "Relative Atomic Mass": "44.96803973(55)" }, { "Atomic Symbol": "Ar", "Mass Number": "46", "Relative Atomic Mass": "45.968083(44)" }, { "Atomic Symbol": "Ar", "Mass Number": "47", "Relative Atomic Mass": "46.972935(96)" }, { "Atomic Symbol": "Ar", "Mass Number": "48", "Relative Atomic Mass": "47.97591(32#)" }, { "Atomic Symbol": "Ar", "Mass Number": "49", "Relative Atomic Mass": "48.98190(43#)" }, { "Atomic Symbol": "Ar", "Mass Number": "50", "Relative Atomic Mass": "49.98613(54#)" }, { "Atomic Symbol": "Ar", "Mass Number": "51", "Relative Atomic Mass": "50.99370(64#)" }, { "Atomic Symbol": "Ar", "Mass Number": "52", "Relative Atomic Mass": "51.99896(64#)" }, { "Atomic Symbol": "Ar", "Mass Number": "53", "Relative Atomic Mass": "53.00729(75#)" } ], "Notes": "g,r", "Standard Atomic Weight": "39.948(1)" }, { "Atomic Symbol": "K", "Atomic Number": "19", "isotopes": [ { "Atomic Symbol": "K", "Mass Number": "32", "Relative Atomic Mass": "32.02265(54#)" }, { "Atomic Symbol": "K", "Mass Number": "33", "Relative Atomic Mass": "33.00756(21#)" }, { "Atomic Symbol": "K", "Mass Number": "34", "Relative Atomic Mass": "33.99869(32#)" }, { "Atomic Symbol": "K", "Mass Number": "35", "Relative Atomic Mass": "34.98800541(55)" }, { "Atomic Symbol": "K", "Mass Number": "36", "Relative Atomic Mass": "35.98130201(37)" }, { "Atomic Symbol": "K", "Mass Number": "37", "Relative Atomic Mass": "36.97337589(10)" }, { "Atomic Symbol": "K", "Mass Number": "38", "Relative Atomic Mass": "37.96908112(21)" }, { "Atomic Symbol": "K", "Mass Number": "39", "Isotopic Composition": "0.932581(44)", "Relative Atomic Mass": "38.9637064864(49)" }, { "Atomic Symbol": "K", "Mass Number": "40", "Isotopic Composition": "0.000117(1)", "Relative Atomic Mass": "39.963998166(60)" }, { "Atomic Symbol": "K", "Mass Number": "41", "Isotopic Composition": "0.067302(44)", "Relative Atomic Mass": "40.9618252579(41)" }, { "Atomic Symbol": "K", "Mass Number": "42", "Relative Atomic Mass": "41.96240231(11)" }, { "Atomic Symbol": "K", "Mass Number": "43", "Relative Atomic Mass": "42.96073470(44)" }, { "Atomic Symbol": "K", "Mass Number": "44", "Relative Atomic Mass": "43.96158699(45)" }, { "Atomic Symbol": "K", "Mass Number": "45", "Relative Atomic Mass": "44.96069149(56)" }, { "Atomic Symbol": "K", "Mass Number": "46", "Relative Atomic Mass": "45.96198159(78)" }, { "Atomic Symbol": "K", "Mass Number": "47", "Relative Atomic Mass": "46.9616616(15)" }, { "Atomic Symbol": "K", "Mass Number": "48", "Relative Atomic Mass": "47.96534119(83)" }, { "Atomic Symbol": "K", "Mass Number": "49", "Relative Atomic Mass": "48.96821075(86)" }, { "Atomic Symbol": "K", "Mass Number": "50", "Relative Atomic Mass": "49.9723800(83)" }, { "Atomic Symbol": "K", "Mass Number": "51", "Relative Atomic Mass": "50.975828(14)" }, { "Atomic Symbol": "K", "Mass Number": "52", "Relative Atomic Mass": "51.98224(43#)" }, { "Atomic Symbol": "K", "Mass Number": "53", "Relative Atomic Mass": "52.98746(54#)" }, { "Atomic Symbol": "K", "Mass Number": "54", "Relative Atomic Mass": "53.99463(64#)" }, { "Atomic Symbol": "K", "Mass Number": "55", "Relative Atomic Mass": "55.00076(75#)" }, { "Atomic Symbol": "K", "Mass Number": "56", "Relative Atomic Mass": "56.00851(86#)" } ], "Standard Atomic Weight": "39.0983(1)" }, { "Atomic Symbol": "Ca", "Atomic Number": "20", "isotopes": [ { "Atomic Symbol": "Ca", "Mass Number": "34", "Relative Atomic Mass": "34.01487(32#)" }, { "Atomic Symbol": "Ca", "Mass Number": "35", "Relative Atomic Mass": "35.00514(21#)" }, { "Atomic Symbol": "Ca", "Mass Number": "36", "Relative Atomic Mass": "35.993074(43)" }, { "Atomic Symbol": "Ca", "Mass Number": "37", "Relative Atomic Mass": "36.98589785(68)" }, { "Atomic Symbol": "Ca", "Mass Number": "38", "Relative Atomic Mass": "37.97631922(21)" }, { "Atomic Symbol": "Ca", "Mass Number": "39", "Relative Atomic Mass": "38.97071081(64)" }, { "Atomic Symbol": "Ca", "Mass Number": "40", "Isotopic Composition": "0.96941(156)", "Relative Atomic Mass": "39.962590863(22)" }, { "Atomic Symbol": "Ca", "Mass Number": "41", "Relative Atomic Mass": "40.96227792(15)" }, { "Atomic Symbol": "Ca", "Mass Number": "42", "Isotopic Composition": "0.00647(23)", "Relative Atomic Mass": "41.95861783(16)" }, { "Atomic Symbol": "Ca", "Mass Number": "43", "Isotopic Composition": "0.00135(10)", "Relative Atomic Mass": "42.95876644(24)" }, { "Atomic Symbol": "Ca", "Mass Number": "44", "Isotopic Composition": "0.02086(110)", "Relative Atomic Mass": "43.95548156(35)" }, { "Atomic Symbol": "Ca", "Mass Number": "45", "Relative Atomic Mass": "44.95618635(39)" }, { "Atomic Symbol": "Ca", "Mass Number": "46", "Isotopic Composition": "0.00004(3)", "Relative Atomic Mass": "45.9536890(24)" }, { "Atomic Symbol": "Ca", "Mass Number": "47", "Relative Atomic Mass": "46.9545424(24)" }, { "Atomic Symbol": "Ca", "Mass Number": "48", "Isotopic Composition": "0.00187(21)", "Relative Atomic Mass": "47.95252276(13)" }, { "Atomic Symbol": "Ca", "Mass Number": "49", "Relative Atomic Mass": "48.95566274(23)" }, { "Atomic Symbol": "Ca", "Mass Number": "50", "Relative Atomic Mass": "49.9574992(17)" }, { "Atomic Symbol": "Ca", "Mass Number": "51", "Relative Atomic Mass": "50.960989(24)" }, { "Atomic Symbol": "Ca", "Mass Number": "52", "Relative Atomic Mass": "51.963217(64)" }, { "Atomic Symbol": "Ca", "Mass Number": "53", "Relative Atomic Mass": "52.96945(43#)" }, { "Atomic Symbol": "Ca", "Mass Number": "54", "Relative Atomic Mass": "53.97340(54#)" }, { "Atomic Symbol": "Ca", "Mass Number": "55", "Relative Atomic Mass": "54.98030(54#)" }, { "Atomic Symbol": "Ca", "Mass Number": "56", "Relative Atomic Mass": "55.98508(64#)" }, { "Atomic Symbol": "Ca", "Mass Number": "57", "Relative Atomic Mass": "56.99262(64#)" }, { "Atomic Symbol": "Ca", "Mass Number": "58", "Relative Atomic Mass": "57.99794(75#)" } ], "Notes": "g", "Standard Atomic Weight": "40.078(4)" }, { "Atomic Symbol": "Sc", "Atomic Number": "21", "isotopes": [ { "Atomic Symbol": "Sc", "Mass Number": "36", "Relative Atomic Mass": "36.01648(32#)" }, { "Atomic Symbol": "Sc", "Mass Number": "37", "Relative Atomic Mass": "37.00374(32#)" }, { "Atomic Symbol": "Sc", "Mass Number": "38", "Relative Atomic Mass": "37.99512(21#)" }, { "Atomic Symbol": "Sc", "Mass Number": "39", "Relative Atomic Mass": "38.984785(26)" }, { "Atomic Symbol": "Sc", "Mass Number": "40", "Relative Atomic Mass": "39.9779673(30)" }, { "Atomic Symbol": "Sc", "Mass Number": "41", "Relative Atomic Mass": "40.969251105(88)" }, { "Atomic Symbol": "Sc", "Mass Number": "42", "Relative Atomic Mass": "41.96551653(18)" }, { "Atomic Symbol": "Sc", "Mass Number": "43", "Relative Atomic Mass": "42.9611505(20)" }, { "Atomic Symbol": "Sc", "Mass Number": "44", "Relative Atomic Mass": "43.9594029(19)" }, { "Atomic Symbol": "Sc", "Mass Number": "45", "Isotopic Composition": "1", "Relative Atomic Mass": "44.95590828(77)" }, { "Atomic Symbol": "Sc", "Mass Number": "46", "Relative Atomic Mass": "45.95516826(78)" }, { "Atomic Symbol": "Sc", "Mass Number": "47", "Relative Atomic Mass": "46.9524037(21)" }, { "Atomic Symbol": "Sc", "Mass Number": "48", "Relative Atomic Mass": "47.9522236(53)" }, { "Atomic Symbol": "Sc", "Mass Number": "49", "Relative Atomic Mass": "48.9500146(29)" }, { "Atomic Symbol": "Sc", "Mass Number": "50", "Relative Atomic Mass": "49.952176(16)" }, { "Atomic Symbol": "Sc", "Mass Number": "51", "Relative Atomic Mass": "50.953592(21)" }, { "Atomic Symbol": "Sc", "Mass Number": "52", "Relative Atomic Mass": "51.95688(15)" }, { "Atomic Symbol": "Sc", "Mass Number": "53", "Relative Atomic Mass": "52.95909(29)" }, { "Atomic Symbol": "Sc", "Mass Number": "54", "Relative Atomic Mass": "53.96393(39)" }, { "Atomic Symbol": "Sc", "Mass Number": "55", "Relative Atomic Mass": "54.96782(50)" }, { "Atomic Symbol": "Sc", "Mass Number": "56", "Relative Atomic Mass": "55.97345(43#)" }, { "Atomic Symbol": "Sc", "Mass Number": "57", "Relative Atomic Mass": "56.97777(54#)" }, { "Atomic Symbol": "Sc", "Mass Number": "58", "Relative Atomic Mass": "57.98403(64#)" }, { "Atomic Symbol": "Sc", "Mass Number": "59", "Relative Atomic Mass": "58.98894(64#)" }, { "Atomic Symbol": "Sc", "Mass Number": "60", "Relative Atomic Mass": "59.99565(75#)" }, { "Atomic Symbol": "Sc", "Mass Number": "61", "Relative Atomic Mass": "61.00100(86#)" } ], "Standard Atomic Weight": "44.955908(5)" }, { "Atomic Symbol": "Ti", "Atomic Number": "22", "isotopes": [ { "Atomic Symbol": "Ti", "Mass Number": "38", "Relative Atomic Mass": "38.01145(32#)" }, { "Atomic Symbol": "Ti", "Mass Number": "39", "Relative Atomic Mass": "39.00236(22#)" }, { "Atomic Symbol": "Ti", "Mass Number": "40", "Relative Atomic Mass": "39.99050(17)" }, { "Atomic Symbol": "Ti", "Mass Number": "41", "Relative Atomic Mass": "40.983148(30)" }, { "Atomic Symbol": "Ti", "Mass Number": "42", "Relative Atomic Mass": "41.97304903(30)" }, { "Atomic Symbol": "Ti", "Mass Number": "43", "Relative Atomic Mass": "42.9685225(78)" }, { "Atomic Symbol": "Ti", "Mass Number": "44", "Relative Atomic Mass": "43.95968995(75)" }, { "Atomic Symbol": "Ti", "Mass Number": "45", "Relative Atomic Mass": "44.95812198(95)" }, { "Atomic Symbol": "Ti", "Mass Number": "46", "Isotopic Composition": "0.0825(3)", "Relative Atomic Mass": "45.95262772(35)" }, { "Atomic Symbol": "Ti", "Mass Number": "47", "Isotopic Composition": "0.0744(2)", "Relative Atomic Mass": "46.95175879(38)" }, { "Atomic Symbol": "Ti", "Mass Number": "48", "Isotopic Composition": "0.7372(3)", "Relative Atomic Mass": "47.94794198(38)" }, { "Atomic Symbol": "Ti", "Mass Number": "49", "Isotopic Composition": "0.0541(2)", "Relative Atomic Mass": "48.94786568(39)" }, { "Atomic Symbol": "Ti", "Mass Number": "50", "Isotopic Composition": "0.0518(2)", "Relative Atomic Mass": "49.94478689(39)" }, { "Atomic Symbol": "Ti", "Mass Number": "51", "Relative Atomic Mass": "50.94661065(65)" }, { "Atomic Symbol": "Ti", "Mass Number": "52", "Relative Atomic Mass": "51.9468930(76)" }, { "Atomic Symbol": "Ti", "Mass Number": "53", "Relative Atomic Mass": "52.94973(11)" }, { "Atomic Symbol": "Ti", "Mass Number": "54", "Relative Atomic Mass": "53.95105(13)" }, { "Atomic Symbol": "Ti", "Mass Number": "55", "Relative Atomic Mass": "54.95527(17)" }, { "Atomic Symbol": "Ti", "Mass Number": "56", "Relative Atomic Mass": "55.95791(15)" }, { "Atomic Symbol": "Ti", "Mass Number": "57", "Relative Atomic Mass": "56.96364(27)" }, { "Atomic Symbol": "Ti", "Mass Number": "58", "Relative Atomic Mass": "57.96660(43#)" }, { "Atomic Symbol": "Ti", "Mass Number": "59", "Relative Atomic Mass": "58.97247(43#)" }, { "Atomic Symbol": "Ti", "Mass Number": "60", "Relative Atomic Mass": "59.97603(54#)" }, { "Atomic Symbol": "Ti", "Mass Number": "61", "Relative Atomic Mass": "60.98245(64#)" }, { "Atomic Symbol": "Ti", "Mass Number": "62", "Relative Atomic Mass": "61.98651(75#)" }, { "Atomic Symbol": "Ti", "Mass Number": "63", "Relative Atomic Mass": "62.99375(75#)" } ], "Standard Atomic Weight": "47.867(1)" }, { "Atomic Symbol": "V", "Atomic Number": "23", "isotopes": [ { "Atomic Symbol": "V", "Mass Number": "40", "Relative Atomic Mass": "40.01276(43#)" }, { "Atomic Symbol": "V", "Mass Number": "41", "Relative Atomic Mass": "41.00021(32#)" }, { "Atomic Symbol": "V", "Mass Number": "42", "Relative Atomic Mass": "41.99182(32#)" }, { "Atomic Symbol": "V", "Mass Number": "43", "Relative Atomic Mass": "42.980766(46)" }, { "Atomic Symbol": "V", "Mass Number": "44", "Relative Atomic Mass": "43.97411(20)" }, { "Atomic Symbol": "V", "Mass Number": "45", "Relative Atomic Mass": "44.9657748(86)" }, { "Atomic Symbol": "V", "Mass Number": "46", "Relative Atomic Mass": "45.96019878(36)" }, { "Atomic Symbol": "V", "Mass Number": "47", "Relative Atomic Mass": "46.95490491(36)" }, { "Atomic Symbol": "V", "Mass Number": "48", "Relative Atomic Mass": "47.9522522(11)" }, { "Atomic Symbol": "V", "Mass Number": "49", "Relative Atomic Mass": "48.94851180(96)" }, { "Atomic Symbol": "V", "Mass Number": "50", "Isotopic Composition": "0.00250(4)", "Relative Atomic Mass": "49.94715601(95)" }, { "Atomic Symbol": "V", "Mass Number": "51", "Isotopic Composition": "0.99750(4)", "Relative Atomic Mass": "50.94395704(94)" }, { "Atomic Symbol": "V", "Mass Number": "52", "Relative Atomic Mass": "51.94477301(95)" }, { "Atomic Symbol": "V", "Mass Number": "53", "Relative Atomic Mass": "52.9443367(34)" }, { "Atomic Symbol": "V", "Mass Number": "54", "Relative Atomic Mass": "53.946439(16)" }, { "Atomic Symbol": "V", "Mass Number": "55", "Relative Atomic Mass": "54.94724(10)" }, { "Atomic Symbol": "V", "Mass Number": "56", "Relative Atomic Mass": "55.95048(19)" }, { "Atomic Symbol": "V", "Mass Number": "57", "Relative Atomic Mass": "56.95252(24)" }, { "Atomic Symbol": "V", "Mass Number": "58", "Relative Atomic Mass": "57.95672(14)" }, { "Atomic Symbol": "V", "Mass Number": "59", "Relative Atomic Mass": "58.95939(17)" }, { "Atomic Symbol": "V", "Mass Number": "60", "Relative Atomic Mass": "59.96431(24)" }, { "Atomic Symbol": "V", "Mass Number": "61", "Relative Atomic Mass": "60.96725(96)" }, { "Atomic Symbol": "V", "Mass Number": "62", "Relative Atomic Mass": "61.97265(32#)" }, { "Atomic Symbol": "V", "Mass Number": "63", "Relative Atomic Mass": "62.97639(43#)" }, { "Atomic Symbol": "V", "Mass Number": "64", "Relative Atomic Mass": "63.98264(43#)" }, { "Atomic Symbol": "V", "Mass Number": "65", "Relative Atomic Mass": "64.98750(54#)" }, { "Atomic Symbol": "V", "Mass Number": "66", "Relative Atomic Mass": "65.99398(64#)" } ], "Standard Atomic Weight": "50.9415(1)" }, { "Atomic Symbol": "Cr", "Atomic Number": "24", "isotopes": [ { "Atomic Symbol": "Cr", "Mass Number": "42", "Relative Atomic Mass": "42.00670(43#)" }, { "Atomic Symbol": "Cr", "Mass Number": "43", "Relative Atomic Mass": "42.99753(43#)" }, { "Atomic Symbol": "Cr", "Mass Number": "44", "Relative Atomic Mass": "43.98536(32#)" }, { "Atomic Symbol": "Cr", "Mass Number": "45", "Relative Atomic Mass": "44.979050(38)" }, { "Atomic Symbol": "Cr", "Mass Number": "46", "Relative Atomic Mass": "45.968359(21)" }, { "Atomic Symbol": "Cr", "Mass Number": "47", "Relative Atomic Mass": "46.9628974(75)" }, { "Atomic Symbol": "Cr", "Mass Number": "48", "Relative Atomic Mass": "47.9540291(79)" }, { "Atomic Symbol": "Cr", "Mass Number": "49", "Relative Atomic Mass": "48.9513333(25)" }, { "Atomic Symbol": "Cr", "Mass Number": "50", "Isotopic Composition": "0.04345(13)", "Relative Atomic Mass": "49.94604183(94)" }, { "Atomic Symbol": "Cr", "Mass Number": "51", "Relative Atomic Mass": "50.94476502(94)" }, { "Atomic Symbol": "Cr", "Mass Number": "52", "Isotopic Composition": "0.83789(18)", "Relative Atomic Mass": "51.94050623(63)" }, { "Atomic Symbol": "Cr", "Mass Number": "53", "Isotopic Composition": "0.09501(17)", "Relative Atomic Mass": "52.94064815(62)" }, { "Atomic Symbol": "Cr", "Mass Number": "54", "Isotopic Composition": "0.02365(7)", "Relative Atomic Mass": "53.93887916(61)" }, { "Atomic Symbol": "Cr", "Mass Number": "55", "Relative Atomic Mass": "54.94083843(64)" }, { "Atomic Symbol": "Cr", "Mass Number": "56", "Relative Atomic Mass": "55.9406531(20)" }, { "Atomic Symbol": "Cr", "Mass Number": "57", "Relative Atomic Mass": "56.9436130(20)" }, { "Atomic Symbol": "Cr", "Mass Number": "58", "Relative Atomic Mass": "57.94435(22)" }, { "Atomic Symbol": "Cr", "Mass Number": "59", "Relative Atomic Mass": "58.94859(26)" }, { "Atomic Symbol": "Cr", "Mass Number": "60", "Relative Atomic Mass": "59.95008(23)" }, { "Atomic Symbol": "Cr", "Mass Number": "61", "Relative Atomic Mass": "60.95442(14)" }, { "Atomic Symbol": "Cr", "Mass Number": "62", "Relative Atomic Mass": "61.95610(16)" }, { "Atomic Symbol": "Cr", "Mass Number": "63", "Relative Atomic Mass": "62.96165(49)" }, { "Atomic Symbol": "Cr", "Mass Number": "64", "Relative Atomic Mass": "63.96408(32#)" }, { "Atomic Symbol": "Cr", "Mass Number": "65", "Relative Atomic Mass": "64.96996(32#)" }, { "Atomic Symbol": "Cr", "Mass Number": "66", "Relative Atomic Mass": "65.97366(54#)" }, { "Atomic Symbol": "Cr", "Mass Number": "67", "Relative Atomic Mass": "66.98016(54#)" }, { "Atomic Symbol": "Cr", "Mass Number": "68", "Relative Atomic Mass": "67.98403(75#)" } ], "Standard Atomic Weight": "51.9961(6)" }, { "Atomic Symbol": "Mn", "Atomic Number": "25", "isotopes": [ { "Atomic Symbol": "Mn", "Mass Number": "44", "Relative Atomic Mass": "44.00715(54#)" }, { "Atomic Symbol": "Mn", "Mass Number": "45", "Relative Atomic Mass": "44.99449(43#)" }, { "Atomic Symbol": "Mn", "Mass Number": "46", "Relative Atomic Mass": "45.98609(43#)" }, { "Atomic Symbol": "Mn", "Mass Number": "47", "Relative Atomic Mass": "46.975775(34)" }, { "Atomic Symbol": "Mn", "Mass Number": "48", "Relative Atomic Mass": "47.96852(18)" }, { "Atomic Symbol": "Mn", "Mass Number": "49", "Relative Atomic Mass": "48.959595(11)" }, { "Atomic Symbol": "Mn", "Mass Number": "50", "Relative Atomic Mass": "49.95423778(95)" }, { "Atomic Symbol": "Mn", "Mass Number": "51", "Relative Atomic Mass": "50.94820847(94)" }, { "Atomic Symbol": "Mn", "Mass Number": "52", "Relative Atomic Mass": "51.9455639(20)" }, { "Atomic Symbol": "Mn", "Mass Number": "53", "Relative Atomic Mass": "52.94128889(68)" }, { "Atomic Symbol": "Mn", "Mass Number": "54", "Relative Atomic Mass": "53.9403576(12)" }, { "Atomic Symbol": "Mn", "Mass Number": "55", "Isotopic Composition": "1", "Relative Atomic Mass": "54.93804391(48)" }, { "Atomic Symbol": "Mn", "Mass Number": "56", "Relative Atomic Mass": "55.93890369(49)" }, { "Atomic Symbol": "Mn", "Mass Number": "57", "Relative Atomic Mass": "56.9382861(16)" }, { "Atomic Symbol": "Mn", "Mass Number": "58", "Relative Atomic Mass": "57.9400666(29)" }, { "Atomic Symbol": "Mn", "Mass Number": "59", "Relative Atomic Mass": "58.9403911(25)" }, { "Atomic Symbol": "Mn", "Mass Number": "60", "Relative Atomic Mass": "59.9431366(25)" }, { "Atomic Symbol": "Mn", "Mass Number": "61", "Relative Atomic Mass": "60.9444525(25)" }, { "Atomic Symbol": "Mn", "Mass Number": "62", "Relative Atomic Mass": "61.94795(16#)" }, { "Atomic Symbol": "Mn", "Mass Number": "63", "Relative Atomic Mass": "62.9496647(40)" }, { "Atomic Symbol": "Mn", "Mass Number": "64", "Relative Atomic Mass": "63.9538494(38)" }, { "Atomic Symbol": "Mn", "Mass Number": "65", "Relative Atomic Mass": "64.9560198(40)" }, { "Atomic Symbol": "Mn", "Mass Number": "66", "Relative Atomic Mass": "65.960547(12)" }, { "Atomic Symbol": "Mn", "Mass Number": "67", "Relative Atomic Mass": "66.96424(43#)" }, { "Atomic Symbol": "Mn", "Mass Number": "68", "Relative Atomic Mass": "67.96962(54#)" }, { "Atomic Symbol": "Mn", "Mass Number": "69", "Relative Atomic Mass": "68.97366(64#)" }, { "Atomic Symbol": "Mn", "Mass Number": "70", "Relative Atomic Mass": "69.97937(75#)" }, { "Atomic Symbol": "Mn", "Mass Number": "71", "Relative Atomic Mass": "70.98368(75#)" } ], "Standard Atomic Weight": "54.938044(3)" }, { "Atomic Symbol": "Fe", "Atomic Number": "26", "isotopes": [ { "Atomic Symbol": "Fe", "Mass Number": "45", "Relative Atomic Mass": "45.01442(43#)" }, { "Atomic Symbol": "Fe", "Mass Number": "46", "Relative Atomic Mass": "46.00063(54#)" }, { "Atomic Symbol": "Fe", "Mass Number": "47", "Relative Atomic Mass": "46.99185(54#)" }, { "Atomic Symbol": "Fe", "Mass Number": "48", "Relative Atomic Mass": "47.98023(43#)" }, { "Atomic Symbol": "Fe", "Mass Number": "49", "Relative Atomic Mass": "48.973429(26)" }, { "Atomic Symbol": "Fe", "Mass Number": "50", "Relative Atomic Mass": "49.962975(64)" }, { "Atomic Symbol": "Fe", "Mass Number": "51", "Relative Atomic Mass": "50.9568410(96)" }, { "Atomic Symbol": "Fe", "Mass Number": "52", "Relative Atomic Mass": "51.9481131(70)" }, { "Atomic Symbol": "Fe", "Mass Number": "53", "Relative Atomic Mass": "52.9453064(18)" }, { "Atomic Symbol": "Fe", "Mass Number": "54", "Isotopic Composition": "0.05845(35)", "Relative Atomic Mass": "53.93960899(53)" }, { "Atomic Symbol": "Fe", "Mass Number": "55", "Relative Atomic Mass": "54.93829199(51)" }, { "Atomic Symbol": "Fe", "Mass Number": "56", "Isotopic Composition": "0.91754(36)", "Relative Atomic Mass": "55.93493633(49)" }, { "Atomic Symbol": "Fe", "Mass Number": "57", "Isotopic Composition": "0.02119(10)", "Relative Atomic Mass": "56.93539284(49)" }, { "Atomic Symbol": "Fe", "Mass Number": "58", "Isotopic Composition": "0.00282(4)", "Relative Atomic Mass": "57.93327443(53)" }, { "Atomic Symbol": "Fe", "Mass Number": "59", "Relative Atomic Mass": "58.93487434(54)" }, { "Atomic Symbol": "Fe", "Mass Number": "60", "Relative Atomic Mass": "59.9340711(37)" }, { "Atomic Symbol": "Fe", "Mass Number": "61", "Relative Atomic Mass": "60.9367462(28)" }, { "Atomic Symbol": "Fe", "Mass Number": "62", "Relative Atomic Mass": "61.9367918(30)" }, { "Atomic Symbol": "Fe", "Mass Number": "63", "Relative Atomic Mass": "62.9402727(46)" }, { "Atomic Symbol": "Fe", "Mass Number": "64", "Relative Atomic Mass": "63.9409878(54)" }, { "Atomic Symbol": "Fe", "Mass Number": "65", "Relative Atomic Mass": "64.9450115(73)" }, { "Atomic Symbol": "Fe", "Mass Number": "66", "Relative Atomic Mass": "65.9462500(44)" }, { "Atomic Symbol": "Fe", "Mass Number": "67", "Relative Atomic Mass": "66.95054(23)" }, { "Atomic Symbol": "Fe", "Mass Number": "68", "Relative Atomic Mass": "67.95295(39)" }, { "Atomic Symbol": "Fe", "Mass Number": "69", "Relative Atomic Mass": "68.95807(43#)" }, { "Atomic Symbol": "Fe", "Mass Number": "70", "Relative Atomic Mass": "69.96102(54#)" }, { "Atomic Symbol": "Fe", "Mass Number": "71", "Relative Atomic Mass": "70.96672(64#)" }, { "Atomic Symbol": "Fe", "Mass Number": "72", "Relative Atomic Mass": "71.96983(75#)" }, { "Atomic Symbol": "Fe", "Mass Number": "73", "Relative Atomic Mass": "72.97572(75#)" }, { "Atomic Symbol": "Fe", "Mass Number": "74", "Relative Atomic Mass": "73.97935(86#)" } ], "Standard Atomic Weight": "55.845(2)" }, { "Atomic Symbol": "Co", "Atomic Number": "27", "isotopes": [ { "Atomic Symbol": "Co", "Mass Number": "47", "Relative Atomic Mass": "47.01057(86#)" }, { "Atomic Symbol": "Co", "Mass Number": "48", "Relative Atomic Mass": "48.00093(86#)" }, { "Atomic Symbol": "Co", "Mass Number": "49", "Relative Atomic Mass": "48.98891(75#)" }, { "Atomic Symbol": "Co", "Mass Number": "50", "Relative Atomic Mass": "49.98091(64#)" }, { "Atomic Symbol": "Co", "Mass Number": "51", "Relative Atomic Mass": "50.970647(52)" }, { "Atomic Symbol": "Co", "Mass Number": "52", "Relative Atomic Mass": "51.96351(21#)" }, { "Atomic Symbol": "Co", "Mass Number": "53", "Relative Atomic Mass": "52.9542041(19)" }, { "Atomic Symbol": "Co", "Mass Number": "54", "Relative Atomic Mass": "53.94845987(54)" }, { "Atomic Symbol": "Co", "Mass Number": "55", "Relative Atomic Mass": "54.94199720(57)" }, { "Atomic Symbol": "Co", "Mass Number": "56", "Relative Atomic Mass": "55.93983880(63)" }, { "Atomic Symbol": "Co", "Mass Number": "57", "Relative Atomic Mass": "56.93629057(66)" }, { "Atomic Symbol": "Co", "Mass Number": "58", "Relative Atomic Mass": "57.9357521(13)" }, { "Atomic Symbol": "Co", "Mass Number": "59", "Isotopic Composition": "1", "Relative Atomic Mass": "58.93319429(56)" }, { "Atomic Symbol": "Co", "Mass Number": "60", "Relative Atomic Mass": "59.93381630(56)" }, { "Atomic Symbol": "Co", "Mass Number": "61", "Relative Atomic Mass": "60.93247662(95)" }, { "Atomic Symbol": "Co", "Mass Number": "62", "Relative Atomic Mass": "61.934059(20)" }, { "Atomic Symbol": "Co", "Mass Number": "63", "Relative Atomic Mass": "62.933600(20)" }, { "Atomic Symbol": "Co", "Mass Number": "64", "Relative Atomic Mass": "63.935811(21)" }, { "Atomic Symbol": "Co", "Mass Number": "65", "Relative Atomic Mass": "64.9364621(22)" }, { "Atomic Symbol": "Co", "Mass Number": "66", "Relative Atomic Mass": "65.939443(15)" }, { "Atomic Symbol": "Co", "Mass Number": "67", "Relative Atomic Mass": "66.9406096(69)" }, { "Atomic Symbol": "Co", "Mass Number": "68", "Relative Atomic Mass": "67.94426(16)" }, { "Atomic Symbol": "Co", "Mass Number": "69", "Relative Atomic Mass": "68.94614(20)" }, { "Atomic Symbol": "Co", "Mass Number": "70", "Relative Atomic Mass": "69.94963(32)" }, { "Atomic Symbol": "Co", "Mass Number": "71", "Relative Atomic Mass": "70.95237(50)" }, { "Atomic Symbol": "Co", "Mass Number": "72", "Relative Atomic Mass": "71.95729(43#)" }, { "Atomic Symbol": "Co", "Mass Number": "73", "Relative Atomic Mass": "72.96039(54#)" }, { "Atomic Symbol": "Co", "Mass Number": "74", "Relative Atomic Mass": "73.96515(64#)" }, { "Atomic Symbol": "Co", "Mass Number": "75", "Relative Atomic Mass": "74.96876(75#)" }, { "Atomic Symbol": "Co", "Mass Number": "76", "Relative Atomic Mass": "75.97413(86#)" } ], "Standard Atomic Weight": "58.933194(4)" }, { "Atomic Symbol": "Ni", "Atomic Number": "28", "isotopes": [ { "Atomic Symbol": "Ni", "Mass Number": "48", "Relative Atomic Mass": "48.01769(54#)" }, { "Atomic Symbol": "Ni", "Mass Number": "49", "Relative Atomic Mass": "49.00770(86#)" }, { "Atomic Symbol": "Ni", "Mass Number": "50", "Relative Atomic Mass": "49.99474(86#)" }, { "Atomic Symbol": "Ni", "Mass Number": "51", "Relative Atomic Mass": "50.98611(86#)" }, { "Atomic Symbol": "Ni", "Mass Number": "52", "Relative Atomic Mass": "51.97480(75#)" }, { "Atomic Symbol": "Ni", "Mass Number": "53", "Relative Atomic Mass": "52.968190(27)" }, { "Atomic Symbol": "Ni", "Mass Number": "54", "Relative Atomic Mass": "53.957892(54)" }, { "Atomic Symbol": "Ni", "Mass Number": "55", "Relative Atomic Mass": "54.95133063(85)" }, { "Atomic Symbol": "Ni", "Mass Number": "56", "Relative Atomic Mass": "55.94212855(57)" }, { "Atomic Symbol": "Ni", "Mass Number": "57", "Relative Atomic Mass": "56.93979218(71)" }, { "Atomic Symbol": "Ni", "Mass Number": "58", "Isotopic Composition": "0.68077(19)", "Relative Atomic Mass": "57.93534241(52)" }, { "Atomic Symbol": "Ni", "Mass Number": "59", "Relative Atomic Mass": "58.93434620(52)" }, { "Atomic Symbol": "Ni", "Mass Number": "60", "Isotopic Composition": "0.26223(15)", "Relative Atomic Mass": "59.93078588(52)" }, { "Atomic Symbol": "Ni", "Mass Number": "61", "Isotopic Composition": "0.011399(13)", "Relative Atomic Mass": "60.93105557(52)" }, { "Atomic Symbol": "Ni", "Mass Number": "62", "Isotopic Composition": "0.036346(40)", "Relative Atomic Mass": "61.92834537(55)" }, { "Atomic Symbol": "Ni", "Mass Number": "63", "Relative Atomic Mass": "62.92966963(56)" }, { "Atomic Symbol": "Ni", "Mass Number": "64", "Isotopic Composition": "0.009255(19)", "Relative Atomic Mass": "63.92796682(58)" }, { "Atomic Symbol": "Ni", "Mass Number": "65", "Relative Atomic Mass": "64.93008517(60)" }, { "Atomic Symbol": "Ni", "Mass Number": "66", "Relative Atomic Mass": "65.9291393(15)" }, { "Atomic Symbol": "Ni", "Mass Number": "67", "Relative Atomic Mass": "66.9315694(31)" }, { "Atomic Symbol": "Ni", "Mass Number": "68", "Relative Atomic Mass": "67.9318688(32)" }, { "Atomic Symbol": "Ni", "Mass Number": "69", "Relative Atomic Mass": "68.9356103(40)" }, { "Atomic Symbol": "Ni", "Mass Number": "70", "Relative Atomic Mass": "69.9364313(23)" }, { "Atomic Symbol": "Ni", "Mass Number": "71", "Relative Atomic Mass": "70.9405190(24)" }, { "Atomic Symbol": "Ni", "Mass Number": "72", "Relative Atomic Mass": "71.9417859(24)" }, { "Atomic Symbol": "Ni", "Mass Number": "73", "Relative Atomic Mass": "72.9462067(26)" }, { "Atomic Symbol": "Ni", "Mass Number": "74", "Relative Atomic Mass": "73.94798(43#)" }, { "Atomic Symbol": "Ni", "Mass Number": "75", "Relative Atomic Mass": "74.95250(32#)" }, { "Atomic Symbol": "Ni", "Mass Number": "76", "Relative Atomic Mass": "75.95533(54#)" }, { "Atomic Symbol": "Ni", "Mass Number": "77", "Relative Atomic Mass": "76.96055(54#)" }, { "Atomic Symbol": "Ni", "Mass Number": "78", "Relative Atomic Mass": "77.96336(86#)" }, { "Atomic Symbol": "Ni", "Mass Number": "79", "Relative Atomic Mass": "78.97025(86#)" } ], "Notes": "r", "Standard Atomic Weight": "58.6934(4)" }, { "Atomic Symbol": "Cu", "Atomic Number": "29", "isotopes": [ { "Atomic Symbol": "Cu", "Mass Number": "52", "Relative Atomic Mass": "51.99671(86#)" }, { "Atomic Symbol": "Cu", "Mass Number": "53", "Relative Atomic Mass": "52.98459(86#)" }, { "Atomic Symbol": "Cu", "Mass Number": "54", "Relative Atomic Mass": "53.97666(54#)" }, { "Atomic Symbol": "Cu", "Mass Number": "55", "Relative Atomic Mass": "54.96604(17)" }, { "Atomic Symbol": "Cu", "Mass Number": "56", "Relative Atomic Mass": "55.95895(21#)" }, { "Atomic Symbol": "Cu", "Mass Number": "57", "Relative Atomic Mass": "56.94921250(66)" }, { "Atomic Symbol": "Cu", "Mass Number": "58", "Relative Atomic Mass": "57.94453305(70)" }, { "Atomic Symbol": "Cu", "Mass Number": "59", "Relative Atomic Mass": "58.93949748(67)" }, { "Atomic Symbol": "Cu", "Mass Number": "60", "Relative Atomic Mass": "59.9373645(18)" }, { "Atomic Symbol": "Cu", "Mass Number": "61", "Relative Atomic Mass": "60.9334576(10)" }, { "Atomic Symbol": "Cu", "Mass Number": "62", "Relative Atomic Mass": "61.93259541(75)" }, { "Atomic Symbol": "Cu", "Mass Number": "63", "Isotopic Composition": "0.6915(15)", "Relative Atomic Mass": "62.92959772(56)" }, { "Atomic Symbol": "Cu", "Mass Number": "64", "Relative Atomic Mass": "63.92976434(56)" }, { "Atomic Symbol": "Cu", "Mass Number": "65", "Isotopic Composition": "0.3085(15)", "Relative Atomic Mass": "64.92778970(71)" }, { "Atomic Symbol": "Cu", "Mass Number": "66", "Relative Atomic Mass": "65.92886903(72)" }, { "Atomic Symbol": "Cu", "Mass Number": "67", "Relative Atomic Mass": "66.9277303(13)" }, { "Atomic Symbol": "Cu", "Mass Number": "68", "Relative Atomic Mass": "67.9296109(17)" }, { "Atomic Symbol": "Cu", "Mass Number": "69", "Relative Atomic Mass": "68.9294293(15)" }, { "Atomic Symbol": "Cu", "Mass Number": "70", "Relative Atomic Mass": "69.9323921(12)" }, { "Atomic Symbol": "Cu", "Mass Number": "71", "Relative Atomic Mass": "70.9326768(16)" }, { "Atomic Symbol": "Cu", "Mass Number": "72", "Relative Atomic Mass": "71.9358203(15)" }, { "Atomic Symbol": "Cu", "Mass Number": "73", "Relative Atomic Mass": "72.9366744(21)" }, { "Atomic Symbol": "Cu", "Mass Number": "74", "Relative Atomic Mass": "73.9398749(66)" }, { "Atomic Symbol": "Cu", "Mass Number": "75", "Relative Atomic Mass": "74.9415226(25)" }, { "Atomic Symbol": "Cu", "Mass Number": "76", "Relative Atomic Mass": "75.9452750(72)" }, { "Atomic Symbol": "Cu", "Mass Number": "77", "Relative Atomic Mass": "76.94792(16#)" }, { "Atomic Symbol": "Cu", "Mass Number": "78", "Relative Atomic Mass": "77.95223(54)" }, { "Atomic Symbol": "Cu", "Mass Number": "79", "Relative Atomic Mass": "78.95502(43#)" }, { "Atomic Symbol": "Cu", "Mass Number": "80", "Relative Atomic Mass": "79.96089(64#)" }, { "Atomic Symbol": "Cu", "Mass Number": "81", "Relative Atomic Mass": "80.96587(86#)" }, { "Atomic Symbol": "Cu", "Mass Number": "82", "Relative Atomic Mass": "81.97244(86#)" } ], "Notes": "r", "Standard Atomic Weight": "63.546(3)" }, { "Atomic Symbol": "Zn", "Atomic Number": "30", "isotopes": [ { "Atomic Symbol": "Zn", "Mass Number": "54", "Relative Atomic Mass": "53.99204(75#)" }, { "Atomic Symbol": "Zn", "Mass Number": "55", "Relative Atomic Mass": "54.98398(75#)" }, { "Atomic Symbol": "Zn", "Mass Number": "56", "Relative Atomic Mass": "55.97254(54#)" }, { "Atomic Symbol": "Zn", "Mass Number": "57", "Relative Atomic Mass": "56.96506(22#)" }, { "Atomic Symbol": "Zn", "Mass Number": "58", "Relative Atomic Mass": "57.954591(54)" }, { "Atomic Symbol": "Zn", "Mass Number": "59", "Relative Atomic Mass": "58.94931266(89)" }, { "Atomic Symbol": "Zn", "Mass Number": "60", "Relative Atomic Mass": "59.94184210(69)" }, { "Atomic Symbol": "Zn", "Mass Number": "61", "Relative Atomic Mass": "60.939507(17)" }, { "Atomic Symbol": "Zn", "Mass Number": "62", "Relative Atomic Mass": "61.93433397(73)" }, { "Atomic Symbol": "Zn", "Mass Number": "63", "Relative Atomic Mass": "62.9332115(17)" }, { "Atomic Symbol": "Zn", "Mass Number": "64", "Isotopic Composition": "0.4917(75)", "Relative Atomic Mass": "63.92914201(71)" }, { "Atomic Symbol": "Zn", "Mass Number": "65", "Relative Atomic Mass": "64.92924077(71)" }, { "Atomic Symbol": "Zn", "Mass Number": "66", "Isotopic Composition": "0.2773(98)", "Relative Atomic Mass": "65.92603381(94)" }, { "Atomic Symbol": "Zn", "Mass Number": "67", "Isotopic Composition": "0.0404(16)", "Relative Atomic Mass": "66.92712775(96)" }, { "Atomic Symbol": "Zn", "Mass Number": "68", "Isotopic Composition": "0.1845(63)", "Relative Atomic Mass": "67.92484455(98)" }, { "Atomic Symbol": "Zn", "Mass Number": "69", "Relative Atomic Mass": "68.9265507(10)" }, { "Atomic Symbol": "Zn", "Mass Number": "70", "Isotopic Composition": "0.0061(10)", "Relative Atomic Mass": "69.9253192(21)" }, { "Atomic Symbol": "Zn", "Mass Number": "71", "Relative Atomic Mass": "70.9277196(28)" }, { "Atomic Symbol": "Zn", "Mass Number": "72", "Relative Atomic Mass": "71.9268428(23)" }, { "Atomic Symbol": "Zn", "Mass Number": "73", "Relative Atomic Mass": "72.9295826(20)" }, { "Atomic Symbol": "Zn", "Mass Number": "74", "Relative Atomic Mass": "73.9294073(27)" }, { "Atomic Symbol": "Zn", "Mass Number": "75", "Relative Atomic Mass": "74.9328402(21)" }, { "Atomic Symbol": "Zn", "Mass Number": "76", "Relative Atomic Mass": "75.9331150(16)" }, { "Atomic Symbol": "Zn", "Mass Number": "77", "Relative Atomic Mass": "76.9368872(21)" }, { "Atomic Symbol": "Zn", "Mass Number": "78", "Relative Atomic Mass": "77.9382892(21)" }, { "Atomic Symbol": "Zn", "Mass Number": "79", "Relative Atomic Mass": "78.9426381(24)" }, { "Atomic Symbol": "Zn", "Mass Number": "80", "Relative Atomic Mass": "79.9445529(28)" }, { "Atomic Symbol": "Zn", "Mass Number": "81", "Relative Atomic Mass": "80.9504026(54)" }, { "Atomic Symbol": "Zn", "Mass Number": "82", "Relative Atomic Mass": "81.95426(32#)" }, { "Atomic Symbol": "Zn", "Mass Number": "83", "Relative Atomic Mass": "82.96056(54#)" }, { "Atomic Symbol": "Zn", "Mass Number": "84", "Relative Atomic Mass": "83.96521(64#)" }, { "Atomic Symbol": "Zn", "Mass Number": "85", "Relative Atomic Mass": "84.97226(75#)" } ], "Notes": "r", "Standard Atomic Weight": "65.38(2)" }, { "Atomic Symbol": "Ga", "Atomic Number": "31", "isotopes": [ { "Atomic Symbol": "Ga", "Mass Number": "56", "Relative Atomic Mass": "55.99536(64#)" }, { "Atomic Symbol": "Ga", "Mass Number": "57", "Relative Atomic Mass": "56.98320(32#)" }, { "Atomic Symbol": "Ga", "Mass Number": "58", "Relative Atomic Mass": "57.97478(21#)" }, { "Atomic Symbol": "Ga", "Mass Number": "59", "Relative Atomic Mass": "58.96353(18#)" }, { "Atomic Symbol": "Ga", "Mass Number": "60", "Relative Atomic Mass": "59.95729(21#)" }, { "Atomic Symbol": "Ga", "Mass Number": "61", "Relative Atomic Mass": "60.949399(41)" }, { "Atomic Symbol": "Ga", "Mass Number": "62", "Relative Atomic Mass": "61.94419025(75)" }, { "Atomic Symbol": "Ga", "Mass Number": "63", "Relative Atomic Mass": "62.9392942(14)" }, { "Atomic Symbol": "Ga", "Mass Number": "64", "Relative Atomic Mass": "63.9368404(15)" }, { "Atomic Symbol": "Ga", "Mass Number": "65", "Relative Atomic Mass": "64.93273459(88)" }, { "Atomic Symbol": "Ga", "Mass Number": "66", "Relative Atomic Mass": "65.9315894(34)" }, { "Atomic Symbol": "Ga", "Mass Number": "67", "Relative Atomic Mass": "66.9282025(13)" }, { "Atomic Symbol": "Ga", "Mass Number": "68", "Relative Atomic Mass": "67.9279805(16)" }, { "Atomic Symbol": "Ga", "Mass Number": "69", "Isotopic Composition": "0.60108(9)", "Relative Atomic Mass": "68.9255735(13)" }, { "Atomic Symbol": "Ga", "Mass Number": "70", "Relative Atomic Mass": "69.9260219(13)" }, { "Atomic Symbol": "Ga", "Mass Number": "71", "Isotopic Composition": "0.39892(9)", "Relative Atomic Mass": "70.92470258(87)" }, { "Atomic Symbol": "Ga", "Mass Number": "72", "Relative Atomic Mass": "71.92636747(88)" }, { "Atomic Symbol": "Ga", "Mass Number": "73", "Relative Atomic Mass": "72.9251747(18)" }, { "Atomic Symbol": "Ga", "Mass Number": "74", "Relative Atomic Mass": "73.9269457(32)" }, { "Atomic Symbol": "Ga", "Mass Number": "75", "Relative Atomic Mass": "74.9265002(26)" }, { "Atomic Symbol": "Ga", "Mass Number": "76", "Relative Atomic Mass": "75.9288276(21)" }, { "Atomic Symbol": "Ga", "Mass Number": "77", "Relative Atomic Mass": "76.9291543(26)" }, { "Atomic Symbol": "Ga", "Mass Number": "78", "Relative Atomic Mass": "77.9316088(20)" }, { "Atomic Symbol": "Ga", "Mass Number": "79", "Relative Atomic Mass": "78.9328523(20)" }, { "Atomic Symbol": "Ga", "Mass Number": "80", "Relative Atomic Mass": "79.9364208(31)" }, { "Atomic Symbol": "Ga", "Mass Number": "81", "Relative Atomic Mass": "80.9381338(35)" }, { "Atomic Symbol": "Ga", "Mass Number": "82", "Relative Atomic Mass": "81.9431765(26)" }, { "Atomic Symbol": "Ga", "Mass Number": "83", "Relative Atomic Mass": "82.9471203(28)" }, { "Atomic Symbol": "Ga", "Mass Number": "84", "Relative Atomic Mass": "83.95246(43#)" }, { "Atomic Symbol": "Ga", "Mass Number": "85", "Relative Atomic Mass": "84.95699(32#)" }, { "Atomic Symbol": "Ga", "Mass Number": "86", "Relative Atomic Mass": "85.96301(75#)" }, { "Atomic Symbol": "Ga", "Mass Number": "87", "Relative Atomic Mass": "86.96824(86#)" } ], "Standard Atomic Weight": "69.723(1)" }, { "Atomic Symbol": "Ge", "Atomic Number": "32", "isotopes": [ { "Atomic Symbol": "Ge", "Mass Number": "58", "Relative Atomic Mass": "57.99172(43#)" }, { "Atomic Symbol": "Ge", "Mass Number": "59", "Relative Atomic Mass": "58.98249(32#)" }, { "Atomic Symbol": "Ge", "Mass Number": "60", "Relative Atomic Mass": "59.97036(21#)" }, { "Atomic Symbol": "Ge", "Mass Number": "61", "Relative Atomic Mass": "60.96379(32#)" }, { "Atomic Symbol": "Ge", "Mass Number": "62", "Relative Atomic Mass": "61.95502(15#)" }, { "Atomic Symbol": "Ge", "Mass Number": "63", "Relative Atomic Mass": "62.949628(40)" }, { "Atomic Symbol": "Ge", "Mass Number": "64", "Relative Atomic Mass": "63.9416899(40)" }, { "Atomic Symbol": "Ge", "Mass Number": "65", "Relative Atomic Mass": "64.9393681(23)" }, { "Atomic Symbol": "Ge", "Mass Number": "66", "Relative Atomic Mass": "65.9338621(26)" }, { "Atomic Symbol": "Ge", "Mass Number": "67", "Relative Atomic Mass": "66.9327339(50)" }, { "Atomic Symbol": "Ge", "Mass Number": "68", "Relative Atomic Mass": "67.9280953(20)" }, { "Atomic Symbol": "Ge", "Mass Number": "69", "Relative Atomic Mass": "68.9279645(14)" }, { "Atomic Symbol": "Ge", "Mass Number": "70", "Isotopic Composition": "0.2057(27)", "Relative Atomic Mass": "69.92424875(90)" }, { "Atomic Symbol": "Ge", "Mass Number": "71", "Relative Atomic Mass": "70.92495233(90)" }, { "Atomic Symbol": "Ge", "Mass Number": "72", "Isotopic Composition": "0.2745(32)", "Relative Atomic Mass": "71.922075826(81)" }, { "Atomic Symbol": "Ge", "Mass Number": "73", "Isotopic Composition": "0.0775(12)", "Relative Atomic Mass": "72.923458956(61)" }, { "Atomic Symbol": "Ge", "Mass Number": "74", "Isotopic Composition": "0.3650(20)", "Relative Atomic Mass": "73.921177761(13)" }, { "Atomic Symbol": "Ge", "Mass Number": "75", "Relative Atomic Mass": "74.922858370(55)" }, { "Atomic Symbol": "Ge", "Mass Number": "76", "Isotopic Composition": "0.0773(12)", "Relative Atomic Mass": "75.921402726(19)" }, { "Atomic Symbol": "Ge", "Mass Number": "77", "Relative Atomic Mass": "76.923549843(57)" }, { "Atomic Symbol": "Ge", "Mass Number": "78", "Relative Atomic Mass": "77.9228529(38)" }, { "Atomic Symbol": "Ge", "Mass Number": "79", "Relative Atomic Mass": "78.925360(40)" }, { "Atomic Symbol": "Ge", "Mass Number": "80", "Relative Atomic Mass": "79.9253508(22)" }, { "Atomic Symbol": "Ge", "Mass Number": "81", "Relative Atomic Mass": "80.9288329(22)" }, { "Atomic Symbol": "Ge", "Mass Number": "82", "Relative Atomic Mass": "81.9297740(24)" }, { "Atomic Symbol": "Ge", "Mass Number": "83", "Relative Atomic Mass": "82.9345391(26)" }, { "Atomic Symbol": "Ge", "Mass Number": "84", "Relative Atomic Mass": "83.9375751(34)" }, { "Atomic Symbol": "Ge", "Mass Number": "85", "Relative Atomic Mass": "84.9429697(40)" }, { "Atomic Symbol": "Ge", "Mass Number": "86", "Relative Atomic Mass": "85.94658(32#)" }, { "Atomic Symbol": "Ge", "Mass Number": "87", "Relative Atomic Mass": "86.95268(43#)" }, { "Atomic Symbol": "Ge", "Mass Number": "88", "Relative Atomic Mass": "87.95691(54#)" }, { "Atomic Symbol": "Ge", "Mass Number": "89", "Relative Atomic Mass": "88.96379(64#)" }, { "Atomic Symbol": "Ge", "Mass Number": "90", "Relative Atomic Mass": "89.96863(75#)" } ], "Standard Atomic Weight": "72.630(8)" }, { "Atomic Symbol": "As", "Atomic Number": "33", "isotopes": [ { "Atomic Symbol": "As", "Mass Number": "60", "Relative Atomic Mass": "59.99388(43#)" }, { "Atomic Symbol": "As", "Mass Number": "61", "Relative Atomic Mass": "60.98112(32#)" }, { "Atomic Symbol": "As", "Mass Number": "62", "Relative Atomic Mass": "61.97361(32#)" }, { "Atomic Symbol": "As", "Mass Number": "63", "Relative Atomic Mass": "62.96390(21#)" }, { "Atomic Symbol": "As", "Mass Number": "64", "Relative Atomic Mass": "63.95743(33#)" }, { "Atomic Symbol": "As", "Mass Number": "65", "Relative Atomic Mass": "64.949611(91)" }, { "Atomic Symbol": "As", "Mass Number": "66", "Relative Atomic Mass": "65.9441488(61)" }, { "Atomic Symbol": "As", "Mass Number": "67", "Relative Atomic Mass": "66.93925111(48)" }, { "Atomic Symbol": "As", "Mass Number": "68", "Relative Atomic Mass": "67.9367741(20)" }, { "Atomic Symbol": "As", "Mass Number": "69", "Relative Atomic Mass": "68.932246(34)" }, { "Atomic Symbol": "As", "Mass Number": "70", "Relative Atomic Mass": "69.930926(54)" }, { "Atomic Symbol": "As", "Mass Number": "71", "Relative Atomic Mass": "70.9271138(45)" }, { "Atomic Symbol": "As", "Mass Number": "72", "Relative Atomic Mass": "71.9267523(44)" }, { "Atomic Symbol": "As", "Mass Number": "73", "Relative Atomic Mass": "72.9238291(41)" }, { "Atomic Symbol": "As", "Mass Number": "74", "Relative Atomic Mass": "73.9239286(18)" }, { "Atomic Symbol": "As", "Mass Number": "75", "Isotopic Composition": "1", "Relative Atomic Mass": "74.92159457(95)" }, { "Atomic Symbol": "As", "Mass Number": "76", "Relative Atomic Mass": "75.92239202(95)" }, { "Atomic Symbol": "As", "Mass Number": "77", "Relative Atomic Mass": "76.9206476(18)" }, { "Atomic Symbol": "As", "Mass Number": "78", "Relative Atomic Mass": "77.921828(11)" }, { "Atomic Symbol": "As", "Mass Number": "79", "Relative Atomic Mass": "78.9209484(58)" }, { "Atomic Symbol": "As", "Mass Number": "80", "Relative Atomic Mass": "79.9224746(36)" }, { "Atomic Symbol": "As", "Mass Number": "81", "Relative Atomic Mass": "80.9221323(29)" }, { "Atomic Symbol": "As", "Mass Number": "82", "Relative Atomic Mass": "81.9247412(46)" }, { "Atomic Symbol": "As", "Mass Number": "83", "Relative Atomic Mass": "82.9252069(30)" }, { "Atomic Symbol": "As", "Mass Number": "84", "Relative Atomic Mass": "83.9293033(34)" }, { "Atomic Symbol": "As", "Mass Number": "85", "Relative Atomic Mass": "84.9321637(33)" }, { "Atomic Symbol": "As", "Mass Number": "86", "Relative Atomic Mass": "85.9367015(37)" }, { "Atomic Symbol": "As", "Mass Number": "87", "Relative Atomic Mass": "86.9402917(32)" }, { "Atomic Symbol": "As", "Mass Number": "88", "Relative Atomic Mass": "87.94555(21#)" }, { "Atomic Symbol": "As", "Mass Number": "89", "Relative Atomic Mass": "88.94976(32#)" }, { "Atomic Symbol": "As", "Mass Number": "90", "Relative Atomic Mass": "89.95563(64#)" }, { "Atomic Symbol": "As", "Mass Number": "91", "Relative Atomic Mass": "90.96039(64#)" }, { "Atomic Symbol": "As", "Mass Number": "92", "Relative Atomic Mass": "91.96674(75#)" } ], "Standard Atomic Weight": "74.921595(6)" }, { "Atomic Symbol": "Se", "Atomic Number": "34", "isotopes": [ { "Atomic Symbol": "Se", "Mass Number": "64", "Relative Atomic Mass": "63.97109(54#)" }, { "Atomic Symbol": "Se", "Mass Number": "65", "Relative Atomic Mass": "64.96440(64#)" }, { "Atomic Symbol": "Se", "Mass Number": "66", "Relative Atomic Mass": "65.95559(32#)" }, { "Atomic Symbol": "Se", "Mass Number": "67", "Relative Atomic Mass": "66.949994(72)" }, { "Atomic Symbol": "Se", "Mass Number": "68", "Relative Atomic Mass": "67.94182524(53)" }, { "Atomic Symbol": "Se", "Mass Number": "69", "Relative Atomic Mass": "68.9394148(16)" }, { "Atomic Symbol": "Se", "Mass Number": "70", "Relative Atomic Mass": "69.9335155(17)" }, { "Atomic Symbol": "Se", "Mass Number": "71", "Relative Atomic Mass": "70.9322094(30)" }, { "Atomic Symbol": "Se", "Mass Number": "72", "Relative Atomic Mass": "71.9271405(21)" }, { "Atomic Symbol": "Se", "Mass Number": "73", "Relative Atomic Mass": "72.9267549(80)" }, { "Atomic Symbol": "Se", "Mass Number": "74", "Isotopic Composition": "0.0089(4)", "Relative Atomic Mass": "73.922475934(15)" }, { "Atomic Symbol": "Se", "Mass Number": "75", "Relative Atomic Mass": "74.922522870(78)" }, { "Atomic Symbol": "Se", "Mass Number": "76", "Isotopic Composition": "0.0937(29)", "Relative Atomic Mass": "75.919213704(17)" }, { "Atomic Symbol": "Se", "Mass Number": "77", "Isotopic Composition": "0.0763(16)", "Relative Atomic Mass": "76.919914154(67)" }, { "Atomic Symbol": "Se", "Mass Number": "78", "Isotopic Composition": "0.2377(28)", "Relative Atomic Mass": "77.91730928(20)" }, { "Atomic Symbol": "Se", "Mass Number": "79", "Relative Atomic Mass": "78.91849929(24)" }, { "Atomic Symbol": "Se", "Mass Number": "80", "Isotopic Composition": "0.4961(41)", "Relative Atomic Mass": "79.9165218(13)" }, { "Atomic Symbol": "Se", "Mass Number": "81", "Relative Atomic Mass": "80.9179930(14)" }, { "Atomic Symbol": "Se", "Mass Number": "82", "Isotopic Composition": "0.0873(22)", "Relative Atomic Mass": "81.9166995(15)" }, { "Atomic Symbol": "Se", "Mass Number": "83", "Relative Atomic Mass": "82.9191186(36)" }, { "Atomic Symbol": "Se", "Mass Number": "84", "Relative Atomic Mass": "83.9184668(21)" }, { "Atomic Symbol": "Se", "Mass Number": "85", "Relative Atomic Mass": "84.9222608(28)" }, { "Atomic Symbol": "Se", "Mass Number": "86", "Relative Atomic Mass": "85.9243117(27)" }, { "Atomic Symbol": "Se", "Mass Number": "87", "Relative Atomic Mass": "86.9286886(24)" }, { "Atomic Symbol": "Se", "Mass Number": "88", "Relative Atomic Mass": "87.9314175(36)" }, { "Atomic Symbol": "Se", "Mass Number": "89", "Relative Atomic Mass": "88.9366691(40)" }, { "Atomic Symbol": "Se", "Mass Number": "90", "Relative Atomic Mass": "89.94010(35)" }, { "Atomic Symbol": "Se", "Mass Number": "91", "Relative Atomic Mass": "90.94596(54#)" }, { "Atomic Symbol": "Se", "Mass Number": "92", "Relative Atomic Mass": "91.94984(64#)" }, { "Atomic Symbol": "Se", "Mass Number": "93", "Relative Atomic Mass": "92.95629(86#)" }, { "Atomic Symbol": "Se", "Mass Number": "94", "Relative Atomic Mass": "93.96049(86#)" }, { "Atomic Symbol": "Se", "Mass Number": "95", "Relative Atomic Mass": "94.96730(86#)" } ], "Notes": "r", "Standard Atomic Weight": "78.971(8)" }, { "Atomic Symbol": "Br", "Atomic Number": "35", "isotopes": [ { "Atomic Symbol": "Br", "Mass Number": "67", "Relative Atomic Mass": "66.96465(54#)" }, { "Atomic Symbol": "Br", "Mass Number": "68", "Relative Atomic Mass": "67.95873(33#)" }, { "Atomic Symbol": "Br", "Mass Number": "69", "Relative Atomic Mass": "68.950497(40)" }, { "Atomic Symbol": "Br", "Mass Number": "70", "Relative Atomic Mass": "69.944792(16)" }, { "Atomic Symbol": "Br", "Mass Number": "71", "Relative Atomic Mass": "70.9393422(58)" }, { "Atomic Symbol": "Br", "Mass Number": "72", "Relative Atomic Mass": "71.9365886(72)" }, { "Atomic Symbol": "Br", "Mass Number": "73", "Relative Atomic Mass": "72.9316715(78)" }, { "Atomic Symbol": "Br", "Mass Number": "74", "Relative Atomic Mass": "73.9299102(63)" }, { "Atomic Symbol": "Br", "Mass Number": "75", "Relative Atomic Mass": "74.9258105(46)" }, { "Atomic Symbol": "Br", "Mass Number": "76", "Relative Atomic Mass": "75.924542(10)" }, { "Atomic Symbol": "Br", "Mass Number": "77", "Relative Atomic Mass": "76.9213792(30)" }, { "Atomic Symbol": "Br", "Mass Number": "78", "Relative Atomic Mass": "77.9211459(38)" }, { "Atomic Symbol": "Br", "Mass Number": "79", "Isotopic Composition": "0.5069(7)", "Relative Atomic Mass": "78.9183376(14)" }, { "Atomic Symbol": "Br", "Mass Number": "80", "Relative Atomic Mass": "79.9185298(14)" }, { "Atomic Symbol": "Br", "Mass Number": "81", "Isotopic Composition": "0.4931(7)", "Relative Atomic Mass": "80.9162897(14)" }, { "Atomic Symbol": "Br", "Mass Number": "82", "Relative Atomic Mass": "81.9168032(14)" }, { "Atomic Symbol": "Br", "Mass Number": "83", "Relative Atomic Mass": "82.9151756(41)" }, { "Atomic Symbol": "Br", "Mass Number": "84", "Relative Atomic Mass": "83.916496(28)" }, { "Atomic Symbol": "Br", "Mass Number": "85", "Relative Atomic Mass": "84.9156458(33)" }, { "Atomic Symbol": "Br", "Mass Number": "86", "Relative Atomic Mass": "85.9188054(33)" }, { "Atomic Symbol": "Br", "Mass Number": "87", "Relative Atomic Mass": "86.9206740(34)" }, { "Atomic Symbol": "Br", "Mass Number": "88", "Relative Atomic Mass": "87.9240833(34)" }, { "Atomic Symbol": "Br", "Mass Number": "89", "Relative Atomic Mass": "88.9267046(35)" }, { "Atomic Symbol": "Br", "Mass Number": "90", "Relative Atomic Mass": "89.9312928(36)" }, { "Atomic Symbol": "Br", "Mass Number": "91", "Relative Atomic Mass": "90.9343986(38)" }, { "Atomic Symbol": "Br", "Mass Number": "92", "Relative Atomic Mass": "91.9396316(72)" }, { "Atomic Symbol": "Br", "Mass Number": "93", "Relative Atomic Mass": "92.94313(48)" }, { "Atomic Symbol": "Br", "Mass Number": "94", "Relative Atomic Mass": "93.94890(43#)" }, { "Atomic Symbol": "Br", "Mass Number": "95", "Relative Atomic Mass": "94.95301(21#)" }, { "Atomic Symbol": "Br", "Mass Number": "96", "Relative Atomic Mass": "95.95903(32#)" }, { "Atomic Symbol": "Br", "Mass Number": "97", "Relative Atomic Mass": "96.96344(43#)" }, { "Atomic Symbol": "Br", "Mass Number": "98", "Relative Atomic Mass": "97.96946(43#)" } ], "Standard Atomic Weight": "[79.901,79.907]" }, { "Atomic Symbol": "Kr", "Atomic Number": "36", "isotopes": [ { "Atomic Symbol": "Kr", "Mass Number": "69", "Relative Atomic Mass": "68.96518(43#)" }, { "Atomic Symbol": "Kr", "Mass Number": "70", "Relative Atomic Mass": "69.95604(21#)" }, { "Atomic Symbol": "Kr", "Mass Number": "71", "Relative Atomic Mass": "70.95027(14)" }, { "Atomic Symbol": "Kr", "Mass Number": "72", "Relative Atomic Mass": "71.9420924(86)" }, { "Atomic Symbol": "Kr", "Mass Number": "73", "Relative Atomic Mass": "72.9392892(71)" }, { "Atomic Symbol": "Kr", "Mass Number": "74", "Relative Atomic Mass": "73.9330840(22)" }, { "Atomic Symbol": "Kr", "Mass Number": "75", "Relative Atomic Mass": "74.9309457(87)" }, { "Atomic Symbol": "Kr", "Mass Number": "76", "Relative Atomic Mass": "75.9259103(43)" }, { "Atomic Symbol": "Kr", "Mass Number": "77", "Relative Atomic Mass": "76.9246700(21)" }, { "Atomic Symbol": "Kr", "Mass Number": "78", "Isotopic Composition": "0.00355(3)", "Relative Atomic Mass": "77.92036494(76)" }, { "Atomic Symbol": "Kr", "Mass Number": "79", "Relative Atomic Mass": "78.9200829(38)" }, { "Atomic Symbol": "Kr", "Mass Number": "80", "Isotopic Composition": "0.02286(10)", "Relative Atomic Mass": "79.91637808(75)" }, { "Atomic Symbol": "Kr", "Mass Number": "81", "Relative Atomic Mass": "80.9165912(15)" }, { "Atomic Symbol": "Kr", "Mass Number": "82", "Isotopic Composition": "0.11593(31)", "Relative Atomic Mass": "81.91348273(94)" }, { "Atomic Symbol": "Kr", "Mass Number": "83", "Isotopic Composition": "0.11500(19)", "Relative Atomic Mass": "82.91412716(32)" }, { "Atomic Symbol": "Kr", "Mass Number": "84", "Isotopic Composition": "0.56987(15)", "Relative Atomic Mass": "83.9114977282(44)" }, { "Atomic Symbol": "Kr", "Mass Number": "85", "Relative Atomic Mass": "84.9125273(21)" }, { "Atomic Symbol": "Kr", "Mass Number": "86", "Isotopic Composition": "0.17279(41)", "Relative Atomic Mass": "85.9106106269(41)" }, { "Atomic Symbol": "Kr", "Mass Number": "87", "Relative Atomic Mass": "86.91335476(26)" }, { "Atomic Symbol": "Kr", "Mass Number": "88", "Relative Atomic Mass": "87.9144479(28)" }, { "Atomic Symbol": "Kr", "Mass Number": "89", "Relative Atomic Mass": "88.9178355(23)" }, { "Atomic Symbol": "Kr", "Mass Number": "90", "Relative Atomic Mass": "89.9195279(20)" }, { "Atomic Symbol": "Kr", "Mass Number": "91", "Relative Atomic Mass": "90.9238063(24)" }, { "Atomic Symbol": "Kr", "Mass Number": "92", "Relative Atomic Mass": "91.9261731(29)" }, { "Atomic Symbol": "Kr", "Mass Number": "93", "Relative Atomic Mass": "92.9311472(27)" }, { "Atomic Symbol": "Kr", "Mass Number": "94", "Relative Atomic Mass": "93.934140(13)" }, { "Atomic Symbol": "Kr", "Mass Number": "95", "Relative Atomic Mass": "94.939711(20)" }, { "Atomic Symbol": "Kr", "Mass Number": "96", "Relative Atomic Mass": "95.943017(22)" }, { "Atomic Symbol": "Kr", "Mass Number": "97", "Relative Atomic Mass": "96.94909(14)" }, { "Atomic Symbol": "Kr", "Mass Number": "98", "Relative Atomic Mass": "97.95243(32#)" }, { "Atomic Symbol": "Kr", "Mass Number": "99", "Relative Atomic Mass": "98.95839(54#)" }, { "Atomic Symbol": "Kr", "Mass Number": "100", "Relative Atomic Mass": "99.96237(43#)" }, { "Atomic Symbol": "Kr", "Mass Number": "101", "Relative Atomic Mass": "100.96873(54#)" } ], "Notes": "g,m", "Standard Atomic Weight": "83.798(2)" }, { "Atomic Symbol": "Rb", "Atomic Number": "37", "isotopes": [ { "Atomic Symbol": "Rb", "Mass Number": "71", "Relative Atomic Mass": "70.96532(54#)" }, { "Atomic Symbol": "Rb", "Mass Number": "72", "Relative Atomic Mass": "71.95908(54#)" }, { "Atomic Symbol": "Rb", "Mass Number": "73", "Relative Atomic Mass": "72.95053(11#)" }, { "Atomic Symbol": "Rb", "Mass Number": "74", "Relative Atomic Mass": "73.9442659(32)" }, { "Atomic Symbol": "Rb", "Mass Number": "75", "Relative Atomic Mass": "74.9385732(13)" }, { "Atomic Symbol": "Rb", "Mass Number": "76", "Relative Atomic Mass": "75.9350730(10)" }, { "Atomic Symbol": "Rb", "Mass Number": "77", "Relative Atomic Mass": "76.9304016(14)" }, { "Atomic Symbol": "Rb", "Mass Number": "78", "Relative Atomic Mass": "77.9281419(35)" }, { "Atomic Symbol": "Rb", "Mass Number": "79", "Relative Atomic Mass": "78.9239899(23)" }, { "Atomic Symbol": "Rb", "Mass Number": "80", "Relative Atomic Mass": "79.9225164(20)" }, { "Atomic Symbol": "Rb", "Mass Number": "81", "Relative Atomic Mass": "80.9189939(53)" }, { "Atomic Symbol": "Rb", "Mass Number": "82", "Relative Atomic Mass": "81.9182090(32)" }, { "Atomic Symbol": "Rb", "Mass Number": "83", "Relative Atomic Mass": "82.9151142(25)" }, { "Atomic Symbol": "Rb", "Mass Number": "84", "Relative Atomic Mass": "83.9143752(24)" }, { "Atomic Symbol": "Rb", "Mass Number": "85", "Isotopic Composition": "0.7217(2)", "Relative Atomic Mass": "84.9117897379(54)" }, { "Atomic Symbol": "Rb", "Mass Number": "86", "Relative Atomic Mass": "85.91116743(21)" }, { "Atomic Symbol": "Rb", "Mass Number": "87", "Isotopic Composition": "0.2783(2)", "Relative Atomic Mass": "86.9091805310(60)" }, { "Atomic Symbol": "Rb", "Mass Number": "88", "Relative Atomic Mass": "87.91131559(17)" }, { "Atomic Symbol": "Rb", "Mass Number": "89", "Relative Atomic Mass": "88.9122783(59)" }, { "Atomic Symbol": "Rb", "Mass Number": "90", "Relative Atomic Mass": "89.9147985(70)" }, { "Atomic Symbol": "Rb", "Mass Number": "91", "Relative Atomic Mass": "90.9165372(84)" }, { "Atomic Symbol": "Rb", "Mass Number": "92", "Relative Atomic Mass": "91.9197284(66)" }, { "Atomic Symbol": "Rb", "Mass Number": "93", "Relative Atomic Mass": "92.9220393(84)" }, { "Atomic Symbol": "Rb", "Mass Number": "94", "Relative Atomic Mass": "93.9263948(22)" }, { "Atomic Symbol": "Rb", "Mass Number": "95", "Relative Atomic Mass": "94.929260(22)" }, { "Atomic Symbol": "Rb", "Mass Number": "96", "Relative Atomic Mass": "95.9341334(36)" }, { "Atomic Symbol": "Rb", "Mass Number": "97", "Relative Atomic Mass": "96.9371771(21)" }, { "Atomic Symbol": "Rb", "Mass Number": "98", "Relative Atomic Mass": "97.9416869(37)" }, { "Atomic Symbol": "Rb", "Mass Number": "99", "Relative Atomic Mass": "98.94503(12)" }, { "Atomic Symbol": "Rb", "Mass Number": "100", "Relative Atomic Mass": "99.95003(21#)" }, { "Atomic Symbol": "Rb", "Mass Number": "101", "Relative Atomic Mass": "100.95404(23#)" }, { "Atomic Symbol": "Rb", "Mass Number": "102", "Relative Atomic Mass": "101.95952(32#)" }, { "Atomic Symbol": "Rb", "Mass Number": "103", "Relative Atomic Mass": "102.96392(43#)" } ], "Notes": "g", "Standard Atomic Weight": "85.4678(3)" }, { "Atomic Symbol": "Sr", "Atomic Number": "38", "isotopes": [ { "Atomic Symbol": "Sr", "Mass Number": "73", "Relative Atomic Mass": "72.96570(43#)" }, { "Atomic Symbol": "Sr", "Mass Number": "74", "Relative Atomic Mass": "73.95617(11#)" }, { "Atomic Symbol": "Sr", "Mass Number": "75", "Relative Atomic Mass": "74.94995(24)" }, { "Atomic Symbol": "Sr", "Mass Number": "76", "Relative Atomic Mass": "75.941763(37)" }, { "Atomic Symbol": "Sr", "Mass Number": "77", "Relative Atomic Mass": "76.9379455(85)" }, { "Atomic Symbol": "Sr", "Mass Number": "78", "Relative Atomic Mass": "77.9321800(80)" }, { "Atomic Symbol": "Sr", "Mass Number": "79", "Relative Atomic Mass": "78.9297077(90)" }, { "Atomic Symbol": "Sr", "Mass Number": "80", "Relative Atomic Mass": "79.9245175(37)" }, { "Atomic Symbol": "Sr", "Mass Number": "81", "Relative Atomic Mass": "80.9232114(34)" }, { "Atomic Symbol": "Sr", "Mass Number": "82", "Relative Atomic Mass": "81.9183999(64)" }, { "Atomic Symbol": "Sr", "Mass Number": "83", "Relative Atomic Mass": "82.9175544(73)" }, { "Atomic Symbol": "Sr", "Mass Number": "84", "Isotopic Composition": "0.0056(1)", "Relative Atomic Mass": "83.9134191(13)" }, { "Atomic Symbol": "Sr", "Mass Number": "85", "Relative Atomic Mass": "84.9129320(30)" }, { "Atomic Symbol": "Sr", "Mass Number": "86", "Isotopic Composition": "0.0986(1)", "Relative Atomic Mass": "85.9092606(12)" }, { "Atomic Symbol": "Sr", "Mass Number": "87", "Isotopic Composition": "0.0700(1)", "Relative Atomic Mass": "86.9088775(12)" }, { "Atomic Symbol": "Sr", "Mass Number": "88", "Isotopic Composition": "0.8258(1)", "Relative Atomic Mass": "87.9056125(12)" }, { "Atomic Symbol": "Sr", "Mass Number": "89", "Relative Atomic Mass": "88.9074511(12)" }, { "Atomic Symbol": "Sr", "Mass Number": "90", "Relative Atomic Mass": "89.9077300(28)" }, { "Atomic Symbol": "Sr", "Mass Number": "91", "Relative Atomic Mass": "90.9101954(61)" }, { "Atomic Symbol": "Sr", "Mass Number": "92", "Relative Atomic Mass": "91.9110382(37)" }, { "Atomic Symbol": "Sr", "Mass Number": "93", "Relative Atomic Mass": "92.9140242(81)" }, { "Atomic Symbol": "Sr", "Mass Number": "94", "Relative Atomic Mass": "93.9153556(18)" }, { "Atomic Symbol": "Sr", "Mass Number": "95", "Relative Atomic Mass": "94.9193529(63)" }, { "Atomic Symbol": "Sr", "Mass Number": "96", "Relative Atomic Mass": "95.9217066(93)" }, { "Atomic Symbol": "Sr", "Mass Number": "97", "Relative Atomic Mass": "96.9263740(36)" }, { "Atomic Symbol": "Sr", "Mass Number": "98", "Relative Atomic Mass": "97.9286888(40)" }, { "Atomic Symbol": "Sr", "Mass Number": "99", "Relative Atomic Mass": "98.9328907(38)" }, { "Atomic Symbol": "Sr", "Mass Number": "100", "Relative Atomic Mass": "99.935770(10)" }, { "Atomic Symbol": "Sr", "Mass Number": "101", "Relative Atomic Mass": "100.940352(86)" }, { "Atomic Symbol": "Sr", "Mass Number": "102", "Relative Atomic Mass": "101.943791(75)" }, { "Atomic Symbol": "Sr", "Mass Number": "103", "Relative Atomic Mass": "102.94909(21#)" }, { "Atomic Symbol": "Sr", "Mass Number": "104", "Relative Atomic Mass": "103.95265(32#)" }, { "Atomic Symbol": "Sr", "Mass Number": "105", "Relative Atomic Mass": "104.95855(54#)" }, { "Atomic Symbol": "Sr", "Mass Number": "106", "Relative Atomic Mass": "105.96265(64#)" }, { "Atomic Symbol": "Sr", "Mass Number": "107", "Relative Atomic Mass": "106.96897(75#)" } ], "Notes": "g,r", "Standard Atomic Weight": "87.62(1)" }, { "Atomic Symbol": "Y", "Atomic Number": "39", "isotopes": [ { "Atomic Symbol": "Y", "Mass Number": "76", "Relative Atomic Mass": "75.95856(54#)" }, { "Atomic Symbol": "Y", "Mass Number": "77", "Relative Atomic Mass": "76.949781(65#)" }, { "Atomic Symbol": "Y", "Mass Number": "78", "Relative Atomic Mass": "77.94361(43#)" }, { "Atomic Symbol": "Y", "Mass Number": "79", "Relative Atomic Mass": "78.93735(48)" }, { "Atomic Symbol": "Y", "Mass Number": "80", "Relative Atomic Mass": "79.9343561(67)" }, { "Atomic Symbol": "Y", "Mass Number": "81", "Relative Atomic Mass": "80.9294556(58)" }, { "Atomic Symbol": "Y", "Mass Number": "82", "Relative Atomic Mass": "81.9269314(59)" }, { "Atomic Symbol": "Y", "Mass Number": "83", "Relative Atomic Mass": "82.922485(20)" }, { "Atomic Symbol": "Y", "Mass Number": "84", "Relative Atomic Mass": "83.9206721(46)" }, { "Atomic Symbol": "Y", "Mass Number": "85", "Relative Atomic Mass": "84.916433(20)" }, { "Atomic Symbol": "Y", "Mass Number": "86", "Relative Atomic Mass": "85.914886(15)" }, { "Atomic Symbol": "Y", "Mass Number": "87", "Relative Atomic Mass": "86.9108761(17)" }, { "Atomic Symbol": "Y", "Mass Number": "88", "Relative Atomic Mass": "87.9095016(20)" }, { "Atomic Symbol": "Y", "Mass Number": "89", "Isotopic Composition": "1", "Relative Atomic Mass": "88.9058403(24)" }, { "Atomic Symbol": "Y", "Mass Number": "90", "Relative Atomic Mass": "89.9071439(24)" }, { "Atomic Symbol": "Y", "Mass Number": "91", "Relative Atomic Mass": "90.9072974(28)" }, { "Atomic Symbol": "Y", "Mass Number": "92", "Relative Atomic Mass": "91.9089451(99)" }, { "Atomic Symbol": "Y", "Mass Number": "93", "Relative Atomic Mass": "92.909578(11)" }, { "Atomic Symbol": "Y", "Mass Number": "94", "Relative Atomic Mass": "93.9115906(69)" }, { "Atomic Symbol": "Y", "Mass Number": "95", "Relative Atomic Mass": "94.9128161(74)" }, { "Atomic Symbol": "Y", "Mass Number": "96", "Relative Atomic Mass": "95.9158968(69)" }, { "Atomic Symbol": "Y", "Mass Number": "97", "Relative Atomic Mass": "96.9182741(75)" }, { "Atomic Symbol": "Y", "Mass Number": "98", "Relative Atomic Mass": "97.9223821(88)" }, { "Atomic Symbol": "Y", "Mass Number": "99", "Relative Atomic Mass": "98.9241480(74)" }, { "Atomic Symbol": "Y", "Mass Number": "100", "Relative Atomic Mass": "99.927715(12)" }, { "Atomic Symbol": "Y", "Mass Number": "101", "Relative Atomic Mass": "100.9301477(79)" }, { "Atomic Symbol": "Y", "Mass Number": "102", "Relative Atomic Mass": "101.9343277(44)" }, { "Atomic Symbol": "Y", "Mass Number": "103", "Relative Atomic Mass": "102.937243(12)" }, { "Atomic Symbol": "Y", "Mass Number": "104", "Relative Atomic Mass": "103.94196(43#)" }, { "Atomic Symbol": "Y", "Mass Number": "105", "Relative Atomic Mass": "104.94544(54#)" }, { "Atomic Symbol": "Y", "Mass Number": "106", "Relative Atomic Mass": "105.95056(54#)" }, { "Atomic Symbol": "Y", "Mass Number": "107", "Relative Atomic Mass": "106.95452(54#)" }, { "Atomic Symbol": "Y", "Mass Number": "108", "Relative Atomic Mass": "107.95996(64#)" }, { "Atomic Symbol": "Y", "Mass Number": "109", "Relative Atomic Mass": "108.96436(75#)" } ], "Standard Atomic Weight": "88.90584(2)" }, { "Atomic Symbol": "Zr", "Atomic Number": "40", "isotopes": [ { "Atomic Symbol": "Zr", "Mass Number": "78", "Relative Atomic Mass": "77.95566(54#)" }, { "Atomic Symbol": "Zr", "Mass Number": "79", "Relative Atomic Mass": "78.94948(43#)" }, { "Atomic Symbol": "Zr", "Mass Number": "80", "Relative Atomic Mass": "79.9404(16)" }, { "Atomic Symbol": "Zr", "Mass Number": "81", "Relative Atomic Mass": "80.93731(18)" }, { "Atomic Symbol": "Zr", "Mass Number": "82", "Relative Atomic Mass": "81.93135(22#)" }, { "Atomic Symbol": "Zr", "Mass Number": "83", "Relative Atomic Mass": "82.9292421(69)" }, { "Atomic Symbol": "Zr", "Mass Number": "84", "Relative Atomic Mass": "83.9233269(59)" }, { "Atomic Symbol": "Zr", "Mass Number": "85", "Relative Atomic Mass": "84.9214444(69)" }, { "Atomic Symbol": "Zr", "Mass Number": "86", "Relative Atomic Mass": "85.9162972(38)" }, { "Atomic Symbol": "Zr", "Mass Number": "87", "Relative Atomic Mass": "86.9148180(45)" }, { "Atomic Symbol": "Zr", "Mass Number": "88", "Relative Atomic Mass": "87.9102213(58)" }, { "Atomic Symbol": "Zr", "Mass Number": "89", "Relative Atomic Mass": "88.9088814(37)" }, { "Atomic Symbol": "Zr", "Mass Number": "90", "Isotopic Composition": "0.5145(40)", "Relative Atomic Mass": "89.9046977(20)" }, { "Atomic Symbol": "Zr", "Mass Number": "91", "Isotopic Composition": "0.1122(5)", "Relative Atomic Mass": "90.9056396(20)" }, { "Atomic Symbol": "Zr", "Mass Number": "92", "Isotopic Composition": "0.1715(8)", "Relative Atomic Mass": "91.9050347(20)" }, { "Atomic Symbol": "Zr", "Mass Number": "93", "Relative Atomic Mass": "92.9064699(20)" }, { "Atomic Symbol": "Zr", "Mass Number": "94", "Isotopic Composition": "0.1738(28)", "Relative Atomic Mass": "93.9063108(20)" }, { "Atomic Symbol": "Zr", "Mass Number": "95", "Relative Atomic Mass": "94.9080385(19)" }, { "Atomic Symbol": "Zr", "Mass Number": "96", "Isotopic Composition": "0.0280(9)", "Relative Atomic Mass": "95.9082714(21)" }, { "Atomic Symbol": "Zr", "Mass Number": "97", "Relative Atomic Mass": "96.9109512(21)" }, { "Atomic Symbol": "Zr", "Mass Number": "98", "Relative Atomic Mass": "97.9127289(93)" }, { "Atomic Symbol": "Zr", "Mass Number": "99", "Relative Atomic Mass": "98.916667(11)" }, { "Atomic Symbol": "Zr", "Mass Number": "100", "Relative Atomic Mass": "99.9180006(89)" }, { "Atomic Symbol": "Zr", "Mass Number": "101", "Relative Atomic Mass": "100.9214480(91)" }, { "Atomic Symbol": "Zr", "Mass Number": "102", "Relative Atomic Mass": "101.9231409(97)" }, { "Atomic Symbol": "Zr", "Mass Number": "103", "Relative Atomic Mass": "102.927191(10)" }, { "Atomic Symbol": "Zr", "Mass Number": "104", "Relative Atomic Mass": "103.929436(10)" }, { "Atomic Symbol": "Zr", "Mass Number": "105", "Relative Atomic Mass": "104.934008(13)" }, { "Atomic Symbol": "Zr", "Mass Number": "106", "Relative Atomic Mass": "105.93676(21#)" }, { "Atomic Symbol": "Zr", "Mass Number": "107", "Relative Atomic Mass": "106.94174(32#)" }, { "Atomic Symbol": "Zr", "Mass Number": "108", "Relative Atomic Mass": "107.94487(43#)" }, { "Atomic Symbol": "Zr", "Mass Number": "109", "Relative Atomic Mass": "108.95041(54#)" }, { "Atomic Symbol": "Zr", "Mass Number": "110", "Relative Atomic Mass": "109.95396(64#)" }, { "Atomic Symbol": "Zr", "Mass Number": "111", "Relative Atomic Mass": "110.95968(75#)" }, { "Atomic Symbol": "Zr", "Mass Number": "112", "Relative Atomic Mass": "111.96370(75#)" } ], "Notes": "g", "Standard Atomic Weight": "91.224(2)" }, { "Atomic Symbol": "Nb", "Atomic Number": "41", "isotopes": [ { "Atomic Symbol": "Nb", "Mass Number": "81", "Relative Atomic Mass": "80.94960(43#)" }, { "Atomic Symbol": "Nb", "Mass Number": "82", "Relative Atomic Mass": "81.94396(32#)" }, { "Atomic Symbol": "Nb", "Mass Number": "83", "Relative Atomic Mass": "82.93729(32)" }, { "Atomic Symbol": "Nb", "Mass Number": "84", "Relative Atomic Mass": "83.93449(32#)" }, { "Atomic Symbol": "Nb", "Mass Number": "85", "Relative Atomic Mass": "84.9288458(44)" }, { "Atomic Symbol": "Nb", "Mass Number": "86", "Relative Atomic Mass": "85.9257828(59)" }, { "Atomic Symbol": "Nb", "Mass Number": "87", "Relative Atomic Mass": "86.9206937(73)" }, { "Atomic Symbol": "Nb", "Mass Number": "88", "Relative Atomic Mass": "87.918222(61)" }, { "Atomic Symbol": "Nb", "Mass Number": "89", "Relative Atomic Mass": "88.913445(25)" }, { "Atomic Symbol": "Nb", "Mass Number": "90", "Relative Atomic Mass": "89.9112584(38)" }, { "Atomic Symbol": "Nb", "Mass Number": "91", "Relative Atomic Mass": "90.9069897(37)" }, { "Atomic Symbol": "Nb", "Mass Number": "92", "Relative Atomic Mass": "91.9071881(26)" }, { "Atomic Symbol": "Nb", "Mass Number": "93", "Isotopic Composition": "1", "Relative Atomic Mass": "92.9063730(20)" }, { "Atomic Symbol": "Nb", "Mass Number": "94", "Relative Atomic Mass": "93.9072788(20)" }, { "Atomic Symbol": "Nb", "Mass Number": "95", "Relative Atomic Mass": "94.90683240(71)" }, { "Atomic Symbol": "Nb", "Mass Number": "96", "Relative Atomic Mass": "95.9080973(35)" }, { "Atomic Symbol": "Nb", "Mass Number": "97", "Relative Atomic Mass": "96.9080959(19)" }, { "Atomic Symbol": "Nb", "Mass Number": "98", "Relative Atomic Mass": "97.9103265(58)" }, { "Atomic Symbol": "Nb", "Mass Number": "99", "Relative Atomic Mass": "98.911613(13)" }, { "Atomic Symbol": "Nb", "Mass Number": "100", "Relative Atomic Mass": "99.9143276(88)" }, { "Atomic Symbol": "Nb", "Mass Number": "101", "Relative Atomic Mass": "100.9153103(42)" }, { "Atomic Symbol": "Nb", "Mass Number": "102", "Relative Atomic Mass": "101.9180772(35)" }, { "Atomic Symbol": "Nb", "Mass Number": "103", "Relative Atomic Mass": "102.9194572(44)" }, { "Atomic Symbol": "Nb", "Mass Number": "104", "Relative Atomic Mass": "103.9228925(37)" }, { "Atomic Symbol": "Nb", "Mass Number": "105", "Relative Atomic Mass": "104.9249465(45)" }, { "Atomic Symbol": "Nb", "Mass Number": "106", "Relative Atomic Mass": "105.9289317(46)" }, { "Atomic Symbol": "Nb", "Mass Number": "107", "Relative Atomic Mass": "106.9315937(87)" }, { "Atomic Symbol": "Nb", "Mass Number": "108", "Relative Atomic Mass": "107.9360748(88)" }, { "Atomic Symbol": "Nb", "Mass Number": "109", "Relative Atomic Mass": "108.93922(56)" }, { "Atomic Symbol": "Nb", "Mass Number": "110", "Relative Atomic Mass": "109.94403(21#)" }, { "Atomic Symbol": "Nb", "Mass Number": "111", "Relative Atomic Mass": "110.94753(32#)" }, { "Atomic Symbol": "Nb", "Mass Number": "112", "Relative Atomic Mass": "111.95247(32#)" }, { "Atomic Symbol": "Nb", "Mass Number": "113", "Relative Atomic Mass": "112.95651(43#)" }, { "Atomic Symbol": "Nb", "Mass Number": "114", "Relative Atomic Mass": "113.96201(54#)" }, { "Atomic Symbol": "Nb", "Mass Number": "115", "Relative Atomic Mass": "114.96634(54#)" } ], "Standard Atomic Weight": "92.90637(2)" }, { "Atomic Symbol": "Mo", "Atomic Number": "42", "isotopes": [ { "Atomic Symbol": "Mo", "Mass Number": "83", "Relative Atomic Mass": "82.94988(43#)" }, { "Atomic Symbol": "Mo", "Mass Number": "84", "Relative Atomic Mass": "83.94149(43#)" }, { "Atomic Symbol": "Mo", "Mass Number": "85", "Relative Atomic Mass": "84.938261(17)" }, { "Atomic Symbol": "Mo", "Mass Number": "86", "Relative Atomic Mass": "85.9311748(40)" }, { "Atomic Symbol": "Mo", "Mass Number": "87", "Relative Atomic Mass": "86.9281962(31)" }, { "Atomic Symbol": "Mo", "Mass Number": "88", "Relative Atomic Mass": "87.9219678(41)" }, { "Atomic Symbol": "Mo", "Mass Number": "89", "Relative Atomic Mass": "88.9194682(42)" }, { "Atomic Symbol": "Mo", "Mass Number": "90", "Relative Atomic Mass": "89.9139309(38)" }, { "Atomic Symbol": "Mo", "Mass Number": "91", "Relative Atomic Mass": "90.9117453(67)" }, { "Atomic Symbol": "Mo", "Mass Number": "92", "Isotopic Composition": "0.1453(30)", "Relative Atomic Mass": "91.90680796(84)" }, { "Atomic Symbol": "Mo", "Mass Number": "93", "Relative Atomic Mass": "92.90680958(84)" }, { "Atomic Symbol": "Mo", "Mass Number": "94", "Isotopic Composition": "0.0915(9)", "Relative Atomic Mass": "93.90508490(48)" }, { "Atomic Symbol": "Mo", "Mass Number": "95", "Isotopic Composition": "0.1584(11)", "Relative Atomic Mass": "94.90583877(47)" }, { "Atomic Symbol": "Mo", "Mass Number": "96", "Isotopic Composition": "0.1667(15)", "Relative Atomic Mass": "95.90467612(47)" }, { "Atomic Symbol": "Mo", "Mass Number": "97", "Isotopic Composition": "0.0960(14)", "Relative Atomic Mass": "96.90601812(49)" }, { "Atomic Symbol": "Mo", "Mass Number": "98", "Isotopic Composition": "0.2439(37)", "Relative Atomic Mass": "97.90540482(49)" }, { "Atomic Symbol": "Mo", "Mass Number": "99", "Relative Atomic Mass": "98.90770851(52)" }, { "Atomic Symbol": "Mo", "Mass Number": "100", "Isotopic Composition": "0.0982(31)", "Relative Atomic Mass": "99.9074718(11)" }, { "Atomic Symbol": "Mo", "Mass Number": "101", "Relative Atomic Mass": "100.9103414(11)" }, { "Atomic Symbol": "Mo", "Mass Number": "102", "Relative Atomic Mass": "101.9102834(91)" }, { "Atomic Symbol": "Mo", "Mass Number": "103", "Relative Atomic Mass": "102.913079(10)" }, { "Atomic Symbol": "Mo", "Mass Number": "104", "Relative Atomic Mass": "103.9137344(98)" }, { "Atomic Symbol": "Mo", "Mass Number": "105", "Relative Atomic Mass": "104.916969(10)" }, { "Atomic Symbol": "Mo", "Mass Number": "106", "Relative Atomic Mass": "105.918259(10)" }, { "Atomic Symbol": "Mo", "Mass Number": "107", "Relative Atomic Mass": "106.922106(10)" }, { "Atomic Symbol": "Mo", "Mass Number": "108", "Relative Atomic Mass": "107.924033(10)" }, { "Atomic Symbol": "Mo", "Mass Number": "109", "Relative Atomic Mass": "108.928424(12)" }, { "Atomic Symbol": "Mo", "Mass Number": "110", "Relative Atomic Mass": "109.930704(26)" }, { "Atomic Symbol": "Mo", "Mass Number": "111", "Relative Atomic Mass": "110.935654(14)" }, { "Atomic Symbol": "Mo", "Mass Number": "112", "Relative Atomic Mass": "111.93831(21#)" }, { "Atomic Symbol": "Mo", "Mass Number": "113", "Relative Atomic Mass": "112.94335(32#)" }, { "Atomic Symbol": "Mo", "Mass Number": "114", "Relative Atomic Mass": "113.94653(32#)" }, { "Atomic Symbol": "Mo", "Mass Number": "115", "Relative Atomic Mass": "114.95196(43#)" }, { "Atomic Symbol": "Mo", "Mass Number": "116", "Relative Atomic Mass": "115.95545(54#)" }, { "Atomic Symbol": "Mo", "Mass Number": "117", "Relative Atomic Mass": "116.96117(54#)" } ], "Notes": "g", "Standard Atomic Weight": "95.95(1)" }, { "Atomic Symbol": "Tc", "Atomic Number": "43", "isotopes": [ { "Atomic Symbol": "Tc", "Mass Number": "85", "Relative Atomic Mass": "84.95058(43#)" }, { "Atomic Symbol": "Tc", "Mass Number": "86", "Relative Atomic Mass": "85.94493(32#)" }, { "Atomic Symbol": "Tc", "Mass Number": "87", "Relative Atomic Mass": "86.9380672(45)" }, { "Atomic Symbol": "Tc", "Mass Number": "88", "Relative Atomic Mass": "87.93378(16)" }, { "Atomic Symbol": "Tc", "Mass Number": "89", "Relative Atomic Mass": "88.9276487(41)" }, { "Atomic Symbol": "Tc", "Mass Number": "90", "Relative Atomic Mass": "89.9240739(11)" }, { "Atomic Symbol": "Tc", "Mass Number": "91", "Relative Atomic Mass": "90.9184254(25)" }, { "Atomic Symbol": "Tc", "Mass Number": "92", "Relative Atomic Mass": "91.9152698(33)" }, { "Atomic Symbol": "Tc", "Mass Number": "93", "Relative Atomic Mass": "92.9102460(14)" }, { "Atomic Symbol": "Tc", "Mass Number": "94", "Relative Atomic Mass": "93.9096536(44)" }, { "Atomic Symbol": "Tc", "Mass Number": "95", "Relative Atomic Mass": "94.9076536(55)" }, { "Atomic Symbol": "Tc", "Mass Number": "96", "Relative Atomic Mass": "95.9078680(55)" }, { "Atomic Symbol": "Tc", "Mass Number": "97", "Relative Atomic Mass": "96.9063667(40)" }, { "Atomic Symbol": "Tc", "Mass Number": "98", "Relative Atomic Mass": "97.9072124(36)" }, { "Atomic Symbol": "Tc", "Mass Number": "99", "Relative Atomic Mass": "98.9062508(10)" }, { "Atomic Symbol": "Tc", "Mass Number": "100", "Relative Atomic Mass": "99.9076539(15)" }, { "Atomic Symbol": "Tc", "Mass Number": "101", "Relative Atomic Mass": "100.907309(26)" }, { "Atomic Symbol": "Tc", "Mass Number": "102", "Relative Atomic Mass": "101.9092097(99)" }, { "Atomic Symbol": "Tc", "Mass Number": "103", "Relative Atomic Mass": "102.909176(11)" }, { "Atomic Symbol": "Tc", "Mass Number": "104", "Relative Atomic Mass": "103.911425(27)" }, { "Atomic Symbol": "Tc", "Mass Number": "105", "Relative Atomic Mass": "104.911655(38)" }, { "Atomic Symbol": "Tc", "Mass Number": "106", "Relative Atomic Mass": "105.914358(13)" }, { "Atomic Symbol": "Tc", "Mass Number": "107", "Relative Atomic Mass": "106.9154606(93)" }, { "Atomic Symbol": "Tc", "Mass Number": "108", "Relative Atomic Mass": "107.9184957(94)" }, { "Atomic Symbol": "Tc", "Mass Number": "109", "Relative Atomic Mass": "108.920256(10)" }, { "Atomic Symbol": "Tc", "Mass Number": "110", "Relative Atomic Mass": "109.923744(10)" }, { "Atomic Symbol": "Tc", "Mass Number": "111", "Relative Atomic Mass": "110.925901(11)" }, { "Atomic Symbol": "Tc", "Mass Number": "112", "Relative Atomic Mass": "111.9299458(60)" }, { "Atomic Symbol": "Tc", "Mass Number": "113", "Relative Atomic Mass": "112.9325690(36)" }, { "Atomic Symbol": "Tc", "Mass Number": "114", "Relative Atomic Mass": "113.93691(11#)" }, { "Atomic Symbol": "Tc", "Mass Number": "115", "Relative Atomic Mass": "114.93998(21#)" }, { "Atomic Symbol": "Tc", "Mass Number": "116", "Relative Atomic Mass": "115.94476(32#)" }, { "Atomic Symbol": "Tc", "Mass Number": "117", "Relative Atomic Mass": "116.94806(43#)" }, { "Atomic Symbol": "Tc", "Mass Number": "118", "Relative Atomic Mass": "117.95299(43#)" }, { "Atomic Symbol": "Tc", "Mass Number": "119", "Relative Atomic Mass": "118.95666(54#)" }, { "Atomic Symbol": "Tc", "Mass Number": "120", "Relative Atomic Mass": "119.96187(54#)" } ], "Standard Atomic Weight": "[98]" }, { "Atomic Symbol": "Ru", "Atomic Number": "44", "isotopes": [ { "Atomic Symbol": "Ru", "Mass Number": "87", "Relative Atomic Mass": "86.95069(43#)" }, { "Atomic Symbol": "Ru", "Mass Number": "88", "Relative Atomic Mass": "87.94160(32#)" }, { "Atomic Symbol": "Ru", "Mass Number": "89", "Relative Atomic Mass": "88.93762(32#)" }, { "Atomic Symbol": "Ru", "Mass Number": "90", "Relative Atomic Mass": "89.9303444(40)" }, { "Atomic Symbol": "Ru", "Mass Number": "91", "Relative Atomic Mass": "90.9267419(24)" }, { "Atomic Symbol": "Ru", "Mass Number": "92", "Relative Atomic Mass": "91.9202344(29)" }, { "Atomic Symbol": "Ru", "Mass Number": "93", "Relative Atomic Mass": "92.9171044(22)" }, { "Atomic Symbol": "Ru", "Mass Number": "94", "Relative Atomic Mass": "93.9113429(34)" }, { "Atomic Symbol": "Ru", "Mass Number": "95", "Relative Atomic Mass": "94.910406(10)" }, { "Atomic Symbol": "Ru", "Mass Number": "96", "Isotopic Composition": "0.0554(14)", "Relative Atomic Mass": "95.90759025(49)" }, { "Atomic Symbol": "Ru", "Mass Number": "97", "Relative Atomic Mass": "96.9075471(30)" }, { "Atomic Symbol": "Ru", "Mass Number": "98", "Isotopic Composition": "0.0187(3)", "Relative Atomic Mass": "97.9052868(69)" }, { "Atomic Symbol": "Ru", "Mass Number": "99", "Isotopic Composition": "0.1276(14)", "Relative Atomic Mass": "98.9059341(11)" }, { "Atomic Symbol": "Ru", "Mass Number": "100", "Isotopic Composition": "0.1260(7)", "Relative Atomic Mass": "99.9042143(11)" }, { "Atomic Symbol": "Ru", "Mass Number": "101", "Isotopic Composition": "0.1706(2)", "Relative Atomic Mass": "100.9055769(12)" }, { "Atomic Symbol": "Ru", "Mass Number": "102", "Isotopic Composition": "0.3155(14)", "Relative Atomic Mass": "101.9043441(12)" }, { "Atomic Symbol": "Ru", "Mass Number": "103", "Relative Atomic Mass": "102.9063186(12)" }, { "Atomic Symbol": "Ru", "Mass Number": "104", "Isotopic Composition": "0.1862(27)", "Relative Atomic Mass": "103.9054275(28)" }, { "Atomic Symbol": "Ru", "Mass Number": "105", "Relative Atomic Mass": "104.9077476(28)" }, { "Atomic Symbol": "Ru", "Mass Number": "106", "Relative Atomic Mass": "105.9073291(58)" }, { "Atomic Symbol": "Ru", "Mass Number": "107", "Relative Atomic Mass": "106.9099720(93)" }, { "Atomic Symbol": "Ru", "Mass Number": "108", "Relative Atomic Mass": "107.9101880(93)" }, { "Atomic Symbol": "Ru", "Mass Number": "109", "Relative Atomic Mass": "108.9133260(96)" }, { "Atomic Symbol": "Ru", "Mass Number": "110", "Relative Atomic Mass": "109.9140407(96)" }, { "Atomic Symbol": "Ru", "Mass Number": "111", "Relative Atomic Mass": "110.917570(10)" }, { "Atomic Symbol": "Ru", "Mass Number": "112", "Relative Atomic Mass": "111.918809(10)" }, { "Atomic Symbol": "Ru", "Mass Number": "113", "Relative Atomic Mass": "112.922844(39)" }, { "Atomic Symbol": "Ru", "Mass Number": "114", "Relative Atomic Mass": "113.9246136(38)" }, { "Atomic Symbol": "Ru", "Mass Number": "115", "Relative Atomic Mass": "114.928820(71)" }, { "Atomic Symbol": "Ru", "Mass Number": "116", "Relative Atomic Mass": "115.9312192(40)" }, { "Atomic Symbol": "Ru", "Mass Number": "117", "Relative Atomic Mass": "116.93610(63)" }, { "Atomic Symbol": "Ru", "Mass Number": "118", "Relative Atomic Mass": "117.93853(32#)" }, { "Atomic Symbol": "Ru", "Mass Number": "119", "Relative Atomic Mass": "118.94357(32#)" }, { "Atomic Symbol": "Ru", "Mass Number": "120", "Relative Atomic Mass": "119.94631(43#)" }, { "Atomic Symbol": "Ru", "Mass Number": "121", "Relative Atomic Mass": "120.95164(43#)" }, { "Atomic Symbol": "Ru", "Mass Number": "122", "Relative Atomic Mass": "121.95447(54#)" }, { "Atomic Symbol": "Ru", "Mass Number": "123", "Relative Atomic Mass": "122.95989(54#)" }, { "Atomic Symbol": "Ru", "Mass Number": "124", "Relative Atomic Mass": "123.96305(64#)" } ], "Notes": "g", "Standard Atomic Weight": "101.07(2)" }, { "Atomic Symbol": "Rh", "Atomic Number": "45", "isotopes": [ { "Atomic Symbol": "Rh", "Mass Number": "89", "Relative Atomic Mass": "88.95058(39#)" }, { "Atomic Symbol": "Rh", "Mass Number": "90", "Relative Atomic Mass": "89.94422(43#)" }, { "Atomic Symbol": "Rh", "Mass Number": "91", "Relative Atomic Mass": "90.93688(43#)" }, { "Atomic Symbol": "Rh", "Mass Number": "92", "Relative Atomic Mass": "91.9323677(47)" }, { "Atomic Symbol": "Rh", "Mass Number": "93", "Relative Atomic Mass": "92.9259128(28)" }, { "Atomic Symbol": "Rh", "Mass Number": "94", "Relative Atomic Mass": "93.9217305(36)" }, { "Atomic Symbol": "Rh", "Mass Number": "95", "Relative Atomic Mass": "94.9158979(42)" }, { "Atomic Symbol": "Rh", "Mass Number": "96", "Relative Atomic Mass": "95.914453(11)" }, { "Atomic Symbol": "Rh", "Mass Number": "97", "Relative Atomic Mass": "96.911329(38)" }, { "Atomic Symbol": "Rh", "Mass Number": "98", "Relative Atomic Mass": "97.910708(13)" }, { "Atomic Symbol": "Rh", "Mass Number": "99", "Relative Atomic Mass": "98.9081282(73)" }, { "Atomic Symbol": "Rh", "Mass Number": "100", "Relative Atomic Mass": "99.908117(19)" }, { "Atomic Symbol": "Rh", "Mass Number": "101", "Relative Atomic Mass": "100.9061606(63)" }, { "Atomic Symbol": "Rh", "Mass Number": "102", "Relative Atomic Mass": "101.9068374(50)" }, { "Atomic Symbol": "Rh", "Mass Number": "103", "Isotopic Composition": "1", "Relative Atomic Mass": "102.9054980(26)" }, { "Atomic Symbol": "Rh", "Mass Number": "104", "Relative Atomic Mass": "103.9066492(26)" }, { "Atomic Symbol": "Rh", "Mass Number": "105", "Relative Atomic Mass": "104.9056885(27)" }, { "Atomic Symbol": "Rh", "Mass Number": "106", "Relative Atomic Mass": "105.9072868(58)" }, { "Atomic Symbol": "Rh", "Mass Number": "107", "Relative Atomic Mass": "106.906748(13)" }, { "Atomic Symbol": "Rh", "Mass Number": "108", "Relative Atomic Mass": "107.908714(15)" }, { "Atomic Symbol": "Rh", "Mass Number": "109", "Relative Atomic Mass": "108.9087488(43)" }, { "Atomic Symbol": "Rh", "Mass Number": "110", "Relative Atomic Mass": "109.911079(19)" }, { "Atomic Symbol": "Rh", "Mass Number": "111", "Relative Atomic Mass": "110.9116423(74)" }, { "Atomic Symbol": "Rh", "Mass Number": "112", "Relative Atomic Mass": "111.914403(47)" }, { "Atomic Symbol": "Rh", "Mass Number": "113", "Relative Atomic Mass": "112.9154393(77)" }, { "Atomic Symbol": "Rh", "Mass Number": "114", "Relative Atomic Mass": "113.918718(77)" }, { "Atomic Symbol": "Rh", "Mass Number": "115", "Relative Atomic Mass": "114.9203116(78)" }, { "Atomic Symbol": "Rh", "Mass Number": "116", "Relative Atomic Mass": "115.924059(76)" }, { "Atomic Symbol": "Rh", "Mass Number": "117", "Relative Atomic Mass": "116.9260354(95)" }, { "Atomic Symbol": "Rh", "Mass Number": "118", "Relative Atomic Mass": "117.930340(26)" }, { "Atomic Symbol": "Rh", "Mass Number": "119", "Relative Atomic Mass": "118.932557(10)" }, { "Atomic Symbol": "Rh", "Mass Number": "120", "Relative Atomic Mass": "119.93686(21#)" }, { "Atomic Symbol": "Rh", "Mass Number": "121", "Relative Atomic Mass": "120.93942(32#)" }, { "Atomic Symbol": "Rh", "Mass Number": "122", "Relative Atomic Mass": "121.94399(32#)" }, { "Atomic Symbol": "Rh", "Mass Number": "123", "Relative Atomic Mass": "122.94685(43#)" }, { "Atomic Symbol": "Rh", "Mass Number": "124", "Relative Atomic Mass": "123.95151(43#)" }, { "Atomic Symbol": "Rh", "Mass Number": "125", "Relative Atomic Mass": "124.95469(54#)" }, { "Atomic Symbol": "Rh", "Mass Number": "126", "Relative Atomic Mass": "125.95946(54#)" } ], "Standard Atomic Weight": "102.90550(2)" }, { "Atomic Symbol": "Pd", "Atomic Number": "46", "isotopes": [ { "Atomic Symbol": "Pd", "Mass Number": "91", "Relative Atomic Mass": "90.95032(54#)" }, { "Atomic Symbol": "Pd", "Mass Number": "92", "Relative Atomic Mass": "91.94088(54#)" }, { "Atomic Symbol": "Pd", "Mass Number": "93", "Relative Atomic Mass": "92.93651(43#)" }, { "Atomic Symbol": "Pd", "Mass Number": "94", "Relative Atomic Mass": "93.9290376(46)" }, { "Atomic Symbol": "Pd", "Mass Number": "95", "Relative Atomic Mass": "94.9248898(33)" }, { "Atomic Symbol": "Pd", "Mass Number": "96", "Relative Atomic Mass": "95.9182151(45)" }, { "Atomic Symbol": "Pd", "Mass Number": "97", "Relative Atomic Mass": "96.9164720(52)" }, { "Atomic Symbol": "Pd", "Mass Number": "98", "Relative Atomic Mass": "97.9126983(51)" }, { "Atomic Symbol": "Pd", "Mass Number": "99", "Relative Atomic Mass": "98.9117748(54)" }, { "Atomic Symbol": "Pd", "Mass Number": "100", "Relative Atomic Mass": "99.908505(19)" }, { "Atomic Symbol": "Pd", "Mass Number": "101", "Relative Atomic Mass": "100.9082864(49)" }, { "Atomic Symbol": "Pd", "Mass Number": "102", "Isotopic Composition": "0.0102(1)", "Relative Atomic Mass": "101.9056022(28)" }, { "Atomic Symbol": "Pd", "Mass Number": "103", "Relative Atomic Mass": "102.9060809(27)" }, { "Atomic Symbol": "Pd", "Mass Number": "104", "Isotopic Composition": "0.1114(8)", "Relative Atomic Mass": "103.9040305(14)" }, { "Atomic Symbol": "Pd", "Mass Number": "105", "Isotopic Composition": "0.2233(8)", "Relative Atomic Mass": "104.9050796(12)" }, { "Atomic Symbol": "Pd", "Mass Number": "106", "Isotopic Composition": "0.2733(3)", "Relative Atomic Mass": "105.9034804(12)" }, { "Atomic Symbol": "Pd", "Mass Number": "107", "Relative Atomic Mass": "106.9051282(13)" }, { "Atomic Symbol": "Pd", "Mass Number": "108", "Isotopic Composition": "0.2646(9)", "Relative Atomic Mass": "107.9038916(12)" }, { "Atomic Symbol": "Pd", "Mass Number": "109", "Relative Atomic Mass": "108.9059504(12)" }, { "Atomic Symbol": "Pd", "Mass Number": "110", "Isotopic Composition": "0.1172(9)", "Relative Atomic Mass": "109.90517220(75)" }, { "Atomic Symbol": "Pd", "Mass Number": "111", "Relative Atomic Mass": "110.90768968(86)" }, { "Atomic Symbol": "Pd", "Mass Number": "112", "Relative Atomic Mass": "111.9073297(70)" }, { "Atomic Symbol": "Pd", "Mass Number": "113", "Relative Atomic Mass": "112.9102610(75)" }, { "Atomic Symbol": "Pd", "Mass Number": "114", "Relative Atomic Mass": "113.9103686(75)" }, { "Atomic Symbol": "Pd", "Mass Number": "115", "Relative Atomic Mass": "114.913659(15)" }, { "Atomic Symbol": "Pd", "Mass Number": "116", "Relative Atomic Mass": "115.9142970(77)" }, { "Atomic Symbol": "Pd", "Mass Number": "117", "Relative Atomic Mass": "116.9179547(78)" }, { "Atomic Symbol": "Pd", "Mass Number": "118", "Relative Atomic Mass": "117.9190667(27)" }, { "Atomic Symbol": "Pd", "Mass Number": "119", "Relative Atomic Mass": "118.9233402(89)" }, { "Atomic Symbol": "Pd", "Mass Number": "120", "Relative Atomic Mass": "119.9245511(25)" }, { "Atomic Symbol": "Pd", "Mass Number": "121", "Relative Atomic Mass": "120.9289503(36)" }, { "Atomic Symbol": "Pd", "Mass Number": "122", "Relative Atomic Mass": "121.930632(21)" }, { "Atomic Symbol": "Pd", "Mass Number": "123", "Relative Atomic Mass": "122.93514(21#)" }, { "Atomic Symbol": "Pd", "Mass Number": "124", "Relative Atomic Mass": "123.93714(32#)" }, { "Atomic Symbol": "Pd", "Mass Number": "125", "Relative Atomic Mass": "124.94179(43#)" }, { "Atomic Symbol": "Pd", "Mass Number": "126", "Relative Atomic Mass": "125.94416(54#)" }, { "Atomic Symbol": "Pd", "Mass Number": "127", "Relative Atomic Mass": "126.94907(54#)" }, { "Atomic Symbol": "Pd", "Mass Number": "128", "Relative Atomic Mass": "127.95183(64#)" } ], "Notes": "g", "Standard Atomic Weight": "106.42(1)" }, { "Atomic Symbol": "Ag", "Atomic Number": "47", "isotopes": [ { "Atomic Symbol": "Ag", "Mass Number": "93", "Relative Atomic Mass": "92.95033(54#)" }, { "Atomic Symbol": "Ag", "Mass Number": "94", "Relative Atomic Mass": "93.94373(69#)" }, { "Atomic Symbol": "Ag", "Mass Number": "95", "Relative Atomic Mass": "94.93602(43#)" }, { "Atomic Symbol": "Ag", "Mass Number": "96", "Relative Atomic Mass": "95.930744(97)" }, { "Atomic Symbol": "Ag", "Mass Number": "97", "Relative Atomic Mass": "96.92397(12)" }, { "Atomic Symbol": "Ag", "Mass Number": "98", "Relative Atomic Mass": "97.921560(35)" }, { "Atomic Symbol": "Ag", "Mass Number": "99", "Relative Atomic Mass": "98.9176458(67)" }, { "Atomic Symbol": "Ag", "Mass Number": "100", "Relative Atomic Mass": "99.9161154(54)" }, { "Atomic Symbol": "Ag", "Mass Number": "101", "Relative Atomic Mass": "100.9126840(52)" }, { "Atomic Symbol": "Ag", "Mass Number": "102", "Relative Atomic Mass": "101.9117047(88)" }, { "Atomic Symbol": "Ag", "Mass Number": "103", "Relative Atomic Mass": "102.9089631(41)" }, { "Atomic Symbol": "Ag", "Mass Number": "104", "Relative Atomic Mass": "103.9086239(45)" }, { "Atomic Symbol": "Ag", "Mass Number": "105", "Relative Atomic Mass": "104.9065256(49)" }, { "Atomic Symbol": "Ag", "Mass Number": "106", "Relative Atomic Mass": "105.9066636(32)" }, { "Atomic Symbol": "Ag", "Mass Number": "107", "Isotopic Composition": "0.51839(8)", "Relative Atomic Mass": "106.9050916(26)" }, { "Atomic Symbol": "Ag", "Mass Number": "108", "Relative Atomic Mass": "107.9059503(26)" }, { "Atomic Symbol": "Ag", "Mass Number": "109", "Isotopic Composition": "0.48161(8)", "Relative Atomic Mass": "108.9047553(14)" }, { "Atomic Symbol": "Ag", "Mass Number": "110", "Relative Atomic Mass": "109.9061102(14)" }, { "Atomic Symbol": "Ag", "Mass Number": "111", "Relative Atomic Mass": "110.9052959(16)" }, { "Atomic Symbol": "Ag", "Mass Number": "112", "Relative Atomic Mass": "111.9070486(26)" }, { "Atomic Symbol": "Ag", "Mass Number": "113", "Relative Atomic Mass": "112.906573(18)" }, { "Atomic Symbol": "Ag", "Mass Number": "114", "Relative Atomic Mass": "113.9088230(49)" }, { "Atomic Symbol": "Ag", "Mass Number": "115", "Relative Atomic Mass": "114.908767(20)" }, { "Atomic Symbol": "Ag", "Mass Number": "116", "Relative Atomic Mass": "115.9113868(35)" }, { "Atomic Symbol": "Ag", "Mass Number": "117", "Relative Atomic Mass": "116.911774(15)" }, { "Atomic Symbol": "Ag", "Mass Number": "118", "Relative Atomic Mass": "117.9145955(27)" }, { "Atomic Symbol": "Ag", "Mass Number": "119", "Relative Atomic Mass": "118.915570(16)" }, { "Atomic Symbol": "Ag", "Mass Number": "120", "Relative Atomic Mass": "119.9187848(48)" }, { "Atomic Symbol": "Ag", "Mass Number": "121", "Relative Atomic Mass": "120.920125(13)" }, { "Atomic Symbol": "Ag", "Mass Number": "122", "Relative Atomic Mass": "121.923664(41)" }, { "Atomic Symbol": "Ag", "Mass Number": "123", "Relative Atomic Mass": "122.925337(33)" }, { "Atomic Symbol": "Ag", "Mass Number": "124", "Relative Atomic Mass": "123.92893(27)" }, { "Atomic Symbol": "Ag", "Mass Number": "125", "Relative Atomic Mass": "124.93105(64)" }, { "Atomic Symbol": "Ag", "Mass Number": "126", "Relative Atomic Mass": "125.93475(21#)" }, { "Atomic Symbol": "Ag", "Mass Number": "127", "Relative Atomic Mass": "126.93711(21#)" }, { "Atomic Symbol": "Ag", "Mass Number": "128", "Relative Atomic Mass": "127.94106(32#)" }, { "Atomic Symbol": "Ag", "Mass Number": "129", "Relative Atomic Mass": "128.94395(32#)" }, { "Atomic Symbol": "Ag", "Mass Number": "130", "Relative Atomic Mass": "129.95070(36#)" } ], "Notes": "g", "Standard Atomic Weight": "107.8682(2)" }, { "Atomic Symbol": "Cd", "Atomic Number": "48", "isotopes": [ { "Atomic Symbol": "Cd", "Mass Number": "95", "Relative Atomic Mass": "94.94994(54#)" }, { "Atomic Symbol": "Cd", "Mass Number": "96", "Relative Atomic Mass": "95.94034(43#)" }, { "Atomic Symbol": "Cd", "Mass Number": "97", "Relative Atomic Mass": "96.93510(32#)" }, { "Atomic Symbol": "Cd", "Mass Number": "98", "Relative Atomic Mass": "97.927389(56)" }, { "Atomic Symbol": "Cd", "Mass Number": "99", "Relative Atomic Mass": "98.9249258(17)" }, { "Atomic Symbol": "Cd", "Mass Number": "100", "Relative Atomic Mass": "99.9203488(18)" }, { "Atomic Symbol": "Cd", "Mass Number": "101", "Relative Atomic Mass": "100.9185862(16)" }, { "Atomic Symbol": "Cd", "Mass Number": "102", "Relative Atomic Mass": "101.9144820(18)" }, { "Atomic Symbol": "Cd", "Mass Number": "103", "Relative Atomic Mass": "102.9134165(19)" }, { "Atomic Symbol": "Cd", "Mass Number": "104", "Relative Atomic Mass": "103.9098564(18)" }, { "Atomic Symbol": "Cd", "Mass Number": "105", "Relative Atomic Mass": "104.9094639(15)" }, { "Atomic Symbol": "Cd", "Mass Number": "106", "Isotopic Composition": "0.0125(6)", "Relative Atomic Mass": "105.9064599(12)" }, { "Atomic Symbol": "Cd", "Mass Number": "107", "Relative Atomic Mass": "106.9066121(18)" }, { "Atomic Symbol": "Cd", "Mass Number": "108", "Isotopic Composition": "0.0089(3)", "Relative Atomic Mass": "107.9041834(12)" }, { "Atomic Symbol": "Cd", "Mass Number": "109", "Relative Atomic Mass": "108.9049867(17)" }, { "Atomic Symbol": "Cd", "Mass Number": "110", "Isotopic Composition": "0.1249(18)", "Relative Atomic Mass": "109.90300661(61)" }, { "Atomic Symbol": "Cd", "Mass Number": "111", "Isotopic Composition": "0.1280(12)", "Relative Atomic Mass": "110.90418287(61)" }, { "Atomic Symbol": "Cd", "Mass Number": "112", "Isotopic Composition": "0.2413(21)", "Relative Atomic Mass": "111.90276287(60)" }, { "Atomic Symbol": "Cd", "Mass Number": "113", "Isotopic Composition": "0.1222(12)", "Relative Atomic Mass": "112.90440813(45)" }, { "Atomic Symbol": "Cd", "Mass Number": "114", "Isotopic Composition": "0.2873(42)", "Relative Atomic Mass": "113.90336509(43)" }, { "Atomic Symbol": "Cd", "Mass Number": "115", "Relative Atomic Mass": "114.90543751(77)" }, { "Atomic Symbol": "Cd", "Mass Number": "116", "Isotopic Composition": "0.0749(18)", "Relative Atomic Mass": "115.90476315(17)" }, { "Atomic Symbol": "Cd", "Mass Number": "117", "Relative Atomic Mass": "116.9072260(11)" }, { "Atomic Symbol": "Cd", "Mass Number": "118", "Relative Atomic Mass": "117.906922(21)" }, { "Atomic Symbol": "Cd", "Mass Number": "119", "Relative Atomic Mass": "118.909847(40)" }, { "Atomic Symbol": "Cd", "Mass Number": "120", "Relative Atomic Mass": "119.9098681(40)" }, { "Atomic Symbol": "Cd", "Mass Number": "121", "Relative Atomic Mass": "120.9129637(21)" }, { "Atomic Symbol": "Cd", "Mass Number": "122", "Relative Atomic Mass": "121.9134591(25)" }, { "Atomic Symbol": "Cd", "Mass Number": "123", "Relative Atomic Mass": "122.9168925(29)" }, { "Atomic Symbol": "Cd", "Mass Number": "124", "Relative Atomic Mass": "123.9176574(32)" }, { "Atomic Symbol": "Cd", "Mass Number": "125", "Relative Atomic Mass": "124.9212576(31)" }, { "Atomic Symbol": "Cd", "Mass Number": "126", "Relative Atomic Mass": "125.9224291(27)" }, { "Atomic Symbol": "Cd", "Mass Number": "127", "Relative Atomic Mass": "126.926472(14)" }, { "Atomic Symbol": "Cd", "Mass Number": "128", "Relative Atomic Mass": "127.9278129(78)" }, { "Atomic Symbol": "Cd", "Mass Number": "129", "Relative Atomic Mass": "128.93182(21#)" }, { "Atomic Symbol": "Cd", "Mass Number": "130", "Relative Atomic Mass": "129.93394(18)" }, { "Atomic Symbol": "Cd", "Mass Number": "131", "Relative Atomic Mass": "130.94060(21#)" }, { "Atomic Symbol": "Cd", "Mass Number": "132", "Relative Atomic Mass": "131.94604(21#)" }, { "Atomic Symbol": "Cd", "Mass Number": "133", "Relative Atomic Mass": "132.95285(32#)" } ], "Notes": "g", "Standard Atomic Weight": "112.414(4)" }, { "Atomic Symbol": "In", "Atomic Number": "49", "isotopes": [ { "Atomic Symbol": "In", "Mass Number": "97", "Relative Atomic Mass": "96.94934(54#)" }, { "Atomic Symbol": "In", "Mass Number": "98", "Relative Atomic Mass": "97.94214(21#)" }, { "Atomic Symbol": "In", "Mass Number": "99", "Relative Atomic Mass": "98.93411(21#)" }, { "Atomic Symbol": "In", "Mass Number": "100", "Relative Atomic Mass": "99.93096(20)" }, { "Atomic Symbol": "In", "Mass Number": "101", "Relative Atomic Mass": "100.92634(32#)" }, { "Atomic Symbol": "In", "Mass Number": "102", "Relative Atomic Mass": "101.9241071(49)" }, { "Atomic Symbol": "In", "Mass Number": "103", "Relative Atomic Mass": "102.9198819(98)" }, { "Atomic Symbol": "In", "Mass Number": "104", "Relative Atomic Mass": "103.9182145(62)" }, { "Atomic Symbol": "In", "Mass Number": "105", "Relative Atomic Mass": "104.914502(11)" }, { "Atomic Symbol": "In", "Mass Number": "106", "Relative Atomic Mass": "105.913464(13)" }, { "Atomic Symbol": "In", "Mass Number": "107", "Relative Atomic Mass": "106.910290(12)" }, { "Atomic Symbol": "In", "Mass Number": "108", "Relative Atomic Mass": "107.9096935(93)" }, { "Atomic Symbol": "In", "Mass Number": "109", "Relative Atomic Mass": "108.9071514(43)" }, { "Atomic Symbol": "In", "Mass Number": "110", "Relative Atomic Mass": "109.907170(12)" }, { "Atomic Symbol": "In", "Mass Number": "111", "Relative Atomic Mass": "110.9051085(38)" }, { "Atomic Symbol": "In", "Mass Number": "112", "Relative Atomic Mass": "111.9055377(46)" }, { "Atomic Symbol": "In", "Mass Number": "113", "Isotopic Composition": "0.0429(5)", "Relative Atomic Mass": "112.90406184(91)" }, { "Atomic Symbol": "In", "Mass Number": "114", "Relative Atomic Mass": "113.90491791(94)" }, { "Atomic Symbol": "In", "Mass Number": "115", "Isotopic Composition": "0.9571(5)", "Relative Atomic Mass": "114.903878776(12)" }, { "Atomic Symbol": "In", "Mass Number": "116", "Relative Atomic Mass": "115.90525999(24)" }, { "Atomic Symbol": "In", "Mass Number": "117", "Relative Atomic Mass": "116.9045157(52)" }, { "Atomic Symbol": "In", "Mass Number": "118", "Relative Atomic Mass": "117.9063566(83)" }, { "Atomic Symbol": "In", "Mass Number": "119", "Relative Atomic Mass": "118.9058507(78)" }, { "Atomic Symbol": "In", "Mass Number": "120", "Relative Atomic Mass": "119.907967(43)" }, { "Atomic Symbol": "In", "Mass Number": "121", "Relative Atomic Mass": "120.907851(29)" }, { "Atomic Symbol": "In", "Mass Number": "122", "Relative Atomic Mass": "121.910281(54)" }, { "Atomic Symbol": "In", "Mass Number": "123", "Relative Atomic Mass": "122.910434(21)" }, { "Atomic Symbol": "In", "Mass Number": "124", "Relative Atomic Mass": "123.913182(33)" }, { "Atomic Symbol": "In", "Mass Number": "125", "Relative Atomic Mass": "124.913605(29)" }, { "Atomic Symbol": "In", "Mass Number": "126", "Relative Atomic Mass": "125.916507(29)" }, { "Atomic Symbol": "In", "Mass Number": "127", "Relative Atomic Mass": "126.917446(23)" }, { "Atomic Symbol": "In", "Mass Number": "128", "Relative Atomic Mass": "127.92040(16)" }, { "Atomic Symbol": "In", "Mass Number": "129", "Relative Atomic Mass": "128.9218053(29)" }, { "Atomic Symbol": "In", "Mass Number": "130", "Relative Atomic Mass": "129.924977(41)" }, { "Atomic Symbol": "In", "Mass Number": "131", "Relative Atomic Mass": "130.9269715(29)" }, { "Atomic Symbol": "In", "Mass Number": "132", "Relative Atomic Mass": "131.933001(64)" }, { "Atomic Symbol": "In", "Mass Number": "133", "Relative Atomic Mass": "132.93831(21#)" }, { "Atomic Symbol": "In", "Mass Number": "134", "Relative Atomic Mass": "133.94454(32#)" }, { "Atomic Symbol": "In", "Mass Number": "135", "Relative Atomic Mass": "134.95005(43#)" } ], "Standard Atomic Weight": "114.818(1)" }, { "Atomic Symbol": "Sn", "Atomic Number": "50", "isotopes": [ { "Atomic Symbol": "Sn", "Mass Number": "99", "Relative Atomic Mass": "98.94853(54#)" }, { "Atomic Symbol": "Sn", "Mass Number": "100", "Relative Atomic Mass": "99.93850(32)" }, { "Atomic Symbol": "Sn", "Mass Number": "101", "Relative Atomic Mass": "100.93526(32)" }, { "Atomic Symbol": "Sn", "Mass Number": "102", "Relative Atomic Mass": "101.93029(11)" }, { "Atomic Symbol": "Sn", "Mass Number": "103", "Relative Atomic Mass": "102.928105(76)" }, { "Atomic Symbol": "Sn", "Mass Number": "104", "Relative Atomic Mass": "103.9231052(62)" }, { "Atomic Symbol": "Sn", "Mass Number": "105", "Relative Atomic Mass": "104.9212684(43)" }, { "Atomic Symbol": "Sn", "Mass Number": "106", "Relative Atomic Mass": "105.9169574(55)" }, { "Atomic Symbol": "Sn", "Mass Number": "107", "Relative Atomic Mass": "106.9157137(57)" }, { "Atomic Symbol": "Sn", "Mass Number": "108", "Relative Atomic Mass": "107.9118943(58)" }, { "Atomic Symbol": "Sn", "Mass Number": "109", "Relative Atomic Mass": "108.9112921(85)" }, { "Atomic Symbol": "Sn", "Mass Number": "110", "Relative Atomic Mass": "109.907845(15)" }, { "Atomic Symbol": "Sn", "Mass Number": "111", "Relative Atomic Mass": "110.9077401(58)" }, { "Atomic Symbol": "Sn", "Mass Number": "112", "Isotopic Composition": "0.0097(1)", "Relative Atomic Mass": "111.90482387(61)" }, { "Atomic Symbol": "Sn", "Mass Number": "113", "Relative Atomic Mass": "112.9051757(18)" }, { "Atomic Symbol": "Sn", "Mass Number": "114", "Isotopic Composition": "0.0066(1)", "Relative Atomic Mass": "113.9027827(10)" }, { "Atomic Symbol": "Sn", "Mass Number": "115", "Isotopic Composition": "0.0034(1)", "Relative Atomic Mass": "114.903344699(16)" }, { "Atomic Symbol": "Sn", "Mass Number": "116", "Isotopic Composition": "0.1454(9)", "Relative Atomic Mass": "115.90174280(10)" }, { "Atomic Symbol": "Sn", "Mass Number": "117", "Isotopic Composition": "0.0768(7)", "Relative Atomic Mass": "116.90295398(52)" }, { "Atomic Symbol": "Sn", "Mass Number": "118", "Isotopic Composition": "0.2422(9)", "Relative Atomic Mass": "117.90160657(54)" }, { "Atomic Symbol": "Sn", "Mass Number": "119", "Isotopic Composition": "0.0859(4)", "Relative Atomic Mass": "118.90331117(78)" }, { "Atomic Symbol": "Sn", "Mass Number": "120", "Isotopic Composition": "0.3258(9)", "Relative Atomic Mass": "119.90220163(97)" }, { "Atomic Symbol": "Sn", "Mass Number": "121", "Relative Atomic Mass": "120.9042426(10)" }, { "Atomic Symbol": "Sn", "Mass Number": "122", "Isotopic Composition": "0.0463(3)", "Relative Atomic Mass": "121.9034438(26)" }, { "Atomic Symbol": "Sn", "Mass Number": "123", "Relative Atomic Mass": "122.9057252(26)" }, { "Atomic Symbol": "Sn", "Mass Number": "124", "Isotopic Composition": "0.0579(5)", "Relative Atomic Mass": "123.9052766(11)" }, { "Atomic Symbol": "Sn", "Mass Number": "125", "Relative Atomic Mass": "124.9077864(11)" }, { "Atomic Symbol": "Sn", "Mass Number": "126", "Relative Atomic Mass": "125.907659(11)" }, { "Atomic Symbol": "Sn", "Mass Number": "127", "Relative Atomic Mass": "126.910390(11)" }, { "Atomic Symbol": "Sn", "Mass Number": "128", "Relative Atomic Mass": "127.910507(19)" }, { "Atomic Symbol": "Sn", "Mass Number": "129", "Relative Atomic Mass": "128.913465(21)" }, { "Atomic Symbol": "Sn", "Mass Number": "130", "Relative Atomic Mass": "129.9139738(23)" }, { "Atomic Symbol": "Sn", "Mass Number": "131", "Relative Atomic Mass": "130.9170450(65)" }, { "Atomic Symbol": "Sn", "Mass Number": "132", "Relative Atomic Mass": "131.9178267(31)" }, { "Atomic Symbol": "Sn", "Mass Number": "133", "Relative Atomic Mass": "132.9239134(26)" }, { "Atomic Symbol": "Sn", "Mass Number": "134", "Relative Atomic Mass": "133.9286821(35)" }, { "Atomic Symbol": "Sn", "Mass Number": "135", "Relative Atomic Mass": "134.9349086(33)" }, { "Atomic Symbol": "Sn", "Mass Number": "136", "Relative Atomic Mass": "135.93999(43#)" }, { "Atomic Symbol": "Sn", "Mass Number": "137", "Relative Atomic Mass": "136.94655(54#)" }, { "Atomic Symbol": "Sn", "Mass Number": "138", "Relative Atomic Mass": "137.95184(64#)" } ], "Notes": "g", "Standard Atomic Weight": "118.710(7)" }, { "Atomic Symbol": "Sb", "Atomic Number": "51", "isotopes": [ { "Atomic Symbol": "Sb", "Mass Number": "103", "Relative Atomic Mass": "102.93969(32#)" }, { "Atomic Symbol": "Sb", "Mass Number": "104", "Relative Atomic Mass": "103.93648(13)" }, { "Atomic Symbol": "Sb", "Mass Number": "105", "Relative Atomic Mass": "104.931276(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "106", "Relative Atomic Mass": "105.9286380(80)" }, { "Atomic Symbol": "Sb", "Mass Number": "107", "Relative Atomic Mass": "106.9241506(45)" }, { "Atomic Symbol": "Sb", "Mass Number": "108", "Relative Atomic Mass": "107.9222267(59)" }, { "Atomic Symbol": "Sb", "Mass Number": "109", "Relative Atomic Mass": "108.9181411(57)" }, { "Atomic Symbol": "Sb", "Mass Number": "110", "Relative Atomic Mass": "109.9168543(64)" }, { "Atomic Symbol": "Sb", "Mass Number": "111", "Relative Atomic Mass": "110.9132182(95)" }, { "Atomic Symbol": "Sb", "Mass Number": "112", "Relative Atomic Mass": "111.912400(19)" }, { "Atomic Symbol": "Sb", "Mass Number": "113", "Relative Atomic Mass": "112.909375(18)" }, { "Atomic Symbol": "Sb", "Mass Number": "114", "Relative Atomic Mass": "113.909290(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "115", "Relative Atomic Mass": "114.906598(17)" }, { "Atomic Symbol": "Sb", "Mass Number": "116", "Relative Atomic Mass": "115.9067931(55)" }, { "Atomic Symbol": "Sb", "Mass Number": "117", "Relative Atomic Mass": "116.9048415(91)" }, { "Atomic Symbol": "Sb", "Mass Number": "118", "Relative Atomic Mass": "117.9055321(32)" }, { "Atomic Symbol": "Sb", "Mass Number": "119", "Relative Atomic Mass": "118.9039455(83)" }, { "Atomic Symbol": "Sb", "Mass Number": "120", "Relative Atomic Mass": "119.9050794(77)" }, { "Atomic Symbol": "Sb", "Mass Number": "121", "Isotopic Composition": "0.5721(5)", "Relative Atomic Mass": "120.9038120(30)" }, { "Atomic Symbol": "Sb", "Mass Number": "122", "Relative Atomic Mass": "121.9051699(30)" }, { "Atomic Symbol": "Sb", "Mass Number": "123", "Isotopic Composition": "0.4279(5)", "Relative Atomic Mass": "122.9042132(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "124", "Relative Atomic Mass": "123.9059350(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "125", "Relative Atomic Mass": "124.9052530(28)" }, { "Atomic Symbol": "Sb", "Mass Number": "126", "Relative Atomic Mass": "125.907253(34)" }, { "Atomic Symbol": "Sb", "Mass Number": "127", "Relative Atomic Mass": "126.9069243(55)" }, { "Atomic Symbol": "Sb", "Mass Number": "128", "Relative Atomic Mass": "127.909146(21)" }, { "Atomic Symbol": "Sb", "Mass Number": "129", "Relative Atomic Mass": "128.909147(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "130", "Relative Atomic Mass": "129.911662(15)" }, { "Atomic Symbol": "Sb", "Mass Number": "131", "Relative Atomic Mass": "130.9119888(23)" }, { "Atomic Symbol": "Sb", "Mass Number": "132", "Relative Atomic Mass": "131.9145077(29)" }, { "Atomic Symbol": "Sb", "Mass Number": "133", "Relative Atomic Mass": "132.9152732(34)" }, { "Atomic Symbol": "Sb", "Mass Number": "134", "Relative Atomic Mass": "133.9205357(18)" }, { "Atomic Symbol": "Sb", "Mass Number": "135", "Relative Atomic Mass": "134.9251851(31)" }, { "Atomic Symbol": "Sb", "Mass Number": "136", "Relative Atomic Mass": "135.9307459(68)" }, { "Atomic Symbol": "Sb", "Mass Number": "137", "Relative Atomic Mass": "136.93555(32)" }, { "Atomic Symbol": "Sb", "Mass Number": "138", "Relative Atomic Mass": "137.94145(32#)" }, { "Atomic Symbol": "Sb", "Mass Number": "139", "Relative Atomic Mass": "138.94655(43#)" }, { "Atomic Symbol": "Sb", "Mass Number": "140", "Relative Atomic Mass": "139.95283(64#)" } ], "Notes": "g", "Standard Atomic Weight": "121.760(1)" }, { "Atomic Symbol": "Te", "Atomic Number": "52", "isotopes": [ { "Atomic Symbol": "Te", "Mass Number": "105", "Relative Atomic Mass": "104.94330(32)" }, { "Atomic Symbol": "Te", "Mass Number": "106", "Relative Atomic Mass": "105.93750(11)" }, { "Atomic Symbol": "Te", "Mass Number": "107", "Relative Atomic Mass": "106.935012(76)" }, { "Atomic Symbol": "Te", "Mass Number": "108", "Relative Atomic Mass": "107.9293805(58)" }, { "Atomic Symbol": "Te", "Mass Number": "109", "Relative Atomic Mass": "108.9273045(47)" }, { "Atomic Symbol": "Te", "Mass Number": "110", "Relative Atomic Mass": "109.9224581(71)" }, { "Atomic Symbol": "Te", "Mass Number": "111", "Relative Atomic Mass": "110.9210006(69)" }, { "Atomic Symbol": "Te", "Mass Number": "112", "Relative Atomic Mass": "111.9167279(90)" }, { "Atomic Symbol": "Te", "Mass Number": "113", "Relative Atomic Mass": "112.915891(30)" }, { "Atomic Symbol": "Te", "Mass Number": "114", "Relative Atomic Mass": "113.912089(30)" }, { "Atomic Symbol": "Te", "Mass Number": "115", "Relative Atomic Mass": "114.911902(30)" }, { "Atomic Symbol": "Te", "Mass Number": "116", "Relative Atomic Mass": "115.908460(30)" }, { "Atomic Symbol": "Te", "Mass Number": "117", "Relative Atomic Mass": "116.908646(14)" }, { "Atomic Symbol": "Te", "Mass Number": "118", "Relative Atomic Mass": "117.905854(20)" }, { "Atomic Symbol": "Te", "Mass Number": "119", "Relative Atomic Mass": "118.9064071(85)" }, { "Atomic Symbol": "Te", "Mass Number": "120", "Isotopic Composition": "0.0009(1)", "Relative Atomic Mass": "119.9040593(33)" }, { "Atomic Symbol": "Te", "Mass Number": "121", "Relative Atomic Mass": "120.904944(28)" }, { "Atomic Symbol": "Te", "Mass Number": "122", "Isotopic Composition": "0.0255(12)", "Relative Atomic Mass": "121.9030435(16)" }, { "Atomic Symbol": "Te", "Mass Number": "123", "Isotopic Composition": "0.0089(3)", "Relative Atomic Mass": "122.9042698(16)" }, { "Atomic Symbol": "Te", "Mass Number": "124", "Isotopic Composition": "0.0474(14)", "Relative Atomic Mass": "123.9028171(16)" }, { "Atomic Symbol": "Te", "Mass Number": "125", "Isotopic Composition": "0.0707(15)", "Relative Atomic Mass": "124.9044299(16)" }, { "Atomic Symbol": "Te", "Mass Number": "126", "Isotopic Composition": "0.1884(25)", "Relative Atomic Mass": "125.9033109(16)" }, { "Atomic Symbol": "Te", "Mass Number": "127", "Relative Atomic Mass": "126.9052257(16)" }, { "Atomic Symbol": "Te", "Mass Number": "128", "Isotopic Composition": "0.3174(8)", "Relative Atomic Mass": "127.90446128(93)" }, { "Atomic Symbol": "Te", "Mass Number": "129", "Relative Atomic Mass": "128.90659646(93)" }, { "Atomic Symbol": "Te", "Mass Number": "130", "Isotopic Composition": "0.3408(62)", "Relative Atomic Mass": "129.906222748(12)" }, { "Atomic Symbol": "Te", "Mass Number": "131", "Relative Atomic Mass": "130.908522213(65)" }, { "Atomic Symbol": "Te", "Mass Number": "132", "Relative Atomic Mass": "131.9085467(37)" }, { "Atomic Symbol": "Te", "Mass Number": "133", "Relative Atomic Mass": "132.9109688(39)" }, { "Atomic Symbol": "Te", "Mass Number": "134", "Relative Atomic Mass": "133.9113940(30)" }, { "Atomic Symbol": "Te", "Mass Number": "135", "Relative Atomic Mass": "134.9165557(29)" }, { "Atomic Symbol": "Te", "Mass Number": "136", "Relative Atomic Mass": "135.9201006(26)" }, { "Atomic Symbol": "Te", "Mass Number": "137", "Relative Atomic Mass": "136.9255989(27)" }, { "Atomic Symbol": "Te", "Mass Number": "138", "Relative Atomic Mass": "137.9294722(47)" }, { "Atomic Symbol": "Te", "Mass Number": "139", "Relative Atomic Mass": "138.9353672(38)" }, { "Atomic Symbol": "Te", "Mass Number": "140", "Relative Atomic Mass": "139.939499(30)" }, { "Atomic Symbol": "Te", "Mass Number": "141", "Relative Atomic Mass": "140.94580(43#)" }, { "Atomic Symbol": "Te", "Mass Number": "142", "Relative Atomic Mass": "141.95022(54#)" }, { "Atomic Symbol": "Te", "Mass Number": "143", "Relative Atomic Mass": "142.95676(54#)" } ], "Notes": "g", "Standard Atomic Weight": "127.60(3)" }, { "Atomic Symbol": "I", "Atomic Number": "53", "isotopes": [ { "Atomic Symbol": "I", "Mass Number": "107", "Relative Atomic Mass": "106.94678(32#)" }, { "Atomic Symbol": "I", "Mass Number": "108", "Relative Atomic Mass": "107.94348(14)" }, { "Atomic Symbol": "I", "Mass Number": "109", "Relative Atomic Mass": "108.9380853(61)" }, { "Atomic Symbol": "I", "Mass Number": "110", "Relative Atomic Mass": "109.935089(54)" }, { "Atomic Symbol": "I", "Mass Number": "111", "Relative Atomic Mass": "110.9302692(51)" }, { "Atomic Symbol": "I", "Mass Number": "112", "Relative Atomic Mass": "111.928005(11)" }, { "Atomic Symbol": "I", "Mass Number": "113", "Relative Atomic Mass": "112.9236501(86)" }, { "Atomic Symbol": "I", "Mass Number": "114", "Relative Atomic Mass": "113.92185(32#)" }, { "Atomic Symbol": "I", "Mass Number": "115", "Relative Atomic Mass": "114.918048(31)" }, { "Atomic Symbol": "I", "Mass Number": "116", "Relative Atomic Mass": "115.91681(10)" }, { "Atomic Symbol": "I", "Mass Number": "117", "Relative Atomic Mass": "116.913648(28)" }, { "Atomic Symbol": "I", "Mass Number": "118", "Relative Atomic Mass": "117.913074(21)" }, { "Atomic Symbol": "I", "Mass Number": "119", "Relative Atomic Mass": "118.910074(30)" }, { "Atomic Symbol": "I", "Mass Number": "120", "Relative Atomic Mass": "119.910087(16)" }, { "Atomic Symbol": "I", "Mass Number": "121", "Relative Atomic Mass": "120.9074051(58)" }, { "Atomic Symbol": "I", "Mass Number": "122", "Relative Atomic Mass": "121.9075888(56)" }, { "Atomic Symbol": "I", "Mass Number": "123", "Relative Atomic Mass": "122.9055885(40)" }, { "Atomic Symbol": "I", "Mass Number": "124", "Relative Atomic Mass": "123.9062090(26)" }, { "Atomic Symbol": "I", "Mass Number": "125", "Relative Atomic Mass": "124.9046294(16)" }, { "Atomic Symbol": "I", "Mass Number": "126", "Relative Atomic Mass": "125.9056233(41)" }, { "Atomic Symbol": "I", "Mass Number": "127", "Isotopic Composition": "1", "Relative Atomic Mass": "126.9044719(39)" }, { "Atomic Symbol": "I", "Mass Number": "128", "Relative Atomic Mass": "127.9058086(39)" }, { "Atomic Symbol": "I", "Mass Number": "129", "Relative Atomic Mass": "128.9049837(34)" }, { "Atomic Symbol": "I", "Mass Number": "130", "Relative Atomic Mass": "129.9066702(34)" }, { "Atomic Symbol": "I", "Mass Number": "131", "Relative Atomic Mass": "130.90612630(69)" }, { "Atomic Symbol": "I", "Mass Number": "132", "Relative Atomic Mass": "131.9079935(44)" }, { "Atomic Symbol": "I", "Mass Number": "133", "Relative Atomic Mass": "132.9077970(50)" }, { "Atomic Symbol": "I", "Mass Number": "134", "Relative Atomic Mass": "133.9097588(59)" }, { "Atomic Symbol": "I", "Mass Number": "135", "Relative Atomic Mass": "134.9100488(58)" }, { "Atomic Symbol": "I", "Mass Number": "136", "Relative Atomic Mass": "135.914604(15)" }, { "Atomic Symbol": "I", "Mass Number": "137", "Relative Atomic Mass": "136.9180282(90)" }, { "Atomic Symbol": "I", "Mass Number": "138", "Relative Atomic Mass": "137.9227264(64)" }, { "Atomic Symbol": "I", "Mass Number": "139", "Relative Atomic Mass": "138.926506(31)" }, { "Atomic Symbol": "I", "Mass Number": "140", "Relative Atomic Mass": "139.93173(20)" }, { "Atomic Symbol": "I", "Mass Number": "141", "Relative Atomic Mass": "140.93569(21#)" }, { "Atomic Symbol": "I", "Mass Number": "142", "Relative Atomic Mass": "141.94120(40)" }, { "Atomic Symbol": "I", "Mass Number": "143", "Relative Atomic Mass": "142.94565(32#)" }, { "Atomic Symbol": "I", "Mass Number": "144", "Relative Atomic Mass": "143.95139(43#)" }, { "Atomic Symbol": "I", "Mass Number": "145", "Relative Atomic Mass": "144.95605(54#)" } ], "Standard Atomic Weight": "126.90447(3)" }, { "Atomic Symbol": "Xe", "Atomic Number": "54", "isotopes": [ { "Atomic Symbol": "Xe", "Mass Number": "109", "Relative Atomic Mass": "108.95043(32)" }, { "Atomic Symbol": "Xe", "Mass Number": "110", "Relative Atomic Mass": "109.94426(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "111", "Relative Atomic Mass": "110.941607(93)" }, { "Atomic Symbol": "Xe", "Mass Number": "112", "Relative Atomic Mass": "111.9355590(89)" }, { "Atomic Symbol": "Xe", "Mass Number": "113", "Relative Atomic Mass": "112.9332217(73)" }, { "Atomic Symbol": "Xe", "Mass Number": "114", "Relative Atomic Mass": "113.927980(12)" }, { "Atomic Symbol": "Xe", "Mass Number": "115", "Relative Atomic Mass": "114.926294(13)" }, { "Atomic Symbol": "Xe", "Mass Number": "116", "Relative Atomic Mass": "115.921581(14)" }, { "Atomic Symbol": "Xe", "Mass Number": "117", "Relative Atomic Mass": "116.920359(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "118", "Relative Atomic Mass": "117.916179(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "119", "Relative Atomic Mass": "118.915411(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "120", "Relative Atomic Mass": "119.911784(13)" }, { "Atomic Symbol": "Xe", "Mass Number": "121", "Relative Atomic Mass": "120.911453(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "122", "Relative Atomic Mass": "121.908368(12)" }, { "Atomic Symbol": "Xe", "Mass Number": "123", "Relative Atomic Mass": "122.908482(10)" }, { "Atomic Symbol": "Xe", "Mass Number": "124", "Isotopic Composition": "0.000952(3)", "Relative Atomic Mass": "123.9058920(19)" }, { "Atomic Symbol": "Xe", "Mass Number": "125", "Relative Atomic Mass": "124.9063944(20)" }, { "Atomic Symbol": "Xe", "Mass Number": "126", "Isotopic Composition": "0.000890(2)", "Relative Atomic Mass": "125.9042983(38)" }, { "Atomic Symbol": "Xe", "Mass Number": "127", "Relative Atomic Mass": "126.9051829(44)" }, { "Atomic Symbol": "Xe", "Mass Number": "128", "Isotopic Composition": "0.019102(8)", "Relative Atomic Mass": "127.9035310(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "129", "Isotopic Composition": "0.264006(82)", "Relative Atomic Mass": "128.9047808611(60)" }, { "Atomic Symbol": "Xe", "Mass Number": "130", "Isotopic Composition": "0.040710(13)", "Relative Atomic Mass": "129.903509349(10)" }, { "Atomic Symbol": "Xe", "Mass Number": "131", "Isotopic Composition": "0.212324(30)", "Relative Atomic Mass": "130.90508406(24)" }, { "Atomic Symbol": "Xe", "Mass Number": "132", "Isotopic Composition": "0.269086(33)", "Relative Atomic Mass": "131.9041550856(56)" }, { "Atomic Symbol": "Xe", "Mass Number": "133", "Relative Atomic Mass": "132.9059108(26)" }, { "Atomic Symbol": "Xe", "Mass Number": "134", "Isotopic Composition": "0.104357(21)", "Relative Atomic Mass": "133.90539466(90)" }, { "Atomic Symbol": "Xe", "Mass Number": "135", "Relative Atomic Mass": "134.9072278(45)" }, { "Atomic Symbol": "Xe", "Mass Number": "136", "Isotopic Composition": "0.088573(44)", "Relative Atomic Mass": "135.907214484(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "137", "Relative Atomic Mass": "136.91155778(11)" }, { "Atomic Symbol": "Xe", "Mass Number": "138", "Relative Atomic Mass": "137.9141463(30)" }, { "Atomic Symbol": "Xe", "Mass Number": "139", "Relative Atomic Mass": "138.9187922(23)" }, { "Atomic Symbol": "Xe", "Mass Number": "140", "Relative Atomic Mass": "139.9216458(25)" }, { "Atomic Symbol": "Xe", "Mass Number": "141", "Relative Atomic Mass": "140.9267872(31)" }, { "Atomic Symbol": "Xe", "Mass Number": "142", "Relative Atomic Mass": "141.9299731(29)" }, { "Atomic Symbol": "Xe", "Mass Number": "143", "Relative Atomic Mass": "142.9353696(50)" }, { "Atomic Symbol": "Xe", "Mass Number": "144", "Relative Atomic Mass": "143.9389451(57)" }, { "Atomic Symbol": "Xe", "Mass Number": "145", "Relative Atomic Mass": "144.944720(12)" }, { "Atomic Symbol": "Xe", "Mass Number": "146", "Relative Atomic Mass": "145.948518(26)" }, { "Atomic Symbol": "Xe", "Mass Number": "147", "Relative Atomic Mass": "146.95426(21#)" }, { "Atomic Symbol": "Xe", "Mass Number": "148", "Relative Atomic Mass": "147.95813(21#)" } ], "Notes": "g,m", "Standard Atomic Weight": "131.293(6)" }, { "Atomic Symbol": "Cs", "Atomic Number": "55", "isotopes": [ { "Atomic Symbol": "Cs", "Mass Number": "112", "Relative Atomic Mass": "111.950309(93)" }, { "Atomic Symbol": "Cs", "Mass Number": "113", "Relative Atomic Mass": "112.9444291(93)" }, { "Atomic Symbol": "Cs", "Mass Number": "114", "Relative Atomic Mass": "113.941296(76)" }, { "Atomic Symbol": "Cs", "Mass Number": "115", "Relative Atomic Mass": "114.93591(32#)" }, { "Atomic Symbol": "Cs", "Mass Number": "116", "Relative Atomic Mass": "115.93337(11#)" }, { "Atomic Symbol": "Cs", "Mass Number": "117", "Relative Atomic Mass": "116.928617(67)" }, { "Atomic Symbol": "Cs", "Mass Number": "118", "Relative Atomic Mass": "117.926560(14)" }, { "Atomic Symbol": "Cs", "Mass Number": "119", "Relative Atomic Mass": "118.922377(15)" }, { "Atomic Symbol": "Cs", "Mass Number": "120", "Relative Atomic Mass": "119.920677(11)" }, { "Atomic Symbol": "Cs", "Mass Number": "121", "Relative Atomic Mass": "120.917227(15)" }, { "Atomic Symbol": "Cs", "Mass Number": "122", "Relative Atomic Mass": "121.916108(36)" }, { "Atomic Symbol": "Cs", "Mass Number": "123", "Relative Atomic Mass": "122.912996(13)" }, { "Atomic Symbol": "Cs", "Mass Number": "124", "Relative Atomic Mass": "123.9122578(89)" }, { "Atomic Symbol": "Cs", "Mass Number": "125", "Relative Atomic Mass": "124.9097280(83)" }, { "Atomic Symbol": "Cs", "Mass Number": "126", "Relative Atomic Mass": "125.909446(11)" }, { "Atomic Symbol": "Cs", "Mass Number": "127", "Relative Atomic Mass": "126.9074174(60)" }, { "Atomic Symbol": "Cs", "Mass Number": "128", "Relative Atomic Mass": "127.9077487(58)" }, { "Atomic Symbol": "Cs", "Mass Number": "129", "Relative Atomic Mass": "128.9060657(49)" }, { "Atomic Symbol": "Cs", "Mass Number": "130", "Relative Atomic Mass": "129.9067093(90)" }, { "Atomic Symbol": "Cs", "Mass Number": "131", "Relative Atomic Mass": "130.9054649(53)" }, { "Atomic Symbol": "Cs", "Mass Number": "132", "Relative Atomic Mass": "131.9064339(21)" }, { "Atomic Symbol": "Cs", "Mass Number": "133", "Isotopic Composition": "1", "Relative Atomic Mass": "132.9054519610(80)" }, { "Atomic Symbol": "Cs", "Mass Number": "134", "Relative Atomic Mass": "133.906718503(17)" }, { "Atomic Symbol": "Cs", "Mass Number": "135", "Relative Atomic Mass": "134.9059770(11)" }, { "Atomic Symbol": "Cs", "Mass Number": "136", "Relative Atomic Mass": "135.9073114(20)" }, { "Atomic Symbol": "Cs", "Mass Number": "137", "Relative Atomic Mass": "136.90708923(36)" }, { "Atomic Symbol": "Cs", "Mass Number": "138", "Relative Atomic Mass": "137.9110171(98)" }, { "Atomic Symbol": "Cs", "Mass Number": "139", "Relative Atomic Mass": "138.9133638(34)" }, { "Atomic Symbol": "Cs", "Mass Number": "140", "Relative Atomic Mass": "139.9172831(88)" }, { "Atomic Symbol": "Cs", "Mass Number": "141", "Relative Atomic Mass": "140.9200455(98)" }, { "Atomic Symbol": "Cs", "Mass Number": "142", "Relative Atomic Mass": "141.9242960(79)" }, { "Atomic Symbol": "Cs", "Mass Number": "143", "Relative Atomic Mass": "142.927349(24)" }, { "Atomic Symbol": "Cs", "Mass Number": "144", "Relative Atomic Mass": "143.932076(27)" }, { "Atomic Symbol": "Cs", "Mass Number": "145", "Relative Atomic Mass": "144.935527(12)" }, { "Atomic Symbol": "Cs", "Mass Number": "146", "Relative Atomic Mass": "145.940344(42)" }, { "Atomic Symbol": "Cs", "Mass Number": "147", "Relative Atomic Mass": "146.944156(57)" }, { "Atomic Symbol": "Cs", "Mass Number": "148", "Relative Atomic Mass": "147.94923(62)" }, { "Atomic Symbol": "Cs", "Mass Number": "149", "Relative Atomic Mass": "148.95302(21#)" }, { "Atomic Symbol": "Cs", "Mass Number": "150", "Relative Atomic Mass": "149.95833(32#)" }, { "Atomic Symbol": "Cs", "Mass Number": "151", "Relative Atomic Mass": "150.96258(43#)" } ], "Standard Atomic Weight": "132.90545196(6)" }, { "Atomic Symbol": "Ba", "Atomic Number": "56", "isotopes": [ { "Atomic Symbol": "Ba", "Mass Number": "114", "Relative Atomic Mass": "113.95066(12)" }, { "Atomic Symbol": "Ba", "Mass Number": "115", "Relative Atomic Mass": "114.94737(54#)" }, { "Atomic Symbol": "Ba", "Mass Number": "116", "Relative Atomic Mass": "115.94128(32#)" }, { "Atomic Symbol": "Ba", "Mass Number": "117", "Relative Atomic Mass": "116.93814(21)" }, { "Atomic Symbol": "Ba", "Mass Number": "118", "Relative Atomic Mass": "117.93306(21#)" }, { "Atomic Symbol": "Ba", "Mass Number": "119", "Relative Atomic Mass": "118.93066(21)" }, { "Atomic Symbol": "Ba", "Mass Number": "120", "Relative Atomic Mass": "119.92605(32)" }, { "Atomic Symbol": "Ba", "Mass Number": "121", "Relative Atomic Mass": "120.92405(15)" }, { "Atomic Symbol": "Ba", "Mass Number": "122", "Relative Atomic Mass": "121.919904(30)" }, { "Atomic Symbol": "Ba", "Mass Number": "123", "Relative Atomic Mass": "122.918781(13)" }, { "Atomic Symbol": "Ba", "Mass Number": "124", "Relative Atomic Mass": "123.915094(13)" }, { "Atomic Symbol": "Ba", "Mass Number": "125", "Relative Atomic Mass": "124.914472(12)" }, { "Atomic Symbol": "Ba", "Mass Number": "126", "Relative Atomic Mass": "125.911250(13)" }, { "Atomic Symbol": "Ba", "Mass Number": "127", "Relative Atomic Mass": "126.911091(12)" }, { "Atomic Symbol": "Ba", "Mass Number": "128", "Relative Atomic Mass": "127.9083420(56)" }, { "Atomic Symbol": "Ba", "Mass Number": "129", "Relative Atomic Mass": "128.908681(11)" }, { "Atomic Symbol": "Ba", "Mass Number": "130", "Isotopic Composition": "0.00106(1)", "Relative Atomic Mass": "129.9063207(28)" }, { "Atomic Symbol": "Ba", "Mass Number": "131", "Relative Atomic Mass": "130.9069410(28)" }, { "Atomic Symbol": "Ba", "Mass Number": "132", "Isotopic Composition": "0.00101(1)", "Relative Atomic Mass": "131.9050611(11)" }, { "Atomic Symbol": "Ba", "Mass Number": "133", "Relative Atomic Mass": "132.9060074(11)" }, { "Atomic Symbol": "Ba", "Mass Number": "134", "Isotopic Composition": "0.02417(18)", "Relative Atomic Mass": "133.90450818(30)" }, { "Atomic Symbol": "Ba", "Mass Number": "135", "Isotopic Composition": "0.06592(12)", "Relative Atomic Mass": "134.90568838(29)" }, { "Atomic Symbol": "Ba", "Mass Number": "136", "Isotopic Composition": "0.07854(24)", "Relative Atomic Mass": "135.90457573(29)" }, { "Atomic Symbol": "Ba", "Mass Number": "137", "Isotopic Composition": "0.11232(24)", "Relative Atomic Mass": "136.90582714(30)" }, { "Atomic Symbol": "Ba", "Mass Number": "138", "Isotopic Composition": "0.71698(42)", "Relative Atomic Mass": "137.90524700(31)" }, { "Atomic Symbol": "Ba", "Mass Number": "139", "Relative Atomic Mass": "138.90884110(31)" }, { "Atomic Symbol": "Ba", "Mass Number": "140", "Relative Atomic Mass": "139.9106057(85)" }, { "Atomic Symbol": "Ba", "Mass Number": "141", "Relative Atomic Mass": "140.9144033(57)" }, { "Atomic Symbol": "Ba", "Mass Number": "142", "Relative Atomic Mass": "141.9164324(64)" }, { "Atomic Symbol": "Ba", "Mass Number": "143", "Relative Atomic Mass": "142.9206253(74)" }, { "Atomic Symbol": "Ba", "Mass Number": "144", "Relative Atomic Mass": "143.9229549(77)" }, { "Atomic Symbol": "Ba", "Mass Number": "145", "Relative Atomic Mass": "144.9275184(91)" }, { "Atomic Symbol": "Ba", "Mass Number": "146", "Relative Atomic Mass": "145.930284(22)" }, { "Atomic Symbol": "Ba", "Mass Number": "147", "Relative Atomic Mass": "146.935304(21)" }, { "Atomic Symbol": "Ba", "Mass Number": "148", "Relative Atomic Mass": "147.938171(68)" }, { "Atomic Symbol": "Ba", "Mass Number": "149", "Relative Atomic Mass": "148.94308(21#)" }, { "Atomic Symbol": "Ba", "Mass Number": "150", "Relative Atomic Mass": "149.94605(32#)" }, { "Atomic Symbol": "Ba", "Mass Number": "151", "Relative Atomic Mass": "150.95127(32#)" }, { "Atomic Symbol": "Ba", "Mass Number": "152", "Relative Atomic Mass": "151.95481(43#)" }, { "Atomic Symbol": "Ba", "Mass Number": "153", "Relative Atomic Mass": "152.96036(43#)" } ], "Standard Atomic Weight": "137.327(7)" }, { "Atomic Symbol": "La", "Atomic Number": "57", "isotopes": [ { "Atomic Symbol": "La", "Mass Number": "116", "Relative Atomic Mass": "115.95630(23#)" }, { "Atomic Symbol": "La", "Mass Number": "117", "Relative Atomic Mass": "116.94999(32#)" }, { "Atomic Symbol": "La", "Mass Number": "118", "Relative Atomic Mass": "117.94673(32#)" }, { "Atomic Symbol": "La", "Mass Number": "119", "Relative Atomic Mass": "118.94099(32#)" }, { "Atomic Symbol": "La", "Mass Number": "120", "Relative Atomic Mass": "119.93807(32#)" }, { "Atomic Symbol": "La", "Mass Number": "121", "Relative Atomic Mass": "120.93315(32#)" }, { "Atomic Symbol": "La", "Mass Number": "122", "Relative Atomic Mass": "121.93071(32#)" }, { "Atomic Symbol": "La", "Mass Number": "123", "Relative Atomic Mass": "122.92630(21#)" }, { "Atomic Symbol": "La", "Mass Number": "124", "Relative Atomic Mass": "123.924574(61)" }, { "Atomic Symbol": "La", "Mass Number": "125", "Relative Atomic Mass": "124.920816(28)" }, { "Atomic Symbol": "La", "Mass Number": "126", "Relative Atomic Mass": "125.919513(97)" }, { "Atomic Symbol": "La", "Mass Number": "127", "Relative Atomic Mass": "126.916375(28)" }, { "Atomic Symbol": "La", "Mass Number": "128", "Relative Atomic Mass": "127.915592(58)" }, { "Atomic Symbol": "La", "Mass Number": "129", "Relative Atomic Mass": "128.912694(23)" }, { "Atomic Symbol": "La", "Mass Number": "130", "Relative Atomic Mass": "129.912369(28)" }, { "Atomic Symbol": "La", "Mass Number": "131", "Relative Atomic Mass": "130.910070(30)" }, { "Atomic Symbol": "La", "Mass Number": "132", "Relative Atomic Mass": "131.910119(39)" }, { "Atomic Symbol": "La", "Mass Number": "133", "Relative Atomic Mass": "132.908218(30)" }, { "Atomic Symbol": "La", "Mass Number": "134", "Relative Atomic Mass": "133.908514(21)" }, { "Atomic Symbol": "La", "Mass Number": "135", "Relative Atomic Mass": "134.906984(10)" }, { "Atomic Symbol": "La", "Mass Number": "136", "Relative Atomic Mass": "135.907635(57)" }, { "Atomic Symbol": "La", "Mass Number": "137", "Relative Atomic Mass": "136.9064504(18)" }, { "Atomic Symbol": "La", "Mass Number": "138", "Isotopic Composition": "0.0008881(71)", "Relative Atomic Mass": "137.9071149(37)" }, { "Atomic Symbol": "La", "Mass Number": "139", "Isotopic Composition": "0.9991119(71)", "Relative Atomic Mass": "138.9063563(24)" }, { "Atomic Symbol": "La", "Mass Number": "140", "Relative Atomic Mass": "139.9094806(24)" }, { "Atomic Symbol": "La", "Mass Number": "141", "Relative Atomic Mass": "140.9109660(48)" }, { "Atomic Symbol": "La", "Mass Number": "142", "Relative Atomic Mass": "141.9140909(69)" }, { "Atomic Symbol": "La", "Mass Number": "143", "Relative Atomic Mass": "142.9160795(79)" }, { "Atomic Symbol": "La", "Mass Number": "144", "Relative Atomic Mass": "143.919646(14)" }, { "Atomic Symbol": "La", "Mass Number": "145", "Relative Atomic Mass": "144.921808(13)" }, { "Atomic Symbol": "La", "Mass Number": "146", "Relative Atomic Mass": "145.925875(36)" }, { "Atomic Symbol": "La", "Mass Number": "147", "Relative Atomic Mass": "146.928418(12)" }, { "Atomic Symbol": "La", "Mass Number": "148", "Relative Atomic Mass": "147.932679(21)" }, { "Atomic Symbol": "La", "Mass Number": "149", "Relative Atomic Mass": "148.93535(21)" }, { "Atomic Symbol": "La", "Mass Number": "150", "Relative Atomic Mass": "149.93947(21#)" }, { "Atomic Symbol": "La", "Mass Number": "151", "Relative Atomic Mass": "150.94232(21#)" }, { "Atomic Symbol": "La", "Mass Number": "152", "Relative Atomic Mass": "151.94682(32#)" }, { "Atomic Symbol": "La", "Mass Number": "153", "Relative Atomic Mass": "152.95036(32#)" }, { "Atomic Symbol": "La", "Mass Number": "154", "Relative Atomic Mass": "153.95517(43#)" }, { "Atomic Symbol": "La", "Mass Number": "155", "Relative Atomic Mass": "154.95901(43#)" } ], "Notes": "g", "Standard Atomic Weight": "138.90547(7)" }, { "Atomic Symbol": "Ce", "Atomic Number": "58", "isotopes": [ { "Atomic Symbol": "Ce", "Mass Number": "119", "Relative Atomic Mass": "118.95271(54#)" }, { "Atomic Symbol": "Ce", "Mass Number": "120", "Relative Atomic Mass": "119.94654(54#)" }, { "Atomic Symbol": "Ce", "Mass Number": "121", "Relative Atomic Mass": "120.94335(43#)" }, { "Atomic Symbol": "Ce", "Mass Number": "122", "Relative Atomic Mass": "121.93787(43#)" }, { "Atomic Symbol": "Ce", "Mass Number": "123", "Relative Atomic Mass": "122.93528(32#)" }, { "Atomic Symbol": "Ce", "Mass Number": "124", "Relative Atomic Mass": "123.93031(32#)" }, { "Atomic Symbol": "Ce", "Mass Number": "125", "Relative Atomic Mass": "124.92844(21#)" }, { "Atomic Symbol": "Ce", "Mass Number": "126", "Relative Atomic Mass": "125.923971(30)" }, { "Atomic Symbol": "Ce", "Mass Number": "127", "Relative Atomic Mass": "126.922727(31)" }, { "Atomic Symbol": "Ce", "Mass Number": "128", "Relative Atomic Mass": "127.918911(30)" }, { "Atomic Symbol": "Ce", "Mass Number": "129", "Relative Atomic Mass": "128.918102(30)" }, { "Atomic Symbol": "Ce", "Mass Number": "130", "Relative Atomic Mass": "129.914736(30)" }, { "Atomic Symbol": "Ce", "Mass Number": "131", "Relative Atomic Mass": "130.914429(35)" }, { "Atomic Symbol": "Ce", "Mass Number": "132", "Relative Atomic Mass": "131.911464(22)" }, { "Atomic Symbol": "Ce", "Mass Number": "133", "Relative Atomic Mass": "132.911520(18)" }, { "Atomic Symbol": "Ce", "Mass Number": "134", "Relative Atomic Mass": "133.908928(22)" }, { "Atomic Symbol": "Ce", "Mass Number": "135", "Relative Atomic Mass": "134.909161(11)" }, { "Atomic Symbol": "Ce", "Mass Number": "136", "Isotopic Composition": "0.00185(2)", "Relative Atomic Mass": "135.90712921(41)" }, { "Atomic Symbol": "Ce", "Mass Number": "137", "Relative Atomic Mass": "136.90776236(45)" }, { "Atomic Symbol": "Ce", "Mass Number": "138", "Isotopic Composition": "0.00251(2)", "Relative Atomic Mass": "137.905991(11)" }, { "Atomic Symbol": "Ce", "Mass Number": "139", "Relative Atomic Mass": "138.9066551(78)" }, { "Atomic Symbol": "Ce", "Mass Number": "140", "Isotopic Composition": "0.88450(51)", "Relative Atomic Mass": "139.9054431(23)" }, { "Atomic Symbol": "Ce", "Mass Number": "141", "Relative Atomic Mass": "140.9082807(23)" }, { "Atomic Symbol": "Ce", "Mass Number": "142", "Isotopic Composition": "0.11114(51)", "Relative Atomic Mass": "141.9092504(29)" }, { "Atomic Symbol": "Ce", "Mass Number": "143", "Relative Atomic Mass": "142.9123921(29)" }, { "Atomic Symbol": "Ce", "Mass Number": "144", "Relative Atomic Mass": "143.9136529(34)" }, { "Atomic Symbol": "Ce", "Mass Number": "145", "Relative Atomic Mass": "144.917265(36)" }, { "Atomic Symbol": "Ce", "Mass Number": "146", "Relative Atomic Mass": "145.918802(18)" }, { "Atomic Symbol": "Ce", "Mass Number": "147", "Relative Atomic Mass": "146.9226899(92)" }, { "Atomic Symbol": "Ce", "Mass Number": "148", "Relative Atomic Mass": "147.924424(12)" }, { "Atomic Symbol": "Ce", "Mass Number": "149", "Relative Atomic Mass": "148.928427(11)" }, { "Atomic Symbol": "Ce", "Mass Number": "150", "Relative Atomic Mass": "149.930384(13)" }, { "Atomic Symbol": "Ce", "Mass Number": "151", "Relative Atomic Mass": "150.934272(19)" }, { "Atomic Symbol": "Ce", "Mass Number": "152", "Relative Atomic Mass": "151.93660(21#)" }, { "Atomic Symbol": "Ce", "Mass Number": "153", "Relative Atomic Mass": "152.94093(21#)" }, { "Atomic Symbol": "Ce", "Mass Number": "154", "Relative Atomic Mass": "153.94380(32#)" }, { "Atomic Symbol": "Ce", "Mass Number": "155", "Relative Atomic Mass": "154.94855(43#)" }, { "Atomic Symbol": "Ce", "Mass Number": "156", "Relative Atomic Mass": "155.95183(43#)" }, { "Atomic Symbol": "Ce", "Mass Number": "157", "Relative Atomic Mass": "156.95705(54#)" } ], "Notes": "g", "Standard Atomic Weight": "140.116(1)" }, { "Atomic Symbol": "Pr", "Atomic Number": "59", "isotopes": [ { "Atomic Symbol": "Pr", "Mass Number": "121", "Relative Atomic Mass": "120.95532(54#)" }, { "Atomic Symbol": "Pr", "Mass Number": "122", "Relative Atomic Mass": "121.95175(54#)" }, { "Atomic Symbol": "Pr", "Mass Number": "123", "Relative Atomic Mass": "122.94596(43#)" }, { "Atomic Symbol": "Pr", "Mass Number": "124", "Relative Atomic Mass": "123.94294(43#)" }, { "Atomic Symbol": "Pr", "Mass Number": "125", "Relative Atomic Mass": "124.93770(32#)" }, { "Atomic Symbol": "Pr", "Mass Number": "126", "Relative Atomic Mass": "125.93524(21#)" }, { "Atomic Symbol": "Pr", "Mass Number": "127", "Relative Atomic Mass": "126.93071(21#)" }, { "Atomic Symbol": "Pr", "Mass Number": "128", "Relative Atomic Mass": "127.928791(32)" }, { "Atomic Symbol": "Pr", "Mass Number": "129", "Relative Atomic Mass": "128.925095(32)" }, { "Atomic Symbol": "Pr", "Mass Number": "130", "Relative Atomic Mass": "129.923590(69)" }, { "Atomic Symbol": "Pr", "Mass Number": "131", "Relative Atomic Mass": "130.920235(50)" }, { "Atomic Symbol": "Pr", "Mass Number": "132", "Relative Atomic Mass": "131.919255(61)" }, { "Atomic Symbol": "Pr", "Mass Number": "133", "Relative Atomic Mass": "132.916331(13)" }, { "Atomic Symbol": "Pr", "Mass Number": "134", "Relative Atomic Mass": "133.915697(22)" }, { "Atomic Symbol": "Pr", "Mass Number": "135", "Relative Atomic Mass": "134.913112(13)" }, { "Atomic Symbol": "Pr", "Mass Number": "136", "Relative Atomic Mass": "135.912677(12)" }, { "Atomic Symbol": "Pr", "Mass Number": "137", "Relative Atomic Mass": "136.9106792(87)" }, { "Atomic Symbol": "Pr", "Mass Number": "138", "Relative Atomic Mass": "137.910754(15)" }, { "Atomic Symbol": "Pr", "Mass Number": "139", "Relative Atomic Mass": "138.9089408(85)" }, { "Atomic Symbol": "Pr", "Mass Number": "140", "Relative Atomic Mass": "139.9090803(69)" }, { "Atomic Symbol": "Pr", "Mass Number": "141", "Isotopic Composition": "1", "Relative Atomic Mass": "140.9076576(23)" }, { "Atomic Symbol": "Pr", "Mass Number": "142", "Relative Atomic Mass": "141.9100496(23)" }, { "Atomic Symbol": "Pr", "Mass Number": "143", "Relative Atomic Mass": "142.9108228(24)" }, { "Atomic Symbol": "Pr", "Mass Number": "144", "Relative Atomic Mass": "143.9133109(32)" }, { "Atomic Symbol": "Pr", "Mass Number": "145", "Relative Atomic Mass": "144.9145182(78)" }, { "Atomic Symbol": "Pr", "Mass Number": "146", "Relative Atomic Mass": "145.917680(37)" }, { "Atomic Symbol": "Pr", "Mass Number": "147", "Relative Atomic Mass": "146.919008(17)" }, { "Atomic Symbol": "Pr", "Mass Number": "148", "Relative Atomic Mass": "147.922130(16)" }, { "Atomic Symbol": "Pr", "Mass Number": "149", "Relative Atomic Mass": "148.923736(11)" }, { "Atomic Symbol": "Pr", "Mass Number": "150", "Relative Atomic Mass": "149.9266765(97)" }, { "Atomic Symbol": "Pr", "Mass Number": "151", "Relative Atomic Mass": "150.928309(13)" }, { "Atomic Symbol": "Pr", "Mass Number": "152", "Relative Atomic Mass": "151.931553(20)" }, { "Atomic Symbol": "Pr", "Mass Number": "153", "Relative Atomic Mass": "152.933904(13)" }, { "Atomic Symbol": "Pr", "Mass Number": "154", "Relative Atomic Mass": "153.93753(16)" }, { "Atomic Symbol": "Pr", "Mass Number": "155", "Relative Atomic Mass": "154.940509(18)" }, { "Atomic Symbol": "Pr", "Mass Number": "156", "Relative Atomic Mass": "155.94464(32#)" }, { "Atomic Symbol": "Pr", "Mass Number": "157", "Relative Atomic Mass": "156.94789(43#)" }, { "Atomic Symbol": "Pr", "Mass Number": "158", "Relative Atomic Mass": "157.95241(43#)" }, { "Atomic Symbol": "Pr", "Mass Number": "159", "Relative Atomic Mass": "158.95589(54#)" } ], "Standard Atomic Weight": "140.90766(2)" }, { "Atomic Symbol": "Nd", "Atomic Number": "60", "isotopes": [ { "Atomic Symbol": "Nd", "Mass Number": "124", "Relative Atomic Mass": "123.95220(54#)" }, { "Atomic Symbol": "Nd", "Mass Number": "125", "Relative Atomic Mass": "124.94890(43#)" }, { "Atomic Symbol": "Nd", "Mass Number": "126", "Relative Atomic Mass": "125.94311(32#)" }, { "Atomic Symbol": "Nd", "Mass Number": "127", "Relative Atomic Mass": "126.94038(32#)" }, { "Atomic Symbol": "Nd", "Mass Number": "128", "Relative Atomic Mass": "127.93525(21#)" }, { "Atomic Symbol": "Nd", "Mass Number": "129", "Relative Atomic Mass": "128.93310(22#)" }, { "Atomic Symbol": "Nd", "Mass Number": "130", "Relative Atomic Mass": "129.928506(30)" }, { "Atomic Symbol": "Nd", "Mass Number": "131", "Relative Atomic Mass": "130.927248(30)" }, { "Atomic Symbol": "Nd", "Mass Number": "132", "Relative Atomic Mass": "131.923321(26)" }, { "Atomic Symbol": "Nd", "Mass Number": "133", "Relative Atomic Mass": "132.922348(50)" }, { "Atomic Symbol": "Nd", "Mass Number": "134", "Relative Atomic Mass": "133.918790(13)" }, { "Atomic Symbol": "Nd", "Mass Number": "135", "Relative Atomic Mass": "134.918181(21)" }, { "Atomic Symbol": "Nd", "Mass Number": "136", "Relative Atomic Mass": "135.914976(13)" }, { "Atomic Symbol": "Nd", "Mass Number": "137", "Relative Atomic Mass": "136.914562(13)" }, { "Atomic Symbol": "Nd", "Mass Number": "138", "Relative Atomic Mass": "137.911950(12)" }, { "Atomic Symbol": "Nd", "Mass Number": "139", "Relative Atomic Mass": "138.911954(30)" }, { "Atomic Symbol": "Nd", "Mass Number": "140", "Relative Atomic Mass": "139.909550(28)" }, { "Atomic Symbol": "Nd", "Mass Number": "141", "Relative Atomic Mass": "140.9096147(38)" }, { "Atomic Symbol": "Nd", "Mass Number": "142", "Isotopic Composition": "0.27152(40)", "Relative Atomic Mass": "141.9077290(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "143", "Isotopic Composition": "0.12174(26)", "Relative Atomic Mass": "142.9098200(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "144", "Isotopic Composition": "0.23798(19)", "Relative Atomic Mass": "143.9100930(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "145", "Isotopic Composition": "0.08293(12)", "Relative Atomic Mass": "144.9125793(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "146", "Isotopic Composition": "0.17189(32)", "Relative Atomic Mass": "145.9131226(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "147", "Relative Atomic Mass": "146.9161061(20)" }, { "Atomic Symbol": "Nd", "Mass Number": "148", "Isotopic Composition": "0.05756(21)", "Relative Atomic Mass": "147.9168993(26)" }, { "Atomic Symbol": "Nd", "Mass Number": "149", "Relative Atomic Mass": "148.9201548(26)" }, { "Atomic Symbol": "Nd", "Mass Number": "150", "Isotopic Composition": "0.05638(28)", "Relative Atomic Mass": "149.9209022(18)" }, { "Atomic Symbol": "Nd", "Mass Number": "151", "Relative Atomic Mass": "150.9238403(18)" }, { "Atomic Symbol": "Nd", "Mass Number": "152", "Relative Atomic Mass": "151.924692(26)" }, { "Atomic Symbol": "Nd", "Mass Number": "153", "Relative Atomic Mass": "152.9277180(29)" }, { "Atomic Symbol": "Nd", "Mass Number": "154", "Relative Atomic Mass": "153.92948(12)" }, { "Atomic Symbol": "Nd", "Mass Number": "155", "Relative Atomic Mass": "154.9331357(98)" }, { "Atomic Symbol": "Nd", "Mass Number": "156", "Relative Atomic Mass": "155.93508(21)" }, { "Atomic Symbol": "Nd", "Mass Number": "157", "Relative Atomic Mass": "156.939386(27)" }, { "Atomic Symbol": "Nd", "Mass Number": "158", "Relative Atomic Mass": "157.94197(32#)" }, { "Atomic Symbol": "Nd", "Mass Number": "159", "Relative Atomic Mass": "158.94653(43#)" }, { "Atomic Symbol": "Nd", "Mass Number": "160", "Relative Atomic Mass": "159.94940(43#)" }, { "Atomic Symbol": "Nd", "Mass Number": "161", "Relative Atomic Mass": "160.95428(54#)" } ], "Notes": "g", "Standard Atomic Weight": "144.242(3)" }, { "Atomic Symbol": "Pm", "Atomic Number": "61", "isotopes": [ { "Atomic Symbol": "Pm", "Mass Number": "126", "Relative Atomic Mass": "125.95792(54#)" }, { "Atomic Symbol": "Pm", "Mass Number": "127", "Relative Atomic Mass": "126.95192(43#)" }, { "Atomic Symbol": "Pm", "Mass Number": "128", "Relative Atomic Mass": "127.94870(32#)" }, { "Atomic Symbol": "Pm", "Mass Number": "129", "Relative Atomic Mass": "128.94323(32#)" }, { "Atomic Symbol": "Pm", "Mass Number": "130", "Relative Atomic Mass": "129.94053(21#)" }, { "Atomic Symbol": "Pm", "Mass Number": "131", "Relative Atomic Mass": "130.93567(21#)" }, { "Atomic Symbol": "Pm", "Mass Number": "132", "Relative Atomic Mass": "131.93384(16#)" }, { "Atomic Symbol": "Pm", "Mass Number": "133", "Relative Atomic Mass": "132.929782(54)" }, { "Atomic Symbol": "Pm", "Mass Number": "134", "Relative Atomic Mass": "133.928353(62)" }, { "Atomic Symbol": "Pm", "Mass Number": "135", "Relative Atomic Mass": "134.924823(70)" }, { "Atomic Symbol": "Pm", "Mass Number": "136", "Relative Atomic Mass": "135.923585(77)" }, { "Atomic Symbol": "Pm", "Mass Number": "137", "Relative Atomic Mass": "136.920480(14)" }, { "Atomic Symbol": "Pm", "Mass Number": "138", "Relative Atomic Mass": "137.919548(30)" }, { "Atomic Symbol": "Pm", "Mass Number": "139", "Relative Atomic Mass": "138.916800(15)" }, { "Atomic Symbol": "Pm", "Mass Number": "140", "Relative Atomic Mass": "139.916040(38)" }, { "Atomic Symbol": "Pm", "Mass Number": "141", "Relative Atomic Mass": "140.913555(15)" }, { "Atomic Symbol": "Pm", "Mass Number": "142", "Relative Atomic Mass": "141.912890(25)" }, { "Atomic Symbol": "Pm", "Mass Number": "143", "Relative Atomic Mass": "142.9109383(34)" }, { "Atomic Symbol": "Pm", "Mass Number": "144", "Relative Atomic Mass": "143.9125964(34)" }, { "Atomic Symbol": "Pm", "Mass Number": "145", "Relative Atomic Mass": "144.9127559(33)" }, { "Atomic Symbol": "Pm", "Mass Number": "146", "Relative Atomic Mass": "145.9147024(48)" }, { "Atomic Symbol": "Pm", "Mass Number": "147", "Relative Atomic Mass": "146.9151450(19)" }, { "Atomic Symbol": "Pm", "Mass Number": "148", "Relative Atomic Mass": "147.9174819(63)" }, { "Atomic Symbol": "Pm", "Mass Number": "149", "Relative Atomic Mass": "148.9183423(27)" }, { "Atomic Symbol": "Pm", "Mass Number": "150", "Relative Atomic Mass": "149.920991(22)" }, { "Atomic Symbol": "Pm", "Mass Number": "151", "Relative Atomic Mass": "150.9212175(51)" }, { "Atomic Symbol": "Pm", "Mass Number": "152", "Relative Atomic Mass": "151.923506(28)" }, { "Atomic Symbol": "Pm", "Mass Number": "153", "Relative Atomic Mass": "152.9241567(97)" }, { "Atomic Symbol": "Pm", "Mass Number": "154", "Relative Atomic Mass": "153.926472(48)" }, { "Atomic Symbol": "Pm", "Mass Number": "155", "Relative Atomic Mass": "154.9281370(51)" }, { "Atomic Symbol": "Pm", "Mass Number": "156", "Relative Atomic Mass": "155.9311175(39)" }, { "Atomic Symbol": "Pm", "Mass Number": "157", "Relative Atomic Mass": "156.9331214(75)" }, { "Atomic Symbol": "Pm", "Mass Number": "158", "Relative Atomic Mass": "157.936565(14)" }, { "Atomic Symbol": "Pm", "Mass Number": "159", "Relative Atomic Mass": "158.939287(11)" }, { "Atomic Symbol": "Pm", "Mass Number": "160", "Relative Atomic Mass": "159.94310(32#)" }, { "Atomic Symbol": "Pm", "Mass Number": "161", "Relative Atomic Mass": "160.94607(32#)" }, { "Atomic Symbol": "Pm", "Mass Number": "162", "Relative Atomic Mass": "161.95022(43#)" }, { "Atomic Symbol": "Pm", "Mass Number": "163", "Relative Atomic Mass": "162.95357(54#)" } ], "Standard Atomic Weight": "[145]" }, { "Atomic Symbol": "Sm", "Atomic Number": "62", "isotopes": [ { "Atomic Symbol": "Sm", "Mass Number": "128", "Relative Atomic Mass": "127.95842(54#)" }, { "Atomic Symbol": "Sm", "Mass Number": "129", "Relative Atomic Mass": "128.95476(54#)" }, { "Atomic Symbol": "Sm", "Mass Number": "130", "Relative Atomic Mass": "129.94900(43#)" }, { "Atomic Symbol": "Sm", "Mass Number": "131", "Relative Atomic Mass": "130.94618(43#)" }, { "Atomic Symbol": "Sm", "Mass Number": "132", "Relative Atomic Mass": "131.94087(32#)" }, { "Atomic Symbol": "Sm", "Mass Number": "133", "Relative Atomic Mass": "132.93856(32#)" }, { "Atomic Symbol": "Sm", "Mass Number": "134", "Relative Atomic Mass": "133.93411(21#)" }, { "Atomic Symbol": "Sm", "Mass Number": "135", "Relative Atomic Mass": "134.93252(17)" }, { "Atomic Symbol": "Sm", "Mass Number": "136", "Relative Atomic Mass": "135.928276(13)" }, { "Atomic Symbol": "Sm", "Mass Number": "137", "Relative Atomic Mass": "136.926971(46)" }, { "Atomic Symbol": "Sm", "Mass Number": "138", "Relative Atomic Mass": "137.923244(13)" }, { "Atomic Symbol": "Sm", "Mass Number": "139", "Relative Atomic Mass": "138.922297(12)" }, { "Atomic Symbol": "Sm", "Mass Number": "140", "Relative Atomic Mass": "139.918995(13)" }, { "Atomic Symbol": "Sm", "Mass Number": "141", "Relative Atomic Mass": "140.9184816(92)" }, { "Atomic Symbol": "Sm", "Mass Number": "142", "Relative Atomic Mass": "141.9152044(36)" }, { "Atomic Symbol": "Sm", "Mass Number": "143", "Relative Atomic Mass": "142.9146353(33)" }, { "Atomic Symbol": "Sm", "Mass Number": "144", "Isotopic Composition": "0.0307(7)", "Relative Atomic Mass": "143.9120065(21)" }, { "Atomic Symbol": "Sm", "Mass Number": "145", "Relative Atomic Mass": "144.9134173(21)" }, { "Atomic Symbol": "Sm", "Mass Number": "146", "Relative Atomic Mass": "145.9130470(35)" }, { "Atomic Symbol": "Sm", "Mass Number": "147", "Isotopic Composition": "0.1499(18)", "Relative Atomic Mass": "146.9149044(19)" }, { "Atomic Symbol": "Sm", "Mass Number": "148", "Isotopic Composition": "0.1124(10)", "Relative Atomic Mass": "147.9148292(19)" }, { "Atomic Symbol": "Sm", "Mass Number": "149", "Isotopic Composition": "0.1382(7)", "Relative Atomic Mass": "148.9171921(18)" }, { "Atomic Symbol": "Sm", "Mass Number": "150", "Isotopic Composition": "0.0738(1)", "Relative Atomic Mass": "149.9172829(18)" }, { "Atomic Symbol": "Sm", "Mass Number": "151", "Relative Atomic Mass": "150.9199398(18)" }, { "Atomic Symbol": "Sm", "Mass Number": "152", "Isotopic Composition": "0.2675(16)", "Relative Atomic Mass": "151.9197397(18)" }, { "Atomic Symbol": "Sm", "Mass Number": "153", "Relative Atomic Mass": "152.9221047(18)" }, { "Atomic Symbol": "Sm", "Mass Number": "154", "Isotopic Composition": "0.2275(29)", "Relative Atomic Mass": "153.9222169(20)" }, { "Atomic Symbol": "Sm", "Mass Number": "155", "Relative Atomic Mass": "154.9246477(20)" }, { "Atomic Symbol": "Sm", "Mass Number": "156", "Relative Atomic Mass": "155.925536(10)" }, { "Atomic Symbol": "Sm", "Mass Number": "157", "Relative Atomic Mass": "156.9284187(48)" }, { "Atomic Symbol": "Sm", "Mass Number": "158", "Relative Atomic Mass": "157.9299510(53)" }, { "Atomic Symbol": "Sm", "Mass Number": "159", "Relative Atomic Mass": "158.9332172(64)" }, { "Atomic Symbol": "Sm", "Mass Number": "160", "Relative Atomic Mass": "159.9353353(64)" }, { "Atomic Symbol": "Sm", "Mass Number": "161", "Relative Atomic Mass": "160.9391602(73)" }, { "Atomic Symbol": "Sm", "Mass Number": "162", "Relative Atomic Mass": "161.94146(21#)" }, { "Atomic Symbol": "Sm", "Mass Number": "163", "Relative Atomic Mass": "162.94555(32#)" }, { "Atomic Symbol": "Sm", "Mass Number": "164", "Relative Atomic Mass": "163.94836(32#)" }, { "Atomic Symbol": "Sm", "Mass Number": "165", "Relative Atomic Mass": "164.95297(43#)" } ], "Notes": "g", "Standard Atomic Weight": "150.36(2)" }, { "Atomic Symbol": "Eu", "Atomic Number": "63", "isotopes": [ { "Atomic Symbol": "Eu", "Mass Number": "130", "Relative Atomic Mass": "129.96369(54#)" }, { "Atomic Symbol": "Eu", "Mass Number": "131", "Relative Atomic Mass": "130.95784(43#)" }, { "Atomic Symbol": "Eu", "Mass Number": "132", "Relative Atomic Mass": "131.95467(43#)" }, { "Atomic Symbol": "Eu", "Mass Number": "133", "Relative Atomic Mass": "132.94929(32#)" }, { "Atomic Symbol": "Eu", "Mass Number": "134", "Relative Atomic Mass": "133.94640(32#)" }, { "Atomic Symbol": "Eu", "Mass Number": "135", "Relative Atomic Mass": "134.94187(21#)" }, { "Atomic Symbol": "Eu", "Mass Number": "136", "Relative Atomic Mass": "135.93962(21#)" }, { "Atomic Symbol": "Eu", "Mass Number": "137", "Relative Atomic Mass": "136.93546(21#)" }, { "Atomic Symbol": "Eu", "Mass Number": "138", "Relative Atomic Mass": "137.933709(30)" }, { "Atomic Symbol": "Eu", "Mass Number": "139", "Relative Atomic Mass": "138.929792(14)" }, { "Atomic Symbol": "Eu", "Mass Number": "140", "Relative Atomic Mass": "139.928088(55)" }, { "Atomic Symbol": "Eu", "Mass Number": "141", "Relative Atomic Mass": "140.924932(14)" }, { "Atomic Symbol": "Eu", "Mass Number": "142", "Relative Atomic Mass": "141.923442(32)" }, { "Atomic Symbol": "Eu", "Mass Number": "143", "Relative Atomic Mass": "142.920299(12)" }, { "Atomic Symbol": "Eu", "Mass Number": "144", "Relative Atomic Mass": "143.918820(12)" }, { "Atomic Symbol": "Eu", "Mass Number": "145", "Relative Atomic Mass": "144.9162726(36)" }, { "Atomic Symbol": "Eu", "Mass Number": "146", "Relative Atomic Mass": "145.9172110(65)" }, { "Atomic Symbol": "Eu", "Mass Number": "147", "Relative Atomic Mass": "146.9167527(31)" }, { "Atomic Symbol": "Eu", "Mass Number": "148", "Relative Atomic Mass": "147.918089(11)" }, { "Atomic Symbol": "Eu", "Mass Number": "149", "Relative Atomic Mass": "148.9179378(44)" }, { "Atomic Symbol": "Eu", "Mass Number": "150", "Relative Atomic Mass": "149.9197077(68)" }, { "Atomic Symbol": "Eu", "Mass Number": "151", "Isotopic Composition": "0.4781(6)", "Relative Atomic Mass": "150.9198578(18)" }, { "Atomic Symbol": "Eu", "Mass Number": "152", "Relative Atomic Mass": "151.9217522(18)" }, { "Atomic Symbol": "Eu", "Mass Number": "153", "Isotopic Composition": "0.5219(6)", "Relative Atomic Mass": "152.9212380(18)" }, { "Atomic Symbol": "Eu", "Mass Number": "154", "Relative Atomic Mass": "153.9229870(19)" }, { "Atomic Symbol": "Eu", "Mass Number": "155", "Relative Atomic Mass": "154.9229011(19)" }, { "Atomic Symbol": "Eu", "Mass Number": "156", "Relative Atomic Mass": "155.9247605(59)" }, { "Atomic Symbol": "Eu", "Mass Number": "157", "Relative Atomic Mass": "156.9254334(46)" }, { "Atomic Symbol": "Eu", "Mass Number": "158", "Relative Atomic Mass": "157.927799(11)" }, { "Atomic Symbol": "Eu", "Mass Number": "159", "Relative Atomic Mass": "158.9291001(47)" }, { "Atomic Symbol": "Eu", "Mass Number": "160", "Relative Atomic Mass": "159.931851(10)" }, { "Atomic Symbol": "Eu", "Mass Number": "161", "Relative Atomic Mass": "160.933664(11)" }, { "Atomic Symbol": "Eu", "Mass Number": "162", "Relative Atomic Mass": "161.936989(65)" }, { "Atomic Symbol": "Eu", "Mass Number": "163", "Relative Atomic Mass": "162.939196(76)" }, { "Atomic Symbol": "Eu", "Mass Number": "164", "Relative Atomic Mass": "163.94274(22#)" }, { "Atomic Symbol": "Eu", "Mass Number": "165", "Relative Atomic Mass": "164.94559(35#)" }, { "Atomic Symbol": "Eu", "Mass Number": "166", "Relative Atomic Mass": "165.94962(32#)" }, { "Atomic Symbol": "Eu", "Mass Number": "167", "Relative Atomic Mass": "166.95289(43#)" } ], "Notes": "g", "Standard Atomic Weight": "151.964(1)" }, { "Atomic Symbol": "Gd", "Atomic Number": "64", "isotopes": [ { "Atomic Symbol": "Gd", "Mass Number": "133", "Relative Atomic Mass": "132.96133(54#)" }, { "Atomic Symbol": "Gd", "Mass Number": "134", "Relative Atomic Mass": "133.95566(43#)" }, { "Atomic Symbol": "Gd", "Mass Number": "135", "Relative Atomic Mass": "134.95245(43#)" }, { "Atomic Symbol": "Gd", "Mass Number": "136", "Relative Atomic Mass": "135.94730(32#)" }, { "Atomic Symbol": "Gd", "Mass Number": "137", "Relative Atomic Mass": "136.94502(32#)" }, { "Atomic Symbol": "Gd", "Mass Number": "138", "Relative Atomic Mass": "137.94025(21#)" }, { "Atomic Symbol": "Gd", "Mass Number": "139", "Relative Atomic Mass": "138.93813(21#)" }, { "Atomic Symbol": "Gd", "Mass Number": "140", "Relative Atomic Mass": "139.933674(30)" }, { "Atomic Symbol": "Gd", "Mass Number": "141", "Relative Atomic Mass": "140.932126(21)" }, { "Atomic Symbol": "Gd", "Mass Number": "142", "Relative Atomic Mass": "141.928116(30)" }, { "Atomic Symbol": "Gd", "Mass Number": "143", "Relative Atomic Mass": "142.92675(22)" }, { "Atomic Symbol": "Gd", "Mass Number": "144", "Relative Atomic Mass": "143.922963(30)" }, { "Atomic Symbol": "Gd", "Mass Number": "145", "Relative Atomic Mass": "144.921713(21)" }, { "Atomic Symbol": "Gd", "Mass Number": "146", "Relative Atomic Mass": "145.9183188(46)" }, { "Atomic Symbol": "Gd", "Mass Number": "147", "Relative Atomic Mass": "146.9191014(25)" }, { "Atomic Symbol": "Gd", "Mass Number": "148", "Relative Atomic Mass": "147.9181215(21)" }, { "Atomic Symbol": "Gd", "Mass Number": "149", "Relative Atomic Mass": "148.9193481(38)" }, { "Atomic Symbol": "Gd", "Mass Number": "150", "Relative Atomic Mass": "149.9186644(66)" }, { "Atomic Symbol": "Gd", "Mass Number": "151", "Relative Atomic Mass": "150.9203560(35)" }, { "Atomic Symbol": "Gd", "Mass Number": "152", "Isotopic Composition": "0.0020(1)", "Relative Atomic Mass": "151.9197995(18)" }, { "Atomic Symbol": "Gd", "Mass Number": "153", "Relative Atomic Mass": "152.9217580(18)" }, { "Atomic Symbol": "Gd", "Mass Number": "154", "Isotopic Composition": "0.0218(3)", "Relative Atomic Mass": "153.9208741(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "155", "Isotopic Composition": "0.1480(12)", "Relative Atomic Mass": "154.9226305(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "156", "Isotopic Composition": "0.2047(9)", "Relative Atomic Mass": "155.9221312(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "157", "Isotopic Composition": "0.1565(2)", "Relative Atomic Mass": "156.9239686(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "158", "Isotopic Composition": "0.2484(7)", "Relative Atomic Mass": "157.9241123(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "159", "Relative Atomic Mass": "158.9263970(17)" }, { "Atomic Symbol": "Gd", "Mass Number": "160", "Isotopic Composition": "0.2186(19)", "Relative Atomic Mass": "159.9270624(18)" }, { "Atomic Symbol": "Gd", "Mass Number": "161", "Relative Atomic Mass": "160.9296775(21)" }, { "Atomic Symbol": "Gd", "Mass Number": "162", "Relative Atomic Mass": "161.9309930(45)" }, { "Atomic Symbol": "Gd", "Mass Number": "163", "Relative Atomic Mass": "162.9341769(90)" }, { "Atomic Symbol": "Gd", "Mass Number": "164", "Relative Atomic Mass": "163.93583(21#)" }, { "Atomic Symbol": "Gd", "Mass Number": "165", "Relative Atomic Mass": "164.93936(32#)" }, { "Atomic Symbol": "Gd", "Mass Number": "166", "Relative Atomic Mass": "165.94146(64#)" }, { "Atomic Symbol": "Gd", "Mass Number": "167", "Relative Atomic Mass": "166.94545(43#)" }, { "Atomic Symbol": "Gd", "Mass Number": "168", "Relative Atomic Mass": "167.94808(43#)" }, { "Atomic Symbol": "Gd", "Mass Number": "169", "Relative Atomic Mass": "168.95260(54#)" } ], "Notes": "g", "Standard Atomic Weight": "157.25(3)" }, { "Atomic Symbol": "Tb", "Atomic Number": "65", "isotopes": [ { "Atomic Symbol": "Tb", "Mass Number": "135", "Relative Atomic Mass": "134.96476(43#)" }, { "Atomic Symbol": "Tb", "Mass Number": "136", "Relative Atomic Mass": "135.96129(54#)" }, { "Atomic Symbol": "Tb", "Mass Number": "137", "Relative Atomic Mass": "136.95602(54#)" }, { "Atomic Symbol": "Tb", "Mass Number": "138", "Relative Atomic Mass": "137.95312(32#)" }, { "Atomic Symbol": "Tb", "Mass Number": "139", "Relative Atomic Mass": "138.94833(32#)" }, { "Atomic Symbol": "Tb", "Mass Number": "140", "Relative Atomic Mass": "139.94581(86)" }, { "Atomic Symbol": "Tb", "Mass Number": "141", "Relative Atomic Mass": "140.94145(11)" }, { "Atomic Symbol": "Tb", "Mass Number": "142", "Relative Atomic Mass": "141.93928(75)" }, { "Atomic Symbol": "Tb", "Mass Number": "143", "Relative Atomic Mass": "142.935137(55)" }, { "Atomic Symbol": "Tb", "Mass Number": "144", "Relative Atomic Mass": "143.933045(30)" }, { "Atomic Symbol": "Tb", "Mass Number": "145", "Relative Atomic Mass": "144.92882(10)" }, { "Atomic Symbol": "Tb", "Mass Number": "146", "Relative Atomic Mass": "145.927253(48)" }, { "Atomic Symbol": "Tb", "Mass Number": "147", "Relative Atomic Mass": "146.9240548(87)" }, { "Atomic Symbol": "Tb", "Mass Number": "148", "Relative Atomic Mass": "147.924282(14)" }, { "Atomic Symbol": "Tb", "Mass Number": "149", "Relative Atomic Mass": "148.9232535(41)" }, { "Atomic Symbol": "Tb", "Mass Number": "150", "Relative Atomic Mass": "149.9236649(80)" }, { "Atomic Symbol": "Tb", "Mass Number": "151", "Relative Atomic Mass": "150.9231096(46)" }, { "Atomic Symbol": "Tb", "Mass Number": "152", "Relative Atomic Mass": "151.924083(43)" }, { "Atomic Symbol": "Tb", "Mass Number": "153", "Relative Atomic Mass": "152.9234424(44)" }, { "Atomic Symbol": "Tb", "Mass Number": "154", "Relative Atomic Mass": "153.924685(49)" }, { "Atomic Symbol": "Tb", "Mass Number": "155", "Relative Atomic Mass": "154.923511(11)" }, { "Atomic Symbol": "Tb", "Mass Number": "156", "Relative Atomic Mass": "155.9247552(43)" }, { "Atomic Symbol": "Tb", "Mass Number": "157", "Relative Atomic Mass": "156.9240330(18)" }, { "Atomic Symbol": "Tb", "Mass Number": "158", "Relative Atomic Mass": "157.9254209(20)" }, { "Atomic Symbol": "Tb", "Mass Number": "159", "Isotopic Composition": "1", "Relative Atomic Mass": "158.9253547(19)" }, { "Atomic Symbol": "Tb", "Mass Number": "160", "Relative Atomic Mass": "159.9271756(19)" }, { "Atomic Symbol": "Tb", "Mass Number": "161", "Relative Atomic Mass": "160.9275778(20)" }, { "Atomic Symbol": "Tb", "Mass Number": "162", "Relative Atomic Mass": "161.929495(39)" }, { "Atomic Symbol": "Tb", "Mass Number": "163", "Relative Atomic Mass": "162.9306547(47)" }, { "Atomic Symbol": "Tb", "Mass Number": "164", "Relative Atomic Mass": "163.93336(11)" }, { "Atomic Symbol": "Tb", "Mass Number": "165", "Relative Atomic Mass": "164.93498(21#)" }, { "Atomic Symbol": "Tb", "Mass Number": "166", "Relative Atomic Mass": "165.937860(75)" }, { "Atomic Symbol": "Tb", "Mass Number": "167", "Relative Atomic Mass": "166.93996(21#)" }, { "Atomic Symbol": "Tb", "Mass Number": "168", "Relative Atomic Mass": "167.94340(32#)" }, { "Atomic Symbol": "Tb", "Mass Number": "169", "Relative Atomic Mass": "168.94597(32#)" }, { "Atomic Symbol": "Tb", "Mass Number": "170", "Relative Atomic Mass": "169.94984(43#)" }, { "Atomic Symbol": "Tb", "Mass Number": "171", "Relative Atomic Mass": "170.95273(54#)" } ], "Standard Atomic Weight": "158.92535(2)" }, { "Atomic Symbol": "Dy", "Atomic Number": "66", "isotopes": [ { "Atomic Symbol": "Dy", "Mass Number": "138", "Relative Atomic Mass": "137.96250(43#)" }, { "Atomic Symbol": "Dy", "Mass Number": "139", "Relative Atomic Mass": "138.95959(54#)" }, { "Atomic Symbol": "Dy", "Mass Number": "140", "Relative Atomic Mass": "139.95402(54#)" }, { "Atomic Symbol": "Dy", "Mass Number": "141", "Relative Atomic Mass": "140.95128(32#)" }, { "Atomic Symbol": "Dy", "Mass Number": "142", "Relative Atomic Mass": "141.94619(78#)" }, { "Atomic Symbol": "Dy", "Mass Number": "143", "Relative Atomic Mass": "142.943994(14)" }, { "Atomic Symbol": "Dy", "Mass Number": "144", "Relative Atomic Mass": "143.9392695(77)" }, { "Atomic Symbol": "Dy", "Mass Number": "145", "Relative Atomic Mass": "144.9374740(70)" }, { "Atomic Symbol": "Dy", "Mass Number": "146", "Relative Atomic Mass": "145.9328445(72)" }, { "Atomic Symbol": "Dy", "Mass Number": "147", "Relative Atomic Mass": "146.9310827(95)" }, { "Atomic Symbol": "Dy", "Mass Number": "148", "Relative Atomic Mass": "147.927157(10)" }, { "Atomic Symbol": "Dy", "Mass Number": "149", "Relative Atomic Mass": "148.927322(10)" }, { "Atomic Symbol": "Dy", "Mass Number": "150", "Relative Atomic Mass": "149.9255933(48)" }, { "Atomic Symbol": "Dy", "Mass Number": "151", "Relative Atomic Mass": "150.9261916(38)" }, { "Atomic Symbol": "Dy", "Mass Number": "152", "Relative Atomic Mass": "151.9247253(51)" }, { "Atomic Symbol": "Dy", "Mass Number": "153", "Relative Atomic Mass": "152.9257724(45)" }, { "Atomic Symbol": "Dy", "Mass Number": "154", "Relative Atomic Mass": "153.9244293(80)" }, { "Atomic Symbol": "Dy", "Mass Number": "155", "Relative Atomic Mass": "154.925759(10)" }, { "Atomic Symbol": "Dy", "Mass Number": "156", "Isotopic Composition": "0.00056(3)", "Relative Atomic Mass": "155.9242847(17)" }, { "Atomic Symbol": "Dy", "Mass Number": "157", "Relative Atomic Mass": "156.9254707(57)" }, { "Atomic Symbol": "Dy", "Mass Number": "158", "Isotopic Composition": "0.00095(3)", "Relative Atomic Mass": "157.9244159(31)" }, { "Atomic Symbol": "Dy", "Mass Number": "159", "Relative Atomic Mass": "158.9257470(22)" }, { "Atomic Symbol": "Dy", "Mass Number": "160", "Isotopic Composition": "0.02329(18)", "Relative Atomic Mass": "159.9252046(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "161", "Isotopic Composition": "0.18889(42)", "Relative Atomic Mass": "160.9269405(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "162", "Isotopic Composition": "0.25475(36)", "Relative Atomic Mass": "161.9268056(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "163", "Isotopic Composition": "0.24896(42)", "Relative Atomic Mass": "162.9287383(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "164", "Isotopic Composition": "0.28260(54)", "Relative Atomic Mass": "163.9291819(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "165", "Relative Atomic Mass": "164.9317105(20)" }, { "Atomic Symbol": "Dy", "Mass Number": "166", "Relative Atomic Mass": "165.9328139(21)" }, { "Atomic Symbol": "Dy", "Mass Number": "167", "Relative Atomic Mass": "166.935661(65)" }, { "Atomic Symbol": "Dy", "Mass Number": "168", "Relative Atomic Mass": "167.93713(15)" }, { "Atomic Symbol": "Dy", "Mass Number": "169", "Relative Atomic Mass": "168.94031(32)" }, { "Atomic Symbol": "Dy", "Mass Number": "170", "Relative Atomic Mass": "169.94239(21#)" }, { "Atomic Symbol": "Dy", "Mass Number": "171", "Relative Atomic Mass": "170.94612(32#)" }, { "Atomic Symbol": "Dy", "Mass Number": "172", "Relative Atomic Mass": "171.94846(32#)" }, { "Atomic Symbol": "Dy", "Mass Number": "173", "Relative Atomic Mass": "172.95283(43#)" } ], "Notes": "g", "Standard Atomic Weight": "162.500(1)" }, { "Atomic Symbol": "Ho", "Atomic Number": "67", "isotopes": [ { "Atomic Symbol": "Ho", "Mass Number": "140", "Relative Atomic Mass": "139.96859(54#)" }, { "Atomic Symbol": "Ho", "Mass Number": "141", "Relative Atomic Mass": "140.96311(54#)" }, { "Atomic Symbol": "Ho", "Mass Number": "142", "Relative Atomic Mass": "141.96001(54#)" }, { "Atomic Symbol": "Ho", "Mass Number": "143", "Relative Atomic Mass": "142.95486(43#)" }, { "Atomic Symbol": "Ho", "Mass Number": "144", "Relative Atomic Mass": "143.9521097(91)" }, { "Atomic Symbol": "Ho", "Mass Number": "145", "Relative Atomic Mass": "144.9472674(80)" }, { "Atomic Symbol": "Ho", "Mass Number": "146", "Relative Atomic Mass": "145.9449935(71)" }, { "Atomic Symbol": "Ho", "Mass Number": "147", "Relative Atomic Mass": "146.9401423(54)" }, { "Atomic Symbol": "Ho", "Mass Number": "148", "Relative Atomic Mass": "147.937744(90)" }, { "Atomic Symbol": "Ho", "Mass Number": "149", "Relative Atomic Mass": "148.933803(16)" }, { "Atomic Symbol": "Ho", "Mass Number": "150", "Relative Atomic Mass": "149.933498(15)" }, { "Atomic Symbol": "Ho", "Mass Number": "151", "Relative Atomic Mass": "150.9316983(89)" }, { "Atomic Symbol": "Ho", "Mass Number": "152", "Relative Atomic Mass": "151.931724(14)" }, { "Atomic Symbol": "Ho", "Mass Number": "153", "Relative Atomic Mass": "152.9302064(56)" }, { "Atomic Symbol": "Ho", "Mass Number": "154", "Relative Atomic Mass": "153.9306068(89)" }, { "Atomic Symbol": "Ho", "Mass Number": "155", "Relative Atomic Mass": "154.929104(19)" }, { "Atomic Symbol": "Ho", "Mass Number": "156", "Relative Atomic Mass": "155.929706(64)" }, { "Atomic Symbol": "Ho", "Mass Number": "157", "Relative Atomic Mass": "156.928254(25)" }, { "Atomic Symbol": "Ho", "Mass Number": "158", "Relative Atomic Mass": "157.928946(29)" }, { "Atomic Symbol": "Ho", "Mass Number": "159", "Relative Atomic Mass": "158.9277197(36)" }, { "Atomic Symbol": "Ho", "Mass Number": "160", "Relative Atomic Mass": "159.928737(16)" }, { "Atomic Symbol": "Ho", "Mass Number": "161", "Relative Atomic Mass": "160.9278615(30)" }, { "Atomic Symbol": "Ho", "Mass Number": "162", "Relative Atomic Mass": "161.9291023(39)" }, { "Atomic Symbol": "Ho", "Mass Number": "163", "Relative Atomic Mass": "162.9287410(20)" }, { "Atomic Symbol": "Ho", "Mass Number": "164", "Relative Atomic Mass": "163.9302403(25)" }, { "Atomic Symbol": "Ho", "Mass Number": "165", "Isotopic Composition": "1", "Relative Atomic Mass": "164.9303288(21)" }, { "Atomic Symbol": "Ho", "Mass Number": "166", "Relative Atomic Mass": "165.9322909(21)" }, { "Atomic Symbol": "Ho", "Mass Number": "167", "Relative Atomic Mass": "166.9331385(59)" }, { "Atomic Symbol": "Ho", "Mass Number": "168", "Relative Atomic Mass": "167.935522(32)" }, { "Atomic Symbol": "Ho", "Mass Number": "169", "Relative Atomic Mass": "168.936878(22)" }, { "Atomic Symbol": "Ho", "Mass Number": "170", "Relative Atomic Mass": "169.939625(54)" }, { "Atomic Symbol": "Ho", "Mass Number": "171", "Relative Atomic Mass": "170.94147(64)" }, { "Atomic Symbol": "Ho", "Mass Number": "172", "Relative Atomic Mass": "171.94473(21#)" }, { "Atomic Symbol": "Ho", "Mass Number": "173", "Relative Atomic Mass": "172.94702(32#)" }, { "Atomic Symbol": "Ho", "Mass Number": "174", "Relative Atomic Mass": "173.95095(32#)" }, { "Atomic Symbol": "Ho", "Mass Number": "175", "Relative Atomic Mass": "174.95362(43#)" } ], "Standard Atomic Weight": "164.93033(2)" }, { "Atomic Symbol": "Er", "Atomic Number": "68", "isotopes": [ { "Atomic Symbol": "Er", "Mass Number": "142", "Relative Atomic Mass": "141.97010(54#)" }, { "Atomic Symbol": "Er", "Mass Number": "143", "Relative Atomic Mass": "142.96662(43#)" }, { "Atomic Symbol": "Er", "Mass Number": "144", "Relative Atomic Mass": "143.96070(21#)" }, { "Atomic Symbol": "Er", "Mass Number": "145", "Relative Atomic Mass": "144.95805(21#)" }, { "Atomic Symbol": "Er", "Mass Number": "146", "Relative Atomic Mass": "145.9524184(72)" }, { "Atomic Symbol": "Er", "Mass Number": "147", "Relative Atomic Mass": "146.949964(41)" }, { "Atomic Symbol": "Er", "Mass Number": "148", "Relative Atomic Mass": "147.944735(11)" }, { "Atomic Symbol": "Er", "Mass Number": "149", "Relative Atomic Mass": "148.942306(30)" }, { "Atomic Symbol": "Er", "Mass Number": "150", "Relative Atomic Mass": "149.937916(18)" }, { "Atomic Symbol": "Er", "Mass Number": "151", "Relative Atomic Mass": "150.937449(18)" }, { "Atomic Symbol": "Er", "Mass Number": "152", "Relative Atomic Mass": "151.935057(10)" }, { "Atomic Symbol": "Er", "Mass Number": "153", "Relative Atomic Mass": "152.935080(10)" }, { "Atomic Symbol": "Er", "Mass Number": "154", "Relative Atomic Mass": "153.9327908(55)" }, { "Atomic Symbol": "Er", "Mass Number": "155", "Relative Atomic Mass": "154.9332159(67)" }, { "Atomic Symbol": "Er", "Mass Number": "156", "Relative Atomic Mass": "155.931067(26)" }, { "Atomic Symbol": "Er", "Mass Number": "157", "Relative Atomic Mass": "156.931949(27)" }, { "Atomic Symbol": "Er", "Mass Number": "158", "Relative Atomic Mass": "157.929893(27)" }, { "Atomic Symbol": "Er", "Mass Number": "159", "Relative Atomic Mass": "158.9306918(42)" }, { "Atomic Symbol": "Er", "Mass Number": "160", "Relative Atomic Mass": "159.929077(26)" }, { "Atomic Symbol": "Er", "Mass Number": "161", "Relative Atomic Mass": "160.9300046(96)" }, { "Atomic Symbol": "Er", "Mass Number": "162", "Isotopic Composition": "0.00139(5)", "Relative Atomic Mass": "161.9287884(20)" }, { "Atomic Symbol": "Er", "Mass Number": "163", "Relative Atomic Mass": "162.9300408(53)" }, { "Atomic Symbol": "Er", "Mass Number": "164", "Isotopic Composition": "0.01601(3)", "Relative Atomic Mass": "163.9292088(20)" }, { "Atomic Symbol": "Er", "Mass Number": "165", "Relative Atomic Mass": "164.9307345(21)" }, { "Atomic Symbol": "Er", "Mass Number": "166", "Isotopic Composition": "0.33503(36)", "Relative Atomic Mass": "165.9302995(22)" }, { "Atomic Symbol": "Er", "Mass Number": "167", "Isotopic Composition": "0.22869(9)", "Relative Atomic Mass": "166.9320546(22)" }, { "Atomic Symbol": "Er", "Mass Number": "168", "Isotopic Composition": "0.26978(18)", "Relative Atomic Mass": "167.9323767(22)" }, { "Atomic Symbol": "Er", "Mass Number": "169", "Relative Atomic Mass": "168.9345968(22)" }, { "Atomic Symbol": "Er", "Mass Number": "170", "Isotopic Composition": "0.14910(36)", "Relative Atomic Mass": "169.9354702(26)" }, { "Atomic Symbol": "Er", "Mass Number": "171", "Relative Atomic Mass": "170.9380357(26)" }, { "Atomic Symbol": "Er", "Mass Number": "172", "Relative Atomic Mass": "171.9393619(47)" }, { "Atomic Symbol": "Er", "Mass Number": "173", "Relative Atomic Mass": "172.94240(21#)" }, { "Atomic Symbol": "Er", "Mass Number": "174", "Relative Atomic Mass": "173.94423(32#)" }, { "Atomic Symbol": "Er", "Mass Number": "175", "Relative Atomic Mass": "174.94777(43#)" }, { "Atomic Symbol": "Er", "Mass Number": "176", "Relative Atomic Mass": "175.94994(43#)" }, { "Atomic Symbol": "Er", "Mass Number": "177", "Relative Atomic Mass": "176.95399(54#)" } ], "Notes": "g", "Standard Atomic Weight": "167.259(3)" }, { "Atomic Symbol": "Tm", "Atomic Number": "69", "isotopes": [ { "Atomic Symbol": "Tm", "Mass Number": "144", "Relative Atomic Mass": "143.97628(43#)" }, { "Atomic Symbol": "Tm", "Mass Number": "145", "Relative Atomic Mass": "144.97039(21#)" }, { "Atomic Symbol": "Tm", "Mass Number": "146", "Relative Atomic Mass": "145.96684(21#)" }, { "Atomic Symbol": "Tm", "Mass Number": "147", "Relative Atomic Mass": "146.9613799(73)" }, { "Atomic Symbol": "Tm", "Mass Number": "148", "Relative Atomic Mass": "147.958384(11)" }, { "Atomic Symbol": "Tm", "Mass Number": "149", "Relative Atomic Mass": "148.95289(32#)" }, { "Atomic Symbol": "Tm", "Mass Number": "150", "Relative Atomic Mass": "149.95009(21#)" }, { "Atomic Symbol": "Tm", "Mass Number": "151", "Relative Atomic Mass": "150.945488(21)" }, { "Atomic Symbol": "Tm", "Mass Number": "152", "Relative Atomic Mass": "151.944422(79)" }, { "Atomic Symbol": "Tm", "Mass Number": "153", "Relative Atomic Mass": "152.942040(16)" }, { "Atomic Symbol": "Tm", "Mass Number": "154", "Relative Atomic Mass": "153.941570(15)" }, { "Atomic Symbol": "Tm", "Mass Number": "155", "Relative Atomic Mass": "154.939210(11)" }, { "Atomic Symbol": "Tm", "Mass Number": "156", "Relative Atomic Mass": "155.938992(16)" }, { "Atomic Symbol": "Tm", "Mass Number": "157", "Relative Atomic Mass": "156.936944(28)" }, { "Atomic Symbol": "Tm", "Mass Number": "158", "Relative Atomic Mass": "157.936980(27)" }, { "Atomic Symbol": "Tm", "Mass Number": "159", "Relative Atomic Mass": "158.934975(30)" }, { "Atomic Symbol": "Tm", "Mass Number": "160", "Relative Atomic Mass": "159.935263(37)" }, { "Atomic Symbol": "Tm", "Mass Number": "161", "Relative Atomic Mass": "160.933549(30)" }, { "Atomic Symbol": "Tm", "Mass Number": "162", "Relative Atomic Mass": "161.934002(28)" }, { "Atomic Symbol": "Tm", "Mass Number": "163", "Relative Atomic Mass": "162.9326592(62)" }, { "Atomic Symbol": "Tm", "Mass Number": "164", "Relative Atomic Mass": "163.933544(26)" }, { "Atomic Symbol": "Tm", "Mass Number": "165", "Relative Atomic Mass": "164.9324431(26)" }, { "Atomic Symbol": "Tm", "Mass Number": "166", "Relative Atomic Mass": "165.933561(13)" }, { "Atomic Symbol": "Tm", "Mass Number": "167", "Relative Atomic Mass": "166.9328562(25)" }, { "Atomic Symbol": "Tm", "Mass Number": "168", "Relative Atomic Mass": "167.9341774(27)" }, { "Atomic Symbol": "Tm", "Mass Number": "169", "Isotopic Composition": "1", "Relative Atomic Mass": "168.9342179(22)" }, { "Atomic Symbol": "Tm", "Mass Number": "170", "Relative Atomic Mass": "169.9358060(22)" }, { "Atomic Symbol": "Tm", "Mass Number": "171", "Relative Atomic Mass": "170.9364339(24)" }, { "Atomic Symbol": "Tm", "Mass Number": "172", "Relative Atomic Mass": "171.9384055(62)" }, { "Atomic Symbol": "Tm", "Mass Number": "173", "Relative Atomic Mass": "172.9396084(53)" }, { "Atomic Symbol": "Tm", "Mass Number": "174", "Relative Atomic Mass": "173.942173(48)" }, { "Atomic Symbol": "Tm", "Mass Number": "175", "Relative Atomic Mass": "174.943841(54)" }, { "Atomic Symbol": "Tm", "Mass Number": "176", "Relative Atomic Mass": "175.94700(11)" }, { "Atomic Symbol": "Tm", "Mass Number": "177", "Relative Atomic Mass": "176.94904(32#)" }, { "Atomic Symbol": "Tm", "Mass Number": "178", "Relative Atomic Mass": "177.95264(43#)" }, { "Atomic Symbol": "Tm", "Mass Number": "179", "Relative Atomic Mass": "178.95534(54#)" } ], "Standard Atomic Weight": "168.93422(2)" }, { "Atomic Symbol": "Yb", "Atomic Number": "70", "isotopes": [ { "Atomic Symbol": "Yb", "Mass Number": "148", "Relative Atomic Mass": "147.96758(64#)" }, { "Atomic Symbol": "Yb", "Mass Number": "149", "Relative Atomic Mass": "148.96436(54#)" }, { "Atomic Symbol": "Yb", "Mass Number": "150", "Relative Atomic Mass": "149.95852(43#)" }, { "Atomic Symbol": "Yb", "Mass Number": "151", "Relative Atomic Mass": "150.95540(32)" }, { "Atomic Symbol": "Yb", "Mass Number": "152", "Relative Atomic Mass": "151.95027(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "153", "Relative Atomic Mass": "152.94932(21#)" }, { "Atomic Symbol": "Yb", "Mass Number": "154", "Relative Atomic Mass": "153.946396(19)" }, { "Atomic Symbol": "Yb", "Mass Number": "155", "Relative Atomic Mass": "154.945783(18)" }, { "Atomic Symbol": "Yb", "Mass Number": "156", "Relative Atomic Mass": "155.942825(11)" }, { "Atomic Symbol": "Yb", "Mass Number": "157", "Relative Atomic Mass": "156.942645(12)" }, { "Atomic Symbol": "Yb", "Mass Number": "158", "Relative Atomic Mass": "157.9398705(86)" }, { "Atomic Symbol": "Yb", "Mass Number": "159", "Relative Atomic Mass": "158.940055(19)" }, { "Atomic Symbol": "Yb", "Mass Number": "160", "Relative Atomic Mass": "159.937557(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "161", "Relative Atomic Mass": "160.937907(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "162", "Relative Atomic Mass": "161.935774(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "163", "Relative Atomic Mass": "162.936340(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "164", "Relative Atomic Mass": "163.934495(17)" }, { "Atomic Symbol": "Yb", "Mass Number": "165", "Relative Atomic Mass": "164.935270(28)" }, { "Atomic Symbol": "Yb", "Mass Number": "166", "Relative Atomic Mass": "165.9338747(78)" }, { "Atomic Symbol": "Yb", "Mass Number": "167", "Relative Atomic Mass": "166.9349530(47)" }, { "Atomic Symbol": "Yb", "Mass Number": "168", "Isotopic Composition": "0.00123(3)", "Relative Atomic Mass": "167.9338896(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "169", "Relative Atomic Mass": "168.9351825(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "170", "Isotopic Composition": "0.02982(39)", "Relative Atomic Mass": "169.9347664(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "171", "Isotopic Composition": "0.1409(14)", "Relative Atomic Mass": "170.9363302(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "172", "Isotopic Composition": "0.2168(13)", "Relative Atomic Mass": "171.9363859(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "173", "Isotopic Composition": "0.16103(63)", "Relative Atomic Mass": "172.9382151(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "174", "Isotopic Composition": "0.32026(80)", "Relative Atomic Mass": "173.9388664(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "175", "Relative Atomic Mass": "174.9412808(22)" }, { "Atomic Symbol": "Yb", "Mass Number": "176", "Isotopic Composition": "0.12996(83)", "Relative Atomic Mass": "175.9425764(24)" }, { "Atomic Symbol": "Yb", "Mass Number": "177", "Relative Atomic Mass": "176.9452656(24)" }, { "Atomic Symbol": "Yb", "Mass Number": "178", "Relative Atomic Mass": "177.946651(11)" }, { "Atomic Symbol": "Yb", "Mass Number": "179", "Relative Atomic Mass": "178.95004(21#)" }, { "Atomic Symbol": "Yb", "Mass Number": "180", "Relative Atomic Mass": "179.95212(32#)" }, { "Atomic Symbol": "Yb", "Mass Number": "181", "Relative Atomic Mass": "180.95589(32#)" } ], "Notes": "g", "Standard Atomic Weight": "173.054(5)" }, { "Atomic Symbol": "Lu", "Atomic Number": "71", "isotopes": [ { "Atomic Symbol": "Lu", "Mass Number": "150", "Relative Atomic Mass": "149.97355(54#)" }, { "Atomic Symbol": "Lu", "Mass Number": "151", "Relative Atomic Mass": "150.96768(43#)" }, { "Atomic Symbol": "Lu", "Mass Number": "152", "Relative Atomic Mass": "151.96412(21#)" }, { "Atomic Symbol": "Lu", "Mass Number": "153", "Relative Atomic Mass": "152.95875(17)" }, { "Atomic Symbol": "Lu", "Mass Number": "154", "Relative Atomic Mass": "153.95736(22#)" }, { "Atomic Symbol": "Lu", "Mass Number": "155", "Relative Atomic Mass": "154.954321(21)" }, { "Atomic Symbol": "Lu", "Mass Number": "156", "Relative Atomic Mass": "155.953033(79)" }, { "Atomic Symbol": "Lu", "Mass Number": "157", "Relative Atomic Mass": "156.950127(16)" }, { "Atomic Symbol": "Lu", "Mass Number": "158", "Relative Atomic Mass": "157.949316(16)" }, { "Atomic Symbol": "Lu", "Mass Number": "159", "Relative Atomic Mass": "158.946636(40)" }, { "Atomic Symbol": "Lu", "Mass Number": "160", "Relative Atomic Mass": "159.946033(61)" }, { "Atomic Symbol": "Lu", "Mass Number": "161", "Relative Atomic Mass": "160.943572(30)" }, { "Atomic Symbol": "Lu", "Mass Number": "162", "Relative Atomic Mass": "161.943283(81)" }, { "Atomic Symbol": "Lu", "Mass Number": "163", "Relative Atomic Mass": "162.941179(30)" }, { "Atomic Symbol": "Lu", "Mass Number": "164", "Relative Atomic Mass": "163.941339(30)" }, { "Atomic Symbol": "Lu", "Mass Number": "165", "Relative Atomic Mass": "164.939407(28)" }, { "Atomic Symbol": "Lu", "Mass Number": "166", "Relative Atomic Mass": "165.939859(32)" }, { "Atomic Symbol": "Lu", "Mass Number": "167", "Relative Atomic Mass": "166.938270(34)" }, { "Atomic Symbol": "Lu", "Mass Number": "168", "Relative Atomic Mass": "167.938736(42)" }, { "Atomic Symbol": "Lu", "Mass Number": "169", "Relative Atomic Mass": "168.9376441(39)" }, { "Atomic Symbol": "Lu", "Mass Number": "170", "Relative Atomic Mass": "169.938478(18)" }, { "Atomic Symbol": "Lu", "Mass Number": "171", "Relative Atomic Mass": "170.9379170(27)" }, { "Atomic Symbol": "Lu", "Mass Number": "172", "Relative Atomic Mass": "171.9390891(30)" }, { "Atomic Symbol": "Lu", "Mass Number": "173", "Relative Atomic Mass": "172.9389340(23)" }, { "Atomic Symbol": "Lu", "Mass Number": "174", "Relative Atomic Mass": "173.9403409(23)" }, { "Atomic Symbol": "Lu", "Mass Number": "175", "Isotopic Composition": "0.97401(13)", "Relative Atomic Mass": "174.9407752(20)" }, { "Atomic Symbol": "Lu", "Mass Number": "176", "Isotopic Composition": "0.02599(13)", "Relative Atomic Mass": "175.9426897(20)" }, { "Atomic Symbol": "Lu", "Mass Number": "177", "Relative Atomic Mass": "176.9437615(20)" }, { "Atomic Symbol": "Lu", "Mass Number": "178", "Relative Atomic Mass": "177.9459580(29)" }, { "Atomic Symbol": "Lu", "Mass Number": "179", "Relative Atomic Mass": "178.9473309(57)" }, { "Atomic Symbol": "Lu", "Mass Number": "180", "Relative Atomic Mass": "179.949888(76)" }, { "Atomic Symbol": "Lu", "Mass Number": "181", "Relative Atomic Mass": "180.95191(17)" }, { "Atomic Symbol": "Lu", "Mass Number": "182", "Relative Atomic Mass": "181.95504(21#)" }, { "Atomic Symbol": "Lu", "Mass Number": "183", "Relative Atomic Mass": "182.957363(98)" }, { "Atomic Symbol": "Lu", "Mass Number": "184", "Relative Atomic Mass": "183.96091(32#)" }, { "Atomic Symbol": "Lu", "Mass Number": "185", "Relative Atomic Mass": "184.96362(32#)" } ], "Notes": "g", "Standard Atomic Weight": "174.9668(1)" }, { "Atomic Symbol": "Hf", "Atomic Number": "72", "isotopes": [ { "Atomic Symbol": "Hf", "Mass Number": "153", "Relative Atomic Mass": "152.97069(54#)" }, { "Atomic Symbol": "Hf", "Mass Number": "154", "Relative Atomic Mass": "153.96486(54#)" }, { "Atomic Symbol": "Hf", "Mass Number": "155", "Relative Atomic Mass": "154.96311(32#)" }, { "Atomic Symbol": "Hf", "Mass Number": "156", "Relative Atomic Mass": "155.95935(17)" }, { "Atomic Symbol": "Hf", "Mass Number": "157", "Relative Atomic Mass": "156.95824(21#)" }, { "Atomic Symbol": "Hf", "Mass Number": "158", "Relative Atomic Mass": "157.954801(19)" }, { "Atomic Symbol": "Hf", "Mass Number": "159", "Relative Atomic Mass": "158.953996(18)" }, { "Atomic Symbol": "Hf", "Mass Number": "160", "Relative Atomic Mass": "159.950691(11)" }, { "Atomic Symbol": "Hf", "Mass Number": "161", "Relative Atomic Mass": "160.950278(24)" }, { "Atomic Symbol": "Hf", "Mass Number": "162", "Relative Atomic Mass": "161.9472148(97)" }, { "Atomic Symbol": "Hf", "Mass Number": "163", "Relative Atomic Mass": "162.947113(27)" }, { "Atomic Symbol": "Hf", "Mass Number": "164", "Relative Atomic Mass": "163.944371(17)" }, { "Atomic Symbol": "Hf", "Mass Number": "165", "Relative Atomic Mass": "164.944567(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "166", "Relative Atomic Mass": "165.942180(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "167", "Relative Atomic Mass": "166.942600(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "168", "Relative Atomic Mass": "167.940568(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "169", "Relative Atomic Mass": "168.941259(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "170", "Relative Atomic Mass": "169.939609(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "171", "Relative Atomic Mass": "170.940492(31)" }, { "Atomic Symbol": "Hf", "Mass Number": "172", "Relative Atomic Mass": "171.939450(26)" }, { "Atomic Symbol": "Hf", "Mass Number": "173", "Relative Atomic Mass": "172.940513(30)" }, { "Atomic Symbol": "Hf", "Mass Number": "174", "Isotopic Composition": "0.0016(1)", "Relative Atomic Mass": "173.9400461(28)" }, { "Atomic Symbol": "Hf", "Mass Number": "175", "Relative Atomic Mass": "174.9415092(29)" }, { "Atomic Symbol": "Hf", "Mass Number": "176", "Isotopic Composition": "0.0526(7)", "Relative Atomic Mass": "175.9414076(22)" }, { "Atomic Symbol": "Hf", "Mass Number": "177", "Isotopic Composition": "0.1860(9)", "Relative Atomic Mass": "176.9432277(20)" }, { "Atomic Symbol": "Hf", "Mass Number": "178", "Isotopic Composition": "0.2728(7)", "Relative Atomic Mass": "177.9437058(20)" }, { "Atomic Symbol": "Hf", "Mass Number": "179", "Isotopic Composition": "0.1362(2)", "Relative Atomic Mass": "178.9458232(20)" }, { "Atomic Symbol": "Hf", "Mass Number": "180", "Isotopic Composition": "0.3508(16)", "Relative Atomic Mass": "179.9465570(20)" }, { "Atomic Symbol": "Hf", "Mass Number": "181", "Relative Atomic Mass": "180.9491083(20)" }, { "Atomic Symbol": "Hf", "Mass Number": "182", "Relative Atomic Mass": "181.9505612(68)" }, { "Atomic Symbol": "Hf", "Mass Number": "183", "Relative Atomic Mass": "182.953530(32)" }, { "Atomic Symbol": "Hf", "Mass Number": "184", "Relative Atomic Mass": "183.955446(43)" }, { "Atomic Symbol": "Hf", "Mass Number": "185", "Relative Atomic Mass": "184.958862(98)" }, { "Atomic Symbol": "Hf", "Mass Number": "186", "Relative Atomic Mass": "185.960897(59)" }, { "Atomic Symbol": "Hf", "Mass Number": "187", "Relative Atomic Mass": "186.96477(32#)" }, { "Atomic Symbol": "Hf", "Mass Number": "188", "Relative Atomic Mass": "187.96685(32#)" }, { "Atomic Symbol": "Hf", "Mass Number": "189", "Relative Atomic Mass": "188.97084(32#)" } ], "Standard Atomic Weight": "178.49(2)" }, { "Atomic Symbol": "Ta", "Atomic Number": "73", "isotopes": [ { "Atomic Symbol": "Ta", "Mass Number": "155", "Relative Atomic Mass": "154.97424(54#)" }, { "Atomic Symbol": "Ta", "Mass Number": "156", "Relative Atomic Mass": "155.97203(32#)" }, { "Atomic Symbol": "Ta", "Mass Number": "157", "Relative Atomic Mass": "156.96818(17)" }, { "Atomic Symbol": "Ta", "Mass Number": "158", "Relative Atomic Mass": "157.96654(22#)" }, { "Atomic Symbol": "Ta", "Mass Number": "159", "Relative Atomic Mass": "158.963023(21)" }, { "Atomic Symbol": "Ta", "Mass Number": "160", "Relative Atomic Mass": "159.961488(79)" }, { "Atomic Symbol": "Ta", "Mass Number": "161", "Relative Atomic Mass": "160.958452(27)" }, { "Atomic Symbol": "Ta", "Mass Number": "162", "Relative Atomic Mass": "161.957294(56)" }, { "Atomic Symbol": "Ta", "Mass Number": "163", "Relative Atomic Mass": "162.954337(41)" }, { "Atomic Symbol": "Ta", "Mass Number": "164", "Relative Atomic Mass": "163.953534(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "165", "Relative Atomic Mass": "164.950781(15)" }, { "Atomic Symbol": "Ta", "Mass Number": "166", "Relative Atomic Mass": "165.950512(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "167", "Relative Atomic Mass": "166.948093(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "168", "Relative Atomic Mass": "167.948047(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "169", "Relative Atomic Mass": "168.946011(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "170", "Relative Atomic Mass": "169.946175(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "171", "Relative Atomic Mass": "170.944476(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "172", "Relative Atomic Mass": "171.944895(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "173", "Relative Atomic Mass": "172.943750(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "174", "Relative Atomic Mass": "173.944454(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "175", "Relative Atomic Mass": "174.943737(30)" }, { "Atomic Symbol": "Ta", "Mass Number": "176", "Relative Atomic Mass": "175.944857(33)" }, { "Atomic Symbol": "Ta", "Mass Number": "177", "Relative Atomic Mass": "176.9444795(38)" }, { "Atomic Symbol": "Ta", "Mass Number": "178", "Relative Atomic Mass": "177.945678(56#)" }, { "Atomic Symbol": "Ta", "Mass Number": "179", "Relative Atomic Mass": "178.9459366(21)" }, { "Atomic Symbol": "Ta", "Mass Number": "180", "Isotopic Composition": "0.0001201(32)", "Relative Atomic Mass": "179.9474648(24)" }, { "Atomic Symbol": "Ta", "Mass Number": "181", "Isotopic Composition": "0.9998799(32)", "Relative Atomic Mass": "180.9479958(20)" }, { "Atomic Symbol": "Ta", "Mass Number": "182", "Relative Atomic Mass": "181.9501519(20)" }, { "Atomic Symbol": "Ta", "Mass Number": "183", "Relative Atomic Mass": "182.9513726(20)" }, { "Atomic Symbol": "Ta", "Mass Number": "184", "Relative Atomic Mass": "183.954008(28)" }, { "Atomic Symbol": "Ta", "Mass Number": "185", "Relative Atomic Mass": "184.955559(15)" }, { "Atomic Symbol": "Ta", "Mass Number": "186", "Relative Atomic Mass": "185.958551(64)" }, { "Atomic Symbol": "Ta", "Mass Number": "187", "Relative Atomic Mass": "186.960386(71)" }, { "Atomic Symbol": "Ta", "Mass Number": "188", "Relative Atomic Mass": "187.963916(71)" }, { "Atomic Symbol": "Ta", "Mass Number": "189", "Relative Atomic Mass": "188.96583(32#)" }, { "Atomic Symbol": "Ta", "Mass Number": "190", "Relative Atomic Mass": "189.96939(21#)" }, { "Atomic Symbol": "Ta", "Mass Number": "191", "Relative Atomic Mass": "190.97156(32#)" }, { "Atomic Symbol": "Ta", "Mass Number": "192", "Relative Atomic Mass": "191.97514(43#)" } ], "Standard Atomic Weight": "180.94788(2)" }, { "Atomic Symbol": "W", "Atomic Number": "74", "isotopes": [ { "Atomic Symbol": "W", "Mass Number": "157", "Relative Atomic Mass": "156.97884(43#)" }, { "Atomic Symbol": "W", "Mass Number": "158", "Relative Atomic Mass": "157.97456(54#)" }, { "Atomic Symbol": "W", "Mass Number": "159", "Relative Atomic Mass": "158.97264(32#)" }, { "Atomic Symbol": "W", "Mass Number": "160", "Relative Atomic Mass": "159.96846(17)" }, { "Atomic Symbol": "W", "Mass Number": "161", "Relative Atomic Mass": "160.96720(21#)" }, { "Atomic Symbol": "W", "Mass Number": "162", "Relative Atomic Mass": "161.963499(19)" }, { "Atomic Symbol": "W", "Mass Number": "163", "Relative Atomic Mass": "162.962524(57)" }, { "Atomic Symbol": "W", "Mass Number": "164", "Relative Atomic Mass": "163.958961(11)" }, { "Atomic Symbol": "W", "Mass Number": "165", "Relative Atomic Mass": "164.958281(27)" }, { "Atomic Symbol": "W", "Mass Number": "166", "Relative Atomic Mass": "165.955031(10)" }, { "Atomic Symbol": "W", "Mass Number": "167", "Relative Atomic Mass": "166.954805(20)" }, { "Atomic Symbol": "W", "Mass Number": "168", "Relative Atomic Mass": "167.951806(14)" }, { "Atomic Symbol": "W", "Mass Number": "169", "Relative Atomic Mass": "168.951779(17)" }, { "Atomic Symbol": "W", "Mass Number": "170", "Relative Atomic Mass": "169.949232(14)" }, { "Atomic Symbol": "W", "Mass Number": "171", "Relative Atomic Mass": "170.949451(30)" }, { "Atomic Symbol": "W", "Mass Number": "172", "Relative Atomic Mass": "171.947292(30)" }, { "Atomic Symbol": "W", "Mass Number": "173", "Relative Atomic Mass": "172.947689(30)" }, { "Atomic Symbol": "W", "Mass Number": "174", "Relative Atomic Mass": "173.946079(30)" }, { "Atomic Symbol": "W", "Mass Number": "175", "Relative Atomic Mass": "174.946717(30)" }, { "Atomic Symbol": "W", "Mass Number": "176", "Relative Atomic Mass": "175.945634(30)" }, { "Atomic Symbol": "W", "Mass Number": "177", "Relative Atomic Mass": "176.946643(30)" }, { "Atomic Symbol": "W", "Mass Number": "178", "Relative Atomic Mass": "177.945883(16)" }, { "Atomic Symbol": "W", "Mass Number": "179", "Relative Atomic Mass": "178.947077(16)" }, { "Atomic Symbol": "W", "Mass Number": "180", "Isotopic Composition": "0.0012(1)", "Relative Atomic Mass": "179.9467108(20)" }, { "Atomic Symbol": "W", "Mass Number": "181", "Relative Atomic Mass": "180.9481978(51)" }, { "Atomic Symbol": "W", "Mass Number": "182", "Isotopic Composition": "0.2650(16)", "Relative Atomic Mass": "181.94820394(91)" }, { "Atomic Symbol": "W", "Mass Number": "183", "Isotopic Composition": "0.1431(4)", "Relative Atomic Mass": "182.95022275(90)" }, { "Atomic Symbol": "W", "Mass Number": "184", "Isotopic Composition": "0.3064(2)", "Relative Atomic Mass": "183.95093092(94)" }, { "Atomic Symbol": "W", "Mass Number": "185", "Relative Atomic Mass": "184.95341897(99)" }, { "Atomic Symbol": "W", "Mass Number": "186", "Isotopic Composition": "0.2843(19)", "Relative Atomic Mass": "185.9543628(17)" }, { "Atomic Symbol": "W", "Mass Number": "187", "Relative Atomic Mass": "186.9571588(17)" }, { "Atomic Symbol": "W", "Mass Number": "188", "Relative Atomic Mass": "187.9584862(36)" }, { "Atomic Symbol": "W", "Mass Number": "189", "Relative Atomic Mass": "188.961763(44)" }, { "Atomic Symbol": "W", "Mass Number": "190", "Relative Atomic Mass": "189.963091(42)" }, { "Atomic Symbol": "W", "Mass Number": "191", "Relative Atomic Mass": "190.966531(48)" }, { "Atomic Symbol": "W", "Mass Number": "192", "Relative Atomic Mass": "191.96817(21#)" }, { "Atomic Symbol": "W", "Mass Number": "193", "Relative Atomic Mass": "192.97178(21#)" }, { "Atomic Symbol": "W", "Mass Number": "194", "Relative Atomic Mass": "193.97367(32#)" } ], "Standard Atomic Weight": "183.84(1)" }, { "Atomic Symbol": "Re", "Atomic Number": "75", "isotopes": [ { "Atomic Symbol": "Re", "Mass Number": "159", "Relative Atomic Mass": "158.98418(54#)" }, { "Atomic Symbol": "Re", "Mass Number": "160", "Relative Atomic Mass": "159.98182(32#)" }, { "Atomic Symbol": "Re", "Mass Number": "161", "Relative Atomic Mass": "160.97757(17)" }, { "Atomic Symbol": "Re", "Mass Number": "162", "Relative Atomic Mass": "161.97584(22#)" }, { "Atomic Symbol": "Re", "Mass Number": "163", "Relative Atomic Mass": "162.972080(20)" }, { "Atomic Symbol": "Re", "Mass Number": "164", "Relative Atomic Mass": "163.970453(79)" }, { "Atomic Symbol": "Re", "Mass Number": "165", "Relative Atomic Mass": "164.967103(27)" }, { "Atomic Symbol": "Re", "Mass Number": "166", "Relative Atomic Mass": "165.965761(78)" }, { "Atomic Symbol": "Re", "Mass Number": "167", "Relative Atomic Mass": "166.962595(44#)" }, { "Atomic Symbol": "Re", "Mass Number": "168", "Relative Atomic Mass": "167.961573(33)" }, { "Atomic Symbol": "Re", "Mass Number": "169", "Relative Atomic Mass": "168.958766(12)" }, { "Atomic Symbol": "Re", "Mass Number": "170", "Relative Atomic Mass": "169.958220(28)" }, { "Atomic Symbol": "Re", "Mass Number": "171", "Relative Atomic Mass": "170.955716(30)" }, { "Atomic Symbol": "Re", "Mass Number": "172", "Relative Atomic Mass": "171.955420(42)" }, { "Atomic Symbol": "Re", "Mass Number": "173", "Relative Atomic Mass": "172.953243(30)" }, { "Atomic Symbol": "Re", "Mass Number": "174", "Relative Atomic Mass": "173.953115(30)" }, { "Atomic Symbol": "Re", "Mass Number": "175", "Relative Atomic Mass": "174.951381(30)" }, { "Atomic Symbol": "Re", "Mass Number": "176", "Relative Atomic Mass": "175.951623(30)" }, { "Atomic Symbol": "Re", "Mass Number": "177", "Relative Atomic Mass": "176.950328(30)" }, { "Atomic Symbol": "Re", "Mass Number": "178", "Relative Atomic Mass": "177.950989(30)" }, { "Atomic Symbol": "Re", "Mass Number": "179", "Relative Atomic Mass": "178.949989(26)" }, { "Atomic Symbol": "Re", "Mass Number": "180", "Relative Atomic Mass": "179.950792(23)" }, { "Atomic Symbol": "Re", "Mass Number": "181", "Relative Atomic Mass": "180.950058(14)" }, { "Atomic Symbol": "Re", "Mass Number": "182", "Relative Atomic Mass": "181.95121(11)" }, { "Atomic Symbol": "Re", "Mass Number": "183", "Relative Atomic Mass": "182.9508196(86)" }, { "Atomic Symbol": "Re", "Mass Number": "184", "Relative Atomic Mass": "183.9525228(47)" }, { "Atomic Symbol": "Re", "Mass Number": "185", "Isotopic Composition": "0.3740(2)", "Relative Atomic Mass": "184.9529545(13)" }, { "Atomic Symbol": "Re", "Mass Number": "186", "Relative Atomic Mass": "185.9549856(13)" }, { "Atomic Symbol": "Re", "Mass Number": "187", "Isotopic Composition": "0.6260(2)", "Relative Atomic Mass": "186.9557501(16)" }, { "Atomic Symbol": "Re", "Mass Number": "188", "Relative Atomic Mass": "187.9581115(16)" }, { "Atomic Symbol": "Re", "Mass Number": "189", "Relative Atomic Mass": "188.9592260(89)" }, { "Atomic Symbol": "Re", "Mass Number": "190", "Relative Atomic Mass": "189.961744(76)" }, { "Atomic Symbol": "Re", "Mass Number": "191", "Relative Atomic Mass": "190.963122(11)" }, { "Atomic Symbol": "Re", "Mass Number": "192", "Relative Atomic Mass": "191.966088(82)" }, { "Atomic Symbol": "Re", "Mass Number": "193", "Relative Atomic Mass": "192.967541(41)" }, { "Atomic Symbol": "Re", "Mass Number": "194", "Relative Atomic Mass": "193.97076(21#)" }, { "Atomic Symbol": "Re", "Mass Number": "195", "Relative Atomic Mass": "194.97254(32#)" }, { "Atomic Symbol": "Re", "Mass Number": "196", "Relative Atomic Mass": "195.97580(32#)" }, { "Atomic Symbol": "Re", "Mass Number": "197", "Relative Atomic Mass": "196.97799(32#)" }, { "Atomic Symbol": "Re", "Mass Number": "198", "Relative Atomic Mass": "197.98160(43#)" } ], "Standard Atomic Weight": "186.207(1)" }, { "Atomic Symbol": "Os", "Atomic Number": "76", "isotopes": [ { "Atomic Symbol": "Os", "Mass Number": "161", "Relative Atomic Mass": "160.98903(43#)" }, { "Atomic Symbol": "Os", "Mass Number": "162", "Relative Atomic Mass": "161.98443(54#)" }, { "Atomic Symbol": "Os", "Mass Number": "163", "Relative Atomic Mass": "162.98241(32#)" }, { "Atomic Symbol": "Os", "Mass Number": "164", "Relative Atomic Mass": "163.97802(17)" }, { "Atomic Symbol": "Os", "Mass Number": "165", "Relative Atomic Mass": "164.97660(22#)" }, { "Atomic Symbol": "Os", "Mass Number": "166", "Relative Atomic Mass": "165.972692(20)" }, { "Atomic Symbol": "Os", "Mass Number": "167", "Relative Atomic Mass": "166.971549(78)" }, { "Atomic Symbol": "Os", "Mass Number": "168", "Relative Atomic Mass": "167.967808(12)" }, { "Atomic Symbol": "Os", "Mass Number": "169", "Relative Atomic Mass": "168.967018(27)" }, { "Atomic Symbol": "Os", "Mass Number": "170", "Relative Atomic Mass": "169.963578(11)" }, { "Atomic Symbol": "Os", "Mass Number": "171", "Relative Atomic Mass": "170.963174(19)" }, { "Atomic Symbol": "Os", "Mass Number": "172", "Relative Atomic Mass": "171.960017(14)" }, { "Atomic Symbol": "Os", "Mass Number": "173", "Relative Atomic Mass": "172.959808(16)" }, { "Atomic Symbol": "Os", "Mass Number": "174", "Relative Atomic Mass": "173.957064(11)" }, { "Atomic Symbol": "Os", "Mass Number": "175", "Relative Atomic Mass": "174.956945(13)" }, { "Atomic Symbol": "Os", "Mass Number": "176", "Relative Atomic Mass": "175.954806(30)" }, { "Atomic Symbol": "Os", "Mass Number": "177", "Relative Atomic Mass": "176.954966(17)" }, { "Atomic Symbol": "Os", "Mass Number": "178", "Relative Atomic Mass": "177.953254(15)" }, { "Atomic Symbol": "Os", "Mass Number": "179", "Relative Atomic Mass": "178.953817(18)" }, { "Atomic Symbol": "Os", "Mass Number": "180", "Relative Atomic Mass": "179.952375(17)" }, { "Atomic Symbol": "Os", "Mass Number": "181", "Relative Atomic Mass": "180.953247(27)" }, { "Atomic Symbol": "Os", "Mass Number": "182", "Relative Atomic Mass": "181.952110(23)" }, { "Atomic Symbol": "Os", "Mass Number": "183", "Relative Atomic Mass": "182.953125(53)" }, { "Atomic Symbol": "Os", "Mass Number": "184", "Isotopic Composition": "0.0002(1)", "Relative Atomic Mass": "183.9524885(14)" }, { "Atomic Symbol": "Os", "Mass Number": "185", "Relative Atomic Mass": "184.9540417(14)" }, { "Atomic Symbol": "Os", "Mass Number": "186", "Isotopic Composition": "0.0159(3)", "Relative Atomic Mass": "185.9538350(16)" }, { "Atomic Symbol": "Os", "Mass Number": "187", "Isotopic Composition": "0.0196(2)", "Relative Atomic Mass": "186.9557474(16)" }, { "Atomic Symbol": "Os", "Mass Number": "188", "Isotopic Composition": "0.1324(8)", "Relative Atomic Mass": "187.9558352(16)" }, { "Atomic Symbol": "Os", "Mass Number": "189", "Isotopic Composition": "0.1615(5)", "Relative Atomic Mass": "188.9581442(17)" }, { "Atomic Symbol": "Os", "Mass Number": "190", "Isotopic Composition": "0.2626(2)", "Relative Atomic Mass": "189.9584437(17)" }, { "Atomic Symbol": "Os", "Mass Number": "191", "Relative Atomic Mass": "190.9609264(17)" }, { "Atomic Symbol": "Os", "Mass Number": "192", "Isotopic Composition": "0.4078(19)", "Relative Atomic Mass": "191.9614770(29)" }, { "Atomic Symbol": "Os", "Mass Number": "193", "Relative Atomic Mass": "192.9641479(29)" }, { "Atomic Symbol": "Os", "Mass Number": "194", "Relative Atomic Mass": "193.9651772(30)" }, { "Atomic Symbol": "Os", "Mass Number": "195", "Relative Atomic Mass": "194.968318(65)" }, { "Atomic Symbol": "Os", "Mass Number": "196", "Relative Atomic Mass": "195.969641(43)" }, { "Atomic Symbol": "Os", "Mass Number": "197", "Relative Atomic Mass": "196.97283(21#)" }, { "Atomic Symbol": "Os", "Mass Number": "198", "Relative Atomic Mass": "197.97441(21#)" }, { "Atomic Symbol": "Os", "Mass Number": "199", "Relative Atomic Mass": "198.97801(21#)" }, { "Atomic Symbol": "Os", "Mass Number": "200", "Relative Atomic Mass": "199.97984(32#)" }, { "Atomic Symbol": "Os", "Mass Number": "201", "Relative Atomic Mass": "200.98364(32#)" }, { "Atomic Symbol": "Os", "Mass Number": "202", "Relative Atomic Mass": "201.98595(43#)" } ], "Notes": "g", "Standard Atomic Weight": "190.23(3)" }, { "Atomic Symbol": "Ir", "Atomic Number": "77", "isotopes": [ { "Atomic Symbol": "Ir", "Mass Number": "164", "Relative Atomic Mass": "163.99191(34#)" }, { "Atomic Symbol": "Ir", "Mass Number": "165", "Relative Atomic Mass": "164.98750(18#)" }, { "Atomic Symbol": "Ir", "Mass Number": "166", "Relative Atomic Mass": "165.98566(22#)" }, { "Atomic Symbol": "Ir", "Mass Number": "167", "Relative Atomic Mass": "166.981666(20)" }, { "Atomic Symbol": "Ir", "Mass Number": "168", "Relative Atomic Mass": "167.979907(80)" }, { "Atomic Symbol": "Ir", "Mass Number": "169", "Relative Atomic Mass": "168.976298(27)" }, { "Atomic Symbol": "Ir", "Mass Number": "170", "Relative Atomic Mass": "169.974922(95#)" }, { "Atomic Symbol": "Ir", "Mass Number": "171", "Relative Atomic Mass": "170.971640(42)" }, { "Atomic Symbol": "Ir", "Mass Number": "172", "Relative Atomic Mass": "171.970607(35)" }, { "Atomic Symbol": "Ir", "Mass Number": "173", "Relative Atomic Mass": "172.967506(12)" }, { "Atomic Symbol": "Ir", "Mass Number": "174", "Relative Atomic Mass": "173.966861(30)" }, { "Atomic Symbol": "Ir", "Mass Number": "175", "Relative Atomic Mass": "174.964150(13)" }, { "Atomic Symbol": "Ir", "Mass Number": "176", "Relative Atomic Mass": "175.963650(22)" }, { "Atomic Symbol": "Ir", "Mass Number": "177", "Relative Atomic Mass": "176.961301(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "178", "Relative Atomic Mass": "177.961082(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "179", "Relative Atomic Mass": "178.959120(10)" }, { "Atomic Symbol": "Ir", "Mass Number": "180", "Relative Atomic Mass": "179.959229(23)" }, { "Atomic Symbol": "Ir", "Mass Number": "181", "Relative Atomic Mass": "180.957625(28)" }, { "Atomic Symbol": "Ir", "Mass Number": "182", "Relative Atomic Mass": "181.958076(23)" }, { "Atomic Symbol": "Ir", "Mass Number": "183", "Relative Atomic Mass": "182.956840(26)" }, { "Atomic Symbol": "Ir", "Mass Number": "184", "Relative Atomic Mass": "183.957476(30)" }, { "Atomic Symbol": "Ir", "Mass Number": "185", "Relative Atomic Mass": "184.956698(30)" }, { "Atomic Symbol": "Ir", "Mass Number": "186", "Relative Atomic Mass": "185.957944(18)" }, { "Atomic Symbol": "Ir", "Mass Number": "187", "Relative Atomic Mass": "186.957542(30)" }, { "Atomic Symbol": "Ir", "Mass Number": "188", "Relative Atomic Mass": "187.958828(10)" }, { "Atomic Symbol": "Ir", "Mass Number": "189", "Relative Atomic Mass": "188.958715(14)" }, { "Atomic Symbol": "Ir", "Mass Number": "190", "Relative Atomic Mass": "189.9605412(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "191", "Isotopic Composition": "0.373(2)", "Relative Atomic Mass": "190.9605893(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "192", "Relative Atomic Mass": "191.9626002(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "193", "Isotopic Composition": "0.627(2)", "Relative Atomic Mass": "192.9629216(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "194", "Relative Atomic Mass": "193.9650735(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "195", "Relative Atomic Mass": "194.9659747(21)" }, { "Atomic Symbol": "Ir", "Mass Number": "196", "Relative Atomic Mass": "195.968397(41)" }, { "Atomic Symbol": "Ir", "Mass Number": "197", "Relative Atomic Mass": "196.969655(22)" }, { "Atomic Symbol": "Ir", "Mass Number": "198", "Relative Atomic Mass": "197.97228(21#)" }, { "Atomic Symbol": "Ir", "Mass Number": "199", "Relative Atomic Mass": "198.973805(44)" }, { "Atomic Symbol": "Ir", "Mass Number": "200", "Relative Atomic Mass": "199.97680(21#)" }, { "Atomic Symbol": "Ir", "Mass Number": "201", "Relative Atomic Mass": "200.97864(21#)" }, { "Atomic Symbol": "Ir", "Mass Number": "202", "Relative Atomic Mass": "201.98199(32#)" }, { "Atomic Symbol": "Ir", "Mass Number": "203", "Relative Atomic Mass": "202.98423(43#)" }, { "Atomic Symbol": "Ir", "Mass Number": "204", "Relative Atomic Mass": "203.98960(43#)" } ], "Standard Atomic Weight": "192.217(3)" }, { "Atomic Symbol": "Pt", "Atomic Number": "78", "isotopes": [ { "Atomic Symbol": "Pt", "Mass Number": "166", "Relative Atomic Mass": "165.99486(54#)" }, { "Atomic Symbol": "Pt", "Mass Number": "167", "Relative Atomic Mass": "166.99269(33#)" }, { "Atomic Symbol": "Pt", "Mass Number": "168", "Relative Atomic Mass": "167.98813(17)" }, { "Atomic Symbol": "Pt", "Mass Number": "169", "Relative Atomic Mass": "168.98657(22#)" }, { "Atomic Symbol": "Pt", "Mass Number": "170", "Relative Atomic Mass": "169.982496(20)" }, { "Atomic Symbol": "Pt", "Mass Number": "171", "Relative Atomic Mass": "170.981245(78)" }, { "Atomic Symbol": "Pt", "Mass Number": "172", "Relative Atomic Mass": "171.977351(12)" }, { "Atomic Symbol": "Pt", "Mass Number": "173", "Relative Atomic Mass": "172.976443(60)" }, { "Atomic Symbol": "Pt", "Mass Number": "174", "Relative Atomic Mass": "173.972820(11)" }, { "Atomic Symbol": "Pt", "Mass Number": "175", "Relative Atomic Mass": "174.972410(19)" }, { "Atomic Symbol": "Pt", "Mass Number": "176", "Relative Atomic Mass": "175.968938(14)" }, { "Atomic Symbol": "Pt", "Mass Number": "177", "Relative Atomic Mass": "176.968470(16)" }, { "Atomic Symbol": "Pt", "Mass Number": "178", "Relative Atomic Mass": "177.965650(11)" }, { "Atomic Symbol": "Pt", "Mass Number": "179", "Relative Atomic Mass": "178.9653590(86)" }, { "Atomic Symbol": "Pt", "Mass Number": "180", "Relative Atomic Mass": "179.963032(12)" }, { "Atomic Symbol": "Pt", "Mass Number": "181", "Relative Atomic Mass": "180.963098(16)" }, { "Atomic Symbol": "Pt", "Mass Number": "182", "Relative Atomic Mass": "181.961172(14)" }, { "Atomic Symbol": "Pt", "Mass Number": "183", "Relative Atomic Mass": "182.961597(17)" }, { "Atomic Symbol": "Pt", "Mass Number": "184", "Relative Atomic Mass": "183.959915(17)" }, { "Atomic Symbol": "Pt", "Mass Number": "185", "Relative Atomic Mass": "184.960614(28)" }, { "Atomic Symbol": "Pt", "Mass Number": "186", "Relative Atomic Mass": "185.959351(23)" }, { "Atomic Symbol": "Pt", "Mass Number": "187", "Relative Atomic Mass": "186.960617(26)" }, { "Atomic Symbol": "Pt", "Mass Number": "188", "Relative Atomic Mass": "187.9593889(61)" }, { "Atomic Symbol": "Pt", "Mass Number": "189", "Relative Atomic Mass": "188.960831(12)" }, { "Atomic Symbol": "Pt", "Mass Number": "190", "Isotopic Composition": "0.00012(2)", "Relative Atomic Mass": "189.9599297(63)" }, { "Atomic Symbol": "Pt", "Mass Number": "191", "Relative Atomic Mass": "190.9616729(53)" }, { "Atomic Symbol": "Pt", "Mass Number": "192", "Isotopic Composition": "0.00782(24)", "Relative Atomic Mass": "191.9610387(32)" }, { "Atomic Symbol": "Pt", "Mass Number": "193", "Relative Atomic Mass": "192.9629824(21)" }, { "Atomic Symbol": "Pt", "Mass Number": "194", "Isotopic Composition": "0.3286(40)", "Relative Atomic Mass": "193.9626809(10)" }, { "Atomic Symbol": "Pt", "Mass Number": "195", "Isotopic Composition": "0.3378(24)", "Relative Atomic Mass": "194.9647917(10)" }, { "Atomic Symbol": "Pt", "Mass Number": "196", "Isotopic Composition": "0.2521(34)", "Relative Atomic Mass": "195.96495209(99)" }, { "Atomic Symbol": "Pt", "Mass Number": "197", "Relative Atomic Mass": "196.96734069(94)" }, { "Atomic Symbol": "Pt", "Mass Number": "198", "Isotopic Composition": "0.07356(130)", "Relative Atomic Mass": "197.9678949(23)" }, { "Atomic Symbol": "Pt", "Mass Number": "199", "Relative Atomic Mass": "198.9705952(24)" }, { "Atomic Symbol": "Pt", "Mass Number": "200", "Relative Atomic Mass": "199.971443(22)" }, { "Atomic Symbol": "Pt", "Mass Number": "201", "Relative Atomic Mass": "200.974513(54)" }, { "Atomic Symbol": "Pt", "Mass Number": "202", "Relative Atomic Mass": "201.975639(27)" }, { "Atomic Symbol": "Pt", "Mass Number": "203", "Relative Atomic Mass": "202.97893(21#)" }, { "Atomic Symbol": "Pt", "Mass Number": "204", "Relative Atomic Mass": "203.98076(21#)" }, { "Atomic Symbol": "Pt", "Mass Number": "205", "Relative Atomic Mass": "204.98608(32#)" }, { "Atomic Symbol": "Pt", "Mass Number": "206", "Relative Atomic Mass": "205.98966(32#)" } ], "Standard Atomic Weight": "195.084(9)" }, { "Atomic Symbol": "Au", "Atomic Number": "79", "isotopes": [ { "Atomic Symbol": "Au", "Mass Number": "169", "Relative Atomic Mass": "168.99808(32#)" }, { "Atomic Symbol": "Au", "Mass Number": "170", "Relative Atomic Mass": "169.99597(22#)" }, { "Atomic Symbol": "Au", "Mass Number": "171", "Relative Atomic Mass": "170.991876(22)" }, { "Atomic Symbol": "Au", "Mass Number": "172", "Relative Atomic Mass": "171.989942(81)" }, { "Atomic Symbol": "Au", "Mass Number": "173", "Relative Atomic Mass": "172.986241(26)" }, { "Atomic Symbol": "Au", "Mass Number": "174", "Relative Atomic Mass": "173.984717(95#)" }, { "Atomic Symbol": "Au", "Mass Number": "175", "Relative Atomic Mass": "174.981304(42)" }, { "Atomic Symbol": "Au", "Mass Number": "176", "Relative Atomic Mass": "175.980250(36)" }, { "Atomic Symbol": "Au", "Mass Number": "177", "Relative Atomic Mass": "176.976870(11)" }, { "Atomic Symbol": "Au", "Mass Number": "178", "Relative Atomic Mass": "177.976032(61)" }, { "Atomic Symbol": "Au", "Mass Number": "179", "Relative Atomic Mass": "178.973174(13)" }, { "Atomic Symbol": "Au", "Mass Number": "180", "Relative Atomic Mass": "179.972523(21)" }, { "Atomic Symbol": "Au", "Mass Number": "181", "Relative Atomic Mass": "180.970079(21)" }, { "Atomic Symbol": "Au", "Mass Number": "182", "Relative Atomic Mass": "181.969618(22)" }, { "Atomic Symbol": "Au", "Mass Number": "183", "Relative Atomic Mass": "182.967591(10)" }, { "Atomic Symbol": "Au", "Mass Number": "184", "Relative Atomic Mass": "183.967452(24)" }, { "Atomic Symbol": "Au", "Mass Number": "185", "Relative Atomic Mass": "184.965790(28)" }, { "Atomic Symbol": "Au", "Mass Number": "186", "Relative Atomic Mass": "185.965953(23)" }, { "Atomic Symbol": "Au", "Mass Number": "187", "Relative Atomic Mass": "186.964543(24)" }, { "Atomic Symbol": "Au", "Mass Number": "188", "Relative Atomic Mass": "187.965349(17)" }, { "Atomic Symbol": "Au", "Mass Number": "189", "Relative Atomic Mass": "188.963948(22)" }, { "Atomic Symbol": "Au", "Mass Number": "190", "Relative Atomic Mass": "189.964698(17)" }, { "Atomic Symbol": "Au", "Mass Number": "191", "Relative Atomic Mass": "190.963702(40)" }, { "Atomic Symbol": "Au", "Mass Number": "192", "Relative Atomic Mass": "191.964814(17)" }, { "Atomic Symbol": "Au", "Mass Number": "193", "Relative Atomic Mass": "192.9641373(93)" }, { "Atomic Symbol": "Au", "Mass Number": "194", "Relative Atomic Mass": "193.9654178(23)" }, { "Atomic Symbol": "Au", "Mass Number": "195", "Relative Atomic Mass": "194.9650352(15)" }, { "Atomic Symbol": "Au", "Mass Number": "196", "Relative Atomic Mass": "195.9665699(32)" }, { "Atomic Symbol": "Au", "Mass Number": "197", "Isotopic Composition": "1", "Relative Atomic Mass": "196.96656879(71)" }, { "Atomic Symbol": "Au", "Mass Number": "198", "Relative Atomic Mass": "197.96824242(70)" }, { "Atomic Symbol": "Au", "Mass Number": "199", "Relative Atomic Mass": "198.96876528(70)" }, { "Atomic Symbol": "Au", "Mass Number": "200", "Relative Atomic Mass": "199.970756(29)" }, { "Atomic Symbol": "Au", "Mass Number": "201", "Relative Atomic Mass": "200.9716575(34)" }, { "Atomic Symbol": "Au", "Mass Number": "202", "Relative Atomic Mass": "201.973856(25)" }, { "Atomic Symbol": "Au", "Mass Number": "203", "Relative Atomic Mass": "202.9751544(33)" }, { "Atomic Symbol": "Au", "Mass Number": "204", "Relative Atomic Mass": "203.97783(22#)" }, { "Atomic Symbol": "Au", "Mass Number": "205", "Relative Atomic Mass": "204.97985(21#)" }, { "Atomic Symbol": "Au", "Mass Number": "206", "Relative Atomic Mass": "205.98474(32#)" }, { "Atomic Symbol": "Au", "Mass Number": "207", "Relative Atomic Mass": "206.98840(32#)" }, { "Atomic Symbol": "Au", "Mass Number": "208", "Relative Atomic Mass": "207.99345(32#)" }, { "Atomic Symbol": "Au", "Mass Number": "209", "Relative Atomic Mass": "208.99735(43#)" }, { "Atomic Symbol": "Au", "Mass Number": "210", "Relative Atomic Mass": "210.00250(43#)" } ], "Standard Atomic Weight": "196.966569(5)" }, { "Atomic Symbol": "Hg", "Atomic Number": "80", "isotopes": [ { "Atomic Symbol": "Hg", "Mass Number": "171", "Relative Atomic Mass": "171.00353(33#)" }, { "Atomic Symbol": "Hg", "Mass Number": "172", "Relative Atomic Mass": "171.99881(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "173", "Relative Atomic Mass": "172.99709(22#)" }, { "Atomic Symbol": "Hg", "Mass Number": "174", "Relative Atomic Mass": "173.992865(21)" }, { "Atomic Symbol": "Hg", "Mass Number": "175", "Relative Atomic Mass": "174.991441(78)" }, { "Atomic Symbol": "Hg", "Mass Number": "176", "Relative Atomic Mass": "175.987361(14)" }, { "Atomic Symbol": "Hg", "Mass Number": "177", "Relative Atomic Mass": "176.986277(81)" }, { "Atomic Symbol": "Hg", "Mass Number": "178", "Relative Atomic Mass": "177.982484(12)" }, { "Atomic Symbol": "Hg", "Mass Number": "179", "Relative Atomic Mass": "178.981831(29)" }, { "Atomic Symbol": "Hg", "Mass Number": "180", "Relative Atomic Mass": "179.978260(14)" }, { "Atomic Symbol": "Hg", "Mass Number": "181", "Relative Atomic Mass": "180.977819(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "182", "Relative Atomic Mass": "181.974689(11)" }, { "Atomic Symbol": "Hg", "Mass Number": "183", "Relative Atomic Mass": "182.9744448(76)" }, { "Atomic Symbol": "Hg", "Mass Number": "184", "Relative Atomic Mass": "183.971714(11)" }, { "Atomic Symbol": "Hg", "Mass Number": "185", "Relative Atomic Mass": "184.971899(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "186", "Relative Atomic Mass": "185.969362(13)" }, { "Atomic Symbol": "Hg", "Mass Number": "187", "Relative Atomic Mass": "186.969814(15)" }, { "Atomic Symbol": "Hg", "Mass Number": "188", "Relative Atomic Mass": "187.967567(12)" }, { "Atomic Symbol": "Hg", "Mass Number": "189", "Relative Atomic Mass": "188.968195(34)" }, { "Atomic Symbol": "Hg", "Mass Number": "190", "Relative Atomic Mass": "189.966323(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "191", "Relative Atomic Mass": "190.967157(24)" }, { "Atomic Symbol": "Hg", "Mass Number": "192", "Relative Atomic Mass": "191.965635(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "193", "Relative Atomic Mass": "192.966653(17)" }, { "Atomic Symbol": "Hg", "Mass Number": "194", "Relative Atomic Mass": "193.9654491(31)" }, { "Atomic Symbol": "Hg", "Mass Number": "195", "Relative Atomic Mass": "194.966721(25)" }, { "Atomic Symbol": "Hg", "Mass Number": "196", "Isotopic Composition": "0.0015(1)", "Relative Atomic Mass": "195.9658326(32)" }, { "Atomic Symbol": "Hg", "Mass Number": "197", "Relative Atomic Mass": "196.9672128(35)" }, { "Atomic Symbol": "Hg", "Mass Number": "198", "Isotopic Composition": "0.0997(20)", "Relative Atomic Mass": "197.96676860(52)" }, { "Atomic Symbol": "Hg", "Mass Number": "199", "Isotopic Composition": "0.1687(22)", "Relative Atomic Mass": "198.96828064(46)" }, { "Atomic Symbol": "Hg", "Mass Number": "200", "Isotopic Composition": "0.2310(19)", "Relative Atomic Mass": "199.96832659(47)" }, { "Atomic Symbol": "Hg", "Mass Number": "201", "Isotopic Composition": "0.1318(9)", "Relative Atomic Mass": "200.97030284(69)" }, { "Atomic Symbol": "Hg", "Mass Number": "202", "Isotopic Composition": "0.2986(26)", "Relative Atomic Mass": "201.97064340(69)" }, { "Atomic Symbol": "Hg", "Mass Number": "203", "Relative Atomic Mass": "202.9728728(18)" }, { "Atomic Symbol": "Hg", "Mass Number": "204", "Isotopic Composition": "0.0687(15)", "Relative Atomic Mass": "203.97349398(53)" }, { "Atomic Symbol": "Hg", "Mass Number": "205", "Relative Atomic Mass": "204.9760734(39)" }, { "Atomic Symbol": "Hg", "Mass Number": "206", "Relative Atomic Mass": "205.977514(22)" }, { "Atomic Symbol": "Hg", "Mass Number": "207", "Relative Atomic Mass": "206.982300(32)" }, { "Atomic Symbol": "Hg", "Mass Number": "208", "Relative Atomic Mass": "207.985759(33)" }, { "Atomic Symbol": "Hg", "Mass Number": "209", "Relative Atomic Mass": "208.99072(16#)" }, { "Atomic Symbol": "Hg", "Mass Number": "210", "Relative Atomic Mass": "209.99424(21#)" }, { "Atomic Symbol": "Hg", "Mass Number": "211", "Relative Atomic Mass": "210.99933(21#)" }, { "Atomic Symbol": "Hg", "Mass Number": "212", "Relative Atomic Mass": "212.00296(32#)" }, { "Atomic Symbol": "Hg", "Mass Number": "213", "Relative Atomic Mass": "213.00823(32#)" }, { "Atomic Symbol": "Hg", "Mass Number": "214", "Relative Atomic Mass": "214.01200(43#)" }, { "Atomic Symbol": "Hg", "Mass Number": "215", "Relative Atomic Mass": "215.01740(43#)" }, { "Atomic Symbol": "Hg", "Mass Number": "216", "Relative Atomic Mass": "216.02132(43#)" } ], "Standard Atomic Weight": "200.592(3)" }, { "Atomic Symbol": "Tl", "Atomic Number": "81", "isotopes": [ { "Atomic Symbol": "Tl", "Mass Number": "176", "Relative Atomic Mass": "176.000624(81)" }, { "Atomic Symbol": "Tl", "Mass Number": "177", "Relative Atomic Mass": "176.996431(25)" }, { "Atomic Symbol": "Tl", "Mass Number": "178", "Relative Atomic Mass": "177.99485(11#)" }, { "Atomic Symbol": "Tl", "Mass Number": "179", "Relative Atomic Mass": "178.991111(43)" }, { "Atomic Symbol": "Tl", "Mass Number": "180", "Relative Atomic Mass": "179.990057(64)" }, { "Atomic Symbol": "Tl", "Mass Number": "181", "Relative Atomic Mass": "180.9862600(98)" }, { "Atomic Symbol": "Tl", "Mass Number": "182", "Relative Atomic Mass": "181.985713(63)" }, { "Atomic Symbol": "Tl", "Mass Number": "183", "Relative Atomic Mass": "182.982193(10)" }, { "Atomic Symbol": "Tl", "Mass Number": "184", "Relative Atomic Mass": "183.981886(22)" }, { "Atomic Symbol": "Tl", "Mass Number": "185", "Relative Atomic Mass": "184.978789(22)" }, { "Atomic Symbol": "Tl", "Mass Number": "186", "Relative Atomic Mass": "185.978651(24)" }, { "Atomic Symbol": "Tl", "Mass Number": "187", "Relative Atomic Mass": "186.9759063(88)" }, { "Atomic Symbol": "Tl", "Mass Number": "188", "Relative Atomic Mass": "187.976021(32)" }, { "Atomic Symbol": "Tl", "Mass Number": "189", "Relative Atomic Mass": "188.973588(12)" }, { "Atomic Symbol": "Tl", "Mass Number": "190", "Relative Atomic Mass": "189.973828(54#)" }, { "Atomic Symbol": "Tl", "Mass Number": "191", "Relative Atomic Mass": "190.9717842(79)" }, { "Atomic Symbol": "Tl", "Mass Number": "192", "Relative Atomic Mass": "191.972225(34)" }, { "Atomic Symbol": "Tl", "Mass Number": "193", "Relative Atomic Mass": "192.9705020(72)" }, { "Atomic Symbol": "Tl", "Mass Number": "194", "Relative Atomic Mass": "193.971081(15)" }, { "Atomic Symbol": "Tl", "Mass Number": "195", "Relative Atomic Mass": "194.969774(12)" }, { "Atomic Symbol": "Tl", "Mass Number": "196", "Relative Atomic Mass": "195.970481(13)" }, { "Atomic Symbol": "Tl", "Mass Number": "197", "Relative Atomic Mass": "196.969576(18)" }, { "Atomic Symbol": "Tl", "Mass Number": "198", "Relative Atomic Mass": "197.970483(86)" }, { "Atomic Symbol": "Tl", "Mass Number": "199", "Relative Atomic Mass": "198.969877(30)" }, { "Atomic Symbol": "Tl", "Mass Number": "200", "Relative Atomic Mass": "199.9709633(62)" }, { "Atomic Symbol": "Tl", "Mass Number": "201", "Relative Atomic Mass": "200.970822(15)" }, { "Atomic Symbol": "Tl", "Mass Number": "202", "Relative Atomic Mass": "201.972102(15)" }, { "Atomic Symbol": "Tl", "Mass Number": "203", "Isotopic Composition": "0.2952(1)", "Relative Atomic Mass": "202.9723446(14)" }, { "Atomic Symbol": "Tl", "Mass Number": "204", "Relative Atomic Mass": "203.9738639(13)" }, { "Atomic Symbol": "Tl", "Mass Number": "205", "Isotopic Composition": "0.7048(1)", "Relative Atomic Mass": "204.9744278(14)" }, { "Atomic Symbol": "Tl", "Mass Number": "206", "Relative Atomic Mass": "205.9761106(15)" }, { "Atomic Symbol": "Tl", "Mass Number": "207", "Relative Atomic Mass": "206.9774197(59)" }, { "Atomic Symbol": "Tl", "Mass Number": "208", "Relative Atomic Mass": "207.9820190(21)" }, { "Atomic Symbol": "Tl", "Mass Number": "209", "Relative Atomic Mass": "208.9853594(86)" }, { "Atomic Symbol": "Tl", "Mass Number": "210", "Relative Atomic Mass": "209.990074(12)" }, { "Atomic Symbol": "Tl", "Mass Number": "211", "Relative Atomic Mass": "210.993475(45)" }, { "Atomic Symbol": "Tl", "Mass Number": "212", "Relative Atomic Mass": "211.99834(22#)" }, { "Atomic Symbol": "Tl", "Mass Number": "213", "Relative Atomic Mass": "213.001915(29)" }, { "Atomic Symbol": "Tl", "Mass Number": "214", "Relative Atomic Mass": "214.00694(21#)" }, { "Atomic Symbol": "Tl", "Mass Number": "215", "Relative Atomic Mass": "215.01064(32#)" }, { "Atomic Symbol": "Tl", "Mass Number": "216", "Relative Atomic Mass": "216.01580(32#)" }, { "Atomic Symbol": "Tl", "Mass Number": "217", "Relative Atomic Mass": "217.01966(43#)" }, { "Atomic Symbol": "Tl", "Mass Number": "218", "Relative Atomic Mass": "218.02479(43#)" } ], "Standard Atomic Weight": "[204.382,204.385]" }, { "Atomic Symbol": "Pb", "Atomic Number": "82", "isotopes": [ { "Atomic Symbol": "Pb", "Mass Number": "178", "Relative Atomic Mass": "178.003831(26)" }, { "Atomic Symbol": "Pb", "Mass Number": "179", "Relative Atomic Mass": "179.002201(81)" }, { "Atomic Symbol": "Pb", "Mass Number": "180", "Relative Atomic Mass": "179.997928(15)" }, { "Atomic Symbol": "Pb", "Mass Number": "181", "Relative Atomic Mass": "180.996653(81)" }, { "Atomic Symbol": "Pb", "Mass Number": "182", "Relative Atomic Mass": "181.992672(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "183", "Relative Atomic Mass": "182.991872(30)" }, { "Atomic Symbol": "Pb", "Mass Number": "184", "Relative Atomic Mass": "183.988136(14)" }, { "Atomic Symbol": "Pb", "Mass Number": "185", "Relative Atomic Mass": "184.987610(17)" }, { "Atomic Symbol": "Pb", "Mass Number": "186", "Relative Atomic Mass": "185.984238(12)" }, { "Atomic Symbol": "Pb", "Mass Number": "187", "Relative Atomic Mass": "186.9839109(55)" }, { "Atomic Symbol": "Pb", "Mass Number": "188", "Relative Atomic Mass": "187.980875(11)" }, { "Atomic Symbol": "Pb", "Mass Number": "189", "Relative Atomic Mass": "188.980807(37)" }, { "Atomic Symbol": "Pb", "Mass Number": "190", "Relative Atomic Mass": "189.978082(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "191", "Relative Atomic Mass": "190.978276(41)" }, { "Atomic Symbol": "Pb", "Mass Number": "192", "Relative Atomic Mass": "191.975775(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "193", "Relative Atomic Mass": "192.976173(53)" }, { "Atomic Symbol": "Pb", "Mass Number": "194", "Relative Atomic Mass": "193.974012(19)" }, { "Atomic Symbol": "Pb", "Mass Number": "195", "Relative Atomic Mass": "194.974543(25)" }, { "Atomic Symbol": "Pb", "Mass Number": "196", "Relative Atomic Mass": "195.972774(15)" }, { "Atomic Symbol": "Pb", "Mass Number": "197", "Relative Atomic Mass": "196.9734312(60)" }, { "Atomic Symbol": "Pb", "Mass Number": "198", "Relative Atomic Mass": "197.972034(16)" }, { "Atomic Symbol": "Pb", "Mass Number": "199", "Relative Atomic Mass": "198.972913(11)" }, { "Atomic Symbol": "Pb", "Mass Number": "200", "Relative Atomic Mass": "199.971819(12)" }, { "Atomic Symbol": "Pb", "Mass Number": "201", "Relative Atomic Mass": "200.972883(23)" }, { "Atomic Symbol": "Pb", "Mass Number": "202", "Relative Atomic Mass": "201.9721520(40)" }, { "Atomic Symbol": "Pb", "Mass Number": "203", "Relative Atomic Mass": "202.9733911(71)" }, { "Atomic Symbol": "Pb", "Mass Number": "204", "Isotopic Composition": "0.014(1)", "Relative Atomic Mass": "203.9730440(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "205", "Relative Atomic Mass": "204.9744822(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "206", "Isotopic Composition": "0.241(1)", "Relative Atomic Mass": "205.9744657(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "207", "Isotopic Composition": "0.221(1)", "Relative Atomic Mass": "206.9758973(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "208", "Isotopic Composition": "0.524(1)", "Relative Atomic Mass": "207.9766525(13)" }, { "Atomic Symbol": "Pb", "Mass Number": "209", "Relative Atomic Mass": "208.9810905(19)" }, { "Atomic Symbol": "Pb", "Mass Number": "210", "Relative Atomic Mass": "209.9841889(16)" }, { "Atomic Symbol": "Pb", "Mass Number": "211", "Relative Atomic Mass": "210.9887371(28)" }, { "Atomic Symbol": "Pb", "Mass Number": "212", "Relative Atomic Mass": "211.9918977(23)" }, { "Atomic Symbol": "Pb", "Mass Number": "213", "Relative Atomic Mass": "212.9965629(72)" }, { "Atomic Symbol": "Pb", "Mass Number": "214", "Relative Atomic Mass": "213.9998059(25)" }, { "Atomic Symbol": "Pb", "Mass Number": "215", "Relative Atomic Mass": "215.00474(11#)" }, { "Atomic Symbol": "Pb", "Mass Number": "216", "Relative Atomic Mass": "216.00803(21#)" }, { "Atomic Symbol": "Pb", "Mass Number": "217", "Relative Atomic Mass": "217.01314(32#)" }, { "Atomic Symbol": "Pb", "Mass Number": "218", "Relative Atomic Mass": "218.01659(32#)" }, { "Atomic Symbol": "Pb", "Mass Number": "219", "Relative Atomic Mass": "219.02177(43#)" }, { "Atomic Symbol": "Pb", "Mass Number": "220", "Relative Atomic Mass": "220.02541(43#)" } ], "Notes": "g,r", "Standard Atomic Weight": "207.2(1)" }, { "Atomic Symbol": "Bi", "Atomic Number": "83", "isotopes": [ { "Atomic Symbol": "Bi", "Mass Number": "184", "Relative Atomic Mass": "184.001275(84)" }, { "Atomic Symbol": "Bi", "Mass Number": "185", "Relative Atomic Mass": "184.997600(87#)" }, { "Atomic Symbol": "Bi", "Mass Number": "186", "Relative Atomic Mass": "185.996644(65)" }, { "Atomic Symbol": "Bi", "Mass Number": "187", "Relative Atomic Mass": "186.993147(11)" }, { "Atomic Symbol": "Bi", "Mass Number": "188", "Relative Atomic Mass": "187.992287(22)" }, { "Atomic Symbol": "Bi", "Mass Number": "189", "Relative Atomic Mass": "188.989195(22)" }, { "Atomic Symbol": "Bi", "Mass Number": "190", "Relative Atomic Mass": "189.988622(24)" }, { "Atomic Symbol": "Bi", "Mass Number": "191", "Relative Atomic Mass": "190.9857866(80)" }, { "Atomic Symbol": "Bi", "Mass Number": "192", "Relative Atomic Mass": "191.985469(33)" }, { "Atomic Symbol": "Bi", "Mass Number": "193", "Relative Atomic Mass": "192.982960(10)" }, { "Atomic Symbol": "Bi", "Mass Number": "194", "Relative Atomic Mass": "193.982785(54#)" }, { "Atomic Symbol": "Bi", "Mass Number": "195", "Relative Atomic Mass": "194.9806488(57)" }, { "Atomic Symbol": "Bi", "Mass Number": "196", "Relative Atomic Mass": "195.980667(26)" }, { "Atomic Symbol": "Bi", "Mass Number": "197", "Relative Atomic Mass": "196.9788651(89)" }, { "Atomic Symbol": "Bi", "Mass Number": "198", "Relative Atomic Mass": "197.979206(30)" }, { "Atomic Symbol": "Bi", "Mass Number": "199", "Relative Atomic Mass": "198.977673(11)" }, { "Atomic Symbol": "Bi", "Mass Number": "200", "Relative Atomic Mass": "199.978131(24)" }, { "Atomic Symbol": "Bi", "Mass Number": "201", "Relative Atomic Mass": "200.977010(16)" }, { "Atomic Symbol": "Bi", "Mass Number": "202", "Relative Atomic Mass": "201.977734(17)" }, { "Atomic Symbol": "Bi", "Mass Number": "203", "Relative Atomic Mass": "202.976893(14)" }, { "Atomic Symbol": "Bi", "Mass Number": "204", "Relative Atomic Mass": "203.9778361(99)" }, { "Atomic Symbol": "Bi", "Mass Number": "205", "Relative Atomic Mass": "204.9773867(55)" }, { "Atomic Symbol": "Bi", "Mass Number": "206", "Relative Atomic Mass": "205.9784993(82)" }, { "Atomic Symbol": "Bi", "Mass Number": "207", "Relative Atomic Mass": "206.9784710(26)" }, { "Atomic Symbol": "Bi", "Mass Number": "208", "Relative Atomic Mass": "207.9797425(25)" }, { "Atomic Symbol": "Bi", "Mass Number": "209", "Isotopic Composition": "1", "Relative Atomic Mass": "208.9803991(16)" }, { "Atomic Symbol": "Bi", "Mass Number": "210", "Relative Atomic Mass": "209.9841207(16)" }, { "Atomic Symbol": "Bi", "Mass Number": "211", "Relative Atomic Mass": "210.9872697(59)" }, { "Atomic Symbol": "Bi", "Mass Number": "212", "Relative Atomic Mass": "211.9912860(21)" }, { "Atomic Symbol": "Bi", "Mass Number": "213", "Relative Atomic Mass": "212.9943851(56)" }, { "Atomic Symbol": "Bi", "Mass Number": "214", "Relative Atomic Mass": "213.998712(12)" }, { "Atomic Symbol": "Bi", "Mass Number": "215", "Relative Atomic Mass": "215.001770(16)" }, { "Atomic Symbol": "Bi", "Mass Number": "216", "Relative Atomic Mass": "216.006306(12)" }, { "Atomic Symbol": "Bi", "Mass Number": "217", "Relative Atomic Mass": "217.009372(19)" }, { "Atomic Symbol": "Bi", "Mass Number": "218", "Relative Atomic Mass": "218.014188(29)" }, { "Atomic Symbol": "Bi", "Mass Number": "219", "Relative Atomic Mass": "219.01748(21#)" }, { "Atomic Symbol": "Bi", "Mass Number": "220", "Relative Atomic Mass": "220.02235(32#)" }, { "Atomic Symbol": "Bi", "Mass Number": "221", "Relative Atomic Mass": "221.02587(32#)" }, { "Atomic Symbol": "Bi", "Mass Number": "222", "Relative Atomic Mass": "222.03078(32#)" }, { "Atomic Symbol": "Bi", "Mass Number": "223", "Relative Atomic Mass": "223.03450(43#)" }, { "Atomic Symbol": "Bi", "Mass Number": "224", "Relative Atomic Mass": "224.03947(43#)" } ], "Standard Atomic Weight": "208.98040(1)" }, { "Atomic Symbol": "Po", "Atomic Number": "84", "isotopes": [ { "Atomic Symbol": "Po", "Mass Number": "186", "Relative Atomic Mass": "186.004393(35)" }, { "Atomic Symbol": "Po", "Mass Number": "187", "Relative Atomic Mass": "187.003041(34)" }, { "Atomic Symbol": "Po", "Mass Number": "188", "Relative Atomic Mass": "187.999416(21)" }, { "Atomic Symbol": "Po", "Mass Number": "189", "Relative Atomic Mass": "188.998473(24)" }, { "Atomic Symbol": "Po", "Mass Number": "190", "Relative Atomic Mass": "189.995101(14)" }, { "Atomic Symbol": "Po", "Mass Number": "191", "Relative Atomic Mass": "190.9945585(76)" }, { "Atomic Symbol": "Po", "Mass Number": "192", "Relative Atomic Mass": "191.991336(12)" }, { "Atomic Symbol": "Po", "Mass Number": "193", "Relative Atomic Mass": "192.991026(37)" }, { "Atomic Symbol": "Po", "Mass Number": "194", "Relative Atomic Mass": "193.988186(14)" }, { "Atomic Symbol": "Po", "Mass Number": "195", "Relative Atomic Mass": "194.988126(41)" }, { "Atomic Symbol": "Po", "Mass Number": "196", "Relative Atomic Mass": "195.985526(14)" }, { "Atomic Symbol": "Po", "Mass Number": "197", "Relative Atomic Mass": "196.985660(53)" }, { "Atomic Symbol": "Po", "Mass Number": "198", "Relative Atomic Mass": "197.983389(19)" }, { "Atomic Symbol": "Po", "Mass Number": "199", "Relative Atomic Mass": "198.983667(25)" }, { "Atomic Symbol": "Po", "Mass Number": "200", "Relative Atomic Mass": "199.981799(15)" }, { "Atomic Symbol": "Po", "Mass Number": "201", "Relative Atomic Mass": "200.9822598(63)" }, { "Atomic Symbol": "Po", "Mass Number": "202", "Relative Atomic Mass": "201.980758(16)" }, { "Atomic Symbol": "Po", "Mass Number": "203", "Relative Atomic Mass": "202.9814161(93)" }, { "Atomic Symbol": "Po", "Mass Number": "204", "Relative Atomic Mass": "203.980310(12)" }, { "Atomic Symbol": "Po", "Mass Number": "205", "Relative Atomic Mass": "204.981203(22)" }, { "Atomic Symbol": "Po", "Mass Number": "206", "Relative Atomic Mass": "205.9804740(43)" }, { "Atomic Symbol": "Po", "Mass Number": "207", "Relative Atomic Mass": "206.9815938(72)" }, { "Atomic Symbol": "Po", "Mass Number": "208", "Relative Atomic Mass": "207.9812461(19)" }, { "Atomic Symbol": "Po", "Mass Number": "209", "Relative Atomic Mass": "208.9824308(20)" }, { "Atomic Symbol": "Po", "Mass Number": "210", "Relative Atomic Mass": "209.9828741(13)" }, { "Atomic Symbol": "Po", "Mass Number": "211", "Relative Atomic Mass": "210.9866536(14)" }, { "Atomic Symbol": "Po", "Mass Number": "212", "Relative Atomic Mass": "211.9888684(13)" }, { "Atomic Symbol": "Po", "Mass Number": "213", "Relative Atomic Mass": "212.9928576(33)" }, { "Atomic Symbol": "Po", "Mass Number": "214", "Relative Atomic Mass": "213.9952017(16)" }, { "Atomic Symbol": "Po", "Mass Number": "215", "Relative Atomic Mass": "214.9994201(27)" }, { "Atomic Symbol": "Po", "Mass Number": "216", "Relative Atomic Mass": "216.0019152(23)" }, { "Atomic Symbol": "Po", "Mass Number": "217", "Relative Atomic Mass": "217.0063182(67)" }, { "Atomic Symbol": "Po", "Mass Number": "218", "Relative Atomic Mass": "218.0089735(25)" }, { "Atomic Symbol": "Po", "Mass Number": "219", "Relative Atomic Mass": "219.013614(17)" }, { "Atomic Symbol": "Po", "Mass Number": "220", "Relative Atomic Mass": "220.016386(19)" }, { "Atomic Symbol": "Po", "Mass Number": "221", "Relative Atomic Mass": "221.021228(21)" }, { "Atomic Symbol": "Po", "Mass Number": "222", "Relative Atomic Mass": "222.024140(43)" }, { "Atomic Symbol": "Po", "Mass Number": "223", "Relative Atomic Mass": "223.02907(21#)" }, { "Atomic Symbol": "Po", "Mass Number": "224", "Relative Atomic Mass": "224.03211(21#)" }, { "Atomic Symbol": "Po", "Mass Number": "225", "Relative Atomic Mass": "225.03707(32#)" }, { "Atomic Symbol": "Po", "Mass Number": "226", "Relative Atomic Mass": "226.04031(43#)" }, { "Atomic Symbol": "Po", "Mass Number": "227", "Relative Atomic Mass": "227.04539(43#)" } ], "Standard Atomic Weight": "[209]" }, { "Atomic Symbol": "At", "Atomic Number": "85", "isotopes": [ { "Atomic Symbol": "At", "Mass Number": "191", "Relative Atomic Mass": "191.004148(17)" }, { "Atomic Symbol": "At", "Mass Number": "192", "Relative Atomic Mass": "192.003152(35)" }, { "Atomic Symbol": "At", "Mass Number": "193", "Relative Atomic Mass": "192.999927(23)" }, { "Atomic Symbol": "At", "Mass Number": "194", "Relative Atomic Mass": "193.999236(29)" }, { "Atomic Symbol": "At", "Mass Number": "195", "Relative Atomic Mass": "194.9962685(98)" }, { "Atomic Symbol": "At", "Mass Number": "196", "Relative Atomic Mass": "195.995800(33)" }, { "Atomic Symbol": "At", "Mass Number": "197", "Relative Atomic Mass": "196.993189(55)" }, { "Atomic Symbol": "At", "Mass Number": "198", "Relative Atomic Mass": "197.992784(54#)" }, { "Atomic Symbol": "At", "Mass Number": "199", "Relative Atomic Mass": "198.9905277(58)" }, { "Atomic Symbol": "At", "Mass Number": "200", "Relative Atomic Mass": "199.990351(26)" }, { "Atomic Symbol": "At", "Mass Number": "201", "Relative Atomic Mass": "200.9884171(88)" }, { "Atomic Symbol": "At", "Mass Number": "202", "Relative Atomic Mass": "201.988630(30)" }, { "Atomic Symbol": "At", "Mass Number": "203", "Relative Atomic Mass": "202.986943(11)" }, { "Atomic Symbol": "At", "Mass Number": "204", "Relative Atomic Mass": "203.987251(24)" }, { "Atomic Symbol": "At", "Mass Number": "205", "Relative Atomic Mass": "204.986076(16)" }, { "Atomic Symbol": "At", "Mass Number": "206", "Relative Atomic Mass": "205.986657(16)" }, { "Atomic Symbol": "At", "Mass Number": "207", "Relative Atomic Mass": "206.985800(13)" }, { "Atomic Symbol": "At", "Mass Number": "208", "Relative Atomic Mass": "207.9866133(96)" }, { "Atomic Symbol": "At", "Mass Number": "209", "Relative Atomic Mass": "208.9861702(55)" }, { "Atomic Symbol": "At", "Mass Number": "210", "Relative Atomic Mass": "209.9871479(83)" }, { "Atomic Symbol": "At", "Mass Number": "211", "Relative Atomic Mass": "210.9874966(30)" }, { "Atomic Symbol": "At", "Mass Number": "212", "Relative Atomic Mass": "211.9907377(26)" }, { "Atomic Symbol": "At", "Mass Number": "213", "Relative Atomic Mass": "212.9929370(53)" }, { "Atomic Symbol": "At", "Mass Number": "214", "Relative Atomic Mass": "213.9963721(46)" }, { "Atomic Symbol": "At", "Mass Number": "215", "Relative Atomic Mass": "214.9986528(73)" }, { "Atomic Symbol": "At", "Mass Number": "216", "Relative Atomic Mass": "216.0024236(39)" }, { "Atomic Symbol": "At", "Mass Number": "217", "Relative Atomic Mass": "217.0047192(55)" }, { "Atomic Symbol": "At", "Mass Number": "218", "Relative Atomic Mass": "218.008695(12)" }, { "Atomic Symbol": "At", "Mass Number": "219", "Relative Atomic Mass": "219.0111618(42)" }, { "Atomic Symbol": "At", "Mass Number": "220", "Relative Atomic Mass": "220.015433(15)" }, { "Atomic Symbol": "At", "Mass Number": "221", "Relative Atomic Mass": "221.018017(15)" }, { "Atomic Symbol": "At", "Mass Number": "222", "Relative Atomic Mass": "222.022494(17)" }, { "Atomic Symbol": "At", "Mass Number": "223", "Relative Atomic Mass": "223.025151(15)" }, { "Atomic Symbol": "At", "Mass Number": "224", "Relative Atomic Mass": "224.029749(24)" }, { "Atomic Symbol": "At", "Mass Number": "225", "Relative Atomic Mass": "225.03263(32#)" }, { "Atomic Symbol": "At", "Mass Number": "226", "Relative Atomic Mass": "226.03716(32#)" }, { "Atomic Symbol": "At", "Mass Number": "227", "Relative Atomic Mass": "227.04024(32#)" }, { "Atomic Symbol": "At", "Mass Number": "228", "Relative Atomic Mass": "228.04475(43#)" }, { "Atomic Symbol": "At", "Mass Number": "229", "Relative Atomic Mass": "229.04812(43#)" } ], "Standard Atomic Weight": "[210]" }, { "Atomic Symbol": "Rn", "Atomic Number": "86", "isotopes": [ { "Atomic Symbol": "Rn", "Mass Number": "193", "Relative Atomic Mass": "193.009708(27)" }, { "Atomic Symbol": "Rn", "Mass Number": "194", "Relative Atomic Mass": "194.006144(18)" }, { "Atomic Symbol": "Rn", "Mass Number": "195", "Relative Atomic Mass": "195.005422(54)" }, { "Atomic Symbol": "Rn", "Mass Number": "196", "Relative Atomic Mass": "196.002116(15)" }, { "Atomic Symbol": "Rn", "Mass Number": "197", "Relative Atomic Mass": "197.001585(38)" }, { "Atomic Symbol": "Rn", "Mass Number": "198", "Relative Atomic Mass": "197.998679(14)" }, { "Atomic Symbol": "Rn", "Mass Number": "199", "Relative Atomic Mass": "198.998390(68)" }, { "Atomic Symbol": "Rn", "Mass Number": "200", "Relative Atomic Mass": "199.995690(14)" }, { "Atomic Symbol": "Rn", "Mass Number": "201", "Relative Atomic Mass": "200.995628(53)" }, { "Atomic Symbol": "Rn", "Mass Number": "202", "Relative Atomic Mass": "201.993264(19)" }, { "Atomic Symbol": "Rn", "Mass Number": "203", "Relative Atomic Mass": "202.993388(25)" }, { "Atomic Symbol": "Rn", "Mass Number": "204", "Relative Atomic Mass": "203.991430(16)" }, { "Atomic Symbol": "Rn", "Mass Number": "205", "Relative Atomic Mass": "204.991719(54)" }, { "Atomic Symbol": "Rn", "Mass Number": "206", "Relative Atomic Mass": "205.990214(16)" }, { "Atomic Symbol": "Rn", "Mass Number": "207", "Relative Atomic Mass": "206.9907303(91)" }, { "Atomic Symbol": "Rn", "Mass Number": "208", "Relative Atomic Mass": "207.989635(12)" }, { "Atomic Symbol": "Rn", "Mass Number": "209", "Relative Atomic Mass": "208.990415(22)" }, { "Atomic Symbol": "Rn", "Mass Number": "210", "Relative Atomic Mass": "209.9896891(49)" }, { "Atomic Symbol": "Rn", "Mass Number": "211", "Relative Atomic Mass": "210.9906011(73)" }, { "Atomic Symbol": "Rn", "Mass Number": "212", "Relative Atomic Mass": "211.9907039(34)" }, { "Atomic Symbol": "Rn", "Mass Number": "213", "Relative Atomic Mass": "212.9938831(61)" }, { "Atomic Symbol": "Rn", "Mass Number": "214", "Relative Atomic Mass": "213.9953630(99)" }, { "Atomic Symbol": "Rn", "Mass Number": "215", "Relative Atomic Mass": "214.9987459(83)" }, { "Atomic Symbol": "Rn", "Mass Number": "216", "Relative Atomic Mass": "216.0002719(65)" }, { "Atomic Symbol": "Rn", "Mass Number": "217", "Relative Atomic Mass": "217.0039280(45)" }, { "Atomic Symbol": "Rn", "Mass Number": "218", "Relative Atomic Mass": "218.0056016(25)" }, { "Atomic Symbol": "Rn", "Mass Number": "219", "Relative Atomic Mass": "219.0094804(27)" }, { "Atomic Symbol": "Rn", "Mass Number": "220", "Relative Atomic Mass": "220.0113941(23)" }, { "Atomic Symbol": "Rn", "Mass Number": "221", "Relative Atomic Mass": "221.0155371(63)" }, { "Atomic Symbol": "Rn", "Mass Number": "222", "Relative Atomic Mass": "222.0175782(25)" }, { "Atomic Symbol": "Rn", "Mass Number": "223", "Relative Atomic Mass": "223.0218893(84)" }, { "Atomic Symbol": "Rn", "Mass Number": "224", "Relative Atomic Mass": "224.024096(11)" }, { "Atomic Symbol": "Rn", "Mass Number": "225", "Relative Atomic Mass": "225.028486(12)" }, { "Atomic Symbol": "Rn", "Mass Number": "226", "Relative Atomic Mass": "226.030861(11)" }, { "Atomic Symbol": "Rn", "Mass Number": "227", "Relative Atomic Mass": "227.035304(15)" }, { "Atomic Symbol": "Rn", "Mass Number": "228", "Relative Atomic Mass": "228.037835(19)" }, { "Atomic Symbol": "Rn", "Mass Number": "229", "Relative Atomic Mass": "229.042257(14)" }, { "Atomic Symbol": "Rn", "Mass Number": "230", "Relative Atomic Mass": "230.04514(21#)" }, { "Atomic Symbol": "Rn", "Mass Number": "231", "Relative Atomic Mass": "231.04987(32#)" } ], "Standard Atomic Weight": "[222]" }, { "Atomic Symbol": "Fr", "Atomic Number": "87", "isotopes": [ { "Atomic Symbol": "Fr", "Mass Number": "199", "Relative Atomic Mass": "199.007259(45)" }, { "Atomic Symbol": "Fr", "Mass Number": "200", "Relative Atomic Mass": "200.006586(63)" }, { "Atomic Symbol": "Fr", "Mass Number": "201", "Relative Atomic Mass": "201.003867(77)" }, { "Atomic Symbol": "Fr", "Mass Number": "202", "Relative Atomic Mass": "202.003320(55#)" }, { "Atomic Symbol": "Fr", "Mass Number": "203", "Relative Atomic Mass": "203.0009407(67)" }, { "Atomic Symbol": "Fr", "Mass Number": "204", "Relative Atomic Mass": "204.000652(26)" }, { "Atomic Symbol": "Fr", "Mass Number": "205", "Relative Atomic Mass": "204.9985939(84)" }, { "Atomic Symbol": "Fr", "Mass Number": "206", "Relative Atomic Mass": "205.998666(30)" }, { "Atomic Symbol": "Fr", "Mass Number": "207", "Relative Atomic Mass": "206.996946(19)" }, { "Atomic Symbol": "Fr", "Mass Number": "208", "Relative Atomic Mass": "207.997138(12)" }, { "Atomic Symbol": "Fr", "Mass Number": "209", "Relative Atomic Mass": "208.995955(16)" }, { "Atomic Symbol": "Fr", "Mass Number": "210", "Relative Atomic Mass": "209.996422(16)" }, { "Atomic Symbol": "Fr", "Mass Number": "211", "Relative Atomic Mass": "210.995556(13)" }, { "Atomic Symbol": "Fr", "Mass Number": "212", "Relative Atomic Mass": "211.9962257(94)" }, { "Atomic Symbol": "Fr", "Mass Number": "213", "Relative Atomic Mass": "212.9961860(55)" }, { "Atomic Symbol": "Fr", "Mass Number": "214", "Relative Atomic Mass": "213.9989713(93)" }, { "Atomic Symbol": "Fr", "Mass Number": "215", "Relative Atomic Mass": "215.0003418(76)" }, { "Atomic Symbol": "Fr", "Mass Number": "216", "Relative Atomic Mass": "216.0031899(45)" }, { "Atomic Symbol": "Fr", "Mass Number": "217", "Relative Atomic Mass": "217.0046323(70)" }, { "Atomic Symbol": "Fr", "Mass Number": "218", "Relative Atomic Mass": "218.0075787(51)" }, { "Atomic Symbol": "Fr", "Mass Number": "219", "Relative Atomic Mass": "219.0092524(76)" }, { "Atomic Symbol": "Fr", "Mass Number": "220", "Relative Atomic Mass": "220.0123277(44)" }, { "Atomic Symbol": "Fr", "Mass Number": "221", "Relative Atomic Mass": "221.0142552(54)" }, { "Atomic Symbol": "Fr", "Mass Number": "222", "Relative Atomic Mass": "222.017552(23)" }, { "Atomic Symbol": "Fr", "Mass Number": "223", "Relative Atomic Mass": "223.0197360(25)" }, { "Atomic Symbol": "Fr", "Mass Number": "224", "Relative Atomic Mass": "224.023398(14)" }, { "Atomic Symbol": "Fr", "Mass Number": "225", "Relative Atomic Mass": "225.025573(13)" }, { "Atomic Symbol": "Fr", "Mass Number": "226", "Relative Atomic Mass": "226.029566(13)" }, { "Atomic Symbol": "Fr", "Mass Number": "227", "Relative Atomic Mass": "227.031869(14)" }, { "Atomic Symbol": "Fr", "Mass Number": "228", "Relative Atomic Mass": "228.035823(14)" }, { "Atomic Symbol": "Fr", "Mass Number": "229", "Relative Atomic Mass": "229.038298(15)" }, { "Atomic Symbol": "Fr", "Mass Number": "230", "Relative Atomic Mass": "230.042416(17)" }, { "Atomic Symbol": "Fr", "Mass Number": "231", "Relative Atomic Mass": "231.045158(27)" }, { "Atomic Symbol": "Fr", "Mass Number": "232", "Relative Atomic Mass": "232.04937(17#)" }, { "Atomic Symbol": "Fr", "Mass Number": "233", "Relative Atomic Mass": "233.05264(32#)" } ], "Standard Atomic Weight": "[223]" }, { "Atomic Symbol": "Ra", "Atomic Number": "88", "isotopes": [ { "Atomic Symbol": "Ra", "Mass Number": "201", "Relative Atomic Mass": "201.01271(11#)" }, { "Atomic Symbol": "Ra", "Mass Number": "202", "Relative Atomic Mass": "202.009760(26)" }, { "Atomic Symbol": "Ra", "Mass Number": "203", "Relative Atomic Mass": "203.009304(86)" }, { "Atomic Symbol": "Ra", "Mass Number": "204", "Relative Atomic Mass": "204.006492(16)" }, { "Atomic Symbol": "Ra", "Mass Number": "205", "Relative Atomic Mass": "205.006268(76)" }, { "Atomic Symbol": "Ra", "Mass Number": "206", "Relative Atomic Mass": "206.003828(19)" }, { "Atomic Symbol": "Ra", "Mass Number": "207", "Relative Atomic Mass": "207.003799(59)" }, { "Atomic Symbol": "Ra", "Mass Number": "208", "Relative Atomic Mass": "208.001841(17)" }, { "Atomic Symbol": "Ra", "Mass Number": "209", "Relative Atomic Mass": "209.001990(54)" }, { "Atomic Symbol": "Ra", "Mass Number": "210", "Relative Atomic Mass": "210.000494(16)" }, { "Atomic Symbol": "Ra", "Mass Number": "211", "Relative Atomic Mass": "211.0008932(85)" }, { "Atomic Symbol": "Ra", "Mass Number": "212", "Relative Atomic Mass": "211.999787(12)" }, { "Atomic Symbol": "Ra", "Mass Number": "213", "Relative Atomic Mass": "213.000384(22)" }, { "Atomic Symbol": "Ra", "Mass Number": "214", "Relative Atomic Mass": "214.0000997(56)" }, { "Atomic Symbol": "Ra", "Mass Number": "215", "Relative Atomic Mass": "215.0027204(82)" }, { "Atomic Symbol": "Ra", "Mass Number": "216", "Relative Atomic Mass": "216.0035334(94)" }, { "Atomic Symbol": "Ra", "Mass Number": "217", "Relative Atomic Mass": "217.0063207(92)" }, { "Atomic Symbol": "Ra", "Mass Number": "218", "Relative Atomic Mass": "218.007141(12)" }, { "Atomic Symbol": "Ra", "Mass Number": "219", "Relative Atomic Mass": "219.0100855(89)" }, { "Atomic Symbol": "Ra", "Mass Number": "220", "Relative Atomic Mass": "220.0110259(89)" }, { "Atomic Symbol": "Ra", "Mass Number": "221", "Relative Atomic Mass": "221.0139177(50)" }, { "Atomic Symbol": "Ra", "Mass Number": "222", "Relative Atomic Mass": "222.0153748(49)" }, { "Atomic Symbol": "Ra", "Mass Number": "223", "Relative Atomic Mass": "223.0185023(27)" }, { "Atomic Symbol": "Ra", "Mass Number": "224", "Relative Atomic Mass": "224.0202120(23)" }, { "Atomic Symbol": "Ra", "Mass Number": "225", "Relative Atomic Mass": "225.0236119(32)" }, { "Atomic Symbol": "Ra", "Mass Number": "226", "Relative Atomic Mass": "226.0254103(25)" }, { "Atomic Symbol": "Ra", "Mass Number": "227", "Relative Atomic Mass": "227.0291783(25)" }, { "Atomic Symbol": "Ra", "Mass Number": "228", "Relative Atomic Mass": "228.0310707(26)" }, { "Atomic Symbol": "Ra", "Mass Number": "229", "Relative Atomic Mass": "229.034942(16)" }, { "Atomic Symbol": "Ra", "Mass Number": "230", "Relative Atomic Mass": "230.037055(11)" }, { "Atomic Symbol": "Ra", "Mass Number": "231", "Relative Atomic Mass": "231.041027(12)" }, { "Atomic Symbol": "Ra", "Mass Number": "232", "Relative Atomic Mass": "232.0434753(98)" }, { "Atomic Symbol": "Ra", "Mass Number": "233", "Relative Atomic Mass": "233.047582(17)" }, { "Atomic Symbol": "Ra", "Mass Number": "234", "Relative Atomic Mass": "234.050342(33)" }, { "Atomic Symbol": "Ra", "Mass Number": "235", "Relative Atomic Mass": "235.05497(32#)" } ], "Standard Atomic Weight": "[226]" }, { "Atomic Symbol": "Ac", "Atomic Number": "89", "isotopes": [ { "Atomic Symbol": "Ac", "Mass Number": "206", "Relative Atomic Mass": "206.014452(77#)" }, { "Atomic Symbol": "Ac", "Mass Number": "207", "Relative Atomic Mass": "207.011966(54)" }, { "Atomic Symbol": "Ac", "Mass Number": "208", "Relative Atomic Mass": "208.011550(60)" }, { "Atomic Symbol": "Ac", "Mass Number": "209", "Relative Atomic Mass": "209.009495(54)" }, { "Atomic Symbol": "Ac", "Mass Number": "210", "Relative Atomic Mass": "210.009436(62)" }, { "Atomic Symbol": "Ac", "Mass Number": "211", "Relative Atomic Mass": "211.007732(57)" }, { "Atomic Symbol": "Ac", "Mass Number": "212", "Relative Atomic Mass": "212.007813(55)" }, { "Atomic Symbol": "Ac", "Mass Number": "213", "Relative Atomic Mass": "213.006609(56)" }, { "Atomic Symbol": "Ac", "Mass Number": "214", "Relative Atomic Mass": "214.006918(16)" }, { "Atomic Symbol": "Ac", "Mass Number": "215", "Relative Atomic Mass": "215.006475(13)" }, { "Atomic Symbol": "Ac", "Mass Number": "216", "Relative Atomic Mass": "216.008743(12)" }, { "Atomic Symbol": "Ac", "Mass Number": "217", "Relative Atomic Mass": "217.009344(12)" }, { "Atomic Symbol": "Ac", "Mass Number": "218", "Relative Atomic Mass": "218.011642(54)" }, { "Atomic Symbol": "Ac", "Mass Number": "219", "Relative Atomic Mass": "219.012421(54)" }, { "Atomic Symbol": "Ac", "Mass Number": "220", "Relative Atomic Mass": "220.0147549(66)" }, { "Atomic Symbol": "Ac", "Mass Number": "221", "Relative Atomic Mass": "221.015592(54)" }, { "Atomic Symbol": "Ac", "Mass Number": "222", "Relative Atomic Mass": "222.0178442(56)" }, { "Atomic Symbol": "Ac", "Mass Number": "223", "Relative Atomic Mass": "223.0191377(77)" }, { "Atomic Symbol": "Ac", "Mass Number": "224", "Relative Atomic Mass": "224.0217232(45)" }, { "Atomic Symbol": "Ac", "Mass Number": "225", "Relative Atomic Mass": "225.0232300(53)" }, { "Atomic Symbol": "Ac", "Mass Number": "226", "Relative Atomic Mass": "226.0260984(36)" }, { "Atomic Symbol": "Ac", "Mass Number": "227", "Relative Atomic Mass": "227.0277523(25)" }, { "Atomic Symbol": "Ac", "Mass Number": "228", "Relative Atomic Mass": "228.0310215(27)" }, { "Atomic Symbol": "Ac", "Mass Number": "229", "Relative Atomic Mass": "229.032956(13)" }, { "Atomic Symbol": "Ac", "Mass Number": "230", "Relative Atomic Mass": "230.036327(17)" }, { "Atomic Symbol": "Ac", "Mass Number": "231", "Relative Atomic Mass": "231.038393(14)" }, { "Atomic Symbol": "Ac", "Mass Number": "232", "Relative Atomic Mass": "232.042034(14)" }, { "Atomic Symbol": "Ac", "Mass Number": "233", "Relative Atomic Mass": "233.044346(14)" }, { "Atomic Symbol": "Ac", "Mass Number": "234", "Relative Atomic Mass": "234.048139(15)" }, { "Atomic Symbol": "Ac", "Mass Number": "235", "Relative Atomic Mass": "235.050840(15)" }, { "Atomic Symbol": "Ac", "Mass Number": "236", "Relative Atomic Mass": "236.054988(41)" }, { "Atomic Symbol": "Ac", "Mass Number": "237", "Relative Atomic Mass": "237.05827(43#)" } ], "Standard Atomic Weight": "[227]" }, { "Atomic Symbol": "Th", "Atomic Number": "90", "isotopes": [ { "Atomic Symbol": "Th", "Mass Number": "208", "Relative Atomic Mass": "208.017900(36)" }, { "Atomic Symbol": "Th", "Mass Number": "209", "Relative Atomic Mass": "209.017753(93)" }, { "Atomic Symbol": "Th", "Mass Number": "210", "Relative Atomic Mass": "210.015094(20)" }, { "Atomic Symbol": "Th", "Mass Number": "211", "Relative Atomic Mass": "211.014929(80)" }, { "Atomic Symbol": "Th", "Mass Number": "212", "Relative Atomic Mass": "212.012988(17)" }, { "Atomic Symbol": "Th", "Mass Number": "213", "Relative Atomic Mass": "213.013009(76)" }, { "Atomic Symbol": "Th", "Mass Number": "214", "Relative Atomic Mass": "214.011500(17)" }, { "Atomic Symbol": "Th", "Mass Number": "215", "Relative Atomic Mass": "215.0117248(95)" }, { "Atomic Symbol": "Th", "Mass Number": "216", "Relative Atomic Mass": "216.011056(13)" }, { "Atomic Symbol": "Th", "Mass Number": "217", "Relative Atomic Mass": "217.013117(22)" }, { "Atomic Symbol": "Th", "Mass Number": "218", "Relative Atomic Mass": "218.013276(11)" }, { "Atomic Symbol": "Th", "Mass Number": "219", "Relative Atomic Mass": "219.015537(54)" }, { "Atomic Symbol": "Th", "Mass Number": "220", "Relative Atomic Mass": "220.015748(24)" }, { "Atomic Symbol": "Th", "Mass Number": "221", "Relative Atomic Mass": "221.018184(10)" }, { "Atomic Symbol": "Th", "Mass Number": "222", "Relative Atomic Mass": "222.018469(13)" }, { "Atomic Symbol": "Th", "Mass Number": "223", "Relative Atomic Mass": "223.0208119(99)" }, { "Atomic Symbol": "Th", "Mass Number": "224", "Relative Atomic Mass": "224.021464(11)" }, { "Atomic Symbol": "Th", "Mass Number": "225", "Relative Atomic Mass": "225.0239514(55)" }, { "Atomic Symbol": "Th", "Mass Number": "226", "Relative Atomic Mass": "226.0249034(50)" }, { "Atomic Symbol": "Th", "Mass Number": "227", "Relative Atomic Mass": "227.0277042(27)" }, { "Atomic Symbol": "Th", "Mass Number": "228", "Relative Atomic Mass": "228.0287413(23)" }, { "Atomic Symbol": "Th", "Mass Number": "229", "Relative Atomic Mass": "229.0317627(30)" }, { "Atomic Symbol": "Th", "Mass Number": "230", "Relative Atomic Mass": "230.0331341(19)" }, { "Atomic Symbol": "Th", "Mass Number": "231", "Relative Atomic Mass": "231.0363046(19)" }, { "Atomic Symbol": "Th", "Mass Number": "232", "Isotopic Composition": "1", "Relative Atomic Mass": "232.0380558(21)" }, { "Atomic Symbol": "Th", "Mass Number": "233", "Relative Atomic Mass": "233.0415823(21)" }, { "Atomic Symbol": "Th", "Mass Number": "234", "Relative Atomic Mass": "234.0436014(37)" }, { "Atomic Symbol": "Th", "Mass Number": "235", "Relative Atomic Mass": "235.047255(14)" }, { "Atomic Symbol": "Th", "Mass Number": "236", "Relative Atomic Mass": "236.049657(15)" }, { "Atomic Symbol": "Th", "Mass Number": "237", "Relative Atomic Mass": "237.053629(17)" }, { "Atomic Symbol": "Th", "Mass Number": "238", "Relative Atomic Mass": "238.05650(30#)" }, { "Atomic Symbol": "Th", "Mass Number": "239", "Relative Atomic Mass": "239.06077(43#)" } ], "Notes": "g", "Standard Atomic Weight": "232.0377(4)" }, { "Atomic Symbol": "Pa", "Atomic Number": "91", "isotopes": [ { "Atomic Symbol": "Pa", "Mass Number": "212", "Relative Atomic Mass": "212.023203(80)" }, { "Atomic Symbol": "Pa", "Mass Number": "213", "Relative Atomic Mass": "213.021109(76)" }, { "Atomic Symbol": "Pa", "Mass Number": "214", "Relative Atomic Mass": "214.020918(82)" }, { "Atomic Symbol": "Pa", "Mass Number": "215", "Relative Atomic Mass": "215.019183(78)" }, { "Atomic Symbol": "Pa", "Mass Number": "216", "Relative Atomic Mass": "216.019109(57)" }, { "Atomic Symbol": "Pa", "Mass Number": "217", "Relative Atomic Mass": "217.018325(56)" }, { "Atomic Symbol": "Pa", "Mass Number": "218", "Relative Atomic Mass": "218.020059(20)" }, { "Atomic Symbol": "Pa", "Mass Number": "219", "Relative Atomic Mass": "219.019904(55)" }, { "Atomic Symbol": "Pa", "Mass Number": "220", "Relative Atomic Mass": "220.021705(55#)" }, { "Atomic Symbol": "Pa", "Mass Number": "221", "Relative Atomic Mass": "221.021875(55)" }, { "Atomic Symbol": "Pa", "Mass Number": "222", "Relative Atomic Mass": "222.023784(78#)" }, { "Atomic Symbol": "Pa", "Mass Number": "223", "Relative Atomic Mass": "223.023963(76)" }, { "Atomic Symbol": "Pa", "Mass Number": "224", "Relative Atomic Mass": "224.0256176(82)" }, { "Atomic Symbol": "Pa", "Mass Number": "225", "Relative Atomic Mass": "225.026131(76)" }, { "Atomic Symbol": "Pa", "Mass Number": "226", "Relative Atomic Mass": "226.027948(12)" }, { "Atomic Symbol": "Pa", "Mass Number": "227", "Relative Atomic Mass": "227.0288054(80)" }, { "Atomic Symbol": "Pa", "Mass Number": "228", "Relative Atomic Mass": "228.0310517(47)" }, { "Atomic Symbol": "Pa", "Mass Number": "229", "Relative Atomic Mass": "229.0320972(38)" }, { "Atomic Symbol": "Pa", "Mass Number": "230", "Relative Atomic Mass": "230.0345410(35)" }, { "Atomic Symbol": "Pa", "Mass Number": "231", "Isotopic Composition": "1", "Relative Atomic Mass": "231.0358842(24)" }, { "Atomic Symbol": "Pa", "Mass Number": "232", "Relative Atomic Mass": "232.0385917(83)" }, { "Atomic Symbol": "Pa", "Mass Number": "233", "Relative Atomic Mass": "233.0402472(22)" }, { "Atomic Symbol": "Pa", "Mass Number": "234", "Relative Atomic Mass": "234.0433072(51)" }, { "Atomic Symbol": "Pa", "Mass Number": "235", "Relative Atomic Mass": "235.045399(15)" }, { "Atomic Symbol": "Pa", "Mass Number": "236", "Relative Atomic Mass": "236.048668(15)" }, { "Atomic Symbol": "Pa", "Mass Number": "237", "Relative Atomic Mass": "237.051023(14)" }, { "Atomic Symbol": "Pa", "Mass Number": "238", "Relative Atomic Mass": "238.054637(17)" }, { "Atomic Symbol": "Pa", "Mass Number": "239", "Relative Atomic Mass": "239.05726(21#)" }, { "Atomic Symbol": "Pa", "Mass Number": "240", "Relative Atomic Mass": "240.06098(32#)" }, { "Atomic Symbol": "Pa", "Mass Number": "241", "Relative Atomic Mass": "241.06408(43#)" } ], "Standard Atomic Weight": "231.03588(2)" }, { "Atomic Symbol": "U", "Atomic Number": "92", "isotopes": [ { "Atomic Symbol": "U", "Mass Number": "217", "Relative Atomic Mass": "217.02466(11#)" }, { "Atomic Symbol": "U", "Mass Number": "218", "Relative Atomic Mass": "218.023523(20)" }, { "Atomic Symbol": "U", "Mass Number": "219", "Relative Atomic Mass": "219.024999(55)" }, { "Atomic Symbol": "U", "Mass Number": "220", "Relative Atomic Mass": "220.02462(11#)" }, { "Atomic Symbol": "U", "Mass Number": "221", "Relative Atomic Mass": "221.02628(11#)" }, { "Atomic Symbol": "U", "Mass Number": "222", "Relative Atomic Mass": "222.02600(11#)" }, { "Atomic Symbol": "U", "Mass Number": "223", "Relative Atomic Mass": "223.027739(76)" }, { "Atomic Symbol": "U", "Mass Number": "224", "Relative Atomic Mass": "224.027605(27)" }, { "Atomic Symbol": "U", "Mass Number": "225", "Relative Atomic Mass": "225.029391(13)" }, { "Atomic Symbol": "U", "Mass Number": "226", "Relative Atomic Mass": "226.029339(14)" }, { "Atomic Symbol": "U", "Mass Number": "227", "Relative Atomic Mass": "227.031157(18)" }, { "Atomic Symbol": "U", "Mass Number": "228", "Relative Atomic Mass": "228.031371(15)" }, { "Atomic Symbol": "U", "Mass Number": "229", "Relative Atomic Mass": "229.0335063(64)" }, { "Atomic Symbol": "U", "Mass Number": "230", "Relative Atomic Mass": "230.0339401(51)" }, { "Atomic Symbol": "U", "Mass Number": "231", "Relative Atomic Mass": "231.0362939(32)" }, { "Atomic Symbol": "U", "Mass Number": "232", "Relative Atomic Mass": "232.0371563(23)" }, { "Atomic Symbol": "U", "Mass Number": "233", "Relative Atomic Mass": "233.0396355(29)" }, { "Atomic Symbol": "U", "Mass Number": "234", "Isotopic Composition": "0.000054(5)", "Relative Atomic Mass": "234.0409523(19)" }, { "Atomic Symbol": "U", "Mass Number": "235", "Isotopic Composition": "0.007204(6)", "Relative Atomic Mass": "235.0439301(19)" }, { "Atomic Symbol": "U", "Mass Number": "236", "Relative Atomic Mass": "236.0455682(19)" }, { "Atomic Symbol": "U", "Mass Number": "237", "Relative Atomic Mass": "237.0487304(20)" }, { "Atomic Symbol": "U", "Mass Number": "238", "Isotopic Composition": "0.992742(10)", "Relative Atomic Mass": "238.0507884(20)" }, { "Atomic Symbol": "U", "Mass Number": "239", "Relative Atomic Mass": "239.0542935(20)" }, { "Atomic Symbol": "U", "Mass Number": "240", "Relative Atomic Mass": "240.0565934(57)" }, { "Atomic Symbol": "U", "Mass Number": "241", "Relative Atomic Mass": "241.06033(32#)" }, { "Atomic Symbol": "U", "Mass Number": "242", "Relative Atomic Mass": "242.06293(22#)" }, { "Atomic Symbol": "U", "Mass Number": "243", "Relative Atomic Mass": "243.06699(43#)" } ], "Notes": "g,m", "Standard Atomic Weight": "238.02891(3)" }, { "Atomic Symbol": "Np", "Atomic Number": "93", "isotopes": [ { "Atomic Symbol": "Np", "Mass Number": "219", "Relative Atomic Mass": "219.03143(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "220", "Relative Atomic Mass": "220.03254(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "221", "Relative Atomic Mass": "221.03204(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "222", "Relative Atomic Mass": "222.03330(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "223", "Relative Atomic Mass": "223.03285(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "224", "Relative Atomic Mass": "224.03422(21#)" }, { "Atomic Symbol": "Np", "Mass Number": "225", "Relative Atomic Mass": "225.033911(77)" }, { "Atomic Symbol": "Np", "Mass Number": "226", "Relative Atomic Mass": "226.035188(95#)" }, { "Atomic Symbol": "Np", "Mass Number": "227", "Relative Atomic Mass": "227.034957(78)" }, { "Atomic Symbol": "Np", "Mass Number": "228", "Relative Atomic Mass": "228.036067(54)" }, { "Atomic Symbol": "Np", "Mass Number": "229", "Relative Atomic Mass": "229.036264(93)" }, { "Atomic Symbol": "Np", "Mass Number": "230", "Relative Atomic Mass": "230.037828(55)" }, { "Atomic Symbol": "Np", "Mass Number": "231", "Relative Atomic Mass": "231.038245(54)" }, { "Atomic Symbol": "Np", "Mass Number": "232", "Relative Atomic Mass": "232.04011(11#)" }, { "Atomic Symbol": "Np", "Mass Number": "233", "Relative Atomic Mass": "233.040741(55)" }, { "Atomic Symbol": "Np", "Mass Number": "234", "Relative Atomic Mass": "234.0428953(91)" }, { "Atomic Symbol": "Np", "Mass Number": "235", "Relative Atomic Mass": "235.0440635(21)" }, { "Atomic Symbol": "Np", "Mass Number": "236", "Relative Atomic Mass": "236.046570(54)" }, { "Atomic Symbol": "Np", "Mass Number": "237", "Relative Atomic Mass": "237.0481736(19)" }, { "Atomic Symbol": "Np", "Mass Number": "238", "Relative Atomic Mass": "238.0509466(19)" }, { "Atomic Symbol": "Np", "Mass Number": "239", "Relative Atomic Mass": "239.0529392(22)" }, { "Atomic Symbol": "Np", "Mass Number": "240", "Relative Atomic Mass": "240.056165(18)" }, { "Atomic Symbol": "Np", "Mass Number": "241", "Relative Atomic Mass": "241.058253(76)" }, { "Atomic Symbol": "Np", "Mass Number": "242", "Relative Atomic Mass": "242.06164(21)" }, { "Atomic Symbol": "Np", "Mass Number": "243", "Relative Atomic Mass": "243.064280(34#)" }, { "Atomic Symbol": "Np", "Mass Number": "244", "Relative Atomic Mass": "244.06785(32#)" }, { "Atomic Symbol": "Np", "Mass Number": "245", "Relative Atomic Mass": "245.07080(43#)" } ], "Standard Atomic Weight": "[237]" }, { "Atomic Symbol": "Pu", "Atomic Number": "94", "isotopes": [ { "Atomic Symbol": "Pu", "Mass Number": "228", "Relative Atomic Mass": "228.038732(33)" }, { "Atomic Symbol": "Pu", "Mass Number": "229", "Relative Atomic Mass": "229.040144(55)" }, { "Atomic Symbol": "Pu", "Mass Number": "230", "Relative Atomic Mass": "230.039650(16)" }, { "Atomic Symbol": "Pu", "Mass Number": "231", "Relative Atomic Mass": "231.041102(28)" }, { "Atomic Symbol": "Pu", "Mass Number": "232", "Relative Atomic Mass": "232.041185(19)" }, { "Atomic Symbol": "Pu", "Mass Number": "233", "Relative Atomic Mass": "233.042998(54)" }, { "Atomic Symbol": "Pu", "Mass Number": "234", "Relative Atomic Mass": "234.0433174(75)" }, { "Atomic Symbol": "Pu", "Mass Number": "235", "Relative Atomic Mass": "235.045286(22)" }, { "Atomic Symbol": "Pu", "Mass Number": "236", "Relative Atomic Mass": "236.0460581(23)" }, { "Atomic Symbol": "Pu", "Mass Number": "237", "Relative Atomic Mass": "237.0484098(24)" }, { "Atomic Symbol": "Pu", "Mass Number": "238", "Relative Atomic Mass": "238.0495601(19)" }, { "Atomic Symbol": "Pu", "Mass Number": "239", "Relative Atomic Mass": "239.0521636(19)" }, { "Atomic Symbol": "Pu", "Mass Number": "240", "Relative Atomic Mass": "240.0538138(19)" }, { "Atomic Symbol": "Pu", "Mass Number": "241", "Relative Atomic Mass": "241.0568517(19)" }, { "Atomic Symbol": "Pu", "Mass Number": "242", "Relative Atomic Mass": "242.0587428(20)" }, { "Atomic Symbol": "Pu", "Mass Number": "243", "Relative Atomic Mass": "243.0620036(34)" }, { "Atomic Symbol": "Pu", "Mass Number": "244", "Relative Atomic Mass": "244.0642053(56)" }, { "Atomic Symbol": "Pu", "Mass Number": "245", "Relative Atomic Mass": "245.067826(15)" }, { "Atomic Symbol": "Pu", "Mass Number": "246", "Relative Atomic Mass": "246.070205(16)" }, { "Atomic Symbol": "Pu", "Mass Number": "247", "Relative Atomic Mass": "247.07419(21#)" } ] }, { "Atomic Symbol": "Am", "Atomic Number": "95", "isotopes": [ { "Atomic Symbol": "Am", "Mass Number": "230", "Relative Atomic Mass": "230.04609(14#)" }, { "Atomic Symbol": "Am", "Mass Number": "231", "Relative Atomic Mass": "231.04556(32#)" }, { "Atomic Symbol": "Am", "Mass Number": "232", "Relative Atomic Mass": "232.04645(32#)" }, { "Atomic Symbol": "Am", "Mass Number": "233", "Relative Atomic Mass": "233.04644(11#)" }, { "Atomic Symbol": "Am", "Mass Number": "234", "Relative Atomic Mass": "234.04773(17#)" }, { "Atomic Symbol": "Am", "Mass Number": "235", "Relative Atomic Mass": "235.047908(56)" }, { "Atomic Symbol": "Am", "Mass Number": "236", "Relative Atomic Mass": "236.04943(12#)" }, { "Atomic Symbol": "Am", "Mass Number": "237", "Relative Atomic Mass": "237.049996(64#)" }, { "Atomic Symbol": "Am", "Mass Number": "238", "Relative Atomic Mass": "238.051985(54)" }, { "Atomic Symbol": "Am", "Mass Number": "239", "Relative Atomic Mass": "239.0530247(26)" }, { "Atomic Symbol": "Am", "Mass Number": "240", "Relative Atomic Mass": "240.055300(15)" }, { "Atomic Symbol": "Am", "Mass Number": "241", "Relative Atomic Mass": "241.0568293(19)" }, { "Atomic Symbol": "Am", "Mass Number": "242", "Relative Atomic Mass": "242.0595494(19)" }, { "Atomic Symbol": "Am", "Mass Number": "243", "Relative Atomic Mass": "243.0613813(24)" }, { "Atomic Symbol": "Am", "Mass Number": "244", "Relative Atomic Mass": "244.0642851(22)" }, { "Atomic Symbol": "Am", "Mass Number": "245", "Relative Atomic Mass": "245.0664548(34)" }, { "Atomic Symbol": "Am", "Mass Number": "246", "Relative Atomic Mass": "246.069775(20#)" }, { "Atomic Symbol": "Am", "Mass Number": "247", "Relative Atomic Mass": "247.07209(11#)" }, { "Atomic Symbol": "Am", "Mass Number": "248", "Relative Atomic Mass": "248.07575(22#)" }, { "Atomic Symbol": "Am", "Mass Number": "249", "Relative Atomic Mass": "249.07848(32#)" } ] }, { "Atomic Symbol": "Cm", "Atomic Number": "96", "isotopes": [ { "Atomic Symbol": "Cm", "Mass Number": "232", "Relative Atomic Mass": "232.04982(22#)" }, { "Atomic Symbol": "Cm", "Mass Number": "233", "Relative Atomic Mass": "233.050770(77)" }, { "Atomic Symbol": "Cm", "Mass Number": "234", "Relative Atomic Mass": "234.050160(20)" }, { "Atomic Symbol": "Cm", "Mass Number": "235", "Relative Atomic Mass": "235.05154(22#)" }, { "Atomic Symbol": "Cm", "Mass Number": "236", "Relative Atomic Mass": "236.051374(20)" }, { "Atomic Symbol": "Cm", "Mass Number": "237", "Relative Atomic Mass": "237.052869(76)" }, { "Atomic Symbol": "Cm", "Mass Number": "238", "Relative Atomic Mass": "238.053081(13)" }, { "Atomic Symbol": "Cm", "Mass Number": "239", "Relative Atomic Mass": "239.054910(58)" }, { "Atomic Symbol": "Cm", "Mass Number": "240", "Relative Atomic Mass": "240.0555297(24)" }, { "Atomic Symbol": "Cm", "Mass Number": "241", "Relative Atomic Mass": "241.0576532(23)" }, { "Atomic Symbol": "Cm", "Mass Number": "242", "Relative Atomic Mass": "242.0588360(19)" }, { "Atomic Symbol": "Cm", "Mass Number": "243", "Relative Atomic Mass": "243.0613893(22)" }, { "Atomic Symbol": "Cm", "Mass Number": "244", "Relative Atomic Mass": "244.0627528(19)" }, { "Atomic Symbol": "Cm", "Mass Number": "245", "Relative Atomic Mass": "245.0654915(22)" }, { "Atomic Symbol": "Cm", "Mass Number": "246", "Relative Atomic Mass": "246.0672238(22)" }, { "Atomic Symbol": "Cm", "Mass Number": "247", "Relative Atomic Mass": "247.0703541(47)" }, { "Atomic Symbol": "Cm", "Mass Number": "248", "Relative Atomic Mass": "248.0723499(56)" }, { "Atomic Symbol": "Cm", "Mass Number": "249", "Relative Atomic Mass": "249.0759548(56)" }, { "Atomic Symbol": "Cm", "Mass Number": "250", "Relative Atomic Mass": "250.078358(12)" }, { "Atomic Symbol": "Cm", "Mass Number": "251", "Relative Atomic Mass": "251.082286(24)" }, { "Atomic Symbol": "Cm", "Mass Number": "252", "Relative Atomic Mass": "252.08487(32#)" } ] }, { "Atomic Symbol": "Bk", "Atomic Number": "97", "isotopes": [ { "Atomic Symbol": "Bk", "Mass Number": "234", "Relative Atomic Mass": "234.05727(15#)" }, { "Atomic Symbol": "Bk", "Mass Number": "235", "Relative Atomic Mass": "235.05658(43#)" }, { "Atomic Symbol": "Bk", "Mass Number": "236", "Relative Atomic Mass": "236.05748(43#)" }, { "Atomic Symbol": "Bk", "Mass Number": "237", "Relative Atomic Mass": "237.05710(24#)" }, { "Atomic Symbol": "Bk", "Mass Number": "238", "Relative Atomic Mass": "238.05820(27#)" }, { "Atomic Symbol": "Bk", "Mass Number": "239", "Relative Atomic Mass": "239.05824(22#)" }, { "Atomic Symbol": "Bk", "Mass Number": "240", "Relative Atomic Mass": "240.05976(16#)" }, { "Atomic Symbol": "Bk", "Mass Number": "241", "Relative Atomic Mass": "241.06016(22#)" }, { "Atomic Symbol": "Bk", "Mass Number": "242", "Relative Atomic Mass": "242.06198(22#)" }, { "Atomic Symbol": "Bk", "Mass Number": "243", "Relative Atomic Mass": "243.0630078(51)" }, { "Atomic Symbol": "Bk", "Mass Number": "244", "Relative Atomic Mass": "244.065181(16)" }, { "Atomic Symbol": "Bk", "Mass Number": "245", "Relative Atomic Mass": "245.0663618(24)" }, { "Atomic Symbol": "Bk", "Mass Number": "246", "Relative Atomic Mass": "246.068673(64)" }, { "Atomic Symbol": "Bk", "Mass Number": "247", "Relative Atomic Mass": "247.0703073(59)" }, { "Atomic Symbol": "Bk", "Mass Number": "248", "Relative Atomic Mass": "248.073088(76#)" }, { "Atomic Symbol": "Bk", "Mass Number": "249", "Relative Atomic Mass": "249.0749877(27)" }, { "Atomic Symbol": "Bk", "Mass Number": "250", "Relative Atomic Mass": "250.0783167(42)" }, { "Atomic Symbol": "Bk", "Mass Number": "251", "Relative Atomic Mass": "251.080762(12)" }, { "Atomic Symbol": "Bk", "Mass Number": "252", "Relative Atomic Mass": "252.08431(22#)" }, { "Atomic Symbol": "Bk", "Mass Number": "253", "Relative Atomic Mass": "253.08688(39#)" }, { "Atomic Symbol": "Bk", "Mass Number": "254", "Relative Atomic Mass": "254.09060(32#)" } ] }, { "Atomic Symbol": "Cf", "Atomic Number": "98", "isotopes": [ { "Atomic Symbol": "Cf", "Mass Number": "237", "Relative Atomic Mass": "237.062198(94)" }, { "Atomic Symbol": "Cf", "Mass Number": "238", "Relative Atomic Mass": "238.06149(32#)" }, { "Atomic Symbol": "Cf", "Mass Number": "239", "Relative Atomic Mass": "239.06253(23#)" }, { "Atomic Symbol": "Cf", "Mass Number": "240", "Relative Atomic Mass": "240.062256(20)" }, { "Atomic Symbol": "Cf", "Mass Number": "241", "Relative Atomic Mass": "241.06369(18#)" }, { "Atomic Symbol": "Cf", "Mass Number": "242", "Relative Atomic Mass": "242.063754(14)" }, { "Atomic Symbol": "Cf", "Mass Number": "243", "Relative Atomic Mass": "243.06548(12#)" }, { "Atomic Symbol": "Cf", "Mass Number": "244", "Relative Atomic Mass": "244.0660008(31)" }, { "Atomic Symbol": "Cf", "Mass Number": "245", "Relative Atomic Mass": "245.0680487(30)" }, { "Atomic Symbol": "Cf", "Mass Number": "246", "Relative Atomic Mass": "246.0688055(22)" }, { "Atomic Symbol": "Cf", "Mass Number": "247", "Relative Atomic Mass": "247.070965(16)" }, { "Atomic Symbol": "Cf", "Mass Number": "248", "Relative Atomic Mass": "248.0721851(57)" }, { "Atomic Symbol": "Cf", "Mass Number": "249", "Relative Atomic Mass": "249.0748539(23)" }, { "Atomic Symbol": "Cf", "Mass Number": "250", "Relative Atomic Mass": "250.0764062(22)" }, { "Atomic Symbol": "Cf", "Mass Number": "251", "Relative Atomic Mass": "251.0795886(48)" }, { "Atomic Symbol": "Cf", "Mass Number": "252", "Relative Atomic Mass": "252.0816272(56)" }, { "Atomic Symbol": "Cf", "Mass Number": "253", "Relative Atomic Mass": "253.0851345(67)" }, { "Atomic Symbol": "Cf", "Mass Number": "254", "Relative Atomic Mass": "254.087324(13)" }, { "Atomic Symbol": "Cf", "Mass Number": "255", "Relative Atomic Mass": "255.09105(22#)" }, { "Atomic Symbol": "Cf", "Mass Number": "256", "Relative Atomic Mass": "256.09344(34#)" } ] }, { "Atomic Symbol": "Es", "Atomic Number": "99", "isotopes": [ { "Atomic Symbol": "Es", "Mass Number": "239", "Relative Atomic Mass": "239.06823(32#)" }, { "Atomic Symbol": "Es", "Mass Number": "240", "Relative Atomic Mass": "240.06892(43#)" }, { "Atomic Symbol": "Es", "Mass Number": "241", "Relative Atomic Mass": "241.06856(24#)" }, { "Atomic Symbol": "Es", "Mass Number": "242", "Relative Atomic Mass": "242.06957(28#)" }, { "Atomic Symbol": "Es", "Mass Number": "243", "Relative Atomic Mass": "243.06951(22#)" }, { "Atomic Symbol": "Es", "Mass Number": "244", "Relative Atomic Mass": "244.07088(20#)" }, { "Atomic Symbol": "Es", "Mass Number": "245", "Relative Atomic Mass": "245.07125(22#)" }, { "Atomic Symbol": "Es", "Mass Number": "246", "Relative Atomic Mass": "246.07290(24#)" }, { "Atomic Symbol": "Es", "Mass Number": "247", "Relative Atomic Mass": "247.073622(21)" }, { "Atomic Symbol": "Es", "Mass Number": "248", "Relative Atomic Mass": "248.075471(56#)" }, { "Atomic Symbol": "Es", "Mass Number": "249", "Relative Atomic Mass": "249.076411(32#)" }, { "Atomic Symbol": "Es", "Mass Number": "250", "Relative Atomic Mass": "250.07861(11#)" }, { "Atomic Symbol": "Es", "Mass Number": "251", "Relative Atomic Mass": "251.0799936(67)" }, { "Atomic Symbol": "Es", "Mass Number": "252", "Relative Atomic Mass": "252.082980(54)" }, { "Atomic Symbol": "Es", "Mass Number": "253", "Relative Atomic Mass": "253.0848257(27)" }, { "Atomic Symbol": "Es", "Mass Number": "254", "Relative Atomic Mass": "254.0880222(45)" }, { "Atomic Symbol": "Es", "Mass Number": "255", "Relative Atomic Mass": "255.090275(12)" }, { "Atomic Symbol": "Es", "Mass Number": "256", "Relative Atomic Mass": "256.09360(11#)" }, { "Atomic Symbol": "Es", "Mass Number": "257", "Relative Atomic Mass": "257.09598(44#)" }, { "Atomic Symbol": "Es", "Mass Number": "258", "Relative Atomic Mass": "258.09952(32#)" } ] }, { "Atomic Symbol": "Fm", "Atomic Number": "100", "isotopes": [ { "Atomic Symbol": "Fm", "Mass Number": "241", "Relative Atomic Mass": "241.07421(32#)" }, { "Atomic Symbol": "Fm", "Mass Number": "242", "Relative Atomic Mass": "242.07343(43#)" }, { "Atomic Symbol": "Fm", "Mass Number": "243", "Relative Atomic Mass": "243.07446(23#)" }, { "Atomic Symbol": "Fm", "Mass Number": "244", "Relative Atomic Mass": "244.07404(22#)" }, { "Atomic Symbol": "Fm", "Mass Number": "245", "Relative Atomic Mass": "245.07535(21#)" }, { "Atomic Symbol": "Fm", "Mass Number": "246", "Relative Atomic Mass": "246.075350(17)" }, { "Atomic Symbol": "Fm", "Mass Number": "247", "Relative Atomic Mass": "247.07694(12#)" }, { "Atomic Symbol": "Fm", "Mass Number": "248", "Relative Atomic Mass": "248.0771865(92)" }, { "Atomic Symbol": "Fm", "Mass Number": "249", "Relative Atomic Mass": "249.0789275(68)" }, { "Atomic Symbol": "Fm", "Mass Number": "250", "Relative Atomic Mass": "250.0795210(86)" }, { "Atomic Symbol": "Fm", "Mass Number": "251", "Relative Atomic Mass": "251.081540(16)" }, { "Atomic Symbol": "Fm", "Mass Number": "252", "Relative Atomic Mass": "252.0824671(61)" }, { "Atomic Symbol": "Fm", "Mass Number": "253", "Relative Atomic Mass": "253.0851846(37)" }, { "Atomic Symbol": "Fm", "Mass Number": "254", "Relative Atomic Mass": "254.0868544(30)" }, { "Atomic Symbol": "Fm", "Mass Number": "255", "Relative Atomic Mass": "255.0899640(52)" }, { "Atomic Symbol": "Fm", "Mass Number": "256", "Relative Atomic Mass": "256.0917745(78)" }, { "Atomic Symbol": "Fm", "Mass Number": "257", "Relative Atomic Mass": "257.0951061(69)" }, { "Atomic Symbol": "Fm", "Mass Number": "258", "Relative Atomic Mass": "258.09708(22#)" }, { "Atomic Symbol": "Fm", "Mass Number": "259", "Relative Atomic Mass": "259.10060(30#)" }, { "Atomic Symbol": "Fm", "Mass Number": "260", "Relative Atomic Mass": "260.10281(55#)" } ] }, { "Atomic Symbol": "Md", "Atomic Number": "101", "isotopes": [ { "Atomic Symbol": "Md", "Mass Number": "245", "Relative Atomic Mass": "245.08081(33#)" }, { "Atomic Symbol": "Md", "Mass Number": "246", "Relative Atomic Mass": "246.08171(28#)" }, { "Atomic Symbol": "Md", "Mass Number": "247", "Relative Atomic Mass": "247.08152(22#)" }, { "Atomic Symbol": "Md", "Mass Number": "248", "Relative Atomic Mass": "248.08282(26#)" }, { "Atomic Symbol": "Md", "Mass Number": "249", "Relative Atomic Mass": "249.08291(22#)" }, { "Atomic Symbol": "Md", "Mass Number": "250", "Relative Atomic Mass": "250.08441(32#)" }, { "Atomic Symbol": "Md", "Mass Number": "251", "Relative Atomic Mass": "251.084774(20)" }, { "Atomic Symbol": "Md", "Mass Number": "252", "Relative Atomic Mass": "252.08643(14#)" }, { "Atomic Symbol": "Md", "Mass Number": "253", "Relative Atomic Mass": "253.087144(34#)" }, { "Atomic Symbol": "Md", "Mass Number": "254", "Relative Atomic Mass": "254.08959(11#)" }, { "Atomic Symbol": "Md", "Mass Number": "255", "Relative Atomic Mass": "255.0910841(73)" }, { "Atomic Symbol": "Md", "Mass Number": "256", "Relative Atomic Mass": "256.09389(13#)" }, { "Atomic Symbol": "Md", "Mass Number": "257", "Relative Atomic Mass": "257.0955424(29)" }, { "Atomic Symbol": "Md", "Mass Number": "258", "Relative Atomic Mass": "258.0984315(50)" }, { "Atomic Symbol": "Md", "Mass Number": "259", "Relative Atomic Mass": "259.10051(22#)" }, { "Atomic Symbol": "Md", "Mass Number": "260", "Relative Atomic Mass": "260.10365(34#)" }, { "Atomic Symbol": "Md", "Mass Number": "261", "Relative Atomic Mass": "261.10583(62#)" }, { "Atomic Symbol": "Md", "Mass Number": "262", "Relative Atomic Mass": "262.10910(45#)" } ] }, { "Atomic Symbol": "No", "Atomic Number": "102", "isotopes": [ { "Atomic Symbol": "No", "Mass Number": "248", "Relative Atomic Mass": "248.08655(24#)" }, { "Atomic Symbol": "No", "Mass Number": "249", "Relative Atomic Mass": "249.08780(30#)" }, { "Atomic Symbol": "No", "Mass Number": "250", "Relative Atomic Mass": "250.08756(22#)" }, { "Atomic Symbol": "No", "Mass Number": "251", "Relative Atomic Mass": "251.08894(12#)" }, { "Atomic Symbol": "No", "Mass Number": "252", "Relative Atomic Mass": "252.088967(10)" }, { "Atomic Symbol": "No", "Mass Number": "253", "Relative Atomic Mass": "253.0905641(75)" }, { "Atomic Symbol": "No", "Mass Number": "254", "Relative Atomic Mass": "254.090956(11)" }, { "Atomic Symbol": "No", "Mass Number": "255", "Relative Atomic Mass": "255.093191(16)" }, { "Atomic Symbol": "No", "Mass Number": "256", "Relative Atomic Mass": "256.0942829(84)" }, { "Atomic Symbol": "No", "Mass Number": "257", "Relative Atomic Mass": "257.0968878(74)" }, { "Atomic Symbol": "No", "Mass Number": "258", "Relative Atomic Mass": "258.09821(11#)" }, { "Atomic Symbol": "No", "Mass Number": "259", "Relative Atomic Mass": "259.10103(11#)" }, { "Atomic Symbol": "No", "Mass Number": "260", "Relative Atomic Mass": "260.10264(22#)" }, { "Atomic Symbol": "No", "Mass Number": "261", "Relative Atomic Mass": "261.10570(22#)" }, { "Atomic Symbol": "No", "Mass Number": "262", "Relative Atomic Mass": "262.10746(39#)" }, { "Atomic Symbol": "No", "Mass Number": "263", "Relative Atomic Mass": "263.11071(53#)" }, { "Atomic Symbol": "No", "Mass Number": "264", "Relative Atomic Mass": "264.11273(70#)" } ] }, { "Atomic Symbol": "Lr", "Atomic Number": "103", "isotopes": [ { "Atomic Symbol": "Lr", "Mass Number": "251", "Relative Atomic Mass": "251.09418(32#)" }, { "Atomic Symbol": "Lr", "Mass Number": "252", "Relative Atomic Mass": "252.09526(26#)" }, { "Atomic Symbol": "Lr", "Mass Number": "253", "Relative Atomic Mass": "253.09509(22#)" }, { "Atomic Symbol": "Lr", "Mass Number": "254", "Relative Atomic Mass": "254.09648(32#)" }, { "Atomic Symbol": "Lr", "Mass Number": "255", "Relative Atomic Mass": "255.096562(19)" }, { "Atomic Symbol": "Lr", "Mass Number": "256", "Relative Atomic Mass": "256.098494(89)" }, { "Atomic Symbol": "Lr", "Mass Number": "257", "Relative Atomic Mass": "257.099418(47#)" }, { "Atomic Symbol": "Lr", "Mass Number": "258", "Relative Atomic Mass": "258.10176(11#)" }, { "Atomic Symbol": "Lr", "Mass Number": "259", "Relative Atomic Mass": "259.102902(76#)" }, { "Atomic Symbol": "Lr", "Mass Number": "260", "Relative Atomic Mass": "260.10550(13#)" }, { "Atomic Symbol": "Lr", "Mass Number": "261", "Relative Atomic Mass": "261.10688(22#)" }, { "Atomic Symbol": "Lr", "Mass Number": "262", "Relative Atomic Mass": "262.10961(22#)" }, { "Atomic Symbol": "Lr", "Mass Number": "263", "Relative Atomic Mass": "263.11136(30#)" }, { "Atomic Symbol": "Lr", "Mass Number": "264", "Relative Atomic Mass": "264.11420(47#)" }, { "Atomic Symbol": "Lr", "Mass Number": "265", "Relative Atomic Mass": "265.11619(65#)" }, { "Atomic Symbol": "Lr", "Mass Number": "266", "Relative Atomic Mass": "266.11983(56#)" } ] }, { "Atomic Symbol": "Rf", "Atomic Number": "104", "isotopes": [ { "Atomic Symbol": "Rf", "Mass Number": "253", "Relative Atomic Mass": "253.10044(44#)" }, { "Atomic Symbol": "Rf", "Mass Number": "254", "Relative Atomic Mass": "254.10005(30#)" }, { "Atomic Symbol": "Rf", "Mass Number": "255", "Relative Atomic Mass": "255.10127(12#)" }, { "Atomic Symbol": "Rf", "Mass Number": "256", "Relative Atomic Mass": "256.101152(19)" }, { "Atomic Symbol": "Rf", "Mass Number": "257", "Relative Atomic Mass": "257.102918(12)" }, { "Atomic Symbol": "Rf", "Mass Number": "258", "Relative Atomic Mass": "258.103428(34)" }, { "Atomic Symbol": "Rf", "Mass Number": "259", "Relative Atomic Mass": "259.105596(78#)" }, { "Atomic Symbol": "Rf", "Mass Number": "260", "Relative Atomic Mass": "260.10644(22#)" }, { "Atomic Symbol": "Rf", "Mass Number": "261", "Relative Atomic Mass": "261.108773(54)" }, { "Atomic Symbol": "Rf", "Mass Number": "262", "Relative Atomic Mass": "262.10992(24#)" }, { "Atomic Symbol": "Rf", "Mass Number": "263", "Relative Atomic Mass": "263.11249(20#)" }, { "Atomic Symbol": "Rf", "Mass Number": "264", "Relative Atomic Mass": "264.11388(39#)" }, { "Atomic Symbol": "Rf", "Mass Number": "265", "Relative Atomic Mass": "265.11668(39#)" }, { "Atomic Symbol": "Rf", "Mass Number": "266", "Relative Atomic Mass": "266.11817(50#)" }, { "Atomic Symbol": "Rf", "Mass Number": "267", "Relative Atomic Mass": "267.12179(62#)" }, { "Atomic Symbol": "Rf", "Mass Number": "268", "Relative Atomic Mass": "268.12397(77#)" } ] }, { "Atomic Symbol": "Db", "Atomic Number": "105", "isotopes": [ { "Atomic Symbol": "Db", "Mass Number": "255", "Relative Atomic Mass": "255.10707(45#)" }, { "Atomic Symbol": "Db", "Mass Number": "256", "Relative Atomic Mass": "256.10789(26#)" }, { "Atomic Symbol": "Db", "Mass Number": "257", "Relative Atomic Mass": "257.10758(22#)" }, { "Atomic Symbol": "Db", "Mass Number": "258", "Relative Atomic Mass": "258.10928(33#)" }, { "Atomic Symbol": "Db", "Mass Number": "259", "Relative Atomic Mass": "259.109492(57)" }, { "Atomic Symbol": "Db", "Mass Number": "260", "Relative Atomic Mass": "260.11130(10#)" }, { "Atomic Symbol": "Db", "Mass Number": "261", "Relative Atomic Mass": "261.11192(12#)" }, { "Atomic Symbol": "Db", "Mass Number": "262", "Relative Atomic Mass": "262.11407(15#)" }, { "Atomic Symbol": "Db", "Mass Number": "263", "Relative Atomic Mass": "263.11499(18#)" }, { "Atomic Symbol": "Db", "Mass Number": "264", "Relative Atomic Mass": "264.11741(25#)" }, { "Atomic Symbol": "Db", "Mass Number": "265", "Relative Atomic Mass": "265.11861(24#)" }, { "Atomic Symbol": "Db", "Mass Number": "266", "Relative Atomic Mass": "266.12103(30#)" }, { "Atomic Symbol": "Db", "Mass Number": "267", "Relative Atomic Mass": "267.12247(44#)" }, { "Atomic Symbol": "Db", "Mass Number": "268", "Relative Atomic Mass": "268.12567(57#)" }, { "Atomic Symbol": "Db", "Mass Number": "269", "Relative Atomic Mass": "269.12791(73#)" }, { "Atomic Symbol": "Db", "Mass Number": "270", "Relative Atomic Mass": "270.13136(64#)" } ] }, { "Atomic Symbol": "Sg", "Atomic Number": "106", "isotopes": [ { "Atomic Symbol": "Sg", "Mass Number": "258", "Relative Atomic Mass": "258.11298(44#)" }, { "Atomic Symbol": "Sg", "Mass Number": "259", "Relative Atomic Mass": "259.11440(13#)" }, { "Atomic Symbol": "Sg", "Mass Number": "260", "Relative Atomic Mass": "260.114384(22)" }, { "Atomic Symbol": "Sg", "Mass Number": "261", "Relative Atomic Mass": "261.115949(20)" }, { "Atomic Symbol": "Sg", "Mass Number": "262", "Relative Atomic Mass": "262.116337(38)" }, { "Atomic Symbol": "Sg", "Mass Number": "263", "Relative Atomic Mass": "263.11829(10#)" }, { "Atomic Symbol": "Sg", "Mass Number": "264", "Relative Atomic Mass": "264.11893(30#)" }, { "Atomic Symbol": "Sg", "Mass Number": "265", "Relative Atomic Mass": "265.12109(13#)" }, { "Atomic Symbol": "Sg", "Mass Number": "266", "Relative Atomic Mass": "266.12198(26#)" }, { "Atomic Symbol": "Sg", "Mass Number": "267", "Relative Atomic Mass": "267.12436(30#)" }, { "Atomic Symbol": "Sg", "Mass Number": "268", "Relative Atomic Mass": "268.12539(50#)" }, { "Atomic Symbol": "Sg", "Mass Number": "269", "Relative Atomic Mass": "269.12863(39#)" }, { "Atomic Symbol": "Sg", "Mass Number": "270", "Relative Atomic Mass": "270.13043(60#)" }, { "Atomic Symbol": "Sg", "Mass Number": "271", "Relative Atomic Mass": "271.13393(63#)" }, { "Atomic Symbol": "Sg", "Mass Number": "272", "Relative Atomic Mass": "272.13589(83#)" }, { "Atomic Symbol": "Sg", "Mass Number": "273", "Relative Atomic Mass": "273.13958(54#)" } ] }, { "Atomic Symbol": "Bh", "Atomic Number": "107", "isotopes": [ { "Atomic Symbol": "Bh", "Mass Number": "260", "Relative Atomic Mass": "260.12166(26#)" }, { "Atomic Symbol": "Bh", "Mass Number": "261", "Relative Atomic Mass": "261.12145(22#)" }, { "Atomic Symbol": "Bh", "Mass Number": "262", "Relative Atomic Mass": "262.12297(33#)" }, { "Atomic Symbol": "Bh", "Mass Number": "263", "Relative Atomic Mass": "263.12292(33#)" }, { "Atomic Symbol": "Bh", "Mass Number": "264", "Relative Atomic Mass": "264.12459(19#)" }, { "Atomic Symbol": "Bh", "Mass Number": "265", "Relative Atomic Mass": "265.12491(25#)" }, { "Atomic Symbol": "Bh", "Mass Number": "266", "Relative Atomic Mass": "266.12679(18#)" }, { "Atomic Symbol": "Bh", "Mass Number": "267", "Relative Atomic Mass": "267.12750(28#)" }, { "Atomic Symbol": "Bh", "Mass Number": "268", "Relative Atomic Mass": "268.12969(41#)" }, { "Atomic Symbol": "Bh", "Mass Number": "269", "Relative Atomic Mass": "269.13042(40#)" }, { "Atomic Symbol": "Bh", "Mass Number": "270", "Relative Atomic Mass": "270.13336(31#)" }, { "Atomic Symbol": "Bh", "Mass Number": "271", "Relative Atomic Mass": "271.13526(48#)" }, { "Atomic Symbol": "Bh", "Mass Number": "272", "Relative Atomic Mass": "272.13826(58#)" }, { "Atomic Symbol": "Bh", "Mass Number": "273", "Relative Atomic Mass": "273.14024(80#)" }, { "Atomic Symbol": "Bh", "Mass Number": "274", "Relative Atomic Mass": "274.14355(65#)" }, { "Atomic Symbol": "Bh", "Mass Number": "275", "Relative Atomic Mass": "275.14567(64#)" } ] }, { "Atomic Symbol": "Hs", "Atomic Number": "108", "isotopes": [ { "Atomic Symbol": "Hs", "Mass Number": "263", "Relative Atomic Mass": "263.12852(14#)" }, { "Atomic Symbol": "Hs", "Mass Number": "264", "Relative Atomic Mass": "264.128357(31)" }, { "Atomic Symbol": "Hs", "Mass Number": "265", "Relative Atomic Mass": "265.129793(26)" }, { "Atomic Symbol": "Hs", "Mass Number": "266", "Relative Atomic Mass": "266.130046(42)" }, { "Atomic Symbol": "Hs", "Mass Number": "267", "Relative Atomic Mass": "267.13167(10#)" }, { "Atomic Symbol": "Hs", "Mass Number": "268", "Relative Atomic Mass": "268.13186(30#)" }, { "Atomic Symbol": "Hs", "Mass Number": "269", "Relative Atomic Mass": "269.13375(13#)" }, { "Atomic Symbol": "Hs", "Mass Number": "270", "Relative Atomic Mass": "270.13429(27#)" }, { "Atomic Symbol": "Hs", "Mass Number": "271", "Relative Atomic Mass": "271.13717(32#)" }, { "Atomic Symbol": "Hs", "Mass Number": "272", "Relative Atomic Mass": "272.13850(55#)" }, { "Atomic Symbol": "Hs", "Mass Number": "273", "Relative Atomic Mass": "273.14168(40#)" }, { "Atomic Symbol": "Hs", "Mass Number": "274", "Relative Atomic Mass": "274.14330(63#)" }, { "Atomic Symbol": "Hs", "Mass Number": "275", "Relative Atomic Mass": "275.14667(63#)" }, { "Atomic Symbol": "Hs", "Mass Number": "276", "Relative Atomic Mass": "276.14846(86#)" }, { "Atomic Symbol": "Hs", "Mass Number": "277", "Relative Atomic Mass": "277.15190(58#)" } ] }, { "Atomic Symbol": "Mt", "Atomic Number": "109", "isotopes": [ { "Atomic Symbol": "Mt", "Mass Number": "265", "Relative Atomic Mass": "265.13600(48#)" }, { "Atomic Symbol": "Mt", "Mass Number": "266", "Relative Atomic Mass": "266.13737(33#)" }, { "Atomic Symbol": "Mt", "Mass Number": "267", "Relative Atomic Mass": "267.13719(54#)" }, { "Atomic Symbol": "Mt", "Mass Number": "268", "Relative Atomic Mass": "268.13865(25#)" }, { "Atomic Symbol": "Mt", "Mass Number": "269", "Relative Atomic Mass": "269.13882(50#)" }, { "Atomic Symbol": "Mt", "Mass Number": "270", "Relative Atomic Mass": "270.14033(18#)" }, { "Atomic Symbol": "Mt", "Mass Number": "271", "Relative Atomic Mass": "271.14074(35#)" }, { "Atomic Symbol": "Mt", "Mass Number": "272", "Relative Atomic Mass": "272.14341(52#)" }, { "Atomic Symbol": "Mt", "Mass Number": "273", "Relative Atomic Mass": "273.14440(52#)" }, { "Atomic Symbol": "Mt", "Mass Number": "274", "Relative Atomic Mass": "274.14724(38#)" }, { "Atomic Symbol": "Mt", "Mass Number": "275", "Relative Atomic Mass": "275.14882(50#)" }, { "Atomic Symbol": "Mt", "Mass Number": "276", "Relative Atomic Mass": "276.15159(59#)" }, { "Atomic Symbol": "Mt", "Mass Number": "277", "Relative Atomic Mass": "277.15327(82#)" }, { "Atomic Symbol": "Mt", "Mass Number": "278", "Relative Atomic Mass": "278.15631(68#)" }, { "Atomic Symbol": "Mt", "Mass Number": "279", "Relative Atomic Mass": "279.15808(72#)" } ] }, { "Atomic Symbol": "Ds", "Atomic Number": "110", "isotopes": [ { "Atomic Symbol": "Ds", "Mass Number": "267", "Relative Atomic Mass": "267.14377(15#)" }, { "Atomic Symbol": "Ds", "Mass Number": "268", "Relative Atomic Mass": "268.14348(32#)" }, { "Atomic Symbol": "Ds", "Mass Number": "269", "Relative Atomic Mass": "269.144752(34)" }, { "Atomic Symbol": "Ds", "Mass Number": "270", "Relative Atomic Mass": "270.144584(52)" }, { "Atomic Symbol": "Ds", "Mass Number": "271", "Relative Atomic Mass": "271.14595(10#)" }, { "Atomic Symbol": "Ds", "Mass Number": "272", "Relative Atomic Mass": "272.14602(44#)" }, { "Atomic Symbol": "Ds", "Mass Number": "273", "Relative Atomic Mass": "273.14856(14#)" }, { "Atomic Symbol": "Ds", "Mass Number": "274", "Relative Atomic Mass": "274.14941(42#)" }, { "Atomic Symbol": "Ds", "Mass Number": "275", "Relative Atomic Mass": "275.15203(45#)" }, { "Atomic Symbol": "Ds", "Mass Number": "276", "Relative Atomic Mass": "276.15303(59#)" }, { "Atomic Symbol": "Ds", "Mass Number": "277", "Relative Atomic Mass": "277.15591(41#)" }, { "Atomic Symbol": "Ds", "Mass Number": "278", "Relative Atomic Mass": "278.15704(67#)" }, { "Atomic Symbol": "Ds", "Mass Number": "279", "Relative Atomic Mass": "279.16010(64#)" }, { "Atomic Symbol": "Ds", "Mass Number": "280", "Relative Atomic Mass": "280.16131(89#)" }, { "Atomic Symbol": "Ds", "Mass Number": "281", "Relative Atomic Mass": "281.16451(59#)" } ] }, { "Atomic Symbol": "Rg", "Atomic Number": "111", "isotopes": [ { "Atomic Symbol": "Rg", "Mass Number": "272", "Relative Atomic Mass": "272.15327(25#)" }, { "Atomic Symbol": "Rg", "Mass Number": "273", "Relative Atomic Mass": "273.15313(56#)" }, { "Atomic Symbol": "Rg", "Mass Number": "274", "Relative Atomic Mass": "274.15525(19#)" }, { "Atomic Symbol": "Rg", "Mass Number": "275", "Relative Atomic Mass": "275.15594(56#)" }, { "Atomic Symbol": "Rg", "Mass Number": "276", "Relative Atomic Mass": "276.15833(68#)" }, { "Atomic Symbol": "Rg", "Mass Number": "277", "Relative Atomic Mass": "277.15907(61#)" }, { "Atomic Symbol": "Rg", "Mass Number": "278", "Relative Atomic Mass": "278.16149(38#)" }, { "Atomic Symbol": "Rg", "Mass Number": "279", "Relative Atomic Mass": "279.16272(51#)" }, { "Atomic Symbol": "Rg", "Mass Number": "280", "Relative Atomic Mass": "280.16514(61#)" }, { "Atomic Symbol": "Rg", "Mass Number": "281", "Relative Atomic Mass": "281.16636(89#)" }, { "Atomic Symbol": "Rg", "Mass Number": "282", "Relative Atomic Mass": "282.16912(72#)" }, { "Atomic Symbol": "Rg", "Mass Number": "283", "Relative Atomic Mass": "283.17054(79#)" } ] }, { "Atomic Symbol": "Cn", "Atomic Number": "112", "isotopes": [ { "Atomic Symbol": "Cn", "Mass Number": "276", "Relative Atomic Mass": "276.16141(64#)" }, { "Atomic Symbol": "Cn", "Mass Number": "277", "Relative Atomic Mass": "277.16364(15#)" }, { "Atomic Symbol": "Cn", "Mass Number": "278", "Relative Atomic Mass": "278.16416(47#)" }, { "Atomic Symbol": "Cn", "Mass Number": "279", "Relative Atomic Mass": "279.16654(50#)" }, { "Atomic Symbol": "Cn", "Mass Number": "280", "Relative Atomic Mass": "280.16715(63#)" }, { "Atomic Symbol": "Cn", "Mass Number": "281", "Relative Atomic Mass": "281.16975(42#)" }, { "Atomic Symbol": "Cn", "Mass Number": "282", "Relative Atomic Mass": "282.17050(70#)" }, { "Atomic Symbol": "Cn", "Mass Number": "283", "Relative Atomic Mass": "283.17327(65#)" }, { "Atomic Symbol": "Cn", "Mass Number": "284", "Relative Atomic Mass": "284.17416(91#)" }, { "Atomic Symbol": "Cn", "Mass Number": "285", "Relative Atomic Mass": "285.17712(60#)" } ] }, { "Atomic Symbol": "Uut", "Atomic Number": "113", "isotopes": [ { "Atomic Symbol": "Uut", "Mass Number": "278", "Relative Atomic Mass": "278.17058(20#)" }, { "Atomic Symbol": "Uut", "Mass Number": "279", "Relative Atomic Mass": "279.17095(75#)" }, { "Atomic Symbol": "Uut", "Mass Number": "280", "Relative Atomic Mass": "280.17293(75#)" }, { "Atomic Symbol": "Uut", "Mass Number": "281", "Relative Atomic Mass": "281.17348(75#)" }, { "Atomic Symbol": "Uut", "Mass Number": "282", "Relative Atomic Mass": "282.17567(39#)" }, { "Atomic Symbol": "Uut", "Mass Number": "283", "Relative Atomic Mass": "283.17657(52#)" }, { "Atomic Symbol": "Uut", "Mass Number": "284", "Relative Atomic Mass": "284.17873(62#)" }, { "Atomic Symbol": "Uut", "Mass Number": "285", "Relative Atomic Mass": "285.17973(89#)" }, { "Atomic Symbol": "Uut", "Mass Number": "286", "Relative Atomic Mass": "286.18221(72#)" }, { "Atomic Symbol": "Uut", "Mass Number": "287", "Relative Atomic Mass": "287.18339(81#)" } ] }, { "Atomic Symbol": "Fl", "Atomic Number": "114", "isotopes": [ { "Atomic Symbol": "Fl", "Mass Number": "285", "Relative Atomic Mass": "285.18364(47#)" }, { "Atomic Symbol": "Fl", "Mass Number": "286", "Relative Atomic Mass": "286.18423(71#)" }, { "Atomic Symbol": "Fl", "Mass Number": "287", "Relative Atomic Mass": "287.18678(66#)" }, { "Atomic Symbol": "Fl", "Mass Number": "288", "Relative Atomic Mass": "288.18757(91#)" }, { "Atomic Symbol": "Fl", "Mass Number": "289", "Relative Atomic Mass": "289.19042(60#)" } ] }, { "Atomic Symbol": "Uup", "Atomic Number": "115", "isotopes": [ { "Atomic Symbol": "Uup", "Mass Number": "287", "Relative Atomic Mass": "287.19070(52#)" }, { "Atomic Symbol": "Uup", "Mass Number": "288", "Relative Atomic Mass": "288.19274(62#)" }, { "Atomic Symbol": "Uup", "Mass Number": "289", "Relative Atomic Mass": "289.19363(89#)" }, { "Atomic Symbol": "Uup", "Mass Number": "290", "Relative Atomic Mass": "290.19598(73#)" }, { "Atomic Symbol": "Uup", "Mass Number": "291", "Relative Atomic Mass": "291.19707(88#)" } ] }, { "Atomic Symbol": "Lv", "Atomic Number": "116", "isotopes": [ { "Atomic Symbol": "Lv", "Mass Number": "289", "Relative Atomic Mass": "289.19816(57#)" }, { "Atomic Symbol": "Lv", "Mass Number": "290", "Relative Atomic Mass": "290.19864(71#)" }, { "Atomic Symbol": "Lv", "Mass Number": "291", "Relative Atomic Mass": "291.20108(66#)" }, { "Atomic Symbol": "Lv", "Mass Number": "292", "Relative Atomic Mass": "292.20174(91#)" }, { "Atomic Symbol": "Lv", "Mass Number": "293", "Relative Atomic Mass": "293.20449(60#)" } ] }, { "Atomic Symbol": "Uus", "Atomic Number": "117", "isotopes": [ { "Atomic Symbol": "Uus", "Mass Number": "291", "Relative Atomic Mass": "291.20553(68#)" }, { "Atomic Symbol": "Uus", "Mass Number": "292", "Relative Atomic Mass": "292.20746(75#)" }, { "Atomic Symbol": "Uus", "Mass Number": "293", "Relative Atomic Mass": "293.20824(89#)" }, { "Atomic Symbol": "Uus", "Mass Number": "294", "Relative Atomic Mass": "294.21046(74#)" } ] } ] } QCElemental-0.5.0/qcelemental/000077500000000000000000000000001351361252000161365ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/__init__.py000066400000000000000000000013431351361252000202500ustar00rootroot00000000000000""" Main init for QCElemental """ from .datum import Datum from .exceptions import (NotAnElementError, ValidationError, MoleculeFormatError, ChoicesError, DataUnavailableError) from .testing import (compare, compare_values) from . import molparse from . import molutil from . import models # Handle singletons, not their classes or modules from .periodic_table import periodictable from .physical_constants import constants, PhysicalConstantsContext from .covalent_radii import covalentradii, CovalentRadii del periodic_table del physical_constants del covalent_radii # Handle versioneer from .extras import get_information __version__ = get_information('version') __git_revision__ = get_information('git_revision') del get_information QCElemental-0.5.0/qcelemental/_version.py000066400000000000000000000435721351361252000203470ustar00rootroot00000000000000# This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by # versioneer-0.18 (https://github.com/warner/python-versioneer) """Git implementation of _version.py.""" import errno import os import re import subprocess import sys def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (tag: v0.5.0)" git_full = "9711d64ee5c435ea4f54344d36f0a5cd30a9ed7a" git_date = "2019-07-17 08:32:16 -0400" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "pep440" cfg.tag_prefix = "" cfg.parentdir_prefix = "None" cfg.versionfile_source = "qcelemental/_version.py" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY = {} HANDLERS = {} def register_vcs_handler(vcs, method): # decorator """Decorator to mark a method as the handler for a particular VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None for c in commands: try: dispcmd = str([c] + args) # remember shell=False, so use git.cmd on windows, not just git p = subprocess.Popen( [c] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None)) break except EnvironmentError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands, )) return None, None stdout = p.communicate()[0].strip() if sys.version_info[0] >= 3: stdout = stdout.decode() if p.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, p.returncode return stdout, p.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for i in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return { "version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None } else: rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: f = open(versionfile_abs, "r") for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) f.close() except EnvironmentError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if not keywords: raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = set([r.strip() for r in refnames.strip("()").split(",")]) # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = set([r for r in refs if re.search(r'\d', r)]) if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] if verbose: print("picking %s" % r) return { "version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date } # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return { "version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None } @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = run_command( GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", "%s*" % tag_prefix], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparseable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%s'" % describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" % (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_pre(pieces): """TAG[.post.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += ".post.dev%d" % pieces["distance"] else: # exception #1 rendered = "0.post.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Eexceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return { "version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None } if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return { "version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date") } def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for i in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return { "version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None } try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return { "version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None } QCElemental-0.5.0/qcelemental/checkup_data/000077500000000000000000000000001351361252000205515ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/checkup_data/README.md000066400000000000000000000003351351361252000220310ustar00rootroot00000000000000This directory is usually not imported. It contains periodic table data used by Psi4 and Cfour so as to run comparisons versus this module through `PeriodicTable.run_comparison()`. Also physical constant data from Psi4. QCElemental-0.5.0/qcelemental/checkup_data/__init__.py000066400000000000000000000001531351361252000226610ustar00rootroot00000000000000from . import periodictable from . import physconst from .cfour_primary_masses import cfour_primary_masses QCElemental-0.5.0/qcelemental/checkup_data/cfour_primary_masses.py000066400000000000000000000044131351361252000253610ustar00rootroot00000000000000# DATA ATMSS from ~line 150 of cfour/joda/pertable.f cfour_primary_masses = [ 1.007825035E+00, 4.00260324E+00, 7.0160030E+00, 9.0121822E+00, 11.0093054E+00, 12.0000000E+00, 14.003074002E+00, 15.99491463E+00, 18.99840322E+00, 19.9924356E+00, 22.9897677E+00, 23.9850423E+00, 26.9815386E+00, 27.9769271E+00, 30.9737620E+00, 31.97207070E+00, 34.968852721E+00, 39.9623837E+00, 38.9637074E+00, 39.9625906E+00, 44.9559100E+00, 47.9479473E+00, 50.9439617E+00, 51.9405098E+00, 54.9380471E+00, 55.9349393E+00, 58.9331976E+00, 57.9353462E+00, 62.9295989E+00, 63.9291448E+00, 68.925580E+00, 73.9211774E+00, 74.9215942E+00, 79.9165196E+00, 78.9183361E+00, 83.911507E+00, 84.911794E+00, 87.9056188E+00, 88.905849E+00, 89.9047026E+00, 92.9063772E+00, 97.9054073E+00, 97.907215E+00, 101.9043485E+00, 102.905500E+00, 105.903478E+00, 106.905092E+00, 113.903357E+00, 114.903882E+00, 119.9021991E+00, 120.9038212E+00, 129.906229E+00, 126.904473E+00, 131.904144E+00, 132.905429E+00, 137.905232E+00, 138.906347E+00, 139.905433E+00, 140.907647E+00, 141.907719E+00, 144.912743E+00, 151.919728E+00, 152.921225E+00, 157.924019E+00, 158.925342E+00, 163.929171E+00, 164.930319E+00, 165.930290E+00, 168.934212E+00, 173.938859E+00, 174.940770E+00, 179.9465457E+00, 180.947462E+00, 183.950928E+00, 186.955744E+00, 191.961467E+00, 192.962917E+00, 194.964766E+00, 196.966543E+00, 201.970617E+00, 204.974401E+00, 207.976627E+00, 208.980374E+00, 208.982404E+00, 209.987126E+00, 222.017571E+00, 223.019736E+00, 226.025410E+00, 227.027752E+00, 232.038055E+00, 231.035884E+00, 238.050788E+00, 237.048173E+00, 244.064204E+00, 243.061381E+00, 247.070354E+00, 247.074987E+00, 251.079587E+00, 252.082980E+00, 257.095105E+00, 258.098431E+00, 259.10103E+00, 262.10963E+00, 265.11670E+00, 268.12545E+00, 271.13347E+00, 272.13803E+00, 270.13465E+00, 276.15116E+00, 281.16206E+00, 280.16447E+00, 285.17411E+00, ] QCElemental-0.5.0/qcelemental/checkup_data/periodictable.py000066400000000000000000002305721351361252000237420ustar00rootroot00000000000000# # @BEGIN LICENSE # # Psi4: an open-source quantum chemistry software package # # Copyright (c) 2007-2017 The Psi4 Developers. # # The copyrights for code used from other parties are included in # the corresponding files. # # This file is part of Psi4. # # Psi4 is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, version 3. # # Psi4 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License along # with Psi4; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # @END LICENSE # """Elemental masses (most common isotope), symbols, and atomic numbers from psi4. """ _temp_element = ["GHOST", "HYDROGEN", "HELIUM", "LITHIUM", "BERYLLIUM", "BORON", "CARBON", "NITROGEN", "OXYGEN", "FLUORINE", "NEON", "SODIUM", "MAGNESIUM", "ALUMINUM", "SILICON", "PHOSPHORUS", "SULFUR", "CHLORINE", "ARGON", "POTASSIUM", "CALCIUM", "SCANDIUM", "TITANIUM", "VANADIUM", "CHROMIUM", "MANGANESE", "IRON", "COBALT", "NICKEL", "COPPER", "ZINC", "GALLIUM", "GERMANIUM", "ARSENIC", "SELENIUM", "BROMINE", "KRYPTON", "RUBIDIUM", "STRONTIUM", "YTTRIUM", "ZIRCONIUM", "NIOBIUM", "MOLYBDENUM", "TECHNETIUM", "RUTHENIUM", "RHODIUM", "PALLADIUM", "SILVER", "CADMIUM", "INDIUM", "TIN", "ANTIMONY", "TELLURIUM", "IODINE", "XENON", "CESIUM", "BARIUM", "LANTHANUM", "CERIUM", "PRASEODYMIUM", "NEODYMIUM", "PROMETHIUM", "SAMARIUM", "EUROPIUM", "GADOLINIUM", "TERBIUM", "DYSPROSIUM", "HOLMIUM", "ERBIUM", "THULIUM", "YTTERBIUM", "LUTETIUM", "HAFNIUM", "TANTALUM", "TUNGSTEN", "RHENIUM", "OSMIUM", "IRIDIUM", "PLATINUM", "GOLD", "MERCURY", "THALLIUM", "LEAD", "BISMUTH", "POLONIUM", "ASTATINE", "RADON", "FRANCIUM", "RADIUM", "ACTINIUM", "THORIUM", "PROTACTINIUM", "URANIUM", "NEPTUNIUM", "PLUTONIUM", "AMERICIUM", "CURIUM", "BERKELIUM", "CALIFORNIUM", "EINSTEINIUM", "FERMIUM", "MENDELEVIUM", "NOBELIUM", "LAWRENCIUM", "RUTHERFORDIUM", "DUBNIUM", "SEABORGIUM", "BOHRIUM"] _temp_symbol = ["X", "H", "HE", "LI", "BE", "B", "C", "N", "O", "F", "NE", "NA", "MG", "AL", "SI", "P", "S", "CL", "AR", "K", "CA", "SC", "TI", "V", "CR", "MN", "FE", "CO", "NI", "CU", "ZN", "GA", "GE", "AS", "SE", "BR", "KR", "RB", "SR", "Y", "ZR", "NB", "MO", "TC", "RU", "RH", "PD", "AG", "CD", "IN", "SN", "SB", "TE", "I", "XE", "CS", "BA", "LA", "CE", "PR", "ND", "PM", "SM", "EU", "GD", "TB", "DY", "HO", "ER", "TM", "YB", "LU", "HF", "TA", "W", "RE", "OS", "IR", "PT", "AU", "HG", "TL", "PB", "BI", "PO", "AT", "RN", "FR", "RA", "AC", "TH", "PA", "U", "NP", "PU", "AM", "CM", "BK", "CF", "ES", "FM", "MD", "NO", "LR", "RF", "DB", "SG", "BH", "HS", "MT", "DS", "RG", "UUB", "UUT", "UUQ", "UUP", "UUH", "UUS", "UUO"] _temp_z = list(range(0, 108)) _temp_mass = [ 0., 1.00782503207, 4.00260325415, 7.016004548, 9.012182201, 11.009305406, 12, 14.00307400478, 15.99491461956, 18.998403224, 19.99244017542, 22.98976928087, 23.985041699, 26.981538627, 27.97692653246, 30.973761629, 31.972070999, 34.968852682, 39.96238312251, 38.963706679, 39.962590983, 44.955911909, 47.947946281, 50.943959507, 51.940507472, 54.938045141, 55.934937475, 58.933195048, 57.935342907, 62.929597474, 63.929142222, 68.925573587, 73.921177767, 74.921596478, 79.916521271, 78.918337087, 85.910610729, 84.911789737, 87.905612124, 88.905848295, 89.904704416, 92.906378058, 97.905408169, 98.906254747, 101.904349312, 102.905504292, 105.903485715, 106.90509682, 113.90335854, 114.903878484, 119.902194676, 120.903815686, 129.906224399, 126.904472681, 131.904153457, 132.905451932, 137.905247237, 138.906353267, 139.905438706, 140.907652769, 141.907723297, 144.912749023, 151.919732425, 152.921230339, 157.924103912, 158.925346757, 163.929174751, 164.93032207, 165.930293061, 168.93421325, 173.938862089, 174.940771819, 179.946549953, 180.947995763, 183.950931188, 186.955753109, 191.96148069, 192.96292643, 194.964791134, 196.966568662, 201.970643011, 204.974427541, 207.976652071, 208.980398734, 208.982430435, 210.987496271, 222.017577738, 222.01755173, 228.031070292, 227.027752127, 232.038055325, 231.03588399, 238.050788247, 237.048173444, 242.058742611, 243.06138108, 247.07035354, 247.07030708, 251.079586788, 252.082978512, 257.095104724, 258.098431319, 255.093241131, 260.105504, 263.112547, 255.107398, 259.114500, 262.122892, 263.128558, 265.136151, 281.162061, 272.153615, 283.171792, 283.176451, 285.183698, 287.191186, 292.199786, 291.206564, 293.214670] _temp_iso_symbol = [ "H", "H1", "H2", "D", "H3", "T", "H4", "H5", "H6", "H7", "HE", "HE3", "HE4", "HE5", "HE6", "HE7", "HE8", "HE9", "HE10", "LI", "LI3", "LI4", "LI5", "LI6", "LI7", "LI8", "LI9", "LI10", "LI11", "LI12", "BE", "BE5", "BE6", "BE7", "BE8", "BE9", "BE10", "BE11", "BE12", "BE13", "BE14", "BE15", "BE16", "B", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "C", "C8", "C9", "C10", "C11", "C12", "C13", "C14", "C15", "C16", "C17", "C18", "C19", "C20", "C21", "C22", "N", "N10", "N11", "N12", "N13", "N14", "N15", "N16", "N17", "N18", "N19", "N20", "N21", "N22", "N23", "N24", "N25", "O", "O12", "O13", "O14", "O15", "O16", "O17", "O18", "O19", "O20", "O21", "O22", "O23", "O24", "O25", "O26", "O27", "O28", "F", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", "NE", "NE16", "NE17", "NE18", "NE19", "NE20", "NE21", "NE22", "NE23", "NE24", "NE25", "NE26", "NE27", "NE28", "NE29", "NE30", "NE31", "NE32", "NE33", "NE34", "NA", "NA18", "NA19", "NA20", "NA21", "NA22", "NA23", "NA24", "NA25", "NA26", "NA27", "NA28", "NA29", "NA30", "NA31", "NA32", "NA33", "NA34", "NA35", "NA36", "NA37", "MG", "MG19", "MG20", "MG21", "MG22", "MG23", "MG24", "MG25", "MG26", "MG27", "MG28", "MG29", "MG30", "MG31", "MG32", "MG33", "MG34", "MG35", "MG36", "MG37", "MG38", "MG39", "MG40", "AL", "AL21", "AL22", "AL23", "AL24", "AL25", "AL26", "AL27", "AL28", "AL29", "AL30", "AL31", "AL32", "AL33", "AL34", "AL35", "AL36", "AL37", "AL38", "AL39", "AL40", "AL41", "AL42", "SI", "SI22", "SI23", "SI24", "SI25", "SI26", "SI27", "SI28", "SI29", "SI30", "SI31", "SI32", "SI33", "SI34", "SI35", "SI36", "SI37", "SI38", "SI39", "SI40", "SI41", "SI42", "SI43", "SI44", "P", "P24", "P25", "P26", "P27", "P28", "P29", "P30", "P31", "P32", "P33", "P34", "P35", "P36", "P37", "P38", "P39", "P40", "P41", "P42", "P43", "P44", "P45", "P46", "S", "S26", "S27", "S28", "S29", "S30", "S31", "S32", "S33", "S34", "S35", "S36", "S37", "S38", "S39", "S40", "S41", "S42", "S43", "S44", "S45", "S46", "S47", "S48", "S49", "CL", "CL28", "CL29", "CL30", "CL31", "CL32", "CL33", "CL34", "CL35", "CL36", "CL37", "CL38", "CL39", "CL40", "CL41", "CL42", "CL43", "CL44", "CL45", "CL46", "CL47", "CL48", "CL49", "CL50", "CL51", "AR", "AR30", "AR31", "AR32", "AR33", "AR34", "AR35", "AR36", "AR37", "AR38", "AR39", "AR40", "AR41", "AR42", "AR43", "AR44", "AR45", "AR46", "AR47", "AR48", "AR49", "AR50", "AR51", "AR52", "AR53", "K", "K32", "K33", "K34", "K35", "K36", "K37", "K38", "K39", "K40", "K41", "K42", "K43", "K44", "K45", "K46", "K47", "K48", "K49", "K50", "K51", "K52", "K53", "K54", "K55", "CA", "CA34", "CA35", "CA36", "CA37", "CA38", "CA39", "CA40", "CA41", "CA42", "CA43", "CA44", "CA45", "CA46", "CA47", "CA48", "CA49", "CA50", "CA51", "CA52", "CA53", "CA54", "CA55", "CA56", "CA57", "SC", "SC36", "SC37", "SC38", "SC39", "SC40", "SC41", "SC42", "SC43", "SC44", "SC45", "SC46", "SC47", "SC48", "SC49", "SC50", "SC51", "SC52", "SC53", "SC54", "SC55", "SC56", "SC57", "SC58", "SC59", "SC60", "TI", "TI38", "TI39", "TI40", "TI41", "TI42", "TI43", "TI44", "TI45", "TI46", "TI47", "TI48", "TI49", "TI50", "TI51", "TI52", "TI53", "TI54", "TI55", "TI56", "TI57", "TI58", "TI59", "TI60", "TI61", "TI62", "TI63", "V", "V40", "V41", "V42", "V43", "V44", "V45", "V46", "V47", "V48", "V49", "V50", "V51", "V52", "V53", "V54", "V55", "V56", "V57", "V58", "V59", "V60", "V61", "V62", "V63", "V64", "V65", "CR", "CR42", "CR43", "CR44", "CR45", "CR46", "CR47", "CR48", "CR49", "CR50", "CR51", "CR52", "CR53", "CR54", "CR55", "CR56", "CR57", "CR58", "CR59", "CR60", "CR61", "CR62", "CR63", "CR64", "CR65", "CR66", "CR67", "MN", "MN44", "MN45", "MN46", "MN47", "MN48", "MN49", "MN50", "MN51", "MN52", "MN53", "MN54", "MN55", "MN56", "MN57", "MN58", "MN59", "MN60", "MN61", "MN62", "MN63", "MN64", "MN65", "MN66", "MN67", "MN68", "MN69", "FE", "FE45", "FE46", "FE47", "FE48", "FE49", "FE50", "FE51", "FE52", "FE53", "FE54", "FE55", "FE56", "FE57", "FE58", "FE59", "FE60", "FE61", "FE62", "FE63", "FE64", "FE65", "FE66", "FE67", "FE68", "FE69", "FE70", "FE71", "FE72", "CO", "CO47", "CO48", "CO49", "CO50", "CO51", "CO52", "CO53", "CO54", "CO55", "CO56", "CO57", "CO58", "CO59", "CO60", "CO61", "CO62", "CO63", "CO64", "CO65", "CO66", "CO67", "CO68", "CO69", "CO70", "CO71", "CO72", "CO73", "CO74", "CO75", "NI", "NI48", "NI49", "NI50", "NI51", "NI52", "NI53", "NI54", "NI55", "NI56", "NI57", "NI58", "NI59", "NI60", "NI61", "NI62", "NI63", "NI64", "NI65", "NI66", "NI67", "NI68", "NI69", "NI70", "NI71", "NI72", "NI73", "NI74", "NI75", "NI76", "NI77", "NI78", "CU", "CU52", "CU53", "CU54", "CU55", "CU56", "CU57", "CU58", "CU59", "CU60", "CU61", "CU62", "CU63", "CU64", "CU65", "CU66", "CU67", "CU68", "CU69", "CU70", "CU71", "CU72", "CU73", "CU74", "CU75", "CU76", "CU77", "CU78", "CU79", "CU80", "ZN", "ZN54", "ZN55", "ZN56", "ZN57", "ZN58", "ZN59", "ZN60", "ZN61", "ZN62", "ZN63", "ZN64", "ZN65", "ZN66", "ZN67", "ZN68", "ZN69", "ZN70", "ZN71", "ZN72", "ZN73", "ZN74", "ZN75", "ZN76", "ZN77", "ZN78", "ZN79", "ZN80", "ZN81", "ZN82", "ZN83", "GA", "GA56", "GA57", "GA58", "GA59", "GA60", "GA61", "GA62", "GA63", "GA64", "GA65", "GA66", "GA67", "GA68", "GA69", "GA70", "GA71", "GA72", "GA73", "GA74", "GA75", "GA76", "GA77", "GA78", "GA79", "GA80", "GA81", "GA82", "GA83", "GA84", "GA85", "GA86", "GE", "GE58", "GE59", "GE60", "GE61", "GE62", "GE63", "GE64", "GE65", "GE66", "GE67", "GE68", "GE69", "GE70", "GE71", "GE72", "GE73", "GE74", "GE75", "GE76", "GE77", "GE78", "GE79", "GE80", "GE81", "GE82", "GE83", "GE84", "GE85", "GE86", "GE87", "GE88", "GE89", "AS", "AS60", "AS61", "AS62", "AS63", "AS64", "AS65", "AS66", "AS67", "AS68", "AS69", "AS70", "AS71", "AS72", "AS73", "AS74", "AS75", "AS76", "AS77", "AS78", "AS79", "AS80", "AS81", "AS82", "AS83", "AS84", "AS85", "AS86", "AS87", "AS88", "AS89", "AS90", "AS91", "AS92", "SE", "SE65", "SE66", "SE67", "SE68", "SE69", "SE70", "SE71", "SE72", "SE73", "SE74", "SE75", "SE76", "SE77", "SE78", "SE79", "SE80", "SE81", "SE82", "SE83", "SE84", "SE85", "SE86", "SE87", "SE88", "SE89", "SE90", "SE91", "SE92", "SE93", "SE94", "BR", "BR67", "BR68", "BR69", "BR70", "BR71", "BR72", "BR73", "BR74", "BR75", "BR76", "BR77", "BR78", "BR79", "BR80", "BR81", "BR82", "BR83", "BR84", "BR85", "BR86", "BR87", "BR88", "BR89", "BR90", "BR91", "BR92", "BR93", "BR94", "BR95", "BR96", "BR97", "KR", "KR69", "KR70", "KR71", "KR72", "KR73", "KR74", "KR75", "KR76", "KR77", "KR78", "KR79", "KR80", "KR81", "KR82", "KR83", "KR84", "KR85", "KR86", "KR87", "KR88", "KR89", "KR90", "KR91", "KR92", "KR93", "KR94", "KR95", "KR96", "KR97", "KR98", "KR99", "KR100", "RB", "RB71", "RB72", "RB73", "RB74", "RB75", "RB76", "RB77", "RB78", "RB79", "RB80", "RB81", "RB82", "RB83", "RB84", "RB85", "RB86", "RB87", "RB88", "RB89", "RB90", "RB91", "RB92", "RB93", "RB94", "RB95", "RB96", "RB97", "RB98", "RB99", "RB100", "RB101", "RB102", "SR", "SR73", "SR74", "SR75", "SR76", "SR77", "SR78", "SR79", "SR80", "SR81", "SR82", "SR83", "SR84", "SR85", "SR86", "SR87", "SR88", "SR89", "SR90", "SR91", "SR92", "SR93", "SR94", "SR95", "SR96", "SR97", "SR98", "SR99", "SR100", "SR101", "SR102", "SR103", "SR104", "SR105", "Y", "Y76", "Y77", "Y78", "Y79", "Y80", "Y81", "Y82", "Y83", "Y84", "Y85", "Y86", "Y87", "Y88", "Y89", "Y90", "Y91", "Y92", "Y93", "Y94", "Y95", "Y96", "Y97", "Y98", "Y99", "Y100", "Y101", "Y102", "Y103", "Y104", "Y105", "Y106", "Y107", "Y108", "ZR", "ZR78", "ZR79", "ZR80", "ZR81", "ZR82", "ZR83", "ZR84", "ZR85", "ZR86", "ZR87", "ZR88", "ZR89", "ZR90", "ZR91", "ZR92", "ZR93", "ZR94", "ZR95", "ZR96", "ZR97", "ZR98", "ZR99", "ZR100", "ZR101", "ZR102", "ZR103", "ZR104", "ZR105", "ZR106", "ZR107", "ZR108", "ZR109", "ZR110", "NB", "NB81", "NB82", "NB83", "NB84", "NB85", "NB86", "NB87", "NB88", "NB89", "NB90", "NB91", "NB92", "NB93", "NB94", "NB95", "NB96", "NB97", "NB98", "NB99", "NB100", "NB101", "NB102", "NB103", "NB104", "NB105", "NB106", "NB107", "NB108", "NB109", "NB110", "NB111", "NB112", "NB113", "MO", "MO83", "MO84", "MO85", "MO86", "MO87", "MO88", "MO89", "MO90", "MO91", "MO92", "MO93", "MO94", "MO95", "MO96", "MO97", "MO98", "MO99", "MO100", "MO101", "MO102", "MO103", "MO104", "MO105", "MO106", "MO107", "MO108", "MO109", "MO110", "MO111", "MO112", "MO113", "MO114", "MO115", "TC", "TC85", "TC86", "TC87", "TC88", "TC89", "TC90", "TC91", "TC92", "TC93", "TC94", "TC95", "TC96", "TC97", "TC98", "TC99", "TC100", "TC101", "TC102", "TC103", "TC104", "TC105", "TC106", "TC107", "TC108", "TC109", "TC110", "TC111", "TC112", "TC113", "TC114", "TC115", "TC116", "TC117", "TC118", "RU", "RU87", "RU88", "RU89", "RU90", "RU91", "RU92", "RU93", "RU94", "RU95", "RU96", "RU97", "RU98", "RU99", "RU100", "RU101", "RU102", "RU103", "RU104", "RU105", "RU106", "RU107", "RU108", "RU109", "RU110", "RU111", "RU112", "RU113", "RU114", "RU115", "RU116", "RU117", "RU118", "RU119", "RU120", "RH", "RH89", "RH90", "RH91", "RH92", "RH93", "RH94", "RH95", "RH96", "RH97", "RH98", "RH99", "RH100", "RH101", "RH102", "RH103", "RH104", "RH105", "RH106", "RH107", "RH108", "RH109", "RH110", "RH111", "RH112", "RH113", "RH114", "RH115", "RH116", "RH117", "RH118", "RH119", "RH120", "RH121", "RH122", "PD", "PD91", "PD92", "PD93", "PD94", "PD95", "PD96", "PD97", "PD98", "PD99", "PD100", "PD101", "PD102", "PD103", "PD104", "PD105", "PD106", "PD107", "PD108", "PD109", "PD110", "PD111", "PD112", "PD113", "PD114", "PD115", "PD116", "PD117", "PD118", "PD119", "PD120", "PD121", "PD122", "PD123", "PD124", "AG", "AG93", "AG94", "AG95", "AG96", "AG97", "AG98", "AG99", "AG100", "AG101", "AG102", "AG103", "AG104", "AG105", "AG106", "AG107", "AG108", "AG109", "AG110", "AG111", "AG112", "AG113", "AG114", "AG115", "AG116", "AG117", "AG118", "AG119", "AG120", "AG121", "AG122", "AG123", "AG124", "AG125", "AG126", "AG127", "AG128", "AG129", "AG130", "CD", "CD95", "CD96", "CD97", "CD98", "CD99", "CD100", "CD101", "CD102", "CD103", "CD104", "CD105", "CD106", "CD107", "CD108", "CD109", "CD110", "CD111", "CD112", "CD113", "CD114", "CD115", "CD116", "CD117", "CD118", "CD119", "CD120", "CD121", "CD122", "CD123", "CD124", "CD125", "CD126", "CD127", "CD128", "CD129", "CD130", "CD131", "CD132", "IN", "IN97", "IN98", "IN99", "IN100", "IN101", "IN102", "IN103", "IN104", "IN105", "IN106", "IN107", "IN108", "IN109", "IN110", "IN111", "IN112", "IN113", "IN114", "IN115", "IN116", "IN117", "IN118", "IN119", "IN120", "IN121", "IN122", "IN123", "IN124", "IN125", "IN126", "IN127", "IN128", "IN129", "IN130", "IN131", "IN132", "IN133", "IN134", "IN135", "SN", "SN99", "SN100", "SN101", "SN102", "SN103", "SN104", "SN105", "SN106", "SN107", "SN108", "SN109", "SN110", "SN111", "SN112", "SN113", "SN114", "SN115", "SN116", "SN117", "SN118", "SN119", "SN120", "SN121", "SN122", "SN123", "SN124", "SN125", "SN126", "SN127", "SN128", "SN129", "SN130", "SN131", "SN132", "SN133", "SN134", "SN135", "SN136", "SN137", "SB", "SB103", "SB104", "SB105", "SB106", "SB107", "SB108", "SB109", "SB110", "SB111", "SB112", "SB113", "SB114", "SB115", "SB116", "SB117", "SB118", "SB119", "SB120", "SB121", "SB122", "SB123", "SB124", "SB125", "SB126", "SB127", "SB128", "SB129", "SB130", "SB131", "SB132", "SB133", "SB134", "SB135", "SB136", "SB137", "SB138", "SB139", "TE", "TE105", "TE106", "TE107", "TE108", "TE109", "TE110", "TE111", "TE112", "TE113", "TE114", "TE115", "TE116", "TE117", "TE118", "TE119", "TE120", "TE121", "TE122", "TE123", "TE124", "TE125", "TE126", "TE127", "TE128", "TE129", "TE130", "TE131", "TE132", "TE133", "TE134", "TE135", "TE136", "TE137", "TE138", "TE139", "TE140", "TE141", "TE142", "I", "I108", "I109", "I110", "I111", "I112", "I113", "I114", "I115", "I116", "I117", "I118", "I119", "I120", "I121", "I122", "I123", "I124", "I125", "I126", "I127", "I128", "I129", "I130", "I131", "I132", "I133", "I134", "I135", "I136", "I137", "I138", "I139", "I140", "I141", "I142", "I143", "I144", "XE", "XE110", "XE111", "XE112", "XE113", "XE114", "XE115", "XE116", "XE117", "XE118", "XE119", "XE120", "XE121", "XE122", "XE123", "XE124", "XE125", "XE126", "XE127", "XE128", "XE129", "XE130", "XE131", "XE132", "XE133", "XE134", "XE135", "XE136", "XE137", "XE138", "XE139", "XE140", "XE141", "XE142", "XE143", "XE144", "XE145", "XE146", "XE147", "CS", "CS112", "CS113", "CS114", "CS115", "CS116", "CS117", "CS118", "CS119", "CS120", "CS121", "CS122", "CS123", "CS124", "CS125", "CS126", "CS127", "CS128", "CS129", "CS130", "CS131", "CS132", "CS133", "CS134", "CS135", "CS136", "CS137", "CS138", "CS139", "CS140", "CS141", "CS142", "CS143", "CS144", "CS145", "CS146", "CS147", "CS148", "CS149", "CS150", "CS151", "BA", "BA114", "BA115", "BA116", "BA117", "BA118", "BA119", "BA120", "BA121", "BA122", "BA123", "BA124", "BA125", "BA126", "BA127", "BA128", "BA129", "BA130", "BA131", "BA132", "BA133", "BA134", "BA135", "BA136", "BA137", "BA138", "BA139", "BA140", "BA141", "BA142", "BA143", "BA144", "BA145", "BA146", "BA147", "BA148", "BA149", "BA150", "BA151", "BA152", "BA153", "LA", "LA117", "LA118", "LA119", "LA120", "LA121", "LA122", "LA123", "LA124", "LA125", "LA126", "LA127", "LA128", "LA129", "LA130", "LA131", "LA132", "LA133", "LA134", "LA135", "LA136", "LA137", "LA138", "LA139", "LA140", "LA141", "LA142", "LA143", "LA144", "LA145", "LA146", "LA147", "LA148", "LA149", "LA150", "LA151", "LA152", "LA153", "LA154", "LA155", "CE", "CE119", "CE120", "CE121", "CE122", "CE123", "CE124", "CE125", "CE126", "CE127", "CE128", "CE129", "CE130", "CE131", "CE132", "CE133", "CE134", "CE135", "CE136", "CE137", "CE138", "CE139", "CE140", "CE141", "CE142", "CE143", "CE144", "CE145", "CE146", "CE147", "CE148", "CE149", "CE150", "CE151", "CE152", "CE153", "CE154", "CE155", "CE156", "CE157", "PR", "PR121", "PR122", "PR123", "PR124", "PR125", "PR126", "PR127", "PR128", "PR129", "PR130", "PR131", "PR132", "PR133", "PR134", "PR135", "PR136", "PR137", "PR138", "PR139", "PR140", "PR141", "PR142", "PR143", "PR144", "PR145", "PR146", "PR147", "PR148", "PR149", "PR150", "PR151", "PR152", "PR153", "PR154", "PR155", "PR156", "PR157", "PR158", "PR159", "ND", "ND124", "ND125", "ND126", "ND127", "ND128", "ND129", "ND130", "ND131", "ND132", "ND133", "ND134", "ND135", "ND136", "ND137", "ND138", "ND139", "ND140", "ND141", "ND142", "ND143", "ND144", "ND145", "ND146", "ND147", "ND148", "ND149", "ND150", "ND151", "ND152", "ND153", "ND154", "ND155", "ND156", "ND157", "ND158", "ND159", "ND160", "ND161", "PM", "PM126", "PM127", "PM128", "PM129", "PM130", "PM131", "PM132", "PM133", "PM134", "PM135", "PM136", "PM137", "PM138", "PM139", "PM140", "PM141", "PM142", "PM143", "PM144", "PM145", "PM146", "PM147", "PM148", "PM149", "PM150", "PM151", "PM152", "PM153", "PM154", "PM155", "PM156", "PM157", "PM158", "PM159", "PM160", "PM161", "PM162", "PM163", "SM", "SM128", "SM129", "SM130", "SM131", "SM132", "SM133", "SM134", "SM135", "SM136", "SM137", "SM138", "SM139", "SM140", "SM141", "SM142", "SM143", "SM144", "SM145", "SM146", "SM147", "SM148", "SM149", "SM150", "SM151", "SM152", "SM153", "SM154", "SM155", "SM156", "SM157", "SM158", "SM159", "SM160", "SM161", "SM162", "SM163", "SM164", "SM165", "EU", "EU130", "EU131", "EU132", "EU133", "EU134", "EU135", "EU136", "EU137", "EU138", "EU139", "EU140", "EU141", "EU142", "EU143", "EU144", "EU145", "EU146", "EU147", "EU148", "EU149", "EU150", "EU151", "EU152", "EU153", "EU154", "EU155", "EU156", "EU157", "EU158", "EU159", "EU160", "EU161", "EU162", "EU163", "EU164", "EU165", "EU166", "EU167", "GD", "GD134", "GD135", "GD136", "GD137", "GD138", "GD139", "GD140", "GD141", "GD142", "GD143", "GD144", "GD145", "GD146", "GD147", "GD148", "GD149", "GD150", "GD151", "GD152", "GD153", "GD154", "GD155", "GD156", "GD157", "GD158", "GD159", "GD160", "GD161", "GD162", "GD163", "GD164", "GD165", "GD166", "GD167", "GD168", "GD169", "TB", "TB136", "TB137", "TB138", "TB139", "TB140", "TB141", "TB142", "TB143", "TB144", "TB145", "TB146", "TB147", "TB148", "TB149", "TB150", "TB151", "TB152", "TB153", "TB154", "TB155", "TB156", "TB157", "TB158", "TB159", "TB160", "TB161", "TB162", "TB163", "TB164", "TB165", "TB166", "TB167", "TB168", "TB169", "TB170", "TB171", "DY", "DY138", "DY139", "DY140", "DY141", "DY142", "DY143", "DY144", "DY145", "DY146", "DY147", "DY148", "DY149", "DY150", "DY151", "DY152", "DY153", "DY154", "DY155", "DY156", "DY157", "DY158", "DY159", "DY160", "DY161", "DY162", "DY163", "DY164", "DY165", "DY166", "DY167", "DY168", "DY169", "DY170", "DY171", "DY172", "DY173", "HO", "HO140", "HO141", "HO142", "HO143", "HO144", "HO145", "HO146", "HO147", "HO148", "HO149", "HO150", "HO151", "HO152", "HO153", "HO154", "HO155", "HO156", "HO157", "HO158", "HO159", "HO160", "HO161", "HO162", "HO163", "HO164", "HO165", "HO166", "HO167", "HO168", "HO169", "HO170", "HO171", "HO172", "HO173", "HO174", "HO175", "ER", "ER143", "ER144", "ER145", "ER146", "ER147", "ER148", "ER149", "ER150", "ER151", "ER152", "ER153", "ER154", "ER155", "ER156", "ER157", "ER158", "ER159", "ER160", "ER161", "ER162", "ER163", "ER164", "ER165", "ER166", "ER167", "ER168", "ER169", "ER170", "ER171", "ER172", "ER173", "ER174", "ER175", "ER176", "ER177", "TM", "TM145", "TM146", "TM147", "TM148", "TM149", "TM150", "TM151", "TM152", "TM153", "TM154", "TM155", "TM156", "TM157", "TM158", "TM159", "TM160", "TM161", "TM162", "TM163", "TM164", "TM165", "TM166", "TM167", "TM168", "TM169", "TM170", "TM171", "TM172", "TM173", "TM174", "TM175", "TM176", "TM177", "TM178", "TM179", "YB", "YB148", "YB149", "YB150", "YB151", "YB152", "YB153", "YB154", "YB155", "YB156", "YB157", "YB158", "YB159", "YB160", "YB161", "YB162", "YB163", "YB164", "YB165", "YB166", "YB167", "YB168", "YB169", "YB170", "YB171", "YB172", "YB173", "YB174", "YB175", "YB176", "YB177", "YB178", "YB179", "YB180", "YB181", "LU", "LU150", "LU151", "LU152", "LU153", "LU154", "LU155", "LU156", "LU157", "LU158", "LU159", "LU160", "LU161", "LU162", "LU163", "LU164", "LU165", "LU166", "LU167", "LU168", "LU169", "LU170", "LU171", "LU172", "LU173", "LU174", "LU175", "LU176", "LU177", "LU178", "LU179", "LU180", "LU181", "LU182", "LU183", "LU184", "HF", "HF153", "HF154", "HF155", "HF156", "HF157", "HF158", "HF159", "HF160", "HF161", "HF162", "HF163", "HF164", "HF165", "HF166", "HF167", "HF168", "HF169", "HF170", "HF171", "HF172", "HF173", "HF174", "HF175", "HF176", "HF177", "HF178", "HF179", "HF180", "HF181", "HF182", "HF183", "HF184", "HF185", "HF186", "HF187", "HF188", "TA", "TA155", "TA156", "TA157", "TA158", "TA159", "TA160", "TA161", "TA162", "TA163", "TA164", "TA165", "TA166", "TA167", "TA168", "TA169", "TA170", "TA171", "TA172", "TA173", "TA174", "TA175", "TA176", "TA177", "TA178", "TA179", "TA180", "TA181", "TA182", "TA183", "TA184", "TA185", "TA186", "TA187", "TA188", "TA189", "TA190", "W", "W158", "W159", "W160", "W161", "W162", "W163", "W164", "W165", "W166", "W167", "W168", "W169", "W170", "W171", "W172", "W173", "W174", "W175", "W176", "W177", "W178", "W179", "W180", "W181", "W182", "W183", "W184", "W185", "W186", "W187", "W188", "W189", "W190", "W191", "W192", "RE", "RE160", "RE161", "RE162", "RE163", "RE164", "RE165", "RE166", "RE167", "RE168", "RE169", "RE170", "RE171", "RE172", "RE173", "RE174", "RE175", "RE176", "RE177", "RE178", "RE179", "RE180", "RE181", "RE182", "RE183", "RE184", "RE185", "RE186", "RE187", "RE188", "RE189", "RE190", "RE191", "RE192", "RE193", "RE194", "OS", "OS162", "OS163", "OS164", "OS165", "OS166", "OS167", "OS168", "OS169", "OS170", "OS171", "OS172", "OS173", "OS174", "OS175", "OS176", "OS177", "OS178", "OS179", "OS180", "OS181", "OS182", "OS183", "OS184", "OS185", "OS186", "OS187", "OS188", "OS189", "OS190", "OS191", "OS192", "OS193", "OS194", "OS195", "OS196", "IR", "IR164", "IR165", "IR166", "IR167", "IR168", "IR169", "IR170", "IR171", "IR172", "IR173", "IR174", "IR175", "IR176", "IR177", "IR178", "IR179", "IR180", "IR181", "IR182", "IR183", "IR184", "IR185", "IR186", "IR187", "IR188", "IR189", "IR190", "IR191", "IR192", "IR193", "IR194", "IR195", "IR196", "IR197", "IR198", "IR199", "PT", "PT166", "PT167", "PT168", "PT169", "PT170", "PT171", "PT172", "PT173", "PT174", "PT175", "PT176", "PT177", "PT178", "PT179", "PT180", "PT181", "PT182", "PT183", "PT184", "PT185", "PT186", "PT187", "PT188", "PT189", "PT190", "PT191", "PT192", "PT193", "PT194", "PT195", "PT196", "PT197", "PT198", "PT199", "PT200", "PT201", "PT202", "AU", "AU169", "AU170", "AU171", "AU172", "AU173", "AU174", "AU175", "AU176", "AU177", "AU178", "AU179", "AU180", "AU181", "AU182", "AU183", "AU184", "AU185", "AU186", "AU187", "AU188", "AU189", "AU190", "AU191", "AU192", "AU193", "AU194", "AU195", "AU196", "AU197", "AU198", "AU199", "AU200", "AU201", "AU202", "AU203", "AU204", "AU205", "HG", "HG171", "HG172", "HG173", "HG174", "HG175", "HG176", "HG177", "HG178", "HG179", "HG180", "HG181", "HG182", "HG183", "HG184", "HG185", "HG186", "HG187", "HG188", "HG189", "HG190", "HG191", "HG192", "HG193", "HG194", "HG195", "HG196", "HG197", "HG198", "HG199", "HG200", "HG201", "HG202", "HG203", "HG204", "HG205", "HG206", "HG207", "HG208", "HG209", "HG210", "TL", "TL176", "TL177", "TL178", "TL179", "TL180", "TL181", "TL182", "TL183", "TL184", "TL185", "TL186", "TL187", "TL188", "TL189", "TL190", "TL191", "TL192", "TL193", "TL194", "TL195", "TL196", "TL197", "TL198", "TL199", "TL200", "TL201", "TL202", "TL203", "TL204", "TL205", "TL206", "TL207", "TL208", "TL209", "TL210", "TL211", "TL212", "PB", "PB178", "PB179", "PB180", "PB181", "PB182", "PB183", "PB184", "PB185", "PB186", "PB187", "PB188", "PB189", "PB190", "PB191", "PB192", "PB193", "PB194", "PB195", "PB196", "PB197", "PB198", "PB199", "PB200", "PB201", "PB202", "PB203", "PB204", "PB205", "PB206", "PB207", "PB208", "PB209", "PB210", "PB211", "PB212", "PB213", "PB214", "PB215", "BI", "BI184", "BI185", "BI186", "BI187", "BI188", "BI189", "BI190", "BI191", "BI192", "BI193", "BI194", "BI195", "BI196", "BI197", "BI198", "BI199", "BI200", "BI201", "BI202", "BI203", "BI204", "BI205", "BI206", "BI207", "BI208", "BI209", "BI210", "BI211", "BI212", "BI213", "BI214", "BI215", "BI216", "BI217", "BI218", "PO", "PO188", "PO189", "PO190", "PO191", "PO192", "PO193", "PO194", "PO195", "PO196", "PO197", "PO198", "PO199", "PO200", "PO201", "PO202", "PO203", "PO204", "PO205", "PO206", "PO207", "PO208", "PO209", "PO210", "PO211", "PO212", "PO213", "PO214", "PO215", "PO216", "PO217", "PO218", "PO219", "PO220", "AT", "AT193", "AT194", "AT195", "AT196", "AT197", "AT198", "AT199", "AT200", "AT201", "AT202", "AT203", "AT204", "AT205", "AT206", "AT207", "AT208", "AT209", "AT210", "AT211", "AT212", "AT213", "AT214", "AT215", "AT216", "AT217", "AT218", "AT219", "AT220", "AT221", "AT222", "AT223", "RN", "RN195", "RN196", "RN197", "RN198", "RN199", "RN200", "RN201", "RN202", "RN203", "RN204", "RN205", "RN206", "RN207", "RN208", "RN209", "RN210", "RN211", "RN212", "RN213", "RN214", "RN215", "RN216", "RN217", "RN218", "RN219", "RN220", "RN221", "RN222", "RN223", "RN224", "RN225", "RN226", "RN227", "RN228", "FR", "FR199", "FR200", "FR201", "FR202", "FR203", "FR204", "FR205", "FR206", "FR207", "FR208", "FR209", "FR210", "FR211", "FR212", "FR213", "FR214", "FR215", "FR216", "FR217", "FR218", "FR219", "FR220", "FR221", "FR222", "FR223", "FR224", "FR225", "FR226", "FR227", "FR228", "FR229", "FR230", "FR231", "FR232", "RA", "RA202", "RA203", "RA204", "RA205", "RA206", "RA207", "RA208", "RA209", "RA210", "RA211", "RA212", "RA213", "RA214", "RA215", "RA216", "RA217", "RA218", "RA219", "RA220", "RA221", "RA222", "RA223", "RA224", "RA225", "RA226", "RA227", "RA228", "RA229", "RA230", "RA231", "RA232", "RA233", "RA234", "AC", "AC206", "AC207", "AC208", "AC209", "AC210", "AC211", "AC212", "AC213", "AC214", "AC215", "AC216", "AC217", "AC218", "AC219", "AC220", "AC221", "AC222", "AC223", "AC224", "AC225", "AC226", "AC227", "AC228", "AC229", "AC230", "AC231", "AC232", "AC233", "AC234", "AC235", "AC236", "TH", "TH209", "TH210", "TH211", "TH212", "TH213", "TH214", "TH215", "TH216", "TH217", "TH218", "TH219", "TH220", "TH221", "TH222", "TH223", "TH224", "TH225", "TH226", "TH227", "TH228", "TH229", "TH230", "TH231", "TH232", "TH233", "TH234", "TH235", "TH236", "TH237", "TH238", "PA", "PA212", "PA213", "PA214", "PA215", "PA216", "PA217", "PA218", "PA219", "PA220", "PA221", "PA222", "PA223", "PA224", "PA225", "PA226", "PA227", "PA228", "PA229", "PA230", "PA231", "PA232", "PA233", "PA234", "PA235", "PA236", "PA237", "PA238", "PA239", "PA240", "U", "U217", "U218", "U219", "U220", "U221", "U222", "U223", "U224", "U225", "U226", "U227", "U228", "U229", "U230", "U231", "U232", "U233", "U234", "U235", "U236", "U237", "U238", "U239", "U240", "U241", "U242", "NP", "NP225", "NP226", "NP227", "NP228", "NP229", "NP230", "NP231", "NP232", "NP233", "NP234", "NP235", "NP236", "NP237", "NP238", "NP239", "NP240", "NP241", "NP242", "NP243", "NP244", "PU", "PU228", "PU229", "PU230", "PU231", "PU232", "PU233", "PU234", "PU235", "PU236", "PU237", "PU238", "PU239", "PU240", "PU241", "PU242", "PU243", "PU244", "PU245", "PU246", "PU247", "AM", "AM231", "AM232", "AM233", "AM234", "AM235", "AM236", "AM237", "AM238", "AM239", "AM240", "AM241", "AM242", "AM243", "AM244", "AM245", "AM246", "AM247", "AM248", "AM249", "CM", "CM233", "CM234", "CM235", "CM236", "CM237", "CM238", "CM239", "CM240", "CM241", "CM242", "CM243", "CM244", "CM245", "CM246", "CM247", "CM248", "CM249", "CM250", "CM251", "CM252", "BK", "BK235", "BK236", "BK237", "BK238", "BK239", "BK240", "BK241", "BK242", "BK243", "BK244", "BK245", "BK246", "BK247", "BK248", "BK249", "BK250", "BK251", "BK252", "BK253", "BK254", "CF", "CF237", "CF238", "CF239", "CF240", "CF241", "CF242", "CF243", "CF244", "CF245", "CF246", "CF247", "CF248", "CF249", "CF250", "CF251", "CF252", "CF253", "CF254", "CF255", "CF256", "ES", "ES240", "ES241", "ES242", "ES243", "ES244", "ES245", "ES246", "ES247", "ES248", "ES249", "ES250", "ES251", "ES252", "ES253", "ES254", "ES255", "ES256", "ES257", "ES258", "FM", "FM242", "FM243", "FM244", "FM245", "FM246", "FM247", "FM248", "FM249", "FM250", "FM251", "FM252", "FM253", "FM254", "FM255", "FM256", "FM257", "FM258", "FM259", "FM260", "MD", "MD245", "MD246", "MD247", "MD248", "MD249", "MD250", "MD251", "MD252", "MD253", "MD254", "MD255", "MD256", "MD257", "MD258", "MD259", "MD260", "MD261", "MD262", "NO", "NO248", "NO249", "NO250", "NO251", "NO252", "NO253", "NO254", "NO255", "NO256", "NO257", "NO258", "NO259", "NO260", "NO261", "NO262", "NO263", "NO264", "LR", "LR251", "LR252", "LR253", "LR254", "LR255", "LR256", "LR257", "LR258", "LR259", "LR260", "LR261", "LR262", "LR263", "LR264", "LR265", "LR266", "RF", "RF253", "RF254", "RF255", "RF256", "RF257", "RF258", "RF259", "RF260", "RF261", "RF262", "RF263", "RF264", "RF265", "RF266", "RF267", "RF268", "DB", "DB255", "DB256", "DB257", "DB258", "DB259", "DB260", "DB261", "DB262", "DB263", "DB264", "DB265", "DB266", "DB267", "DB268", "DB269", "DB270", "SG", "SG258", "SG259", "SG260", "SG261", "SG262", "SG263", "SG264", "SG265", "SG266", "SG267", "SG268", "SG269", "SG270", "SG271", "SG272", "SG273", "BH", "BH260", "BH261", "BH262", "BH263", "BH264", "BH265", "BH266", "BH267", "BH268", "BH269", "BH270", "BH271", "BH272", "BH273", "BH274", "BH275", "HS", "HS263", "HS264", "HS265", "HS266", "HS267", "HS268", "HS269", "HS270", "HS271", "HS272", "HS273", "HS274", "HS275", "HS276", "HS277", "MT", "MT265", "MT266", "MT267", "MT268", "MT269", "MT270", "MT271", "MT272", "MT273", "MT274", "MT275", "MT276", "MT277", "MT278", "MT279", "DS", "DS267", "DS268", "DS269", "DS270", "DS271", "DS272", "DS273", "DS274", "DS275", "DS276", "DS277", "DS278", "DS279", "DS280", "DS281", "RG", "RG272", "RG273", "RG274", "RG275", "RG276", "RG277", "RG278", "RG279", "RG280", "RG281", "RG282", "RG283", "UUB", "UUB277", "UUB278", "UUB279", "UUB280", "UUB281", "UUB282", "UUB283", "UUB284", "UUB285", "UUT", "UUT283", "UUT284", "UUT285", "UUT286", "UUT287", "UUQ", "UUQ285", "UUQ286", "UUQ287", "UUQ288", "UUQ289", "UUP", "UUP287", "UUP288", "UUP289", "UUP290", "UUP291", "UUH", "UUH289", "UUH290", "UUH291", "UUH292", "UUS", "UUS291", "UUS292", "UUO", "UUO293"] _temp_iso_mass = [ 1.00782503207, 1.00782503207, 2.01410177785, 2.01410177785, 3.01604927767, 3.01604927767, 4.027806424, 5.035311488, 6.044942594, 7.052749, 4.00260325415, 3.01602931914, 4.00260325415, 5.012223624, 6.018889124, 7.028020618, 8.033921897, 9.043950286, 10.052398837, 7.016004548, 3.030775, 4.027185558, 5.0125378, 6.015122794, 7.016004548, 8.022487362, 9.026789505, 10.035481259, 11.043797715, 12.053780, 9.012182201, 5.040790, 6.019726317, 7.016929828, 8.005305103, 9.012182201, 10.013533818, 11.021657749, 12.026920737, 13.035693007, 14.04289292, 15.053460, 16.061920, 11.009305406, 6.046810, 7.029917901, 8.024607233, 9.013328782, 10.012936992, 11.009305406, 12.014352104, 13.017780217, 14.025404009, 15.031103021, 16.039808829, 17.046989906, 18.056170, 19.063730, 12, 8.037675025, 9.031036689, 10.016853228, 11.011433613, 12, 13.00335483778, 14.0032419887, 15.010599256, 16.014701252, 17.022586116, 18.026759354, 19.034805018, 20.040319754, 21.049340, 22.057200, 14.00307400478, 10.041653674, 11.026090956, 12.018613197, 13.005738609, 14.00307400478, 15.00010889823, 16.006101658, 17.008450261, 18.014078959, 19.017028697, 20.023365807, 21.02710824, 22.034394934, 23.041220, 24.051040, 25.060660, 15.99491461956, 12.034404895, 13.024812213, 14.00859625, 15.003065617, 15.99491461956, 16.999131703, 17.999161001, 19.00358013, 20.004076742, 21.008655886, 22.009966947, 23.015687659, 24.020472917, 25.029460, 26.038340, 27.048260, 28.057810, 18.998403224, 14.035060, 15.018009103, 16.011465724, 17.002095237, 18.000937956, 18.998403224, 19.999981315, 20.999948951, 22.002998815, 23.003574631, 24.008115485, 25.012101747, 26.019615555, 27.026760086, 28.035670, 29.043260, 30.052500, 31.060429, 19.99244017542, 16.025761262, 17.017671504, 18.005708213, 19.001880248, 19.99244017542, 20.993846684, 21.991385113, 22.994466904, 23.993610779, 24.997736888, 26.000461206, 27.007589903, 28.012071575, 29.019385933, 30.024801045, 31.033110, 32.040020, 33.049380, 34.057028, 22.98976928087, 18.025969, 19.013877499, 20.007351328, 20.997655206, 21.994436425, 22.98976928087, 23.990962782, 24.989953968, 25.992633, 26.994076788, 27.998938, 29.002861, 30.008976, 31.013585452, 32.02046656, 33.026719756, 34.035170, 35.042493, 36.051480, 37.059340, 23.985041699, 19.03547, 20.018862545, 21.01171291, 21.999573843, 22.994123669, 23.985041699, 24.985836917, 25.982592929, 26.984340585, 27.983876825, 28.9886, 29.990434, 30.996546, 31.998975, 33.005254, 34.009456424, 35.017340, 36.023000, 37.031400, 38.037570, 39.046772, 40.053930, 26.981538627, 21.028040, 22.019520, 23.007267432, 23.999938865, 24.990428095, 25.986891692, 26.981538627, 27.981910306, 28.980445046, 29.982960256, 30.983946619, 31.988124489, 32.990843336, 33.996851837, 34.999860235, 36.006207204, 37.01067782, 38.017231021, 39.02297, 40.031450, 41.038330, 42.046890, 27.97692653246, 22.034530, 23.025520, 24.011545616, 25.004105574, 25.992329921, 26.986704905, 27.97692653246, 28.9764947, 29.973770171, 30.975363226999998, 31.974148082, 32.97800022, 33.978575524, 34.984583575, 35.986599477, 36.99293608, 37.995633601, 39.002070013, 40.005869121, 41.01456, 42.019790, 43.028660, 44.035260, 30.973761629, 24.034350, 25.020260, 26.011780, 26.999230236, 27.992314761, 28.981800606, 29.978313789, 30.973761629, 31.973907274, 32.971725543, 33.973636257, 34.973314117, 35.97825968, 36.979608946, 37.984156827, 38.986179475, 39.991296951, 40.994335435, 42.001007913, 43.00619, 44.012990, 45.019220, 46.027380, 31.972070999, 26.027880, 27.018833, 28.004372763, 28.996608049, 29.984903249, 30.979554728, 31.972070999, 32.971458759, 33.967866902, 34.969032161, 35.96708076, 36.971125567, 37.971163317, 38.975134306, 39.975451728, 40.979582149, 41.981022419, 42.98715479, 43.99021339, 44.996508112, 46.000750, 47.008590, 48.014170, 49.023619, 34.968852682, 28.028510, 29.014110, 30.004770, 30.992413086, 31.985689901, 32.977451887, 33.973762819, 34.968852682, 35.968306981, 36.965902591, 37.968010425, 38.968008164, 39.970415472, 40.970684525, 41.973254804, 42.974054403, 43.978281071, 44.980286886, 45.98421004, 46.988710, 47.994950, 49.000320, 50.007840, 51.014490, 39.96238312251, 30.021560, 31.012123, 31.997637984, 32.989925709, 33.980271244, 34.975257585, 35.967545105, 36.96677632, 37.962732394, 38.964313231, 39.96238312251, 40.964500611, 41.963045736, 42.965636056, 43.964924033, 44.968039956, 45.968094129, 46.972186792, 47.974540, 48.980520, 49.984430, 50.991630, 51.996780, 53.004940, 38.963706679, 32.021920, 33.007260, 33.998410, 34.988009692, 35.981292235, 36.973375889, 37.969081184, 38.963706679, 39.963998475, 40.961825762, 41.96240281, 42.96071554, 43.961556804, 44.960699493, 45.961976864, 46.961678473, 47.965513535, 48.967450928, 49.972783355, 50.976380, 51.982610, 52.987120, 53.994200, 54.999710, 39.962590983, 34.014120, 35.004940, 35.993087063, 36.985870269, 37.976318452, 38.970719725, 39.962590983, 40.962278062, 41.958618014, 42.958766628, 43.955481754, 44.956186566, 45.953692587, 46.954546006, 47.952534177, 48.955674148, 49.957518962, 50.961499214, 51.9651, 52.970050, 53.974350, 54.980550, 55.985570, 56.992356, 44.955911909, 36.014920, 37.003050, 37.994700, 38.984790002, 39.977967407, 40.969251125, 41.965516429, 42.961150658, 43.959402752, 44.955911909, 45.95517189, 46.952407508, 47.952231468, 48.950023975, 49.952187685, 50.953603368, 51.956675468, 52.959610, 53.963264561, 54.968243949, 55.972870, 56.977790, 57.983710, 58.989220, 59.995710, 47.947946281, 38.009770, 39.001610, 39.990498838, 40.983145, 41.973030902, 42.968522499, 43.959690069, 44.958125616, 45.952631555, 46.951763088, 47.947946281, 48.947869982, 49.944791194, 50.946614955, 51.946897311, 52.949727171, 53.951052401, 54.955265056, 55.958199639, 56.963989137, 57.966970, 58.972930, 59.976760, 60.983200, 61.987490, 62.994420, 50.943959507, 40.011090, 40.999780, 41.991230, 42.980650, 43.97411, 44.965775808, 45.960200481, 46.95490894, 47.952253707, 48.948516101, 49.947158485, 50.943959507, 51.944775479, 52.944337979, 53.946439854, 54.947233701, 55.950530966, 56.952561432, 57.956834136, 58.960207407, 59.965026862, 60.968480, 61.973780, 62.977550, 63.983470, 64.987920, 51.940507472, 42.006430, 42.997710, 43.985549, 44.97964, 45.968358635, 46.962900046, 47.954031716, 48.951335721, 49.946044205, 50.944767431, 51.940507472, 52.940649386, 53.938880395, 54.940839672, 55.940653139, 56.943613013, 57.944353129, 58.948586367, 59.950076033, 60.954717204, 61.95661319, 62.961860, 63.964410, 64.970160, 65.973380, 66.979550, 54.938045141, 44.006870, 44.994510, 45.986720, 46.976100, 47.96852, 48.959618005, 49.95423823, 50.948210787, 51.945565464, 52.941290117, 53.940358854, 54.938045141, 55.93890491, 56.938285378, 57.939981549, 58.940440237, 59.942911246, 60.944652638, 61.94842822, 62.95023999, 63.95424909, 64.956336065, 65.961080, 66.964140, 67.969300, 68.972840, 55.934937475, 45.014578, 46.000810, 46.992890, 47.980504, 48.973610, 49.962988982, 50.956819538, 51.948113875, 52.945307942, 53.939610501, 54.938293357, 55.934937475, 56.935393969, 57.933275558, 58.934875464, 59.934071683, 60.936745281, 61.936767442, 62.940369091, 63.941201265, 64.94538027, 65.946780638, 66.950947244, 67.9537, 68.958780, 69.961460, 70.966720, 71.969620, 58.933195048, 47.011490, 48.001760, 48.989720, 49.981540, 50.970720, 51.963590, 52.954218896, 53.948459635, 54.941999029, 55.939839278, 56.936291373, 57.935752814, 58.933195048, 59.933817059, 60.932475763, 61.934050563, 62.933611611, 63.935809908, 64.93647846, 65.939762004, 66.940889529, 67.944873058, 68.94632, 69.951, 70.9529, 71.957810, 72.960240, 73.965380, 74.968330, 57.935342907, 48.019750, 49.009660, 49.995930, 50.987720, 51.975680, 52.968470, 53.957905495, 54.951330251, 55.942132022, 56.939793526, 57.935342907, 58.934346705, 59.930786372, 60.931056033, 61.928345115, 62.929669374, 63.927965959, 64.930084304, 65.929139334, 66.931569414, 67.931868789, 68.935610269, 69.9365, 70.940736283, 71.942092682, 72.946470, 73.948070, 74.952870, 75.955330, 76.960550, 77.963180, 62.929597474, 51.997180, 52.985550, 53.976710, 54.966050, 55.958560, 56.949211078, 57.944538499, 58.939498028, 59.93736503, 60.933457821, 61.932583745, 62.929597474, 63.929764183, 64.927789485, 65.928868813, 66.927730314, 67.929610889, 68.929429269, 69.932392343, 70.932676833, 71.935820307, 72.936675282, 73.939874862, 74.9419, 75.945275026, 76.947850, 77.951960, 78.954560, 79.960870, 63.929142222, 53.992950, 54.983980, 55.972380, 56.964788, 57.954591555, 58.949263764, 59.941827035, 60.939510635, 61.934329764, 62.933211566, 63.929142222, 64.929240984, 65.926033419, 66.927127345, 67.924844154, 68.926550281, 69.925319274, 70.927721599, 71.926857951, 72.929779104, 73.929458609, 74.932936741, 75.93329357, 76.936958967, 77.938440216, 78.942652, 79.944342348, 80.950480, 81.954420, 82.961030, 68.925573587, 55.994910, 56.982930, 57.974250, 58.963370, 59.957060, 60.949446287, 61.944175238, 62.939294196, 63.936838747, 64.932734754, 65.93158901, 66.928201703, 67.927980084, 68.925573587, 69.926021972, 70.924701349, 71.926366268, 72.925174682, 73.926945762, 74.926500246, 75.928827626, 76.9291543, 77.93160818, 78.93289326, 79.936515781, 80.937752355, 81.942990, 82.946980, 83.952650, 84.957000, 85.963120, 73.921177767, 57.991010, 58.981750, 59.970190, 60.963790, 61.954650, 62.949640, 63.941653, 64.939436406, 65.933843453, 66.93273407, 67.92809424, 68.927964533, 69.924247381, 70.924950954, 71.922075815, 72.923458945, 73.921177767, 74.922858948, 75.921402557, 76.923548591, 77.922852739, 78.925400995, 79.925372392, 80.928820467, 81.929549725, 82.934620, 83.937470, 84.943030, 85.946490, 86.952510, 87.956910, 88.963830, 74.921596478, 59.993130, 60.980620, 61.973200, 62.963690, 63.957572, 64.949564, 65.94471, 66.939186071, 67.936769069, 68.932273675, 69.930924826, 70.927112428, 71.926752283, 72.923824844, 73.923928692, 74.921596478, 75.922394021, 76.920647286, 77.921827281, 78.920947934, 79.922533816, 80.922132287, 81.924504067, 82.924980024, 83.929058, 84.932020, 85.936500, 86.939900, 87.944940, 88.949390, 89.955500, 90.960430, 91.966800, 79.916521271, 64.964660, 65.955210, 66.950090, 67.941798, 68.939557817, 69.933390644, 70.932241822, 71.927112352, 72.926765345, 73.922476436, 74.922523368, 75.919213597, 76.919914038, 77.91730909, 78.918499098, 79.916521271, 80.917992474, 81.916699401, 82.919118473, 83.918462354, 84.922245053, 85.924271579, 86.928521358, 87.931423998, 88.936450, 89.939960, 90.945960, 91.949920, 92.956290, 93.960490, 78.918337087, 66.964790, 67.958516, 68.950106, 69.944792, 70.93874, 71.936644572, 72.931691524, 73.929891034, 74.925776207, 75.924541469, 76.921379082, 77.921145706, 78.918337087, 79.918529296, 80.916290563, 81.916804119, 82.915180421, 83.916478974, 84.915608403, 85.918797577, 86.920711324, 87.924065926, 88.926385334, 89.930627737, 90.933968095, 91.939258714, 92.943050, 93.948680, 94.952870, 95.958530, 96.962800, 85.910610729, 68.965180, 69.955259, 70.949625738, 71.942092038, 72.939289195, 73.933084369, 74.930945746, 75.925910078, 76.92467, 77.920364783, 78.920082431, 79.916378965, 80.916592015, 81.9134836, 82.914136099, 83.911506687, 84.912527331, 85.910610729, 86.913354862, 87.914446969, 88.917630581, 89.919516555, 90.923445215, 91.92615621, 92.931274357, 93.934360, 94.939840, 95.943070, 96.948560, 97.951910, 98.957600, 99.961140, 84.911789737, 70.965320, 71.959080, 72.950561, 73.944264751, 74.93857, 75.935072226, 76.930408, 77.928141, 78.92398946, 79.92251925, 80.918995913, 81.918208598, 82.915109701, 83.914384821, 84.911789737, 85.911167419, 86.909180526, 87.911315588, 88.912278016, 89.914801694, 90.916536958, 91.9197289, 92.922041876, 93.926404946, 94.929302889, 95.934272637, 96.937351916, 97.941790668, 98.945379283, 99.949870, 100.953196445, 101.958870, 87.905612124, 72.965970, 73.956310, 74.949949568, 75.941766782, 76.937944782, 77.93218, 78.929708, 79.924521013, 80.923211846, 81.918401639, 82.917556701, 83.913425275, 84.912932803, 85.909260204, 86.908877124, 87.905612124, 88.907450675, 89.907737888, 90.910203095, 91.911037858, 92.914025634, 93.915361312, 94.919358766, 95.921696802, 96.926152923, 97.928452934, 98.933240926, 99.935351911, 100.940517888, 101.943018987, 102.948950, 103.952330, 104.958580, 88.905848295, 75.958450, 76.949645, 77.943610, 78.937351634, 79.93428, 80.929127468, 81.926792451, 82.922354243, 83.920388264, 84.916433039, 85.914885576, 86.91087573, 87.909501146, 88.905848295, 89.907151886, 90.907304791, 91.908949143, 92.909582713, 93.911595245, 94.912820621, 95.915891343, 96.918133995, 97.92220302, 98.924636204, 99.927756586, 100.93031385, 101.933555695, 102.936730, 103.941050, 104.944870, 105.949790, 106.954140, 107.959480, 89.904704416, 77.955230, 78.949160, 79.9404, 80.937210026, 81.931087, 82.928653801, 83.923250, 84.921471182, 85.916473591, 86.914816252, 87.910226904, 88.9088895, 89.904704416, 90.905645767, 91.905040847, 92.906476006, 93.906315192, 94.9080426, 95.908273386, 96.910953109, 97.912734892, 98.916512106, 99.917761889, 100.921140415, 101.922981285, 102.926599606, 103.928780, 104.933050, 105.935910, 106.940750, 107.943960, 108.949240, 109.952870, 92.906378058, 80.949030, 81.943130, 82.936705382, 83.933570, 84.927912447, 85.925038326, 86.920361108, 87.918332163, 88.913418245, 89.911264845, 90.906996243, 91.907193888, 92.906378058, 93.907283888, 94.906835792, 95.908100647, 96.908098556, 97.910328412, 98.911618375, 99.914181619, 100.915252025, 101.918037614, 102.919143842, 103.922464701, 104.923936545, 105.927970, 106.930310, 107.934840, 108.937630, 109.942440, 110.945650, 111.950830, 112.954700, 97.905408169, 82.948740, 83.940090, 84.936550, 85.930695904, 86.927326502, 87.921953241, 88.919480009, 89.913936896, 90.911750194, 91.906810991, 92.90681261, 93.905088269, 94.905842129, 95.904679477, 96.906021465, 97.905408169, 98.90771187, 99.907477336, 100.910347001, 101.91029736, 102.913207142, 103.913763625, 104.91697461, 105.918136802, 106.921692604, 107.923453, 108.927810, 109.929730, 110.934410, 111.936840, 112.941880, 113.944920, 114.950290, 98.906254747, 84.948830, 85.942880, 86.936530, 87.932678, 88.927167, 89.923556564, 90.918427639, 91.915260166, 92.910248984, 93.909657002, 94.907657084, 95.907871383, 96.906365358, 97.907215966, 98.906254747, 99.90765778, 100.907314659, 101.909215019, 102.909181351, 103.911447454, 104.911660566, 105.914357927, 106.915079572, 107.918461226, 108.919982665, 109.923820483, 110.92569283, 111.929146493, 112.931590, 113.935880, 114.938690, 115.943370, 116.946480, 117.951480, 101.904349312, 86.949180, 87.940260, 88.936110, 89.929890, 90.926292, 91.920120, 92.917052034, 93.911359711, 94.910412929, 95.907597835, 96.9075547, 97.905287132, 98.905939302, 99.904219476, 100.905582087, 101.904349312, 102.906323847, 103.905432701, 104.907752866, 105.907329433, 106.909905089, 107.910173465, 108.913203233, 109.914136041, 110.917696, 111.918965, 112.922487194, 113.924281, 114.928686173, 115.930810, 116.935580, 117.937820, 118.942840, 119.945310, 102.905504292, 88.948837, 89.942870, 90.936550, 91.931980, 92.925740, 93.921698, 94.91589874, 95.914460631, 96.911336797, 97.910708158, 98.908132104, 99.90812155, 100.906163625, 101.906843196, 102.905504292, 103.906655518, 104.905693821, 105.907287135, 106.906748423, 107.908728018, 108.908737289, 109.911136411, 110.911585913, 111.914394159, 112.915530627, 113.918806, 114.920334, 115.924062, 116.925980, 117.930070, 118.932110, 119.936410, 120.938720, 121.943210, 105.903485715, 90.949110, 91.940420, 92.935910, 93.928770, 94.924690, 95.918164359, 96.916479073, 97.912720902, 98.911767833, 99.908505886, 100.908289242, 101.905608544, 102.906087307, 103.904035834, 104.90508492, 105.903485715, 106.905133481, 107.903891701, 108.905950451, 109.905153254, 110.907670734, 111.907314058, 112.910152908, 113.910362638, 114.913683824, 115.914158662, 116.917841338, 117.9189843, 118.923110, 119.924691878, 120.928870, 121.930550, 122.934930, 123.936880, 106.90509682, 92.949780, 93.942780, 94.935480, 95.930680, 96.923972412, 97.921566201, 98.917597178, 99.916104255, 100.912802233, 101.911685, 102.90897272, 103.908629157, 104.906528661, 105.906668921, 106.90509682, 107.905955556, 108.904752292, 109.906107231, 110.905291157, 111.907004814, 112.906566579, 113.908803704, 114.908762698, 115.911359933, 116.911684562, 117.914582768, 118.915665059, 119.918787384, 120.919848046, 121.923530, 122.924900, 123.928640, 124.930430, 125.934500, 126.936770, 127.941170, 128.943690, 129.950448, 113.90335854, 94.949870, 95.939770, 96.934940, 97.927395546, 98.925010, 99.920289525, 100.918681538, 101.914462258, 102.913419246, 103.909849475, 104.909467905, 105.90645941, 106.906617928, 107.904183683, 108.904982293, 109.90300207, 110.904178107, 111.902757809, 112.904401662, 113.90335854, 114.905430969, 115.904755809, 116.907218618, 117.90691453, 118.909921597, 119.909850129, 120.912977363, 121.913332432, 122.917002999, 123.917647616, 124.92124637, 125.922353321, 126.926443864, 127.927762285, 128.932150, 129.933901937, 130.940670, 131.945550, 114.903878484, 96.949540, 97.942140, 98.934220, 99.931110851, 100.926340, 101.924090238, 102.919914188, 103.918296171, 104.91467354, 105.913465411, 106.9102951, 107.90969818, 108.907150507, 109.907165274, 110.905103278, 111.905532331, 112.904057761, 113.904913876, 114.903878484, 115.905259703, 116.904513564, 117.906354367, 118.90584535, 119.907959608, 120.907845822, 121.91027601, 122.910438276, 123.913175231, 124.913600588, 125.916463857, 126.917353091, 127.920172328, 128.92169698, 129.924970049, 130.926851767, 131.93299026, 132.937810, 133.944150, 134.949330, 119.902194676, 98.949330, 99.939044343, 100.936060, 101.930295324, 102.928100, 103.923143223, 104.921349437, 105.91688062, 106.915644329, 107.911925378, 108.911283214, 109.907842791, 110.90773446, 111.904818207, 112.905170577, 113.902778869, 114.903342397, 115.90174053, 116.902951656, 117.901603167, 118.90330763, 119.902194676, 120.90423548, 121.903439046, 122.905720838, 123.905273946, 124.907784125, 125.90765328, 126.910360024, 127.910536624, 128.913479, 129.913967295, 130.916999769, 131.917815713, 132.923829249, 133.928291765, 134.934730, 135.939340, 136.945990, 120.903815686, 102.939690, 103.936472, 104.931486348, 105.928791, 106.924150, 107.922160, 108.918132426, 109.916753, 110.913163, 111.912398009, 112.909371672, 113.909269, 114.906598, 115.906793629, 116.904835941, 117.905528731, 118.903942009, 119.905072427, 120.903815686, 121.905173651, 122.90421397, 123.905935743, 124.905253818, 125.90724748, 126.906923609, 127.909169001, 128.909148442, 129.911656324, 130.911982275, 131.914466896, 132.91525163, 133.920379744, 134.925165771, 135.930350, 136.935310, 137.940790, 138.945980, 129.906224399, 104.943640, 105.937504237, 106.935006, 107.929444597, 108.927415515, 109.922407316, 110.921110692, 111.917013672, 112.915891, 113.912089, 114.911902, 115.90846, 116.908644719, 117.905827581, 118.906403645, 119.904020222, 120.904936424, 121.903043898, 122.904270029, 123.902817896, 124.904430731, 125.903311696, 126.905226336, 127.904463056, 128.906598238, 129.906224399, 130.908523864, 131.90855316, 132.910955306, 133.911368737, 134.916448592, 135.920101246, 136.925322954, 137.929220, 138.934730, 139.938850, 140.944650, 141.949080, 126.904472681, 107.943475, 108.938149417, 109.935242, 110.930276, 111.927970, 112.923640583, 113.921850, 114.918048, 115.916808633, 116.91365, 117.913074, 118.910074, 119.910048173, 120.907366811, 121.907589284, 122.905588965, 123.906209852, 124.904630164, 125.905624153, 126.904472681, 127.905809443, 128.904987722, 129.906674247, 130.906124609, 131.907997381, 132.907796939, 133.909744465, 134.910048121, 135.914653993, 136.91787084, 137.922349591, 138.926099478, 139.931000, 140.935030, 141.940180, 142.944560, 143.949990, 131.904153457, 109.944278068, 110.941602, 111.935623112, 112.933341174, 113.927980306, 114.92629392, 115.921581087, 116.920358735, 117.916178655, 118.915410688, 119.911784244, 120.911461829, 121.908367632, 122.90848191, 123.905893003, 124.906395464, 125.904273634, 126.905183723, 127.903531275, 128.904779435, 129.903508007, 130.905082362, 131.904153457, 132.905910722, 133.905394464, 134.907227495, 135.907218794, 136.911562125, 137.913954475, 138.918792936, 139.921640943, 140.926648049, 141.92970959, 142.935110, 143.938510, 144.944070, 145.947750, 146.953560, 132.905451932, 111.950301, 112.944493274, 113.941450, 114.935910, 115.933367, 116.928670701, 117.926559494, 118.922377304, 119.920677253, 120.917229209, 121.916113434, 122.912996036, 123.912257798, 124.90972827, 125.909451977, 126.907417525, 127.907748866, 128.906064426, 129.906708552, 130.905463926, 131.90643426, 132.905451932, 133.906718475, 134.905977008, 135.907311576, 136.907089473, 137.911016704, 138.913363999, 139.917282354, 140.920045752, 141.924298927, 142.92735175, 143.932076914, 144.93552617, 145.940289423, 146.944155008, 147.949218153, 148.952930, 149.958170, 150.962190, 137.905247237, 113.950675405, 114.947370, 115.941380, 116.938499, 117.933040, 118.930659661, 119.926044974, 120.924054499, 121.919904, 122.918781036, 123.915093603, 124.914472912, 125.911250177, 126.911093797, 127.908317698, 128.908679439, 129.906320811, 130.906941118, 131.905061288, 132.90600749, 133.904508383, 134.905688591, 135.904575945, 136.905827384, 137.905247237, 138.908841341, 139.910604505, 140.914411009, 141.91645341, 142.920626719, 143.922952853, 144.927627032, 145.930219572, 146.934945, 147.937720047, 148.942580, 149.945680, 150.950810, 151.954270, 152.959610, 138.906353267, 116.950068, 117.946730, 118.940990, 119.938070, 120.933010, 121.930710, 122.926240, 123.924574275, 124.920816034, 125.919512667, 126.916375448, 127.915585177, 128.912692815, 129.912368724, 130.91007, 131.910101145, 132.908218, 133.908514011, 134.906976844, 135.907635536, 136.906493598, 137.90711193, 138.906353267, 139.909477645, 140.910962152, 141.91407913, 142.91606272, 143.919599647, 144.921645401, 145.92579346, 146.928235284, 147.932228868, 148.934734, 149.938770, 150.941720, 151.946250, 152.949620, 153.954500, 154.958350, 139.905438706, 118.952760, 119.946640, 120.943420, 121.937910, 122.935400, 123.930410, 124.928440, 125.923971, 126.922731, 127.918911, 128.918102, 129.914736, 130.914422, 131.911460487, 132.91151502, 133.908924821, 134.909151396, 135.907172422, 136.907805577, 137.905991321, 138.906652651, 139.905438706, 140.90827627, 141.909244205, 142.91238591, 143.913647336, 144.917233135, 145.918759009, 146.922673954, 147.92443241, 148.928399883, 149.930408931, 150.933976196, 151.936540, 152.940580, 153.943420, 154.948040, 155.951260, 156.956340, 140.907652769, 120.955364, 121.951810, 122.945960, 123.942960, 124.937830, 125.935310, 126.930830, 127.928791, 128.925095, 129.92359, 130.920259, 131.919255, 132.916330532, 133.915711737, 134.913111745, 135.912691611, 136.910705455, 137.910754636, 138.908938399, 139.909075874, 140.907652769, 141.910044806, 142.910816926, 143.913305245, 144.9145117, 145.917644336, 146.918995992, 147.922135026, 148.923717651, 149.926672997, 150.928318618, 151.931499225, 152.933838905, 153.937518153, 154.940120, 155.944270, 156.947430, 157.951980, 158.955500, 141.907723297, 123.952230, 124.948880, 125.943220, 126.940500, 127.935390, 128.933188, 129.928506, 130.927247, 131.923321237, 132.922348, 133.918790181, 134.91818116, 135.914976035, 136.914567137, 137.911949961, 138.911978288, 139.909552, 140.909609854, 141.907723297, 142.90981429, 143.910087274, 144.912573636, 145.913116939, 146.916100441, 147.916893288, 148.920148842, 149.920890888, 150.923828929, 151.924682219, 152.927698232, 153.929477307, 154.932932, 155.935018114, 156.939030, 157.941600, 158.946090, 159.949090, 160.953880, 144.912749023, 125.957520, 126.951630, 127.948420, 128.943160, 129.940450, 130.935870, 131.933750, 132.929782, 133.928353, 134.924876, 135.923565829, 136.920479493, 137.919548281, 138.916804082, 139.916041789, 140.913555054, 141.912874471, 142.910932616, 143.912590843, 144.912749023, 145.914696305, 146.915138545, 147.917474618, 148.918334155, 149.920983561, 150.921206973, 151.923496795, 152.924116889, 153.926463943, 154.928101267, 155.931056736, 156.933039369, 157.936561407, 158.938970, 159.942990, 160.945860, 161.950290, 162.953680, 151.919732425, 127.958080, 128.954640, 129.948920, 130.946110, 131.940690, 132.938670, 133.933970, 134.93252, 135.928275527, 136.926971746, 137.923243961, 138.922296605, 139.918994687, 140.918476488, 141.915197641, 142.914628338, 143.911999478, 144.913410353, 145.9130409, 146.914897923, 147.914822674, 148.917184735, 149.917275539, 150.919932409, 151.919732425, 152.922097356, 153.922209273, 154.924640161, 155.925527887, 156.928358717, 157.929991317, 158.933211271, 159.935140, 160.938830, 161.941220, 162.945360, 163.948280, 164.952980, 152.921230339, 129.963569, 130.957753, 131.954370, 132.949240, 133.946510, 134.941820, 135.939600, 136.935570, 137.933709, 138.92979228, 139.928087607, 140.92493072, 141.923434945, 142.920297509, 143.918816823, 144.916265237, 145.917205817, 146.916746111, 147.918085895, 148.917931238, 149.919701819, 150.919850161, 151.921744534, 152.921230339, 153.922979237, 154.92289326, 155.924752249, 156.925423647, 157.927845302, 158.929088861, 159.931971, 160.933680, 161.937040, 162.939210, 163.942990, 164.945720, 165.949970, 166.953210, 157.924103912, 133.955370, 134.952570, 135.947340, 136.945020, 137.940120, 138.938240, 139.933674, 140.932126, 141.928116, 142.92674951, 143.922963, 144.921709252, 145.918310608, 146.91909442, 147.918114524, 148.919340915, 149.918658876, 150.920348482, 151.919790996, 152.921749543, 153.920865598, 154.922622022, 155.922122743, 156.923960135, 157.924103912, 158.926388658, 159.927054146, 160.929669211, 161.930984751, 162.933990, 163.935860, 164.939380, 165.941600, 166.945570, 167.948360, 168.952870, 158.925346757, 135.961380, 136.955980, 137.953160, 138.948290, 139.945805049, 140.941448, 141.938744, 142.935121, 143.933045, 144.929274, 145.927246584, 146.924044585, 147.924271701, 148.923245909, 149.923659686, 150.923102543, 151.924074438, 152.923434588, 153.924678019, 154.923505236, 155.924747213, 156.924024604, 157.925413137, 158.925346757, 159.927167606, 160.927569919, 161.929488234, 162.930647536, 163.933350838, 164.934880, 165.937991959, 166.940050, 167.943640, 168.946220, 169.950250, 170.953300, 163.929174751, 137.962490, 138.959540, 139.954010, 140.951350, 141.946366, 142.943830, 143.939254, 144.937425, 145.932845369, 146.9310915, 147.927149831, 148.927304787, 149.925585184, 150.926184601, 151.9247183, 152.92576467, 153.924424457, 154.925753775, 155.92428311, 156.925466095, 157.924409487, 158.925739214, 159.925197517, 160.926933364, 161.926798447, 162.928731159, 163.929174751, 164.931703333, 165.932806741, 166.935655462, 167.937128769, 168.940307614, 169.942390, 170.946200, 171.948760, 172.953000, 164.93032207, 139.968539, 140.963098, 141.959770, 142.954610, 143.951480, 144.947200, 145.944640, 146.940056, 147.937718, 148.933774771, 149.933496182, 150.931688142, 151.931713714, 152.930198789, 153.930601579, 154.929103491, 155.929839, 156.928256188, 157.928941007, 158.927711959, 159.928729478, 160.927854776, 161.929095504, 162.928733903, 163.930233507, 164.93032207, 165.932284162, 166.933132633, 167.935515708, 168.936872273, 169.939618929, 170.94146515, 171.944820, 172.947290, 173.951150, 174.954050, 165.930293061, 142.966340, 143.960380, 144.957390, 145.952000, 146.949490, 147.944550, 148.942306, 149.937913839, 150.937448903, 151.935050389, 152.935063492, 153.932783081, 154.933208949, 155.931064698, 156.931916, 157.929893474, 158.930684066, 159.929083292, 160.929995309, 161.928778264, 162.930032749, 163.929200229, 164.930726003, 165.930293061, 166.932048159, 167.932370224, 168.934590364, 169.935464312, 170.938029808, 171.939356113, 172.942400, 173.944230, 174.947770, 175.950080, 176.954050, 168.93421325, 144.970073, 145.966425, 146.960961, 147.957840, 148.952720, 149.949960, 150.94548349, 151.944422, 152.942012112, 153.941567808, 154.939199459, 155.938979933, 156.936973, 157.936979525, 158.934975, 159.935262801, 160.933549, 161.933994682, 162.932651124, 163.93356, 164.932435492, 165.933554131, 166.932851622, 167.934172776, 168.93421325, 169.935801397, 170.93642944, 171.938400044, 172.939603607, 173.942168605, 174.943836853, 175.946994685, 176.949040, 177.952640, 178.955340, 173.938862089, 147.967420, 148.964040, 149.958420, 150.955400769, 151.950288919, 152.949480, 153.946393928, 154.945782332, 155.942818215, 156.942627848, 157.939865617, 158.940050099, 159.937552344, 160.937901678, 161.93576821, 162.936334305, 163.934489416, 164.935279, 165.933882042, 166.934949605, 167.933896895, 168.935189802, 169.934761837, 170.936325799, 171.936381469, 172.938210787, 173.938862089, 174.94127645, 175.942571683, 176.945260822, 177.94664668, 178.950170, 179.952330, 180.956150, 174.940771819, 149.973228, 150.967577, 151.964120, 152.958767331, 153.957522, 154.954316216, 155.953032523, 156.9500983, 157.949313283, 158.946628776, 159.946033, 160.943572, 161.943277288, 162.941179, 163.941339, 164.939406724, 165.939859, 166.93827, 167.938739111, 168.937651439, 169.938474968, 170.937913136, 171.939085669, 172.938930602, 173.94033748, 174.940771819, 175.94268631, 176.943758055, 177.945954559, 178.947327443, 179.94988116, 180.951970, 181.955040, 182.957570, 183.960910, 179.946549953, 152.970690, 153.964860, 154.963390, 155.959364025, 156.958396, 157.954799366, 158.95399487, 159.950684379, 160.950274844, 161.947210498, 162.947089, 163.944367284, 164.944567, 165.94218, 166.9426, 167.940568, 168.941259, 169.939609, 170.940492, 171.939448301, 172.940513, 173.940046178, 174.941509181, 175.941408631, 176.943220651, 177.943698766, 178.945816145, 179.946549953, 180.949101246, 181.950554096, 182.953530439, 183.955446515, 184.958820, 185.960890, 186.964590, 187.966850, 180.947995763, 154.974592, 155.972303, 156.968192445, 157.966699, 158.963018173, 159.961486056, 160.958417, 161.957291859, 162.954330271, 163.953534, 164.950772514, 165.950512, 166.948093, 167.948047, 168.946011, 169.946175, 170.944476, 171.944895, 172.94375, 173.944454, 174.943737, 175.944857, 176.944472403, 177.945778221, 178.945929535, 179.947464831, 180.947995763, 181.950151849, 182.951372616, 183.954007966, 184.955559375, 185.958552023, 186.960530, 187.963700, 188.965830, 189.969230, 183.950931188, 157.974562, 158.972918, 159.968478805, 160.967357, 161.963497417, 162.962523542, 163.958954382, 164.958279949, 165.955027253, 166.954816014, 167.951808394, 168.95177879, 169.949228482, 170.949451, 171.947292, 172.947689, 173.946079, 174.946717, 175.945634, 176.946643, 177.945876236, 178.947070447, 179.946704459, 180.948197248, 181.948204156, 182.950222951, 183.950931188, 184.953419264, 185.954364127, 186.957160466, 187.958489105, 188.961912868, 189.963181378, 190.966600, 191.968170, 186.955753109, 159.982115, 160.977589119, 161.976002, 162.972080535, 163.970323, 164.967088557, 165.965808, 166.962601, 167.961572608, 168.958791096, 169.958220071, 170.955716, 171.955422961, 172.953243, 173.953115, 174.951381, 175.951623, 176.950328, 177.950989, 178.949987641, 179.950789084, 180.950067916, 181.95121008, 182.950819841, 183.952520756, 184.952954982, 185.954986084, 186.955753109, 187.958114438, 188.959229007, 189.961817977, 190.963125242, 191.965960, 192.967470, 193.970420, 191.96148069, 161.984431, 162.982690, 163.978035649, 164.976762, 165.972690753, 166.971547969, 167.967803678, 168.96701927, 169.963577028, 170.963184819, 171.960023303, 172.959808409, 173.957062202, 174.956945835, 175.954806, 176.954965324, 177.953251241, 178.953816017, 179.952378803, 180.953244, 181.952110186, 182.953126102, 183.952489071, 184.954042265, 185.953838158, 186.955750458, 187.955838228, 188.95814747, 189.958447048, 190.960929718, 191.96148069, 192.964151563, 193.965182083, 194.968126661, 195.969639333, 192.96292643, 163.992201, 164.987520, 165.985824, 166.981665156, 167.979881, 168.976294942, 169.974965, 170.971626042, 171.970456, 172.967501739, 173.966861045, 174.964112895, 175.963648688, 176.9613015, 177.961082, 178.959122266, 179.959229446, 180.957625297, 181.958076296, 182.956846458, 183.957476, 184.956698, 185.957946104, 186.957363361, 187.958853121, 188.958718935, 189.960545968, 190.960594046, 191.962605012, 192.96292643, 193.965078378, 194.965979573, 195.968396542, 196.969653285, 197.972280, 198.973804583, 194.964791134, 165.994855, 166.992979, 167.988150742, 168.986715, 169.982495289, 170.981244542, 171.977347128, 172.976444754, 173.972818767, 174.972420552, 175.968944622, 176.968469481, 177.965648724, 178.965363404, 179.963031477, 180.963097285, 181.961170656, 182.961596703, 183.959922251, 184.960619, 185.959350813, 186.960587, 187.959395391, 188.960833686, 189.959931655, 190.961676661, 191.961038005, 192.962987401, 193.962680253, 194.964791134, 195.964951521, 196.967340182, 197.96789279, 198.970593094, 199.971440677, 200.974512868, 201.975740, 196.966568662, 168.998080, 169.996122, 170.991878881, 171.990035, 172.98623738, 173.984761, 174.981274107, 175.980099, 176.976864908, 177.97603192, 178.973212812, 179.972521124, 180.970079048, 181.969617874, 182.967593034, 183.967451524, 184.965789411, 185.965952703, 186.964567541, 187.965323661, 188.963948286, 189.964700339, 190.963704225, 191.964812953, 192.964149715, 193.96536525, 194.96503464, 195.966569813, 196.966568662, 197.968242303, 198.968765193, 199.970725647, 200.97165724, 201.973805838, 202.975154542, 203.977724, 204.979870, 201.970643011, 171.003760, 171.998832686, 172.997242, 173.992863695, 174.99142327, 175.98735458, 176.986279158, 177.982483143, 178.981833861, 179.978266394, 180.977819311, 181.974689964, 182.974449841, 183.971713051, 184.971899086, 185.96936179, 186.969814236, 187.967577049, 188.968190034, 189.966322449, 190.967157105, 191.965634327, 192.966665421, 193.965439409, 194.966720113, 195.965832649, 196.967212908, 197.966769032, 198.968279932, 199.968326004, 200.970302268, 201.970643011, 202.972872484, 203.973493933, 204.976073386, 205.977514066, 206.982588545, 207.985940, 208.991040, 209.994510, 204.974427541, 176.000590, 176.996427286, 177.994897, 178.991089082, 179.989906, 180.986257447, 181.985667104, 182.982192802, 183.981873122, 184.978791305, 185.978325, 186.975905897, 187.976009782, 188.973588428, 189.973877149, 190.971786154, 191.972225, 192.970672, 193.9712, 194.969774335, 195.970481151, 196.969574511, 197.970483495, 198.969877, 199.970962672, 200.970818891, 201.972105808, 202.97234422, 203.973863522, 204.974427541, 205.97611032, 206.977419429, 207.9820187, 208.985358952, 209.990073689, 210.993477, 211.998228, 207.976652071, 178.003830191, 179.002150, 179.997918173, 180.996623958, 181.992671842, 182.991874629, 183.988142339, 184.987609944, 185.984238945, 186.98391837, 187.980874338, 188.980807, 189.978081517, 190.978265, 191.975785171, 192.976173234, 193.97401207, 194.97454205, 195.972774109, 196.973431124, 197.972033959, 198.97291665, 199.971826675, 200.972884511, 201.972159133, 202.973390521, 203.973043589, 204.974481755, 205.974465278, 206.975896887, 207.976652071, 208.98109012, 209.984188527, 210.988736964, 211.991897543, 212.996581499, 213.999805408, 215.004807, 208.980398734, 184.001124, 184.997625, 185.996597625, 186.993157835, 187.992265154, 188.989199012, 189.988295129, 190.985786119, 191.985457954, 192.982959771, 193.98283396, 194.980650737, 195.980666509, 196.978864454, 197.979206, 198.977671961, 199.978131829, 200.977009036, 201.977742324, 202.976876001, 203.977812736, 204.977389366, 205.97849913, 206.978470679, 207.979742196, 208.980398734, 209.984120371, 210.98726946, 211.991285724, 212.994384666, 213.998711539, 215.001769776, 216.006305943, 217.009470, 218.014316, 208.982430435, 187.999422048, 188.998480562, 189.995101185, 190.994574485, 191.991335149, 192.991025275, 193.988185606, 194.988110728, 195.98553458, 196.98565963, 197.983388616, 198.983666063, 199.981798604, 200.982259764, 201.980757541, 202.981420103, 203.980318121, 204.981203322, 205.980481099, 206.981593173, 207.981245702, 208.982430435, 209.982873673, 210.986653154, 211.988867969, 212.99285728, 213.99520135, 214.999419988, 216.001915035, 217.006334796, 218.008973037, 219.013744, 220.016602, 210.987496271, 192.999843112, 193.998725085, 194.996268098, 195.995788077, 196.993189215, 197.992837202, 198.990532254, 199.990351264, 200.988416999, 201.988630236, 202.986941984, 203.987251326, 204.986074483, 205.986667036, 206.985783502, 207.986589977, 208.986173143, 209.98714771, 210.987496271, 211.990744771, 212.992936646, 213.996371733, 214.99865257, 216.002423257, 217.004718822, 218.008694336, 219.011161691, 220.015407682, 221.018050, 222.022330, 223.025190, 222.017577738, 195.005437696, 196.002115223, 197.001584351, 197.998678663, 198.998370297, 199.9956993, 200.995628335, 201.993263492, 202.993386687, 203.99142874, 204.991718799, 205.990214104, 206.990734225, 207.98964247, 208.990414742, 209.989696216, 210.990600523, 211.990703529, 212.993882668, 213.995362554, 214.998745483, 216.00027437, 217.003927675, 218.005601256, 219.009480204, 220.011393981, 221.015536782, 222.017577738, 223.021790, 224.024090, 225.028440, 226.030890, 227.035407, 228.037986, 222.01755173, 199.007258147, 200.00657249, 201.003860867, 202.003372847, 203.000924647, 204.000653204, 204.99859396, 205.998666066, 206.996949414, 207.997138783, 208.995953555, 209.996407738, 210.995536544, 211.996202244, 212.996189081, 213.998971145, 215.000341497, 216.00319799, 217.004631951, 218.007578322, 219.009252149, 220.012327405, 221.014254762, 222.01755173, 223.019735857, 224.023249951, 225.025565414, 226.029386231, 227.031835938, 228.035729, 229.038450228, 230.042510, 231.045440, 232.049772, 228.031070292, 202.009890686, 203.009271619, 204.006499668, 205.00626857, 206.00382727, 207.003798105, 208.00183994, 209.001991373, 210.000494978, 211.000897987, 211.999794499, 213.000383959, 214.000107894, 215.002719834, 216.003533035, 217.006320327, 218.00714023, 219.010085078, 220.011028384, 221.013917338, 222.01537453, 223.018502171, 224.020211821, 225.023611564, 226.025409823, 227.029177842, 228.031070292, 229.034957577, 230.037056394, 231.041220, 232.043638, 233.048060, 234.050704, 227.027752127, 206.01450498, 207.011949748, 208.011551551, 209.009494863, 210.009435986, 211.007734835, 212.007813822, 213.006607643, 214.006901798, 215.006453625, 216.008720075, 217.009346914, 218.011641453, 219.012420389, 220.014762979, 221.015591248, 222.017843851, 223.019137468, 224.021722866, 225.023229585, 226.026098089, 227.027752127, 228.031021112, 229.033015243, 230.036294178, 231.038558786, 232.042027438, 233.044550, 234.048420, 235.051232, 236.055296, 232.038055325, 209.017715682, 210.015075342, 211.014928413, 212.012980288, 213.01301014, 214.01149977, 215.01173033, 216.011062115, 217.013114328, 218.013284499, 219.015536895, 220.015747762, 221.018183674, 222.018468121, 223.020811448, 224.021466895, 225.023951021, 226.024903069, 227.02770407, 228.028741127, 229.03176243, 230.033133843, 231.036304343, 232.038055325, 233.041581843, 234.04360123, 235.047510074, 236.049870, 237.053894, 238.056496, 231.03588399, 212.023204138, 213.02110934, 214.020918417, 215.019185865, 216.019109564, 217.018323986, 218.020041889, 219.019883143, 220.021875303, 221.021877983, 222.023742, 223.023962273, 224.025625738, 225.026130678, 226.027947753, 227.028805072, 228.031051376, 229.032096793, 230.034540754, 231.03588399, 232.038591592, 233.040247277, 234.043308058, 235.045443615, 236.048681284, 237.051145659, 238.05450271, 239.057260, 240.060980, 238.050788247, 217.024368791, 218.023535671, 219.02491916, 220.024723, 221.026399, 222.026086, 223.0277386, 224.027604778, 225.029390717, 226.029338702, 227.031156367, 228.031374006, 229.033505939, 230.033939784, 231.036293704, 232.037156152, 233.039635207, 234.040952088, 235.043929918, 236.045568006, 237.048730184, 238.050788247, 239.054293299, 240.056591988, 241.060330, 242.062931, 237.048173444, 225.033913933, 226.035145, 227.034956789, 228.036180, 229.036263808, 230.037827597, 231.038245085, 232.040108, 233.040740546, 234.042895038, 235.044063267, 236.0465696, 237.048173444, 238.050946405, 239.052939025, 240.056162182, 241.058252431, 242.06164118, 243.064279, 244.067850, 242.058742611, 228.038742328, 229.040150212, 230.039649886, 231.041101107, 232.041187097, 233.042997375, 234.043317076, 235.04528605, 236.046057964, 237.048409658, 238.049559894, 239.052163381, 240.053813545, 241.056851456, 242.058742611, 243.062003092, 244.064203907, 245.067747154, 246.070204627, 247.074070, 243.06138108, 231.045560, 232.046590, 233.046348, 234.047809, 235.047946, 236.049579, 237.049996, 238.051984324, 239.053024479, 240.055300179, 241.056829144, 242.059549159, 243.06138108, 244.064284847, 245.066452114, 246.069774619, 247.072093, 248.075752, 249.078480, 247.07035354, 233.050771232, 234.050159841, 235.051434, 236.051413, 237.052901, 238.053028697, 239.054957, 240.055529539, 241.057653001, 242.058835824, 243.061389114, 244.062752578, 245.065491249, 246.067223662, 247.07035354, 248.072348508, 249.075953413, 250.078356959, 251.082284605, 252.084870, 247.07030708, 235.056580, 236.057330, 237.057003, 238.058281, 239.058279, 240.059759, 241.060230, 242.061981, 243.063007572, 244.065180774, 245.066361616, 246.068672947, 247.07030708, 248.073086, 249.074986657, 250.07831652, 251.080760172, 252.084310, 253.086880, 254.090600, 251.079586788, 237.062070, 238.061410, 239.062422, 240.062302, 241.063726, 242.063701552, 243.065427, 244.066000689, 245.068048612, 246.068805309, 247.071000589, 248.072184861, 249.074853537, 250.076406066, 251.079586788, 252.081625846, 253.085133145, 254.087322909, 255.091046, 256.093440, 252.082978512, 240.068920, 241.068538, 242.069745, 243.069548, 244.070883, 245.071324, 246.072896, 247.073656, 248.075471, 249.076411, 250.078612, 251.079992142, 252.082978512, 253.084824697, 254.088022021, 255.090273122, 256.093598, 257.095979, 258.099520, 257.095104724, 242.073430, 243.074353, 244.074084, 245.075385, 246.075299023, 247.076847, 248.077194714, 249.079034, 250.079521264, 251.081575017, 252.082466855, 253.085185236, 254.08685422, 255.089962202, 256.091773117, 257.095104724, 258.097076, 259.100595, 260.102678, 258.098431319, 245.080829, 246.081886, 247.081635, 248.082823, 249.083013, 250.084420, 251.084839, 252.086560, 253.087280, 254.089656, 255.091082705, 256.094059025, 257.095541368, 258.098431319, 259.100509, 260.103652, 261.105721, 262.108865, 255.093241131, 248.086596, 249.087833, 250.087510, 251.089012, 252.088976521, 253.090678, 254.090955253, 255.093241131, 256.094282666, 257.09687719, 258.098207, 259.101031, 260.102643, 261.105749, 262.107301, 263.110552, 264.112345, 260.105504, 251.094360, 252.095371, 253.095210, 254.096454, 255.096681, 256.098629, 257.099555, 258.101814, 259.102901, 260.105504, 261.106883, 262.109634, 263.111293, 264.114038, 265.115839, 266.119305, 263.112547, 253.100689, 254.100184, 255.101340, 256.101166194, 257.102990, 258.103489, 259.105637, 260.106440, 261.108766556, 262.109925, 263.112547, 264.113985, 265.116704, 266.117956, 267.121529, 268.123644, 255.107398, 255.107398, 256.108127, 257.107722, 258.109231, 259.109610, 260.111300, 261.112056, 262.114084, 263.114988, 264.117404, 265.118601, 266.121029, 267.122377, 268.125445, 269.127460, 270.130712, 259.114500, 258.113168, 259.114500, 260.114422071, 261.116117, 262.116398, 263.118322, 264.118931, 265.121114693, 266.122065, 267.124425, 268.125606, 269.128755, 270.130329, 271.133472, 272.135158, 273.138220, 262.122892, 260.121970, 261.121664, 262.122892, 263.123035, 264.124604, 265.125147, 266.126942, 267.127650, 268.129755, 269.130694, 270.133616, 271.135179, 272.138032, 273.139618, 274.142440, 275.144250, 263.128558, 263.128558, 264.128394885, 265.130085, 266.130097, 267.131789, 268.132162, 269.134056, 270.134650, 271.137657, 272.139052, 273.141986, 274.143131, 275.145952, 276.147208, 277.149841, 265.136151, 265.136151, 266.137299, 267.137307, 268.138728, 269.139055, 270.140657, 271.141139, 272.143738, 273.144913, 274.147492, 275.148647, 276.151156, 277.152420, 278.154812, 279.156193, 281.162061, 267.144341, 268.143795, 269.145124, 270.144720, 271.146062, 272.146317, 273.148863, 274.149492, 275.152176, 276.153034, 277.155647, 278.156469, 279.158861, 280.159795, 281.162061, 272.153615, 272.153615, 273.153682, 274.155713, 275.156142, 276.158493, 277.159519, 278.161604, 279.162468, 280.164473, 281.165372, 282.167486, 283.168415, 283.171792, 277.163943, 278.164312, 279.166546, 280.167039, 281.169286, 282.169765, 283.171792, 284.172384, 285.174105, 283.176451, 283.176451, 284.178080, 285.178732, 286.180481, 287.181045, 285.183698, 285.183698, 286.183855, 287.185599, 288.185689, 289.187279, 287.191186, 287.191186, 288.192492, 289.192715, 290.194141, 291.194384, 292.199786, 289.198862, 290.198590, 291.200011, 292.199786, 291.206564, 291.206564, 292.207549, 293.214670, 293.214670] el2mass = dict(zip(_temp_symbol, _temp_mass)) el2mass["GH"] = 0. # note that ghost atoms in Cfour have mass 100. eliso2mass = dict(zip(_temp_iso_symbol, _temp_iso_mass)) # encompasses el2mass eliso2mass["GH"] = 0. # note that ghost atoms in Cfour have mass 100. # encompasses el2mass eliso2mass["X0"] = 0. # probably needed, just checking el2z = dict(zip(_temp_symbol, _temp_z)) el2z["GH"] = 0 z2mass = dict(zip(_temp_z, _temp_mass)) z2el = dict(zip(_temp_z, _temp_symbol)) z2element = dict(zip(_temp_z, _temp_element)) QCElemental-0.5.0/qcelemental/checkup_data/physconst.py000066400000000000000000000067261351361252000231700ustar00rootroot00000000000000# # @BEGIN LICENSE # # Psi4: an open-source quantum chemistry software package # # Copyright (c) 2007-2018 The Psi4 Developers. # # The copyrights for code used from other parties are included in # the corresponding files. # # This file is part of Psi4. # # Psi4 is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, version 3. # # Psi4 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License along # with Psi4; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # @END LICENSE # # Do not modify this file! It is auto-generated by the document_options_and_tests # script, from psi4topdir/psi4/include/psi4/physconst.h h = 6.62606896E-34 # The Planck constant (Js) c = 2.99792458E8 # Speed of light (ms$^{-1}$) kb = 1.3806504E-23 # The Boltzmann constant (JK$^{-1}$) R = 8.314472 # Universal gas constant (JK$^{-1}$mol$^{-1}$) bohr2angstroms = 0.52917720859 # Bohr to Angstroms conversion factor bohr2m = 0.52917720859E-10 # Bohr to meters conversion factor bohr2cm = 0.52917720859E-8 # Bohr to centimeters conversion factor amu2g = 1.660538782E-24 # Atomic mass units to grams conversion factor amu2kg = 1.660538782E-27 # Atomic mass units to kg conversion factor au2amu = 5.485799097E-4 # Atomic units (m$@@e$) to atomic mass units conversion factor hartree2J = 4.359744E-18 # Hartree to joule conversion factor hartree2aJ = 4.359744 # Hartree to attojoule (10$^{-18}$J) conversion factor cal2J = 4.184 # Calorie to joule conversion factor dipmom_au2si = 8.47835281E-30 # Atomic units to SI units (Cm) conversion factor for dipoles dipmom_au2debye = 2.54174623 # Atomic units to Debye conversion factor for dipoles dipmom_debye2si = 3.335640952E-30 # Debye to SI units (Cm) conversion factor for dipoles c_au = 137.035999679 # Speed of light in atomic units hartree2ev = 27.21138 # Hartree to eV conversion factor hartree2wavenumbers = 219474.6 # Hartree to cm$^{-1}$ conversion factor hartree2kcalmol = 627.5095 # Hartree to kcal mol$^{-1}$ conversion factor hartree2kJmol = 2625.500 # Hartree to kilojoule mol$^{-1}$ conversion factor hartree2MHz = 6.579684E9 # Hartree to MHz conversion factor kcalmol2wavenumbers = 349.7551 # kcal mol$^{-1}$ to cm$^{-1}$ conversion factor e0 = 8.854187817E-12 # Vacuum permittivity (Fm$^{-1}$) na = 6.02214179E23 # Avagadro's number me = 9.10938215E-31 # Electron rest mass (in kg) QCElemental-0.5.0/qcelemental/covalent_radii.py000066400000000000000000000152111351361252000214730ustar00rootroot00000000000000""" Contains covalent radii """ import collections from decimal import Decimal from typing import Union from .datum import Datum, print_variables from .exceptions import DataUnavailableError from .periodic_table import periodictable class CovalentRadii: """Covalent radii sets. Parameters ---------- context : {'ALVAREZ2008'} Origin of loaded data. Attributes ---------- name : str The name of the context ('ALVAREZ2008') cr : dict of Datum Each covalent radius is an entry in `cr`, where key is the "Fe"-cased element symbol if generic or symbol-prefixed label if specialized within element. The value is a Datum object with `lbl` the same as key, `units`, `data` value as Decimal object, and any uncertainty in the `comment` field. year : int The year the context was created. """ def __init__(self, context="ALVAREZ2008"): self.cr = collections.OrderedDict() from .data import alvarez_2008_covalent_radii if context == "ALVAREZ2008": self.doi = alvarez_2008_covalent_radii["doi"] self.native_units = alvarez_2008_covalent_radii["units"] for cr in alvarez_2008_covalent_radii["covalent_radii"]: self.cr[cr[0]] = Datum(cr[0], self.native_units, Decimal(cr[1]), comment=cr[2], doi=self.doi) else: raise KeyError("Context set as '{}', only contexts {'ALVAREZ2008', } are currently supported") self.name = context self.year = int(alvarez_2008_covalent_radii["date"][:4]) # Extra relationships aliases = [ ('C', 'angstrom', self.cr['C_sp3'].data, 'Largest (sp3) chosen for generic atom'), ('Mn', 'angstrom', self.cr['Mn_highspin'].data, 'Larger (high-spin) chosen for generic atom'), ('Fe', 'angstrom', self.cr['Fe_highspin'].data, 'Larger (high-spin) chosen for generic atom'), ('Co', 'angstrom', self.cr['Co_highspin'].data, 'Larger (high-spin) chosen for generic atom'), ] # yapf: disable # add alternate names to help QC programs for alias in aliases: ident, units, value, comment = alias self.cr[ident.capitalize()] = Datum(ident, units, value, comment=comment) def __str__(self): return "CovalentRadii(context='{}')".format(self.name) def get(self, atom: Union[int, str], *, return_tuple:bool=False, units:str='bohr', missing:float=None) -> Union[float, 'Datum']: """Access a covalent radius for species `atom`. Parameters ---------- atom : int or str Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`. In general, one value recommended for each element; however, certain other exact labels may be available. ALVAREZ2008: C_sp3, C_sp2, C_sp, Mn_lowspin, Mn_highspin, Fe_lowspin, Fe_highspin, Co_lowspin, Co_highspin units : str, optional Units of returned value. To return in native unit (ALVAREZ2008: angstrom), pass it explicitly. Only relevant for ``return_tuple=False`` since ``True`` returns underlying data structure with native units. missing : float or None, optional How to handle when `atom` is valid but outside the available data range. When ``None``, raises DataUnavailableError. When a float, returns that float, so supply in `units` units. Supplying a float is a more compact assurance that a call will work over all the periodic table than the equivalent ``try:\n\trad = qcel.covalentradii.get(atom)\texcept qcel.DataUnavailableError:\n\trad = 4.0``. Only relevant for ``return_tuple=False``. return_tuple : bool, optional See below. Returns ------- float When ``return_tuple=False``, value of covalent radius. If multiple defined for element, returns largest. qcelemental.Datum When ``return_tuple=True``, Datum namedtuple with units, description, uncertainty, and value of covalent radius as Decimal (preserving significant figures). If multiple defined for element, returns largest. Raises ------ NotAnElementError If `atom` cannot be resolved into an element or nuclide or label. DataUnavailableError If `atom` is a valid element or nuclide but not one for which a covalent radius is available and `missing=None`. """ if atom in self.cr.keys(): # catch extra labels like 'C_sp3' identifier = atom else: identifier = periodictable.to_E(atom) try: qca = self.cr[identifier] except KeyError as e: if missing is not None and return_tuple is False: return missing else: raise DataUnavailableError('covalent radius', identifier) from e if return_tuple: return qca else: return qca.to_units(units) def string_representation(self): """Print name, value, and units of all covalent radii.""" return print_variables(self.cr) def write_c_header(self, filename='covrad.h', missing=2.0): """Write C header file defining covalent radii array. Parameters ---------- filename : str, optional File name for header. Note that changing this won't change the header guard. missing : float, optional In order that the C array be atomic-number indexable and that it span the periodic table, this value is used anywhere data is missing. """ text = [ '#ifndef _qcelemental_covrad_h_', '#define _qcelemental_covrad_h_', '', '/* This file is autogenerated from the QCElemental python module */', '', 'const double covalent_radii[] = {', ] for el in periodictable.E: try: qca = self.cr[el] text.append('{}, /*- [{}] {} {} -*/'.format(qca.data, qca.units, qca.label, qca.comment)) except KeyError: text.append('{:.2f}, /*- [{}] {} {} -*/'.format(missing, self.native_units, el, 'Default value for missing data')) text.append('};') text.append('#endif /* header guard */') text.append('') with open(filename, 'w') as handle: handle.write('\n'.join(text)) print('File written ({}). Remember to add license and clang-format it.'.format(filename)) # singleton covalentradii = CovalentRadii("ALVAREZ2008") QCElemental-0.5.0/qcelemental/data/000077500000000000000000000000001351361252000170475ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/data/README.md000066400000000000000000000002301351361252000203210ustar00rootroot00000000000000# Sources These are automatically generated python scripts. For more information please consult the GitHub repository at github.com/MolSSI/QCElemental QCElemental-0.5.0/qcelemental/data/__init__.py000066400000000000000000000003311351361252000211550ustar00rootroot00000000000000import json import os import pathlib from .nist_2011_atomic_weights import nist_2011_atomic_weights from .nist_2014_codata import nist_2014_codata from .alvarez_2008_covalent_radii import alvarez_2008_covalent_radii QCElemental-0.5.0/qcelemental/data/alvarez_2008_covalent_radii.py000066400000000000000000000126121351361252000246030ustar00rootroot00000000000000""" This is a file transcribed from Table 2 of the journal article below. File Authors: QCElemental Authors """ alvarez_2008_covalent_radii = { 'title': 'Covalent radii revisited', 'date': '2008-04-07', 'doi': 'DOI: 10.1039/b801115j', 'url': 'https://pubs.rsc.org/en/content/articlepdf/2008/dt/b801115j', 'access_data': '2018-10-30 21:39:18', 'units': 'angstrom', 'covalent_radii': [ ('H', '0.31', 'e.s.d.=5 n=129'), ('He', '0.28', ''), ('Li', '1.28', 'e.s.d.=7 n=5789'), ('Be', '0.96', 'e.s.d.=3 n=310'), ('B', '0.84', 'e.s.d.=3 n=1770'), ('C_sp3', '0.76', 'e.s.d.=1 n=10 000'), ('C_sp2', '0.73', 'e.s.d.=2 n=10 000'), ('C_sp', '0.69', 'e.s.d.=1 n=171'), ('N', '0.71', 'e.s.d.=1 n=2200'), ('O', '0.66', 'e.s.d.=2 n=10 000'), ('F', '0.57', 'e.s.d.=3 n=10 000'), ('Ne', '0.58', ''), ('Na', '1.66', 'e.s.d.=9 n=1629'), ('Mg', '1.41', 'e.s.d.=7 n=3234'), ('Al', '1.21', 'e.s.d.=4 n=3206'), ('Si', '1.11', 'e.s.d.=2 n=10 000'), ('P', '1.07', 'e.s.d.=3 n=10 000'), ('S', '1.05', 'e.s.d.=3 n=10 000'), ('Cl', '1.02', 'e.s.d.=4 n=1987'), ('Ar', '1.06', 'e.s.d.=10 n=9'), ('K', '2.03', 'e.s.d.=12 n=435'), ('Ca', '1.76', 'e.s.d.=10 n=2647'), ('Sc', '1.70', 'e.s.d.=7 n=32'), ('Ti', '1.60', 'e.s.d.=8 n=231'), ('V', '1.53', 'e.s.d.=8 n=389'), ('Cr', '1.39', 'e.s.d.=5 n=916'), ('Mn_lowspin', '1.39', 'e.s.d.=5 n=321'), ('Mn_highspin', '1.61', 'e.s.d.=8 n=929'), ('Fe_lowspin', '1.32', 'e.s.d.=3 n=336'), ('Fe_highspin', '1.52', 'e.s.d.=6 n=1540'), ('Co_lowspin', '1.26', 'e.s.d.=3 n=5733'), ('Co_highspin', '1.50', 'e.s.d.=7 n=780'), ('Ni', '1.24', 'e.s.d.=4 n=1030'), ('Cu', '1.32', 'e.s.d.=4 n=1149'), ('Zn', '1.22', 'e.s.d.=4 n=443'), ('Ga', '1.22', 'e.s.d.=3 n=1330'), ('Ge', '1.20', 'e.s.d.=4 n=1013'), ('As', '1.19', 'e.s.d.=4 n=2015'), ('Se', '1.20', 'e.s.d.=4 n=1717'), ('Br', '1.20', 'e.s.d.=3 n=2140'), ('Kr', '1.16', 'e.s.d.=4 n=5'), ('Rb', '2.20', 'e.s.d.=9 n=23'), ('Sr', '1.95', 'e.s.d.=10 n=1500'), ('Y', '1.90', 'e.s.d.=7 n=30'), ('Zr', '1.75', 'e.s.d.=7 n=93'), ('Nb', '1.64', 'e.s.d.=6 n=18'), ('Mo', '1.54', 'e.s.d.=5 n=97'), ('Tc', '1.47', 'e.s.d.=7 n=96'), ('Ru', '1.46', 'e.s.d.=7 n=1032'), ('Rh', '1.42', 'e.s.d.=7 n=458'), ('Pd', '1.39', 'e.s.d.=6 n=1892'), ('Ag', '1.45', 'e.s.d.=5 n=1728'), ('Cd', '1.44', 'e.s.d.=9 n=19'), ('In', '1.42', 'e.s.d.=5 n=546'), ('Sn', '1.39', 'e.s.d.=4 n=2999'), ('Sb', '1.39', 'e.s.d.=5 n=609'), ('Te', '1.38', 'e.s.d.=4 n=692'), ('I', '1.39', 'e.s.d.=3 n=451'), ('Xe', '1.40', 'e.s.d.=9 n=2'), ('Cs', '2.44', 'e.s.d.=11 n=24'), ('Ba', '2.15', 'e.s.d.=11 n=3076'), ('La', '2.07', 'e.s.d.=8 n=190'), ('Ce', '2.04', 'e.s.d.=9 n=47'), ('Pr', '2.03', 'e.s.d.=7 n=58'), ('Nd', '2.01', 'e.s.d.=6 n=96'), ('Pm', '1.99', ''), ('Sm', '1.98', 'e.s.d.=8 n=53'), ('Eu', '1.98', 'e.s.d.=6 n=167'), ('Gd', '1.96', 'e.s.d.=6 n=178'), ('Tb', '1.94', 'e.s.d.=5 n=55'), ('Dy', '1.92', 'e.s.d.=7 n=59'), ('Ho', '1.92', 'e.s.d.=7 n=48'), ('Er', '1.89', 'e.s.d.=6 n=66'), ('Tm', '1.90', 'e.s.d.=10 n=15'), ('Yb', '1.87', 'e.s.d.=8 n=122'), ('Lu', '1.87', 'e.s.d.=8 n=61'), ('Hf', '1.75', 'e.s.d.=10 n=53'), ('Ta', '1.70', 'e.s.d.=8 n=88'), ('W', '1.62', 'e.s.d.=7 n=219'), ('Re', '1.51', 'e.s.d.=7 n=476'), ('Os', '1.44', 'e.s.d.=4 n=99'), ('Ir', '1.41', 'e.s.d.=6 n=131'), ('Pt', '1.36', 'e.s.d.=5 n=1768'), ('Au', '1.36', 'e.s.d.=6 n=114'), ('Hg', '1.32', 'e.s.d.=5 n=137'), ('Tl', '1.45', 'e.s.d.=7 n=291'), ('Pb', '1.46', 'e.s.d.=5 n=112'), ('Bi', '1.48', 'e.s.d.=4 n=51'), ('Po', '1.40', 'e.s.d.=4 n=4'), ('At', '1.50', ''), ('Rn', '1.50', ''), ('Fr', '2.60', ''), ('Ra', '2.21', 'e.s.d.=2 n=3'), ('Ac', '2.15', 'e.s.d.=1'), ('Th', '2.06', 'e.s.d.=6 n=11'), ('Pa', '2.00', 'e.s.d.=1'), ('U', '1.96', 'e.s.d.=7 n=57'), ('Np', '1.90', 'e.s.d.=1 n=22'), ('Pu', '1.87', 'e.s.d.=1 n=9'), ('Am', '1.80', 'e.s.d.=6 n=11'), ('Cm', '1.69', 'e.s.d.=3 n=16'), ] } QCElemental-0.5.0/qcelemental/data/nist_2011_atomic_weights.py000066400000000000000000003460341351361252000241410ustar00rootroot00000000000000 """ This is a automatically generated file from the 2011 NIST atomic weights. Title: Atomic Weights and Isotopic Compositions with Relative Atomic Masses - SRD144 Date: 2011-01-14 DOI: 10.1351/PAC-REP-10-06-02 URL: https://nist.gov/srd/srd_data//srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json Access Date: 2018-09-26 22:16:25.183679 UTC File Authors: QCElemental Authors """ nist_2011_atomic_weights = {"title": "Atomic Weights and Isotopic Compositions with Relative Atomic Masses - SRD144", "date": "2011-01-14", "doi": "10.1351/PAC-REP-10-06-02", "url": "https://nist.gov/srd/srd_data//srd144_Atomic_Weights_and_Isotopic_Compositions_for_All_Elements.json", "access_data": "2018-09-26 22:16:25.183679", "Z": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117], "E": ["X", "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts"], "name": ["Dummy", "Hydrogen", "Helium", "Lithium", "Beryllium", "Boron", "Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon", "Sodium", "Magnesium", "Aluminum", "Silicon", "Phosphorus", "Sulfur", "Chlorine", "Argon", "Potassium", "Calcium", "Scandium", "Titanium", "Vanadium", "Chromium", "Manganese", "Iron", "Cobalt", "Nickel", "Copper", "Zinc", "Gallium", "Germanium", "Arsenic", "Selenium", "Bromine", "Krypton", "Rubidium", "Strontium", "Yttrium", "Zirconium", "Niobium", "Molybdenum", "Technetium", "Ruthenium", "Rhodium", "Palladium", "Silver", "Cadmium", "Indium", "Tin", "Antimony", "Tellurium", "Iodine", "Xenon", "Cesium", "Barium", "Lanthanum", "Cerium", "Praseodymium", "Neodymium", "Promethium", "Samarium", "Europium", "Gadolinium", "Terbium", "Dysprosium", "Holmium", "Erbium", "Thulium", "Ytterbium", "Lutetium", "Hafnium", "Tantalum", "Tungsten", "Rhenium", "Osmium", "Iridium", "Platinum", "Gold", "Mercury", "Thallium", "Lead", "Bismuth", "Polonium", "Astatine", "Radon", "Francium", "Radium", "Actinium", "Thorium", "Protactinium", "Uranium", "Neptunium", "Plutonium", "Americium", "Curium", "Berkelium", "Californium", "Einsteinium", "Fermium", "Mendelevium", "Nobelium", "Lawrencium", "Rutherfordium", "Dubnium", "Seaborgium", "Bohrium", "Hassium", "Meitnerium", "Darmstadtium", "Roentgenium", "Copernicium", "Nihonium", "Flerovium", "Moscovium", "Livermorium", "Tennessine"], "_EE": ["X", "X", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "He", "He", "He", "He", "He", "He", "He", "He", "He", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Li", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "Be", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Ne", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Na", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Mg", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Al", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Cl", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "Ar", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "K", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Ca", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Sc", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "Ti", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "V", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Cr", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Mn", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Fe", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Co", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Ni", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Cu", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Zn", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ga", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "Ge", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "As", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Se", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Br", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Kr", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Rb", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Sr", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Zr", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Nb", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Mo", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Tc", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Ru", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Rh", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Pd", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Ag", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "Cd", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "In", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sn", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Sb", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "Te", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Xe", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Cs", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "Ba", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "La", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Ce", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Pr", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Nd", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Pm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Sm", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Eu", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Gd", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Tb", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Dy", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Ho", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Er", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Tm", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Yb", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Lu", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Hf", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "Ta", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "W", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Re", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Os", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Ir", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Pt", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Au", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Hg", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Tl", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Pb", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Bi", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "Po", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "At", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Rn", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Fr", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ra", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Ac", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Th", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "Pa", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "U", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Np", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Pu", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Am", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Cm", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Bk", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Cf", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Es", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Fm", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "Md", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Lr", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Rf", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Db", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Sg", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Bh", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Hs", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Mt", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Ds", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Rg", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Cn", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Nh", "Fl", "Fl", "Fl", "Fl", "Fl", "Fl", "Mc", "Mc", "Mc", "Mc", "Mc", "Mc", "Lv", "Lv", "Lv", "Lv", "Lv", "Lv", "Ts", "Ts", "Ts", "Ts", "Ts"], "EA": ["X", "X0", "H1", "H2", "D", "H3", "T", "H4", "H5", "H6", "H7", "H", "He3", "He4", "He5", "He6", "He7", "He8", "He9", "He10", "He", "Li3", "Li4", "Li5", "Li6", "Li7", "Li8", "Li9", "Li10", "Li11", "Li12", "Li13", "Li", "Be5", "Be6", "Be7", "Be8", "Be9", "Be10", "Be11", "Be12", "Be13", "Be14", "Be15", "Be16", "Be", "B6", "B7", "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "B20", "B21", "B", "C8", "C9", "C10", "C11", "C12", "C13", "C14", "C15", "C16", "C17", "C18", "C19", "C20", "C21", "C22", "C23", "C", "N10", "N11", "N12", "N13", "N14", "N15", "N16", "N17", "N18", "N19", "N20", "N21", "N22", "N23", "N24", "N25", "N", "O12", "O13", "O14", "O15", "O16", "O17", "O18", "O19", "O20", "O21", "O22", "O23", "O24", "O25", "O26", "O27", "O28", "O", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", "F", "Ne16", "Ne17", "Ne18", "Ne19", "Ne20", "Ne21", "Ne22", "Ne23", "Ne24", "Ne25", "Ne26", "Ne27", "Ne28", "Ne29", "Ne30", "Ne31", "Ne32", "Ne33", "Ne34", "Ne", "Na18", "Na19", "Na20", "Na21", "Na22", "Na23", "Na24", "Na25", "Na26", "Na27", "Na28", "Na29", "Na30", "Na31", "Na32", "Na33", "Na34", "Na35", "Na36", "Na37", "Na", "Mg19", "Mg20", "Mg21", "Mg22", "Mg23", "Mg24", "Mg25", "Mg26", "Mg27", "Mg28", "Mg29", "Mg30", "Mg31", "Mg32", "Mg33", "Mg34", "Mg35", "Mg36", "Mg37", "Mg38", "Mg39", "Mg40", "Mg", "Al21", "Al22", "Al23", "Al24", "Al25", "Al26", "Al27", "Al28", "Al29", "Al30", "Al31", "Al32", "Al33", "Al34", "Al35", "Al36", "Al37", "Al38", "Al39", "Al40", "Al41", "Al42", "Al43", "Al", "Si22", "Si23", "Si24", "Si25", "Si26", "Si27", "Si28", "Si29", "Si30", "Si31", "Si32", "Si33", "Si34", "Si35", "Si36", "Si37", "Si38", "Si39", "Si40", "Si41", "Si42", "Si43", "Si44", "Si45", "Si", "P24", "P25", "P26", "P27", "P28", "P29", "P30", "P31", "P32", "P33", "P34", "P35", "P36", "P37", "P38", "P39", "P40", "P41", "P42", "P43", "P44", "P45", "P46", "P47", "P", "S26", "S27", "S28", "S29", "S30", "S31", "S32", "S33", "S34", "S35", "S36", "S37", "S38", "S39", "S40", "S41", "S42", "S43", "S44", "S45", "S46", "S47", "S48", "S49", "S", "Cl28", "Cl29", "Cl30", "Cl31", "Cl32", "Cl33", "Cl34", "Cl35", "Cl36", "Cl37", "Cl38", "Cl39", "Cl40", "Cl41", "Cl42", "Cl43", "Cl44", "Cl45", "Cl46", "Cl47", "Cl48", "Cl49", "Cl50", "Cl51", "Cl", "Ar30", "Ar31", "Ar32", "Ar33", "Ar34", "Ar35", "Ar36", "Ar37", "Ar38", "Ar39", "Ar40", "Ar41", "Ar42", "Ar43", "Ar44", "Ar45", "Ar46", "Ar47", "Ar48", "Ar49", "Ar50", "Ar51", "Ar52", "Ar53", "Ar", "K32", "K33", "K34", "K35", "K36", "K37", "K38", "K39", "K40", "K41", "K42", "K43", "K44", "K45", "K46", "K47", "K48", "K49", "K50", "K51", "K52", "K53", "K54", "K55", "K56", "K", "Ca34", "Ca35", "Ca36", "Ca37", "Ca38", "Ca39", "Ca40", "Ca41", "Ca42", "Ca43", "Ca44", "Ca45", "Ca46", "Ca47", "Ca48", "Ca49", "Ca50", "Ca51", "Ca52", "Ca53", "Ca54", "Ca55", "Ca56", "Ca57", "Ca58", "Ca", "Sc36", "Sc37", "Sc38", "Sc39", "Sc40", "Sc41", "Sc42", "Sc43", "Sc44", "Sc45", "Sc46", "Sc47", "Sc48", "Sc49", "Sc50", "Sc51", "Sc52", "Sc53", "Sc54", "Sc55", "Sc56", "Sc57", "Sc58", "Sc59", "Sc60", "Sc61", "Sc", "Ti38", "Ti39", "Ti40", "Ti41", "Ti42", "Ti43", "Ti44", "Ti45", "Ti46", "Ti47", "Ti48", "Ti49", "Ti50", "Ti51", "Ti52", "Ti53", "Ti54", "Ti55", "Ti56", "Ti57", "Ti58", "Ti59", "Ti60", "Ti61", "Ti62", "Ti63", "Ti", "V40", "V41", "V42", "V43", "V44", "V45", "V46", "V47", "V48", "V49", "V50", "V51", "V52", "V53", "V54", "V55", "V56", "V57", "V58", "V59", "V60", "V61", "V62", "V63", "V64", "V65", "V66", "V", "Cr42", "Cr43", "Cr44", "Cr45", "Cr46", "Cr47", "Cr48", "Cr49", "Cr50", "Cr51", "Cr52", "Cr53", "Cr54", "Cr55", "Cr56", "Cr57", "Cr58", "Cr59", "Cr60", "Cr61", "Cr62", "Cr63", "Cr64", "Cr65", "Cr66", "Cr67", "Cr68", "Cr", "Mn44", "Mn45", "Mn46", "Mn47", "Mn48", "Mn49", "Mn50", "Mn51", "Mn52", "Mn53", "Mn54", "Mn55", "Mn56", "Mn57", "Mn58", "Mn59", "Mn60", "Mn61", "Mn62", "Mn63", "Mn64", "Mn65", "Mn66", "Mn67", "Mn68", "Mn69", "Mn70", "Mn71", "Mn", "Fe45", "Fe46", "Fe47", "Fe48", "Fe49", "Fe50", "Fe51", "Fe52", "Fe53", "Fe54", "Fe55", "Fe56", "Fe57", "Fe58", "Fe59", "Fe60", "Fe61", "Fe62", "Fe63", "Fe64", "Fe65", "Fe66", "Fe67", "Fe68", "Fe69", "Fe70", "Fe71", "Fe72", "Fe73", "Fe74", "Fe", "Co47", "Co48", "Co49", "Co50", "Co51", "Co52", "Co53", "Co54", "Co55", "Co56", "Co57", "Co58", "Co59", "Co60", "Co61", "Co62", "Co63", "Co64", "Co65", "Co66", "Co67", "Co68", "Co69", "Co70", "Co71", "Co72", "Co73", "Co74", "Co75", "Co76", "Co", "Ni48", "Ni49", "Ni50", "Ni51", "Ni52", "Ni53", "Ni54", "Ni55", "Ni56", "Ni57", "Ni58", "Ni59", "Ni60", "Ni61", "Ni62", "Ni63", "Ni64", "Ni65", "Ni66", "Ni67", "Ni68", "Ni69", "Ni70", "Ni71", "Ni72", "Ni73", "Ni74", "Ni75", "Ni76", "Ni77", "Ni78", "Ni79", "Ni", "Cu52", "Cu53", "Cu54", "Cu55", "Cu56", "Cu57", "Cu58", "Cu59", "Cu60", "Cu61", "Cu62", "Cu63", "Cu64", "Cu65", "Cu66", "Cu67", "Cu68", "Cu69", "Cu70", "Cu71", "Cu72", "Cu73", "Cu74", "Cu75", "Cu76", "Cu77", "Cu78", "Cu79", "Cu80", "Cu81", "Cu82", "Cu", "Zn54", "Zn55", "Zn56", "Zn57", "Zn58", "Zn59", "Zn60", "Zn61", "Zn62", "Zn63", "Zn64", "Zn65", "Zn66", "Zn67", "Zn68", "Zn69", "Zn70", "Zn71", "Zn72", "Zn73", "Zn74", "Zn75", "Zn76", "Zn77", "Zn78", "Zn79", "Zn80", "Zn81", "Zn82", "Zn83", "Zn84", "Zn85", "Zn", "Ga56", "Ga57", "Ga58", "Ga59", "Ga60", "Ga61", "Ga62", "Ga63", "Ga64", "Ga65", "Ga66", "Ga67", "Ga68", "Ga69", "Ga70", "Ga71", "Ga72", "Ga73", "Ga74", "Ga75", "Ga76", "Ga77", "Ga78", "Ga79", "Ga80", "Ga81", "Ga82", "Ga83", "Ga84", "Ga85", "Ga86", "Ga87", "Ga", "Ge58", "Ge59", "Ge60", "Ge61", "Ge62", "Ge63", "Ge64", "Ge65", "Ge66", "Ge67", "Ge68", "Ge69", "Ge70", "Ge71", "Ge72", "Ge73", "Ge74", "Ge75", "Ge76", "Ge77", "Ge78", "Ge79", "Ge80", "Ge81", "Ge82", "Ge83", "Ge84", "Ge85", "Ge86", "Ge87", "Ge88", "Ge89", "Ge90", "Ge", "As60", "As61", "As62", "As63", "As64", "As65", "As66", "As67", "As68", "As69", "As70", "As71", "As72", "As73", "As74", "As75", "As76", "As77", "As78", "As79", "As80", "As81", "As82", "As83", "As84", "As85", "As86", "As87", "As88", "As89", "As90", "As91", "As92", "As", "Se64", "Se65", "Se66", "Se67", "Se68", "Se69", "Se70", "Se71", "Se72", "Se73", "Se74", "Se75", "Se76", "Se77", "Se78", "Se79", "Se80", "Se81", "Se82", "Se83", "Se84", "Se85", "Se86", "Se87", "Se88", "Se89", "Se90", "Se91", "Se92", "Se93", "Se94", "Se95", "Se", "Br67", "Br68", "Br69", "Br70", "Br71", "Br72", "Br73", "Br74", "Br75", "Br76", "Br77", "Br78", "Br79", "Br80", "Br81", "Br82", "Br83", "Br84", "Br85", "Br86", "Br87", "Br88", "Br89", "Br90", "Br91", "Br92", "Br93", "Br94", "Br95", "Br96", "Br97", "Br98", "Br", "Kr69", "Kr70", "Kr71", "Kr72", "Kr73", "Kr74", "Kr75", "Kr76", "Kr77", "Kr78", "Kr79", "Kr80", "Kr81", "Kr82", "Kr83", "Kr84", "Kr85", "Kr86", "Kr87", "Kr88", "Kr89", "Kr90", "Kr91", "Kr92", "Kr93", "Kr94", "Kr95", "Kr96", "Kr97", "Kr98", "Kr99", "Kr100", "Kr101", "Kr", "Rb71", "Rb72", "Rb73", "Rb74", "Rb75", "Rb76", "Rb77", "Rb78", "Rb79", "Rb80", "Rb81", "Rb82", "Rb83", "Rb84", "Rb85", "Rb86", "Rb87", "Rb88", "Rb89", "Rb90", "Rb91", "Rb92", "Rb93", "Rb94", "Rb95", "Rb96", "Rb97", "Rb98", "Rb99", "Rb100", "Rb101", "Rb102", "Rb103", "Rb", "Sr73", "Sr74", "Sr75", "Sr76", "Sr77", "Sr78", "Sr79", "Sr80", "Sr81", "Sr82", "Sr83", "Sr84", "Sr85", "Sr86", "Sr87", "Sr88", "Sr89", "Sr90", "Sr91", "Sr92", "Sr93", "Sr94", "Sr95", "Sr96", "Sr97", "Sr98", "Sr99", "Sr100", "Sr101", "Sr102", "Sr103", "Sr104", "Sr105", "Sr106", "Sr107", "Sr", "Y76", "Y77", "Y78", "Y79", "Y80", "Y81", "Y82", "Y83", "Y84", "Y85", "Y86", "Y87", "Y88", "Y89", "Y90", "Y91", "Y92", "Y93", "Y94", "Y95", "Y96", "Y97", "Y98", "Y99", "Y100", "Y101", "Y102", "Y103", "Y104", "Y105", "Y106", "Y107", "Y108", "Y109", "Y", "Zr78", "Zr79", "Zr80", "Zr81", "Zr82", "Zr83", "Zr84", "Zr85", "Zr86", "Zr87", "Zr88", "Zr89", "Zr90", "Zr91", "Zr92", "Zr93", "Zr94", "Zr95", "Zr96", "Zr97", "Zr98", "Zr99", "Zr100", "Zr101", "Zr102", "Zr103", "Zr104", "Zr105", "Zr106", "Zr107", "Zr108", "Zr109", "Zr110", "Zr111", "Zr112", "Zr", "Nb81", "Nb82", "Nb83", "Nb84", "Nb85", "Nb86", "Nb87", "Nb88", "Nb89", "Nb90", "Nb91", "Nb92", "Nb93", "Nb94", "Nb95", "Nb96", "Nb97", "Nb98", "Nb99", "Nb100", "Nb101", "Nb102", "Nb103", "Nb104", "Nb105", "Nb106", "Nb107", "Nb108", "Nb109", "Nb110", "Nb111", "Nb112", "Nb113", "Nb114", "Nb115", "Nb", "Mo83", "Mo84", "Mo85", "Mo86", "Mo87", "Mo88", "Mo89", "Mo90", "Mo91", "Mo92", "Mo93", "Mo94", "Mo95", "Mo96", "Mo97", "Mo98", "Mo99", "Mo100", "Mo101", "Mo102", "Mo103", "Mo104", "Mo105", "Mo106", "Mo107", "Mo108", "Mo109", "Mo110", "Mo111", "Mo112", "Mo113", "Mo114", "Mo115", "Mo116", "Mo117", "Mo", "Tc85", "Tc86", "Tc87", "Tc88", "Tc89", "Tc90", "Tc91", "Tc92", "Tc93", "Tc94", "Tc95", "Tc96", "Tc97", "Tc98", "Tc99", "Tc100", "Tc101", "Tc102", "Tc103", "Tc104", "Tc105", "Tc106", "Tc107", "Tc108", "Tc109", "Tc110", "Tc111", "Tc112", "Tc113", "Tc114", "Tc115", "Tc116", "Tc117", "Tc118", "Tc119", "Tc120", "Tc", "Ru87", "Ru88", "Ru89", "Ru90", "Ru91", "Ru92", "Ru93", "Ru94", "Ru95", "Ru96", "Ru97", "Ru98", "Ru99", "Ru100", "Ru101", "Ru102", "Ru103", "Ru104", "Ru105", "Ru106", "Ru107", "Ru108", "Ru109", "Ru110", "Ru111", "Ru112", "Ru113", "Ru114", "Ru115", "Ru116", "Ru117", "Ru118", "Ru119", "Ru120", "Ru121", "Ru122", "Ru123", "Ru124", "Ru", "Rh89", "Rh90", "Rh91", "Rh92", "Rh93", "Rh94", "Rh95", "Rh96", "Rh97", "Rh98", "Rh99", "Rh100", "Rh101", "Rh102", "Rh103", "Rh104", "Rh105", "Rh106", "Rh107", "Rh108", "Rh109", "Rh110", "Rh111", "Rh112", "Rh113", "Rh114", "Rh115", "Rh116", "Rh117", "Rh118", "Rh119", "Rh120", "Rh121", "Rh122", "Rh123", "Rh124", "Rh125", "Rh126", "Rh", "Pd91", "Pd92", "Pd93", "Pd94", "Pd95", "Pd96", "Pd97", "Pd98", "Pd99", "Pd100", "Pd101", "Pd102", "Pd103", "Pd104", "Pd105", "Pd106", "Pd107", "Pd108", "Pd109", "Pd110", "Pd111", "Pd112", "Pd113", "Pd114", "Pd115", "Pd116", "Pd117", "Pd118", "Pd119", "Pd120", "Pd121", "Pd122", "Pd123", "Pd124", "Pd125", "Pd126", "Pd127", "Pd128", "Pd", "Ag93", "Ag94", "Ag95", "Ag96", "Ag97", "Ag98", "Ag99", "Ag100", "Ag101", "Ag102", "Ag103", "Ag104", "Ag105", "Ag106", "Ag107", "Ag108", "Ag109", "Ag110", "Ag111", "Ag112", "Ag113", "Ag114", "Ag115", "Ag116", "Ag117", "Ag118", "Ag119", "Ag120", "Ag121", "Ag122", "Ag123", "Ag124", "Ag125", "Ag126", "Ag127", "Ag128", "Ag129", "Ag130", "Ag", "Cd95", "Cd96", "Cd97", "Cd98", "Cd99", "Cd100", "Cd101", "Cd102", "Cd103", "Cd104", "Cd105", "Cd106", "Cd107", "Cd108", "Cd109", "Cd110", "Cd111", "Cd112", "Cd113", "Cd114", "Cd115", "Cd116", "Cd117", "Cd118", "Cd119", "Cd120", "Cd121", "Cd122", "Cd123", "Cd124", "Cd125", "Cd126", "Cd127", "Cd128", "Cd129", "Cd130", "Cd131", "Cd132", "Cd133", "Cd", "In97", "In98", "In99", "In100", "In101", "In102", "In103", "In104", "In105", "In106", "In107", "In108", "In109", "In110", "In111", "In112", "In113", "In114", "In115", "In116", "In117", "In118", "In119", "In120", "In121", "In122", "In123", "In124", "In125", "In126", "In127", "In128", "In129", "In130", "In131", "In132", "In133", "In134", "In135", "In", "Sn99", "Sn100", "Sn101", "Sn102", "Sn103", "Sn104", "Sn105", "Sn106", "Sn107", "Sn108", "Sn109", "Sn110", "Sn111", "Sn112", "Sn113", "Sn114", "Sn115", "Sn116", "Sn117", "Sn118", "Sn119", "Sn120", "Sn121", "Sn122", "Sn123", "Sn124", "Sn125", "Sn126", "Sn127", "Sn128", "Sn129", "Sn130", "Sn131", "Sn132", "Sn133", "Sn134", "Sn135", "Sn136", "Sn137", "Sn138", "Sn", "Sb103", "Sb104", "Sb105", "Sb106", "Sb107", "Sb108", "Sb109", "Sb110", "Sb111", "Sb112", "Sb113", "Sb114", "Sb115", "Sb116", "Sb117", "Sb118", "Sb119", "Sb120", "Sb121", "Sb122", "Sb123", "Sb124", "Sb125", "Sb126", "Sb127", "Sb128", "Sb129", "Sb130", "Sb131", "Sb132", "Sb133", "Sb134", "Sb135", "Sb136", "Sb137", "Sb138", "Sb139", "Sb140", "Sb", "Te105", "Te106", "Te107", "Te108", "Te109", "Te110", "Te111", "Te112", "Te113", "Te114", "Te115", "Te116", "Te117", "Te118", "Te119", "Te120", "Te121", "Te122", "Te123", "Te124", "Te125", "Te126", "Te127", "Te128", "Te129", "Te130", "Te131", "Te132", "Te133", "Te134", "Te135", "Te136", "Te137", "Te138", "Te139", "Te140", "Te141", "Te142", "Te143", "Te", "I107", "I108", "I109", "I110", "I111", "I112", "I113", "I114", "I115", "I116", "I117", "I118", "I119", "I120", "I121", "I122", "I123", "I124", "I125", "I126", "I127", "I128", "I129", "I130", "I131", "I132", "I133", "I134", "I135", "I136", "I137", "I138", "I139", "I140", "I141", "I142", "I143", "I144", "I145", "I", "Xe109", "Xe110", "Xe111", "Xe112", "Xe113", "Xe114", "Xe115", "Xe116", "Xe117", "Xe118", "Xe119", "Xe120", "Xe121", "Xe122", "Xe123", "Xe124", "Xe125", "Xe126", "Xe127", "Xe128", "Xe129", "Xe130", "Xe131", "Xe132", "Xe133", "Xe134", "Xe135", "Xe136", "Xe137", "Xe138", "Xe139", "Xe140", "Xe141", "Xe142", "Xe143", "Xe144", "Xe145", "Xe146", "Xe147", "Xe148", "Xe", "Cs112", "Cs113", "Cs114", "Cs115", "Cs116", "Cs117", "Cs118", "Cs119", "Cs120", "Cs121", "Cs122", "Cs123", "Cs124", "Cs125", "Cs126", "Cs127", "Cs128", "Cs129", "Cs130", "Cs131", "Cs132", "Cs133", "Cs134", "Cs135", "Cs136", "Cs137", "Cs138", "Cs139", "Cs140", "Cs141", "Cs142", "Cs143", "Cs144", "Cs145", "Cs146", "Cs147", "Cs148", "Cs149", "Cs150", "Cs151", "Cs", "Ba114", "Ba115", "Ba116", "Ba117", "Ba118", "Ba119", "Ba120", "Ba121", "Ba122", "Ba123", "Ba124", "Ba125", "Ba126", "Ba127", "Ba128", "Ba129", "Ba130", "Ba131", "Ba132", "Ba133", "Ba134", "Ba135", "Ba136", "Ba137", "Ba138", "Ba139", "Ba140", "Ba141", "Ba142", "Ba143", "Ba144", "Ba145", "Ba146", "Ba147", "Ba148", "Ba149", "Ba150", "Ba151", "Ba152", "Ba153", "Ba", "La116", "La117", "La118", "La119", "La120", "La121", "La122", "La123", "La124", "La125", "La126", "La127", "La128", "La129", "La130", "La131", "La132", "La133", "La134", "La135", "La136", "La137", "La138", "La139", "La140", "La141", "La142", "La143", "La144", "La145", "La146", "La147", "La148", "La149", "La150", "La151", "La152", "La153", "La154", "La155", "La", "Ce119", "Ce120", "Ce121", "Ce122", "Ce123", "Ce124", "Ce125", "Ce126", "Ce127", "Ce128", "Ce129", "Ce130", "Ce131", "Ce132", "Ce133", "Ce134", "Ce135", "Ce136", "Ce137", "Ce138", "Ce139", "Ce140", "Ce141", "Ce142", "Ce143", "Ce144", "Ce145", "Ce146", "Ce147", "Ce148", "Ce149", "Ce150", "Ce151", "Ce152", "Ce153", "Ce154", "Ce155", "Ce156", "Ce157", "Ce", "Pr121", "Pr122", "Pr123", "Pr124", "Pr125", "Pr126", "Pr127", "Pr128", "Pr129", "Pr130", "Pr131", "Pr132", "Pr133", "Pr134", "Pr135", "Pr136", "Pr137", "Pr138", "Pr139", "Pr140", "Pr141", "Pr142", "Pr143", "Pr144", "Pr145", "Pr146", "Pr147", "Pr148", "Pr149", "Pr150", "Pr151", "Pr152", "Pr153", "Pr154", "Pr155", "Pr156", "Pr157", "Pr158", "Pr159", "Pr", "Nd124", "Nd125", "Nd126", "Nd127", "Nd128", "Nd129", "Nd130", "Nd131", "Nd132", "Nd133", "Nd134", "Nd135", "Nd136", "Nd137", "Nd138", "Nd139", "Nd140", "Nd141", "Nd142", "Nd143", "Nd144", "Nd145", "Nd146", "Nd147", "Nd148", "Nd149", "Nd150", "Nd151", "Nd152", "Nd153", "Nd154", "Nd155", "Nd156", "Nd157", "Nd158", "Nd159", "Nd160", "Nd161", "Nd", "Pm126", "Pm127", "Pm128", "Pm129", "Pm130", "Pm131", "Pm132", "Pm133", "Pm134", "Pm135", "Pm136", "Pm137", "Pm138", "Pm139", "Pm140", "Pm141", "Pm142", "Pm143", "Pm144", "Pm145", "Pm146", "Pm147", "Pm148", "Pm149", "Pm150", "Pm151", "Pm152", "Pm153", "Pm154", "Pm155", "Pm156", "Pm157", "Pm158", "Pm159", "Pm160", "Pm161", "Pm162", "Pm163", "Pm", "Sm128", "Sm129", "Sm130", "Sm131", "Sm132", "Sm133", "Sm134", "Sm135", "Sm136", "Sm137", "Sm138", "Sm139", "Sm140", "Sm141", "Sm142", "Sm143", "Sm144", "Sm145", "Sm146", "Sm147", "Sm148", "Sm149", "Sm150", "Sm151", "Sm152", "Sm153", "Sm154", "Sm155", "Sm156", "Sm157", "Sm158", "Sm159", "Sm160", "Sm161", "Sm162", "Sm163", "Sm164", "Sm165", "Sm", "Eu130", "Eu131", "Eu132", "Eu133", "Eu134", "Eu135", "Eu136", "Eu137", "Eu138", "Eu139", "Eu140", "Eu141", "Eu142", "Eu143", "Eu144", "Eu145", "Eu146", "Eu147", "Eu148", "Eu149", "Eu150", "Eu151", "Eu152", "Eu153", "Eu154", "Eu155", "Eu156", "Eu157", "Eu158", "Eu159", "Eu160", "Eu161", "Eu162", "Eu163", "Eu164", "Eu165", "Eu166", "Eu167", "Eu", "Gd133", "Gd134", "Gd135", "Gd136", "Gd137", "Gd138", "Gd139", "Gd140", "Gd141", "Gd142", "Gd143", "Gd144", "Gd145", "Gd146", "Gd147", "Gd148", "Gd149", "Gd150", "Gd151", "Gd152", "Gd153", "Gd154", "Gd155", "Gd156", "Gd157", "Gd158", "Gd159", "Gd160", "Gd161", "Gd162", "Gd163", "Gd164", "Gd165", "Gd166", "Gd167", "Gd168", "Gd169", "Gd", "Tb135", "Tb136", "Tb137", "Tb138", "Tb139", "Tb140", "Tb141", "Tb142", "Tb143", "Tb144", "Tb145", "Tb146", "Tb147", "Tb148", "Tb149", "Tb150", "Tb151", "Tb152", "Tb153", "Tb154", "Tb155", "Tb156", "Tb157", "Tb158", "Tb159", "Tb160", "Tb161", "Tb162", "Tb163", "Tb164", "Tb165", "Tb166", "Tb167", "Tb168", "Tb169", "Tb170", "Tb171", "Tb", "Dy138", "Dy139", "Dy140", "Dy141", "Dy142", "Dy143", "Dy144", "Dy145", "Dy146", "Dy147", "Dy148", "Dy149", "Dy150", "Dy151", "Dy152", "Dy153", "Dy154", "Dy155", "Dy156", "Dy157", "Dy158", "Dy159", "Dy160", "Dy161", "Dy162", "Dy163", "Dy164", "Dy165", "Dy166", "Dy167", "Dy168", "Dy169", "Dy170", "Dy171", "Dy172", "Dy173", "Dy", "Ho140", "Ho141", "Ho142", "Ho143", "Ho144", "Ho145", "Ho146", "Ho147", "Ho148", "Ho149", "Ho150", "Ho151", "Ho152", "Ho153", "Ho154", "Ho155", "Ho156", "Ho157", "Ho158", "Ho159", "Ho160", "Ho161", "Ho162", "Ho163", "Ho164", "Ho165", "Ho166", "Ho167", "Ho168", "Ho169", "Ho170", "Ho171", "Ho172", "Ho173", "Ho174", "Ho175", "Ho", "Er142", "Er143", "Er144", "Er145", "Er146", "Er147", "Er148", "Er149", "Er150", "Er151", "Er152", "Er153", "Er154", "Er155", "Er156", "Er157", "Er158", "Er159", "Er160", "Er161", "Er162", "Er163", "Er164", "Er165", "Er166", "Er167", "Er168", "Er169", "Er170", "Er171", "Er172", "Er173", "Er174", "Er175", "Er176", "Er177", "Er", "Tm144", "Tm145", "Tm146", "Tm147", "Tm148", "Tm149", "Tm150", "Tm151", "Tm152", "Tm153", "Tm154", "Tm155", "Tm156", "Tm157", "Tm158", "Tm159", "Tm160", "Tm161", "Tm162", "Tm163", "Tm164", "Tm165", "Tm166", "Tm167", "Tm168", "Tm169", "Tm170", "Tm171", "Tm172", "Tm173", "Tm174", "Tm175", "Tm176", "Tm177", "Tm178", "Tm179", "Tm", "Yb148", "Yb149", "Yb150", "Yb151", "Yb152", "Yb153", "Yb154", "Yb155", "Yb156", "Yb157", "Yb158", "Yb159", "Yb160", "Yb161", "Yb162", "Yb163", "Yb164", "Yb165", "Yb166", "Yb167", "Yb168", "Yb169", "Yb170", "Yb171", "Yb172", "Yb173", "Yb174", "Yb175", "Yb176", "Yb177", "Yb178", "Yb179", "Yb180", "Yb181", "Yb", "Lu150", "Lu151", "Lu152", "Lu153", "Lu154", "Lu155", "Lu156", "Lu157", "Lu158", "Lu159", "Lu160", "Lu161", "Lu162", "Lu163", "Lu164", "Lu165", "Lu166", "Lu167", "Lu168", "Lu169", "Lu170", "Lu171", "Lu172", "Lu173", "Lu174", "Lu175", "Lu176", "Lu177", "Lu178", "Lu179", "Lu180", "Lu181", "Lu182", "Lu183", "Lu184", "Lu185", "Lu", "Hf153", "Hf154", "Hf155", "Hf156", "Hf157", "Hf158", "Hf159", "Hf160", "Hf161", "Hf162", "Hf163", "Hf164", "Hf165", "Hf166", "Hf167", "Hf168", "Hf169", "Hf170", "Hf171", "Hf172", "Hf173", "Hf174", "Hf175", "Hf176", "Hf177", "Hf178", "Hf179", "Hf180", "Hf181", "Hf182", "Hf183", "Hf184", "Hf185", "Hf186", "Hf187", "Hf188", "Hf189", "Hf", "Ta155", "Ta156", "Ta157", "Ta158", "Ta159", "Ta160", "Ta161", "Ta162", "Ta163", "Ta164", "Ta165", "Ta166", "Ta167", "Ta168", "Ta169", "Ta170", "Ta171", "Ta172", "Ta173", "Ta174", "Ta175", "Ta176", "Ta177", "Ta178", "Ta179", "Ta180", "Ta181", "Ta182", "Ta183", "Ta184", "Ta185", "Ta186", "Ta187", "Ta188", "Ta189", "Ta190", "Ta191", "Ta192", "Ta", "W157", "W158", "W159", "W160", "W161", "W162", "W163", "W164", "W165", "W166", "W167", "W168", "W169", "W170", "W171", "W172", "W173", "W174", "W175", "W176", "W177", "W178", "W179", "W180", "W181", "W182", "W183", "W184", "W185", "W186", "W187", "W188", "W189", "W190", "W191", "W192", "W193", "W194", "W", "Re159", "Re160", "Re161", "Re162", "Re163", "Re164", "Re165", "Re166", "Re167", "Re168", "Re169", "Re170", "Re171", "Re172", "Re173", "Re174", "Re175", "Re176", "Re177", "Re178", "Re179", "Re180", "Re181", "Re182", "Re183", "Re184", "Re185", "Re186", "Re187", "Re188", "Re189", "Re190", "Re191", "Re192", "Re193", "Re194", "Re195", "Re196", "Re197", "Re198", "Re", "Os161", "Os162", "Os163", "Os164", "Os165", "Os166", "Os167", "Os168", "Os169", "Os170", "Os171", "Os172", "Os173", "Os174", "Os175", "Os176", "Os177", "Os178", "Os179", "Os180", "Os181", "Os182", "Os183", "Os184", "Os185", "Os186", "Os187", "Os188", "Os189", "Os190", "Os191", "Os192", "Os193", "Os194", "Os195", "Os196", "Os197", "Os198", "Os199", "Os200", "Os201", "Os202", "Os", "Ir164", "Ir165", "Ir166", "Ir167", "Ir168", "Ir169", "Ir170", "Ir171", "Ir172", "Ir173", "Ir174", "Ir175", "Ir176", "Ir177", "Ir178", "Ir179", "Ir180", "Ir181", "Ir182", "Ir183", "Ir184", "Ir185", "Ir186", "Ir187", "Ir188", "Ir189", "Ir190", "Ir191", "Ir192", "Ir193", "Ir194", "Ir195", "Ir196", "Ir197", "Ir198", "Ir199", "Ir200", "Ir201", "Ir202", "Ir203", "Ir204", "Ir", "Pt166", "Pt167", "Pt168", "Pt169", "Pt170", "Pt171", "Pt172", "Pt173", "Pt174", "Pt175", "Pt176", "Pt177", "Pt178", "Pt179", "Pt180", "Pt181", "Pt182", "Pt183", "Pt184", "Pt185", "Pt186", "Pt187", "Pt188", "Pt189", "Pt190", "Pt191", "Pt192", "Pt193", "Pt194", "Pt195", "Pt196", "Pt197", "Pt198", "Pt199", "Pt200", "Pt201", "Pt202", "Pt203", "Pt204", "Pt205", "Pt206", "Pt", "Au169", "Au170", "Au171", "Au172", "Au173", "Au174", "Au175", "Au176", "Au177", "Au178", "Au179", "Au180", "Au181", "Au182", "Au183", "Au184", "Au185", "Au186", "Au187", "Au188", "Au189", "Au190", "Au191", "Au192", "Au193", "Au194", "Au195", "Au196", "Au197", "Au198", "Au199", "Au200", "Au201", "Au202", "Au203", "Au204", "Au205", "Au206", "Au207", "Au208", "Au209", "Au210", "Au", "Hg171", "Hg172", "Hg173", "Hg174", "Hg175", "Hg176", "Hg177", "Hg178", "Hg179", "Hg180", "Hg181", "Hg182", "Hg183", "Hg184", "Hg185", "Hg186", "Hg187", "Hg188", "Hg189", "Hg190", "Hg191", "Hg192", "Hg193", "Hg194", "Hg195", "Hg196", "Hg197", "Hg198", "Hg199", "Hg200", "Hg201", "Hg202", "Hg203", "Hg204", "Hg205", "Hg206", "Hg207", "Hg208", "Hg209", "Hg210", "Hg211", "Hg212", "Hg213", "Hg214", "Hg215", "Hg216", "Hg", "Tl176", "Tl177", "Tl178", "Tl179", "Tl180", "Tl181", "Tl182", "Tl183", "Tl184", "Tl185", "Tl186", "Tl187", "Tl188", "Tl189", "Tl190", "Tl191", "Tl192", "Tl193", "Tl194", "Tl195", "Tl196", "Tl197", "Tl198", "Tl199", "Tl200", "Tl201", "Tl202", "Tl203", "Tl204", "Tl205", "Tl206", "Tl207", "Tl208", "Tl209", "Tl210", "Tl211", "Tl212", "Tl213", "Tl214", "Tl215", "Tl216", "Tl217", "Tl218", "Tl", "Pb178", "Pb179", "Pb180", "Pb181", "Pb182", "Pb183", "Pb184", "Pb185", "Pb186", "Pb187", "Pb188", "Pb189", "Pb190", "Pb191", "Pb192", "Pb193", "Pb194", "Pb195", "Pb196", "Pb197", "Pb198", "Pb199", "Pb200", "Pb201", "Pb202", "Pb203", "Pb204", "Pb205", "Pb206", "Pb207", "Pb208", "Pb209", "Pb210", "Pb211", "Pb212", "Pb213", "Pb214", "Pb215", "Pb216", "Pb217", "Pb218", "Pb219", "Pb220", "Pb", "Bi184", "Bi185", "Bi186", "Bi187", "Bi188", "Bi189", "Bi190", "Bi191", "Bi192", "Bi193", "Bi194", "Bi195", "Bi196", "Bi197", "Bi198", "Bi199", "Bi200", "Bi201", "Bi202", "Bi203", "Bi204", "Bi205", "Bi206", "Bi207", "Bi208", "Bi209", "Bi210", "Bi211", "Bi212", "Bi213", "Bi214", "Bi215", "Bi216", "Bi217", "Bi218", "Bi219", "Bi220", "Bi221", "Bi222", "Bi223", "Bi224", "Bi", "Po186", "Po187", "Po188", "Po189", "Po190", "Po191", "Po192", "Po193", "Po194", "Po195", "Po196", "Po197", "Po198", "Po199", "Po200", "Po201", "Po202", "Po203", "Po204", "Po205", "Po206", "Po207", "Po208", "Po209", "Po210", "Po211", "Po212", "Po213", "Po214", "Po215", "Po216", "Po217", "Po218", "Po219", "Po220", "Po221", "Po222", "Po223", "Po224", "Po225", "Po226", "Po227", "Po", "At191", "At192", "At193", "At194", "At195", "At196", "At197", "At198", "At199", "At200", "At201", "At202", "At203", "At204", "At205", "At206", "At207", "At208", "At209", "At210", "At211", "At212", "At213", "At214", "At215", "At216", "At217", "At218", "At219", "At220", "At221", "At222", "At223", "At224", "At225", "At226", "At227", "At228", "At229", "At", "Rn193", "Rn194", "Rn195", "Rn196", "Rn197", "Rn198", "Rn199", "Rn200", "Rn201", "Rn202", "Rn203", "Rn204", "Rn205", "Rn206", "Rn207", "Rn208", "Rn209", "Rn210", "Rn211", "Rn212", "Rn213", "Rn214", "Rn215", "Rn216", "Rn217", "Rn218", "Rn219", "Rn220", "Rn221", "Rn222", "Rn223", "Rn224", "Rn225", "Rn226", "Rn227", "Rn228", "Rn229", "Rn230", "Rn231", "Rn", "Fr199", "Fr200", "Fr201", "Fr202", "Fr203", "Fr204", "Fr205", "Fr206", "Fr207", "Fr208", "Fr209", "Fr210", "Fr211", "Fr212", "Fr213", "Fr214", "Fr215", "Fr216", "Fr217", "Fr218", "Fr219", "Fr220", "Fr221", "Fr222", "Fr223", "Fr224", "Fr225", "Fr226", "Fr227", "Fr228", "Fr229", "Fr230", "Fr231", "Fr232", "Fr233", "Fr", "Ra201", "Ra202", "Ra203", "Ra204", "Ra205", "Ra206", "Ra207", "Ra208", "Ra209", "Ra210", "Ra211", "Ra212", "Ra213", "Ra214", "Ra215", "Ra216", "Ra217", "Ra218", "Ra219", "Ra220", "Ra221", "Ra222", "Ra223", "Ra224", "Ra225", "Ra226", "Ra227", "Ra228", "Ra229", "Ra230", "Ra231", "Ra232", "Ra233", "Ra234", "Ra235", "Ra", "Ac206", "Ac207", "Ac208", "Ac209", "Ac210", "Ac211", "Ac212", "Ac213", "Ac214", "Ac215", "Ac216", "Ac217", "Ac218", "Ac219", "Ac220", "Ac221", "Ac222", "Ac223", "Ac224", "Ac225", "Ac226", "Ac227", "Ac228", "Ac229", "Ac230", "Ac231", "Ac232", "Ac233", "Ac234", "Ac235", "Ac236", "Ac237", "Ac", "Th208", "Th209", "Th210", "Th211", "Th212", "Th213", "Th214", "Th215", "Th216", "Th217", "Th218", "Th219", "Th220", "Th221", "Th222", "Th223", "Th224", "Th225", "Th226", "Th227", "Th228", "Th229", "Th230", "Th231", "Th232", "Th233", "Th234", "Th235", "Th236", "Th237", "Th238", "Th239", "Th", "Pa212", "Pa213", "Pa214", "Pa215", "Pa216", "Pa217", "Pa218", "Pa219", "Pa220", "Pa221", "Pa222", "Pa223", "Pa224", "Pa225", "Pa226", "Pa227", "Pa228", "Pa229", "Pa230", "Pa231", "Pa232", "Pa233", "Pa234", "Pa235", "Pa236", "Pa237", "Pa238", "Pa239", "Pa240", "Pa241", "Pa", "U217", "U218", "U219", "U220", "U221", "U222", "U223", "U224", "U225", "U226", "U227", "U228", "U229", "U230", "U231", "U232", "U233", "U234", "U235", "U236", "U237", "U238", "U239", "U240", "U241", "U242", "U243", "U", "Np219", "Np220", "Np221", "Np222", "Np223", "Np224", "Np225", "Np226", "Np227", "Np228", "Np229", "Np230", "Np231", "Np232", "Np233", "Np234", "Np235", "Np236", "Np237", "Np238", "Np239", "Np240", "Np241", "Np242", "Np243", "Np244", "Np245", "Np", "Pu228", "Pu229", "Pu230", "Pu231", "Pu232", "Pu233", "Pu234", "Pu235", "Pu236", "Pu237", "Pu238", "Pu239", "Pu240", "Pu241", "Pu242", "Pu243", "Pu244", "Pu245", "Pu246", "Pu247", "Pu", "Am230", "Am231", "Am232", "Am233", "Am234", "Am235", "Am236", "Am237", "Am238", "Am239", "Am240", "Am241", "Am242", "Am243", "Am244", "Am245", "Am246", "Am247", "Am248", "Am249", "Am", "Cm232", "Cm233", "Cm234", "Cm235", "Cm236", "Cm237", "Cm238", "Cm239", "Cm240", "Cm241", "Cm242", "Cm243", "Cm244", "Cm245", "Cm246", "Cm247", "Cm248", "Cm249", "Cm250", "Cm251", "Cm252", "Cm", "Bk234", "Bk235", "Bk236", "Bk237", "Bk238", "Bk239", "Bk240", "Bk241", "Bk242", "Bk243", "Bk244", "Bk245", "Bk246", "Bk247", "Bk248", "Bk249", "Bk250", "Bk251", "Bk252", "Bk253", "Bk254", "Bk", "Cf237", "Cf238", "Cf239", "Cf240", "Cf241", "Cf242", "Cf243", "Cf244", "Cf245", "Cf246", "Cf247", "Cf248", "Cf249", "Cf250", "Cf251", "Cf252", "Cf253", "Cf254", "Cf255", "Cf256", "Cf", "Es239", "Es240", "Es241", "Es242", "Es243", "Es244", "Es245", "Es246", "Es247", "Es248", "Es249", "Es250", "Es251", "Es252", "Es253", "Es254", "Es255", "Es256", "Es257", "Es258", "Es", "Fm241", "Fm242", "Fm243", "Fm244", "Fm245", "Fm246", "Fm247", "Fm248", "Fm249", "Fm250", "Fm251", "Fm252", "Fm253", "Fm254", "Fm255", "Fm256", "Fm257", "Fm258", "Fm259", "Fm260", "Fm", "Md245", "Md246", "Md247", "Md248", "Md249", "Md250", "Md251", "Md252", "Md253", "Md254", "Md255", "Md256", "Md257", "Md258", "Md259", "Md260", "Md261", "Md262", "Md", "No248", "No249", "No250", "No251", "No252", "No253", "No254", "No255", "No256", "No257", "No258", "No259", "No260", "No261", "No262", "No263", "No264", "No", "Lr251", "Lr252", "Lr253", "Lr254", "Lr255", "Lr256", "Lr257", "Lr258", "Lr259", "Lr260", "Lr261", "Lr262", "Lr263", "Lr264", "Lr265", "Lr266", "Lr", "Rf253", "Rf254", "Rf255", "Rf256", "Rf257", "Rf258", "Rf259", "Rf260", "Rf261", "Rf262", "Rf263", "Rf264", "Rf265", "Rf266", "Rf267", "Rf268", "Rf", "Db255", "Db256", "Db257", "Db258", "Db259", "Db260", "Db261", "Db262", "Db263", "Db264", "Db265", "Db266", "Db267", "Db268", "Db269", "Db270", "Db", "Sg258", "Sg259", "Sg260", "Sg261", "Sg262", "Sg263", "Sg264", "Sg265", "Sg266", "Sg267", "Sg268", "Sg269", "Sg270", "Sg271", "Sg272", "Sg273", "Sg", "Bh260", "Bh261", "Bh262", "Bh263", "Bh264", "Bh265", "Bh266", "Bh267", "Bh268", "Bh269", "Bh270", "Bh271", "Bh272", "Bh273", "Bh274", "Bh275", "Bh", "Hs263", "Hs264", "Hs265", "Hs266", "Hs267", "Hs268", "Hs269", "Hs270", "Hs271", "Hs272", "Hs273", "Hs274", "Hs275", "Hs276", "Hs277", "Hs", "Mt265", "Mt266", "Mt267", "Mt268", "Mt269", "Mt270", "Mt271", "Mt272", "Mt273", "Mt274", "Mt275", "Mt276", "Mt277", "Mt278", "Mt279", "Mt", "Ds267", "Ds268", "Ds269", "Ds270", "Ds271", "Ds272", "Ds273", "Ds274", "Ds275", "Ds276", "Ds277", "Ds278", "Ds279", "Ds280", "Ds281", "Ds", "Rg272", "Rg273", "Rg274", "Rg275", "Rg276", "Rg277", "Rg278", "Rg279", "Rg280", "Rg281", "Rg282", "Rg283", "Rg", "Cn276", "Cn277", "Cn278", "Cn279", "Cn280", "Cn281", "Cn282", "Cn283", "Cn284", "Cn285", "Cn", "Nh278", "Nh279", "Nh280", "Nh281", "Nh282", "Nh283", "Nh284", "Nh285", "Nh286", "Nh287", "Nh", "Fl285", "Fl286", "Fl287", "Fl288", "Fl289", "Fl", "Mc287", "Mc288", "Mc289", "Mc290", "Mc291", "Mc", "Lv289", "Lv290", "Lv291", "Lv292", "Lv293", "Lv", "Ts291", "Ts292", "Ts293", "Ts294", "Ts"], "A": [0, 0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 1, 3, 4, 5, 6, 7, 8, 9, 10, 4, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 7, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 9, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 11, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 12, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 14, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 19, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 20, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 23, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 24, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 27, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 28, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 31, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 32, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 35, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 40, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 39, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 40, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 45, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 48, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 51, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 52, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 55, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 56, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 58, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 63, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 64, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 69, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 74, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 75, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 80, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 79, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 84, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 85, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 88, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 89, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 90, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 93, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 98, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 98, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 102, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 103, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 106, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 107, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 114, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 115, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 120, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 121, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 130, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 127, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 132, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 133, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 138, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 139, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 140, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 141, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 142, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 145, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 152, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 153, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 158, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 159, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 164, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 165, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 166, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 169, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 174, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 175, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 180, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 181, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 184, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 187, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 192, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 193, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 195, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 197, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 202, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 205, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 208, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 209, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 209, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 210, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 222, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 223, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 226, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 227, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 232, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 231, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 238, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 237, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 244, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 243, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 247, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 247, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 251, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 252, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 257, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 258, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 259, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 266, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 267, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 268, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 271, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 270, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 269, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 278, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 281, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 282, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 285, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 286, 285, 286, 287, 288, 289, 289, 287, 288, 289, 290, 291, 289, 289, 290, 291, 292, 293, 293, 291, 292, 293, 294, 294], "mass": ["0", "0", "1.00782503223", "2.01410177812", "2.01410177812", "3.0160492779", "3.0160492779", "4.02643", "5.035311", "6.04496", "7.0527", "1.00782503223", "3.0160293201", "4.00260325413", "5.012057", "6.018885891", "7.0279907", "8.033934390", "9.043946", "10.05279", "4.00260325413", "3.0308", "4.02719", "5.012538", "6.0151228874", "7.0160034366", "8.022486246", "9.02679019", "10.035483", "11.04372358", "12.052517", "13.06263", "7.0160034366", "5.0399", "6.0197264", "7.016928717", "8.005305102", "9.012183065", "10.013534695", "11.02166108", "12.0269221", "13.036135", "14.04289", "15.05342", "16.06167", "9.012183065", "6.0508", "7.029712", "8.0246073", "9.01332965", "10.01293695", "11.00930536", "12.0143527", "13.0177802", "14.025404", "15.031088", "16.039842", "17.04699", "18.05566", "19.06310", "20.07207", "21.08129", "11.00930536", "8.037643", "9.0310372", "10.01685331", "11.0114336", "12.0000000", "13.00335483507", "14.0032419884", "15.01059926", "16.0147013", "17.022577", "18.026751", "19.03480", "20.04032", "21.04900", "22.05753", "23.0689", "12.0000000", "10.04165", "11.026091", "12.0186132", "13.00573861", "14.00307400443", "15.00010889888", "16.0061019", "17.008449", "18.014078", "19.017022", "20.023366", "21.02711", "22.03439", "23.04114", "24.05039", "25.06010", "14.00307400443", "12.034262", "13.024815", "14.00859636", "15.00306562", "15.99491461957", "16.99913175650", "17.99915961286", "19.0035780", "20.00407535", "21.008655", "22.009966", "23.015696", "24.01986", "25.02936", "26.03729", "27.04772", "28.05591", "15.99491461957", "14.034315", "15.018043", "16.0114657", "17.00209524", "18.00093733", "18.99840316273", "19.999981252", "20.9999489", "22.002999", "23.003557", "24.008115", "25.012199", "26.020038", "27.02644", "28.03534", "29.04254", "30.05165", "31.05971", "18.99840316273", "16.025750", "17.01771396", "18.00570870", "19.00188091", "19.9924401762", "20.993846685", "21.991385114", "22.99446691", "23.99361065", "24.997789", "26.000515", "27.007553", "28.01212", "29.01975", "30.02473", "31.0331", "32.03972", "33.04938", "34.05673", "19.9924401762", "18.02688", "19.013880", "20.0073544", "20.99765469", "21.99443741", "22.9897692820", "23.990962950", "24.9899540", "25.9926346", "26.9940765", "27.998939", "29.0028771", "30.0090979", "31.013163", "32.02019", "33.02573", "34.03359", "35.04062", "36.04929", "37.05705", "22.9897692820", "19.034169", "20.018850", "21.011716", "21.99957065", "22.99412421", "23.985041697", "24.985836976", "25.982592968", "26.984340624", "27.9838767", "28.988617", "29.9904629", "30.9966480", "31.9991102", "33.0053271", "34.008935", "35.01679", "36.02188", "37.03037", "38.03658", "39.04538", "40.05218", "23.985041697", "21.02897", "22.01954", "23.00724435", "23.9999489", "24.99042810", "25.986891904", "26.98153853", "27.98191021", "28.9804565", "29.982960", "30.983945", "31.988085", "32.990909", "33.996705", "34.999764", "36.00639", "37.01053", "38.01740", "39.02254", "40.03003", "41.03638", "42.04384", "43.05147", "26.98153853", "22.03579", "23.02544", "24.011535", "25.004109", "25.99233384", "26.98670481", "27.97692653465", "28.97649466490", "29.973770136", "30.975363194", "31.97415154", "32.97797696", "33.978576", "34.984583", "35.986695", "36.992921", "37.995523", "39.002491", "40.00583", "41.01301", "42.01778", "43.02480", "44.03061", "45.03995", "27.97692653465", "24.03577", "25.02119", "26.01178", "26.999224", "27.9923266", "28.98180079", "29.97831375", "30.97376199842", "31.973907643", "32.9717257", "33.97364589", "34.9733141", "35.978260", "36.979607", "37.984252", "38.986227", "39.99133", "40.994654", "42.00108", "43.00502", "44.01121", "45.01645", "46.02446", "47.03139", "30.97376199842", "26.02907", "27.01828", "28.00437", "28.996611", "29.98490703", "30.97955701", "31.9720711744", "32.9714589098", "33.967867004", "34.969032310", "35.96708071", "36.97112551", "37.9711633", "38.975134", "39.9754826", "40.9795935", "41.9810651", "42.9869076", "43.9901188", "44.99572", "46.00004", "47.00795", "48.01370", "49.02276", "31.9720711744", "28.02954", "29.01478", "30.00477", "30.992414", "31.98568464", "32.97745199", "33.973762485", "34.968852682", "35.968306809", "36.965902602", "37.96801044", "38.9680082", "39.970415", "40.970685", "41.97325", "42.97389", "43.97787", "44.98029", "45.98517", "46.98916", "47.99564", "49.00123", "50.00905", "51.01554", "34.968852682", "30.02307", "31.01212", "31.9976378", "32.98992555", "33.980270090", "34.97525759", "35.967545105", "36.96677633", "37.96273211", "38.9643130", "39.9623831237", "40.96450057", "41.9630457", "42.9656361", "43.9649238", "44.96803973", "45.968083", "46.972935", "47.97591", "48.98190", "49.98613", "50.99370", "51.99896", "53.00729", "39.9623831237", "32.02265", "33.00756", "33.99869", "34.98800541", "35.98130201", "36.97337589", "37.96908112", "38.9637064864", "39.963998166", "40.9618252579", "41.96240231", "42.96073470", "43.96158699", "44.96069149", "45.96198159", "46.9616616", "47.96534119", "48.96821075", "49.9723800", "50.975828", "51.98224", "52.98746", "53.99463", "55.00076", "56.00851", "38.9637064864", "34.01487", "35.00514", "35.993074", "36.98589785", "37.97631922", "38.97071081", "39.962590863", "40.96227792", "41.95861783", "42.95876644", "43.95548156", "44.95618635", "45.9536890", "46.9545424", "47.95252276", "48.95566274", "49.9574992", "50.960989", "51.963217", "52.96945", "53.97340", "54.98030", "55.98508", "56.99262", "57.99794", "39.962590863", "36.01648", "37.00374", "37.99512", "38.984785", "39.9779673", "40.969251105", "41.96551653", "42.9611505", "43.9594029", "44.95590828", "45.95516826", "46.9524037", "47.9522236", "48.9500146", "49.952176", "50.953592", "51.95688", "52.95909", "53.96393", "54.96782", "55.97345", "56.97777", "57.98403", "58.98894", "59.99565", "61.00100", "44.95590828", "38.01145", "39.00236", "39.99050", "40.983148", "41.97304903", "42.9685225", "43.95968995", "44.95812198", "45.95262772", "46.95175879", "47.94794198", "48.94786568", "49.94478689", "50.94661065", "51.9468930", "52.94973", "53.95105", "54.95527", "55.95791", "56.96364", "57.96660", "58.97247", "59.97603", "60.98245", "61.98651", "62.99375", "47.94794198", "40.01276", "41.00021", "41.99182", "42.980766", "43.97411", "44.9657748", "45.96019878", "46.95490491", "47.9522522", "48.94851180", "49.94715601", "50.94395704", "51.94477301", "52.9443367", "53.946439", "54.94724", "55.95048", "56.95252", "57.95672", "58.95939", "59.96431", "60.96725", "61.97265", "62.97639", "63.98264", "64.98750", "65.99398", "50.94395704", "42.00670", "42.99753", "43.98536", "44.979050", "45.968359", "46.9628974", "47.9540291", "48.9513333", "49.94604183", "50.94476502", "51.94050623", "52.94064815", "53.93887916", "54.94083843", "55.9406531", "56.9436130", "57.94435", "58.94859", "59.95008", "60.95442", "61.95610", "62.96165", "63.96408", "64.96996", "65.97366", "66.98016", "67.98403", "51.94050623", "44.00715", "44.99449", "45.98609", "46.975775", "47.96852", "48.959595", "49.95423778", "50.94820847", "51.9455639", "52.94128889", "53.9403576", "54.93804391", "55.93890369", "56.9382861", "57.9400666", "58.9403911", "59.9431366", "60.9444525", "61.94795", "62.9496647", "63.9538494", "64.9560198", "65.960547", "66.96424", "67.96962", "68.97366", "69.97937", "70.98368", "54.93804391", "45.01442", "46.00063", "46.99185", "47.98023", "48.973429", "49.962975", "50.9568410", "51.9481131", "52.9453064", "53.93960899", "54.93829199", "55.93493633", "56.93539284", "57.93327443", "58.93487434", "59.9340711", "60.9367462", "61.9367918", "62.9402727", "63.9409878", "64.9450115", "65.9462500", "66.95054", "67.95295", "68.95807", "69.96102", "70.96672", "71.96983", "72.97572", "73.97935", "55.93493633", "47.01057", "48.00093", "48.98891", "49.98091", "50.970647", "51.96351", "52.9542041", "53.94845987", "54.94199720", "55.93983880", "56.93629057", "57.9357521", "58.93319429", "59.93381630", "60.93247662", "61.934059", "62.933600", "63.935811", "64.9364621", "65.939443", "66.9406096", "67.94426", "68.94614", "69.94963", "70.95237", "71.95729", "72.96039", "73.96515", "74.96876", "75.97413", "58.93319429", "48.01769", "49.00770", "49.99474", "50.98611", "51.97480", "52.968190", "53.957892", "54.95133063", "55.94212855", "56.93979218", "57.93534241", "58.93434620", "59.93078588", "60.93105557", "61.92834537", "62.92966963", "63.92796682", "64.93008517", "65.9291393", "66.9315694", "67.9318688", "68.9356103", "69.9364313", "70.9405190", "71.9417859", "72.9462067", "73.94798", "74.95250", "75.95533", "76.96055", "77.96336", "78.97025", "57.93534241", "51.99671", "52.98459", "53.97666", "54.96604", "55.95895", "56.94921250", "57.94453305", "58.93949748", "59.9373645", "60.9334576", "61.93259541", "62.92959772", "63.92976434", "64.92778970", "65.92886903", "66.9277303", "67.9296109", "68.9294293", "69.9323921", "70.9326768", "71.9358203", "72.9366744", "73.9398749", "74.9415226", "75.9452750", "76.94792", "77.95223", "78.95502", "79.96089", "80.96587", "81.97244", "62.92959772", "53.99204", "54.98398", "55.97254", "56.96506", "57.954591", "58.94931266", "59.94184210", "60.939507", "61.93433397", "62.9332115", "63.92914201", "64.92924077", "65.92603381", "66.92712775", "67.92484455", "68.9265507", "69.9253192", "70.9277196", "71.9268428", "72.9295826", "73.9294073", "74.9328402", "75.9331150", "76.9368872", "77.9382892", "78.9426381", "79.9445529", "80.9504026", "81.95426", "82.96056", "83.96521", "84.97226", "63.92914201", "55.99536", "56.98320", "57.97478", "58.96353", "59.95729", "60.949399", "61.94419025", "62.9392942", "63.9368404", "64.93273459", "65.9315894", "66.9282025", "67.9279805", "68.9255735", "69.9260219", "70.92470258", "71.92636747", "72.9251747", "73.9269457", "74.9265002", "75.9288276", "76.9291543", "77.9316088", "78.9328523", "79.9364208", "80.9381338", "81.9431765", "82.9471203", "83.95246", "84.95699", "85.96301", "86.96824", "68.9255735", "57.99172", "58.98249", "59.97036", "60.96379", "61.95502", "62.949628", "63.9416899", "64.9393681", "65.9338621", "66.9327339", "67.9280953", "68.9279645", "69.92424875", "70.92495233", "71.922075826", "72.923458956", "73.921177761", "74.922858370", "75.921402726", "76.923549843", "77.9228529", "78.925360", "79.9253508", "80.9288329", "81.9297740", "82.9345391", "83.9375751", "84.9429697", "85.94658", "86.95268", "87.95691", "88.96379", "89.96863", "73.921177761", "59.99388", "60.98112", "61.97361", "62.96390", "63.95743", "64.949611", "65.9441488", "66.93925111", "67.9367741", "68.932246", "69.930926", "70.9271138", "71.9267523", "72.9238291", "73.9239286", "74.92159457", "75.92239202", "76.9206476", "77.921828", "78.9209484", "79.9224746", "80.9221323", "81.9247412", "82.9252069", "83.9293033", "84.9321637", "85.9367015", "86.9402917", "87.94555", "88.94976", "89.95563", "90.96039", "91.96674", "74.92159457", "63.97109", "64.96440", "65.95559", "66.949994", "67.94182524", "68.9394148", "69.9335155", "70.9322094", "71.9271405", "72.9267549", "73.922475934", "74.922522870", "75.919213704", "76.919914154", "77.91730928", "78.91849929", "79.9165218", "80.9179930", "81.9166995", "82.9191186", "83.9184668", "84.9222608", "85.9243117", "86.9286886", "87.9314175", "88.9366691", "89.94010", "90.94596", "91.94984", "92.95629", "93.96049", "94.96730", "79.9165218", "66.96465", "67.95873", "68.950497", "69.944792", "70.9393422", "71.9365886", "72.9316715", "73.9299102", "74.9258105", "75.924542", "76.9213792", "77.9211459", "78.9183376", "79.9185298", "80.9162897", "81.9168032", "82.9151756", "83.916496", "84.9156458", "85.9188054", "86.9206740", "87.9240833", "88.9267046", "89.9312928", "90.9343986", "91.9396316", "92.94313", "93.94890", "94.95301", "95.95903", "96.96344", "97.96946", "78.9183376", "68.96518", "69.95604", "70.95027", "71.9420924", "72.9392892", "73.9330840", "74.9309457", "75.9259103", "76.9246700", "77.92036494", "78.9200829", "79.91637808", "80.9165912", "81.91348273", "82.91412716", "83.9114977282", "84.9125273", "85.9106106269", "86.91335476", "87.9144479", "88.9178355", "89.9195279", "90.9238063", "91.9261731", "92.9311472", "93.934140", "94.939711", "95.943017", "96.94909", "97.95243", "98.95839", "99.96237", "100.96873", "83.9114977282", "70.96532", "71.95908", "72.95053", "73.9442659", "74.9385732", "75.9350730", "76.9304016", "77.9281419", "78.9239899", "79.9225164", "80.9189939", "81.9182090", "82.9151142", "83.9143752", "84.9117897379", "85.91116743", "86.9091805310", "87.91131559", "88.9122783", "89.9147985", "90.9165372", "91.9197284", "92.9220393", "93.9263948", "94.929260", "95.9341334", "96.9371771", "97.9416869", "98.94503", "99.95003", "100.95404", "101.95952", "102.96392", "84.9117897379", "72.96570", "73.95617", "74.94995", "75.941763", "76.9379455", "77.9321800", "78.9297077", "79.9245175", "80.9232114", "81.9183999", "82.9175544", "83.9134191", "84.9129320", "85.9092606", "86.9088775", "87.9056125", "88.9074511", "89.9077300", "90.9101954", "91.9110382", "92.9140242", "93.9153556", "94.9193529", "95.9217066", "96.9263740", "97.9286888", "98.9328907", "99.935770", "100.940352", "101.943791", "102.94909", "103.95265", "104.95855", "105.96265", "106.96897", "87.9056125", "75.95856", "76.949781", "77.94361", "78.93735", "79.9343561", "80.9294556", "81.9269314", "82.922485", "83.9206721", "84.916433", "85.914886", "86.9108761", "87.9095016", "88.9058403", "89.9071439", "90.9072974", "91.9089451", "92.909578", "93.9115906", "94.9128161", "95.9158968", "96.9182741", "97.9223821", "98.9241480", "99.927715", "100.9301477", "101.9343277", "102.937243", "103.94196", "104.94544", "105.95056", "106.95452", "107.95996", "108.96436", "88.9058403", "77.95566", "78.94948", "79.9404", "80.93731", "81.93135", "82.9292421", "83.9233269", "84.9214444", "85.9162972", "86.9148180", "87.9102213", "88.9088814", "89.9046977", "90.9056396", "91.9050347", "92.9064699", "93.9063108", "94.9080385", "95.9082714", "96.9109512", "97.9127289", "98.916667", "99.9180006", "100.9214480", "101.9231409", "102.927191", "103.929436", "104.934008", "105.93676", "106.94174", "107.94487", "108.95041", "109.95396", "110.95968", "111.96370", "89.9046977", "80.94960", "81.94396", "82.93729", "83.93449", "84.9288458", "85.9257828", "86.9206937", "87.918222", "88.913445", "89.9112584", "90.9069897", "91.9071881", "92.9063730", "93.9072788", "94.90683240", "95.9080973", "96.9080959", "97.9103265", "98.911613", "99.9143276", "100.9153103", "101.9180772", "102.9194572", "103.9228925", "104.9249465", "105.9289317", "106.9315937", "107.9360748", "108.93922", "109.94403", "110.94753", "111.95247", "112.95651", "113.96201", "114.96634", "92.9063730", "82.94988", "83.94149", "84.938261", "85.9311748", "86.9281962", "87.9219678", "88.9194682", "89.9139309", "90.9117453", "91.90680796", "92.90680958", "93.90508490", "94.90583877", "95.90467612", "96.90601812", "97.90540482", "98.90770851", "99.9074718", "100.9103414", "101.9102834", "102.913079", "103.9137344", "104.916969", "105.918259", "106.922106", "107.924033", "108.928424", "109.930704", "110.935654", "111.93831", "112.94335", "113.94653", "114.95196", "115.95545", "116.96117", "97.90540482", "84.95058", "85.94493", "86.9380672", "87.93378", "88.9276487", "89.9240739", "90.9184254", "91.9152698", "92.9102460", "93.9096536", "94.9076536", "95.9078680", "96.9063667", "97.9072124", "98.9062508", "99.9076539", "100.907309", "101.9092097", "102.909176", "103.911425", "104.911655", "105.914358", "106.9154606", "107.9184957", "108.920256", "109.923744", "110.925901", "111.9299458", "112.9325690", "113.93691", "114.93998", "115.94476", "116.94806", "117.95299", "118.95666", "119.96187", "97.9072124", "86.95069", "87.94160", "88.93762", "89.9303444", "90.9267419", "91.9202344", "92.9171044", "93.9113429", "94.910406", "95.90759025", "96.9075471", "97.9052868", "98.9059341", "99.9042143", "100.9055769", "101.9043441", "102.9063186", "103.9054275", "104.9077476", "105.9073291", "106.9099720", "107.9101880", "108.9133260", "109.9140407", "110.917570", "111.918809", "112.922844", "113.9246136", "114.928820", "115.9312192", "116.93610", "117.93853", "118.94357", "119.94631", "120.95164", "121.95447", "122.95989", "123.96305", "101.9043441", "88.95058", "89.94422", "90.93688", "91.9323677", "92.9259128", "93.9217305", "94.9158979", "95.914453", "96.911329", "97.910708", "98.9081282", "99.908117", "100.9061606", "101.9068374", "102.9054980", "103.9066492", "104.9056885", "105.9072868", "106.906748", "107.908714", "108.9087488", "109.911079", "110.9116423", "111.914403", "112.9154393", "113.918718", "114.9203116", "115.924059", "116.9260354", "117.930340", "118.932557", "119.93686", "120.93942", "121.94399", "122.94685", "123.95151", "124.95469", "125.95946", "102.9054980", "90.95032", "91.94088", "92.93651", "93.9290376", "94.9248898", "95.9182151", "96.9164720", "97.9126983", "98.9117748", "99.908505", "100.9082864", "101.9056022", "102.9060809", "103.9040305", "104.9050796", "105.9034804", "106.9051282", "107.9038916", "108.9059504", "109.90517220", "110.90768968", "111.9073297", "112.9102610", "113.9103686", "114.913659", "115.9142970", "116.9179547", "117.9190667", "118.9233402", "119.9245511", "120.9289503", "121.930632", "122.93514", "123.93714", "124.94179", "125.94416", "126.94907", "127.95183", "105.9034804", "92.95033", "93.94373", "94.93602", "95.930744", "96.92397", "97.921560", "98.9176458", "99.9161154", "100.9126840", "101.9117047", "102.9089631", "103.9086239", "104.9065256", "105.9066636", "106.9050916", "107.9059503", "108.9047553", "109.9061102", "110.9052959", "111.9070486", "112.906573", "113.9088230", "114.908767", "115.9113868", "116.911774", "117.9145955", "118.915570", "119.9187848", "120.920125", "121.923664", "122.925337", "123.92893", "124.93105", "125.93475", "126.93711", "127.94106", "128.94395", "129.95070", "106.9050916", "94.94994", "95.94034", "96.93510", "97.927389", "98.9249258", "99.9203488", "100.9185862", "101.9144820", "102.9134165", "103.9098564", "104.9094639", "105.9064599", "106.9066121", "107.9041834", "108.9049867", "109.90300661", "110.90418287", "111.90276287", "112.90440813", "113.90336509", "114.90543751", "115.90476315", "116.9072260", "117.906922", "118.909847", "119.9098681", "120.9129637", "121.9134591", "122.9168925", "123.9176574", "124.9212576", "125.9224291", "126.926472", "127.9278129", "128.93182", "129.93394", "130.94060", "131.94604", "132.95285", "113.90336509", "96.94934", "97.94214", "98.93411", "99.93096", "100.92634", "101.9241071", "102.9198819", "103.9182145", "104.914502", "105.913464", "106.910290", "107.9096935", "108.9071514", "109.907170", "110.9051085", "111.9055377", "112.90406184", "113.90491791", "114.903878776", "115.90525999", "116.9045157", "117.9063566", "118.9058507", "119.907967", "120.907851", "121.910281", "122.910434", "123.913182", "124.913605", "125.916507", "126.917446", "127.92040", "128.9218053", "129.924977", "130.9269715", "131.933001", "132.93831", "133.94454", "134.95005", "114.903878776", "98.94853", "99.93850", "100.93526", "101.93029", "102.928105", "103.9231052", "104.9212684", "105.9169574", "106.9157137", "107.9118943", "108.9112921", "109.907845", "110.9077401", "111.90482387", "112.9051757", "113.9027827", "114.903344699", "115.90174280", "116.90295398", "117.90160657", "118.90331117", "119.90220163", "120.9042426", "121.9034438", "122.9057252", "123.9052766", "124.9077864", "125.907659", "126.910390", "127.910507", "128.913465", "129.9139738", "130.9170450", "131.9178267", "132.9239134", "133.9286821", "134.9349086", "135.93999", "136.94655", "137.95184", "119.90220163", "102.93969", "103.93648", "104.931276", "105.9286380", "106.9241506", "107.9222267", "108.9181411", "109.9168543", "110.9132182", "111.912400", "112.909375", "113.909290", "114.906598", "115.9067931", "116.9048415", "117.9055321", "118.9039455", "119.9050794", "120.9038120", "121.9051699", "122.9042132", "123.9059350", "124.9052530", "125.907253", "126.9069243", "127.909146", "128.909147", "129.911662", "130.9119888", "131.9145077", "132.9152732", "133.9205357", "134.9251851", "135.9307459", "136.93555", "137.94145", "138.94655", "139.95283", "120.9038120", "104.94330", "105.93750", "106.935012", "107.9293805", "108.9273045", "109.9224581", "110.9210006", "111.9167279", "112.915891", "113.912089", "114.911902", "115.908460", "116.908646", "117.905854", "118.9064071", "119.9040593", "120.904944", "121.9030435", "122.9042698", "123.9028171", "124.9044299", "125.9033109", "126.9052257", "127.90446128", "128.90659646", "129.906222748", "130.908522213", "131.9085467", "132.9109688", "133.9113940", "134.9165557", "135.9201006", "136.9255989", "137.9294722", "138.9353672", "139.939499", "140.94580", "141.95022", "142.95676", "129.906222748", "106.94678", "107.94348", "108.9380853", "109.935089", "110.9302692", "111.928005", "112.9236501", "113.92185", "114.918048", "115.91681", "116.913648", "117.913074", "118.910074", "119.910087", "120.9074051", "121.9075888", "122.9055885", "123.9062090", "124.9046294", "125.9056233", "126.9044719", "127.9058086", "128.9049837", "129.9066702", "130.90612630", "131.9079935", "132.9077970", "133.9097588", "134.9100488", "135.914604", "136.9180282", "137.9227264", "138.926506", "139.93173", "140.93569", "141.94120", "142.94565", "143.95139", "144.95605", "126.9044719", "108.95043", "109.94426", "110.941607", "111.9355590", "112.9332217", "113.927980", "114.926294", "115.921581", "116.920359", "117.916179", "118.915411", "119.911784", "120.911453", "121.908368", "122.908482", "123.9058920", "124.9063944", "125.9042983", "126.9051829", "127.9035310", "128.9047808611", "129.903509349", "130.90508406", "131.9041550856", "132.9059108", "133.90539466", "134.9072278", "135.907214484", "136.91155778", "137.9141463", "138.9187922", "139.9216458", "140.9267872", "141.9299731", "142.9353696", "143.9389451", "144.944720", "145.948518", "146.95426", "147.95813", "131.9041550856", "111.950309", "112.9444291", "113.941296", "114.93591", "115.93337", "116.928617", "117.926560", "118.922377", "119.920677", "120.917227", "121.916108", "122.912996", "123.9122578", "124.9097280", "125.909446", "126.9074174", "127.9077487", "128.9060657", "129.9067093", "130.9054649", "131.9064339", "132.9054519610", "133.906718503", "134.9059770", "135.9073114", "136.90708923", "137.9110171", "138.9133638", "139.9172831", "140.9200455", "141.9242960", "142.927349", "143.932076", "144.935527", "145.940344", "146.944156", "147.94923", "148.95302", "149.95833", "150.96258", "132.9054519610", "113.95066", "114.94737", "115.94128", "116.93814", "117.93306", "118.93066", "119.92605", "120.92405", "121.919904", "122.918781", "123.915094", "124.914472", "125.911250", "126.911091", "127.9083420", "128.908681", "129.9063207", "130.9069410", "131.9050611", "132.9060074", "133.90450818", "134.90568838", "135.90457573", "136.90582714", "137.90524700", "138.90884110", "139.9106057", "140.9144033", "141.9164324", "142.9206253", "143.9229549", "144.9275184", "145.930284", "146.935304", "147.938171", "148.94308", "149.94605", "150.95127", "151.95481", "152.96036", "137.90524700", "115.95630", "116.94999", "117.94673", "118.94099", "119.93807", "120.93315", "121.93071", "122.92630", "123.924574", "124.920816", "125.919513", "126.916375", "127.915592", "128.912694", "129.912369", "130.910070", "131.910119", "132.908218", "133.908514", "134.906984", "135.907635", "136.9064504", "137.9071149", "138.9063563", "139.9094806", "140.9109660", "141.9140909", "142.9160795", "143.919646", "144.921808", "145.925875", "146.928418", "147.932679", "148.93535", "149.93947", "150.94232", "151.94682", "152.95036", "153.95517", "154.95901", "138.9063563", "118.95271", "119.94654", "120.94335", "121.93787", "122.93528", "123.93031", "124.92844", "125.923971", "126.922727", "127.918911", "128.918102", "129.914736", "130.914429", "131.911464", "132.911520", "133.908928", "134.909161", "135.90712921", "136.90776236", "137.905991", "138.9066551", "139.9054431", "140.9082807", "141.9092504", "142.9123921", "143.9136529", "144.917265", "145.918802", "146.9226899", "147.924424", "148.928427", "149.930384", "150.934272", "151.93660", "152.94093", "153.94380", "154.94855", "155.95183", "156.95705", "139.9054431", "120.95532", "121.95175", "122.94596", "123.94294", "124.93770", "125.93524", "126.93071", "127.928791", "128.925095", "129.923590", "130.920235", "131.919255", "132.916331", "133.915697", "134.913112", "135.912677", "136.9106792", "137.910754", "138.9089408", "139.9090803", "140.9076576", "141.9100496", "142.9108228", "143.9133109", "144.9145182", "145.917680", "146.919008", "147.922130", "148.923736", "149.9266765", "150.928309", "151.931553", "152.933904", "153.93753", "154.940509", "155.94464", "156.94789", "157.95241", "158.95589", "140.9076576", "123.95220", "124.94890", "125.94311", "126.94038", "127.93525", "128.93310", "129.928506", "130.927248", "131.923321", "132.922348", "133.918790", "134.918181", "135.914976", "136.914562", "137.911950", "138.911954", "139.909550", "140.9096147", "141.9077290", "142.9098200", "143.9100930", "144.9125793", "145.9131226", "146.9161061", "147.9168993", "148.9201548", "149.9209022", "150.9238403", "151.924692", "152.9277180", "153.92948", "154.9331357", "155.93508", "156.939386", "157.94197", "158.94653", "159.94940", "160.95428", "141.9077290", "125.95792", "126.95192", "127.94870", "128.94323", "129.94053", "130.93567", "131.93384", "132.929782", "133.928353", "134.924823", "135.923585", "136.920480", "137.919548", "138.916800", "139.916040", "140.913555", "141.912890", "142.9109383", "143.9125964", "144.9127559", "145.9147024", "146.9151450", "147.9174819", "148.9183423", "149.920991", "150.9212175", "151.923506", "152.9241567", "153.926472", "154.9281370", "155.9311175", "156.9331214", "157.936565", "158.939287", "159.94310", "160.94607", "161.95022", "162.95357", "144.9127559", "127.95842", "128.95476", "129.94900", "130.94618", "131.94087", "132.93856", "133.93411", "134.93252", "135.928276", "136.926971", "137.923244", "138.922297", "139.918995", "140.9184816", "141.9152044", "142.9146353", "143.9120065", "144.9134173", "145.9130470", "146.9149044", "147.9148292", "148.9171921", "149.9172829", "150.9199398", "151.9197397", "152.9221047", "153.9222169", "154.9246477", "155.925536", "156.9284187", "157.9299510", "158.9332172", "159.9353353", "160.9391602", "161.94146", "162.94555", "163.94836", "164.95297", "151.9197397", "129.96369", "130.95784", "131.95467", "132.94929", "133.94640", "134.94187", "135.93962", "136.93546", "137.933709", "138.929792", "139.928088", "140.924932", "141.923442", "142.920299", "143.918820", "144.9162726", "145.9172110", "146.9167527", "147.918089", "148.9179378", "149.9197077", "150.9198578", "151.9217522", "152.9212380", "153.9229870", "154.9229011", "155.9247605", "156.9254334", "157.927799", "158.9291001", "159.931851", "160.933664", "161.936989", "162.939196", "163.94274", "164.94559", "165.94962", "166.95289", "152.9212380", "132.96133", "133.95566", "134.95245", "135.94730", "136.94502", "137.94025", "138.93813", "139.933674", "140.932126", "141.928116", "142.92675", "143.922963", "144.921713", "145.9183188", "146.9191014", "147.9181215", "148.9193481", "149.9186644", "150.9203560", "151.9197995", "152.9217580", "153.9208741", "154.9226305", "155.9221312", "156.9239686", "157.9241123", "158.9263970", "159.9270624", "160.9296775", "161.9309930", "162.9341769", "163.93583", "164.93936", "165.94146", "166.94545", "167.94808", "168.95260", "157.9241123", "134.96476", "135.96129", "136.95602", "137.95312", "138.94833", "139.94581", "140.94145", "141.93928", "142.935137", "143.933045", "144.92882", "145.927253", "146.9240548", "147.924282", "148.9232535", "149.9236649", "150.9231096", "151.924083", "152.9234424", "153.924685", "154.923511", "155.9247552", "156.9240330", "157.9254209", "158.9253547", "159.9271756", "160.9275778", "161.929495", "162.9306547", "163.93336", "164.93498", "165.937860", "166.93996", "167.94340", "168.94597", "169.94984", "170.95273", "158.9253547", "137.96250", "138.95959", "139.95402", "140.95128", "141.94619", "142.943994", "143.9392695", "144.9374740", "145.9328445", "146.9310827", "147.927157", "148.927322", "149.9255933", "150.9261916", "151.9247253", "152.9257724", "153.9244293", "154.925759", "155.9242847", "156.9254707", "157.9244159", "158.9257470", "159.9252046", "160.9269405", "161.9268056", "162.9287383", "163.9291819", "164.9317105", "165.9328139", "166.935661", "167.93713", "168.94031", "169.94239", "170.94612", "171.94846", "172.95283", "163.9291819", "139.96859", "140.96311", "141.96001", "142.95486", "143.9521097", "144.9472674", "145.9449935", "146.9401423", "147.937744", "148.933803", "149.933498", "150.9316983", "151.931724", "152.9302064", "153.9306068", "154.929104", "155.929706", "156.928254", "157.928946", "158.9277197", "159.928737", "160.9278615", "161.9291023", "162.9287410", "163.9302403", "164.9303288", "165.9322909", "166.9331385", "167.935522", "168.936878", "169.939625", "170.94147", "171.94473", "172.94702", "173.95095", "174.95362", "164.9303288", "141.97010", "142.96662", "143.96070", "144.95805", "145.9524184", "146.949964", "147.944735", "148.942306", "149.937916", "150.937449", "151.935057", "152.935080", "153.9327908", "154.9332159", "155.931067", "156.931949", "157.929893", "158.9306918", "159.929077", "160.9300046", "161.9287884", "162.9300408", "163.9292088", "164.9307345", "165.9302995", "166.9320546", "167.9323767", "168.9345968", "169.9354702", "170.9380357", "171.9393619", "172.94240", "173.94423", "174.94777", "175.94994", "176.95399", "165.9302995", "143.97628", "144.97039", "145.96684", "146.9613799", "147.958384", "148.95289", "149.95009", "150.945488", "151.944422", "152.942040", "153.941570", "154.939210", "155.938992", "156.936944", "157.936980", "158.934975", "159.935263", "160.933549", "161.934002", "162.9326592", "163.933544", "164.9324431", "165.933561", "166.9328562", "167.9341774", "168.9342179", "169.9358060", "170.9364339", "171.9384055", "172.9396084", "173.942173", "174.943841", "175.94700", "176.94904", "177.95264", "178.95534", "168.9342179", "147.96758", "148.96436", "149.95852", "150.95540", "151.95027", "152.94932", "153.946396", "154.945783", "155.942825", "156.942645", "157.9398705", "158.940055", "159.937557", "160.937907", "161.935774", "162.936340", "163.934495", "164.935270", "165.9338747", "166.9349530", "167.9338896", "168.9351825", "169.9347664", "170.9363302", "171.9363859", "172.9382151", "173.9388664", "174.9412808", "175.9425764", "176.9452656", "177.946651", "178.95004", "179.95212", "180.95589", "173.9388664", "149.97355", "150.96768", "151.96412", "152.95875", "153.95736", "154.954321", "155.953033", "156.950127", "157.949316", "158.946636", "159.946033", "160.943572", "161.943283", "162.941179", "163.941339", "164.939407", "165.939859", "166.938270", "167.938736", "168.9376441", "169.938478", "170.9379170", "171.9390891", "172.9389340", "173.9403409", "174.9407752", "175.9426897", "176.9437615", "177.9459580", "178.9473309", "179.949888", "180.95191", "181.95504", "182.957363", "183.96091", "184.96362", "174.9407752", "152.97069", "153.96486", "154.96311", "155.95935", "156.95824", "157.954801", "158.953996", "159.950691", "160.950278", "161.9472148", "162.947113", "163.944371", "164.944567", "165.942180", "166.942600", "167.940568", "168.941259", "169.939609", "170.940492", "171.939450", "172.940513", "173.9400461", "174.9415092", "175.9414076", "176.9432277", "177.9437058", "178.9458232", "179.9465570", "180.9491083", "181.9505612", "182.953530", "183.955446", "184.958862", "185.960897", "186.96477", "187.96685", "188.97084", "179.9465570", "154.97424", "155.97203", "156.96818", "157.96654", "158.963023", "159.961488", "160.958452", "161.957294", "162.954337", "163.953534", "164.950781", "165.950512", "166.948093", "167.948047", "168.946011", "169.946175", "170.944476", "171.944895", "172.943750", "173.944454", "174.943737", "175.944857", "176.9444795", "177.945678", "178.9459366", "179.9474648", "180.9479958", "181.9501519", "182.9513726", "183.954008", "184.955559", "185.958551", "186.960386", "187.963916", "188.96583", "189.96939", "190.97156", "191.97514", "180.9479958", "156.97884", "157.97456", "158.97264", "159.96846", "160.96720", "161.963499", "162.962524", "163.958961", "164.958281", "165.955031", "166.954805", "167.951806", "168.951779", "169.949232", "170.949451", "171.947292", "172.947689", "173.946079", "174.946717", "175.945634", "176.946643", "177.945883", "178.947077", "179.9467108", "180.9481978", "181.94820394", "182.95022275", "183.95093092", "184.95341897", "185.9543628", "186.9571588", "187.9584862", "188.961763", "189.963091", "190.966531", "191.96817", "192.97178", "193.97367", "183.95093092", "158.98418", "159.98182", "160.97757", "161.97584", "162.972080", "163.970453", "164.967103", "165.965761", "166.962595", "167.961573", "168.958766", "169.958220", "170.955716", "171.955420", "172.953243", "173.953115", "174.951381", "175.951623", "176.950328", "177.950989", "178.949989", "179.950792", "180.950058", "181.95121", "182.9508196", "183.9525228", "184.9529545", "185.9549856", "186.9557501", "187.9581115", "188.9592260", "189.961744", "190.963122", "191.966088", "192.967541", "193.97076", "194.97254", "195.97580", "196.97799", "197.98160", "186.9557501", "160.98903", "161.98443", "162.98241", "163.97802", "164.97660", "165.972692", "166.971549", "167.967808", "168.967018", "169.963578", "170.963174", "171.960017", "172.959808", "173.957064", "174.956945", "175.954806", "176.954966", "177.953254", "178.953817", "179.952375", "180.953247", "181.952110", "182.953125", "183.9524885", "184.9540417", "185.9538350", "186.9557474", "187.9558352", "188.9581442", "189.9584437", "190.9609264", "191.9614770", "192.9641479", "193.9651772", "194.968318", "195.969641", "196.97283", "197.97441", "198.97801", "199.97984", "200.98364", "201.98595", "191.9614770", "163.99191", "164.98750", "165.98566", "166.981666", "167.979907", "168.976298", "169.974922", "170.971640", "171.970607", "172.967506", "173.966861", "174.964150", "175.963650", "176.961301", "177.961082", "178.959120", "179.959229", "180.957625", "181.958076", "182.956840", "183.957476", "184.956698", "185.957944", "186.957542", "187.958828", "188.958715", "189.9605412", "190.9605893", "191.9626002", "192.9629216", "193.9650735", "194.9659747", "195.968397", "196.969655", "197.97228", "198.973805", "199.97680", "200.97864", "201.98199", "202.98423", "203.98960", "192.9629216", "165.99486", "166.99269", "167.98813", "168.98657", "169.982496", "170.981245", "171.977351", "172.976443", "173.972820", "174.972410", "175.968938", "176.968470", "177.965650", "178.9653590", "179.963032", "180.963098", "181.961172", "182.961597", "183.959915", "184.960614", "185.959351", "186.960617", "187.9593889", "188.960831", "189.9599297", "190.9616729", "191.9610387", "192.9629824", "193.9626809", "194.9647917", "195.96495209", "196.96734069", "197.9678949", "198.9705952", "199.971443", "200.974513", "201.975639", "202.97893", "203.98076", "204.98608", "205.98966", "194.9647917", "168.99808", "169.99597", "170.991876", "171.989942", "172.986241", "173.984717", "174.981304", "175.980250", "176.976870", "177.976032", "178.973174", "179.972523", "180.970079", "181.969618", "182.967591", "183.967452", "184.965790", "185.965953", "186.964543", "187.965349", "188.963948", "189.964698", "190.963702", "191.964814", "192.9641373", "193.9654178", "194.9650352", "195.9665699", "196.96656879", "197.96824242", "198.96876528", "199.970756", "200.9716575", "201.973856", "202.9751544", "203.97783", "204.97985", "205.98474", "206.98840", "207.99345", "208.99735", "210.00250", "196.96656879", "171.00353", "171.99881", "172.99709", "173.992865", "174.991441", "175.987361", "176.986277", "177.982484", "178.981831", "179.978260", "180.977819", "181.974689", "182.9744448", "183.971714", "184.971899", "185.969362", "186.969814", "187.967567", "188.968195", "189.966323", "190.967157", "191.965635", "192.966653", "193.9654491", "194.966721", "195.9658326", "196.9672128", "197.96676860", "198.96828064", "199.96832659", "200.97030284", "201.97064340", "202.9728728", "203.97349398", "204.9760734", "205.977514", "206.982300", "207.985759", "208.99072", "209.99424", "210.99933", "212.00296", "213.00823", "214.01200", "215.01740", "216.02132", "201.97064340", "176.000624", "176.996431", "177.99485", "178.991111", "179.990057", "180.9862600", "181.985713", "182.982193", "183.981886", "184.978789", "185.978651", "186.9759063", "187.976021", "188.973588", "189.973828", "190.9717842", "191.972225", "192.9705020", "193.971081", "194.969774", "195.970481", "196.969576", "197.970483", "198.969877", "199.9709633", "200.970822", "201.972102", "202.9723446", "203.9738639", "204.9744278", "205.9761106", "206.9774197", "207.9820190", "208.9853594", "209.990074", "210.993475", "211.99834", "213.001915", "214.00694", "215.01064", "216.01580", "217.01966", "218.02479", "204.9744278", "178.003831", "179.002201", "179.997928", "180.996653", "181.992672", "182.991872", "183.988136", "184.987610", "185.984238", "186.9839109", "187.980875", "188.980807", "189.978082", "190.978276", "191.975775", "192.976173", "193.974012", "194.974543", "195.972774", "196.9734312", "197.972034", "198.972913", "199.971819", "200.972883", "201.9721520", "202.9733911", "203.9730440", "204.9744822", "205.9744657", "206.9758973", "207.9766525", "208.9810905", "209.9841889", "210.9887371", "211.9918977", "212.9965629", "213.9998059", "215.00474", "216.00803", "217.01314", "218.01659", "219.02177", "220.02541", "207.9766525", "184.001275", "184.997600", "185.996644", "186.993147", "187.992287", "188.989195", "189.988622", "190.9857866", "191.985469", "192.982960", "193.982785", "194.9806488", "195.980667", "196.9788651", "197.979206", "198.977673", "199.978131", "200.977010", "201.977734", "202.976893", "203.9778361", "204.9773867", "205.9784993", "206.9784710", "207.9797425", "208.9803991", "209.9841207", "210.9872697", "211.9912860", "212.9943851", "213.998712", "215.001770", "216.006306", "217.009372", "218.014188", "219.01748", "220.02235", "221.02587", "222.03078", "223.03450", "224.03947", "208.9803991", "186.004393", "187.003041", "187.999416", "188.998473", "189.995101", "190.9945585", "191.991336", "192.991026", "193.988186", "194.988126", "195.985526", "196.985660", "197.983389", "198.983667", "199.981799", "200.9822598", "201.980758", "202.9814161", "203.980310", "204.981203", "205.9804740", "206.9815938", "207.9812461", "208.9824308", "209.9828741", "210.9866536", "211.9888684", "212.9928576", "213.9952017", "214.9994201", "216.0019152", "217.0063182", "218.0089735", "219.013614", "220.016386", "221.021228", "222.024140", "223.02907", "224.03211", "225.03707", "226.04031", "227.04539", "208.9824308", "191.004148", "192.003152", "192.999927", "193.999236", "194.9962685", "195.995800", "196.993189", "197.992784", "198.9905277", "199.990351", "200.9884171", "201.988630", "202.986943", "203.987251", "204.986076", "205.986657", "206.985800", "207.9866133", "208.9861702", "209.9871479", "210.9874966", "211.9907377", "212.9929370", "213.9963721", "214.9986528", "216.0024236", "217.0047192", "218.008695", "219.0111618", "220.015433", "221.018017", "222.022494", "223.025151", "224.029749", "225.03263", "226.03716", "227.04024", "228.04475", "229.04812", "209.9871479", "193.009708", "194.006144", "195.005422", "196.002116", "197.001585", "197.998679", "198.998390", "199.995690", "200.995628", "201.993264", "202.993388", "203.991430", "204.991719", "205.990214", "206.9907303", "207.989635", "208.990415", "209.9896891", "210.9906011", "211.9907039", "212.9938831", "213.9953630", "214.9987459", "216.0002719", "217.0039280", "218.0056016", "219.0094804", "220.0113941", "221.0155371", "222.0175782", "223.0218893", "224.024096", "225.028486", "226.030861", "227.035304", "228.037835", "229.042257", "230.04514", "231.04987", "222.0175782", "199.007259", "200.006586", "201.003867", "202.003320", "203.0009407", "204.000652", "204.9985939", "205.998666", "206.996946", "207.997138", "208.995955", "209.996422", "210.995556", "211.9962257", "212.9961860", "213.9989713", "215.0003418", "216.0031899", "217.0046323", "218.0075787", "219.0092524", "220.0123277", "221.0142552", "222.017552", "223.0197360", "224.023398", "225.025573", "226.029566", "227.031869", "228.035823", "229.038298", "230.042416", "231.045158", "232.04937", "233.05264", "223.0197360", "201.01271", "202.009760", "203.009304", "204.006492", "205.006268", "206.003828", "207.003799", "208.001841", "209.001990", "210.000494", "211.0008932", "211.999787", "213.000384", "214.0000997", "215.0027204", "216.0035334", "217.0063207", "218.007141", "219.0100855", "220.0110259", "221.0139177", "222.0153748", "223.0185023", "224.0202120", "225.0236119", "226.0254103", "227.0291783", "228.0310707", "229.034942", "230.037055", "231.041027", "232.0434753", "233.047582", "234.050342", "235.05497", "226.0254103", "206.014452", "207.011966", "208.011550", "209.009495", "210.009436", "211.007732", "212.007813", "213.006609", "214.006918", "215.006475", "216.008743", "217.009344", "218.011642", "219.012421", "220.0147549", "221.015592", "222.0178442", "223.0191377", "224.0217232", "225.0232300", "226.0260984", "227.0277523", "228.0310215", "229.032956", "230.036327", "231.038393", "232.042034", "233.044346", "234.048139", "235.050840", "236.054988", "237.05827", "227.0277523", "208.017900", "209.017753", "210.015094", "211.014929", "212.012988", "213.013009", "214.011500", "215.0117248", "216.011056", "217.013117", "218.013276", "219.015537", "220.015748", "221.018184", "222.018469", "223.0208119", "224.021464", "225.0239514", "226.0249034", "227.0277042", "228.0287413", "229.0317627", "230.0331341", "231.0363046", "232.0380558", "233.0415823", "234.0436014", "235.047255", "236.049657", "237.053629", "238.05650", "239.06077", "232.0380558", "212.023203", "213.021109", "214.020918", "215.019183", "216.019109", "217.018325", "218.020059", "219.019904", "220.021705", "221.021875", "222.023784", "223.023963", "224.0256176", "225.026131", "226.027948", "227.0288054", "228.0310517", "229.0320972", "230.0345410", "231.0358842", "232.0385917", "233.0402472", "234.0433072", "235.045399", "236.048668", "237.051023", "238.054637", "239.05726", "240.06098", "241.06408", "231.0358842", "217.02466", "218.023523", "219.024999", "220.02462", "221.02628", "222.02600", "223.027739", "224.027605", "225.029391", "226.029339", "227.031157", "228.031371", "229.0335063", "230.0339401", "231.0362939", "232.0371563", "233.0396355", "234.0409523", "235.0439301", "236.0455682", "237.0487304", "238.0507884", "239.0542935", "240.0565934", "241.06033", "242.06293", "243.06699", "238.0507884", "219.03143", "220.03254", "221.03204", "222.03330", "223.03285", "224.03422", "225.033911", "226.035188", "227.034957", "228.036067", "229.036264", "230.037828", "231.038245", "232.04011", "233.040741", "234.0428953", "235.0440635", "236.046570", "237.0481736", "238.0509466", "239.0529392", "240.056165", "241.058253", "242.06164", "243.064280", "244.06785", "245.07080", "237.0481736", "228.038732", "229.040144", "230.039650", "231.041102", "232.041185", "233.042998", "234.0433174", "235.045286", "236.0460581", "237.0484098", "238.0495601", "239.0521636", "240.0538138", "241.0568517", "242.0587428", "243.0620036", "244.0642053", "245.067826", "246.070205", "247.07419", "244.0642053", "230.04609", "231.04556", "232.04645", "233.04644", "234.04773", "235.047908", "236.04943", "237.049996", "238.051985", "239.0530247", "240.055300", "241.0568293", "242.0595494", "243.0613813", "244.0642851", "245.0664548", "246.069775", "247.07209", "248.07575", "249.07848", "243.0613813", "232.04982", "233.050770", "234.050160", "235.05154", "236.051374", "237.052869", "238.053081", "239.054910", "240.0555297", "241.0576532", "242.0588360", "243.0613893", "244.0627528", "245.0654915", "246.0672238", "247.0703541", "248.0723499", "249.0759548", "250.078358", "251.082286", "252.08487", "247.0703541", "234.05727", "235.05658", "236.05748", "237.05710", "238.05820", "239.05824", "240.05976", "241.06016", "242.06198", "243.0630078", "244.065181", "245.0663618", "246.068673", "247.0703073", "248.073088", "249.0749877", "250.0783167", "251.080762", "252.08431", "253.08688", "254.09060", "247.0703073", "237.062198", "238.06149", "239.06253", "240.062256", "241.06369", "242.063754", "243.06548", "244.0660008", "245.0680487", "246.0688055", "247.070965", "248.0721851", "249.0748539", "250.0764062", "251.0795886", "252.0816272", "253.0851345", "254.087324", "255.09105", "256.09344", "251.0795886", "239.06823", "240.06892", "241.06856", "242.06957", "243.06951", "244.07088", "245.07125", "246.07290", "247.073622", "248.075471", "249.076411", "250.07861", "251.0799936", "252.082980", "253.0848257", "254.0880222", "255.090275", "256.09360", "257.09598", "258.09952", "252.082980", "241.07421", "242.07343", "243.07446", "244.07404", "245.07535", "246.075350", "247.07694", "248.0771865", "249.0789275", "250.0795210", "251.081540", "252.0824671", "253.0851846", "254.0868544", "255.0899640", "256.0917745", "257.0951061", "258.09708", "259.10060", "260.10281", "257.0951061", "245.08081", "246.08171", "247.08152", "248.08282", "249.08291", "250.08441", "251.084774", "252.08643", "253.087144", "254.08959", "255.0910841", "256.09389", "257.0955424", "258.0984315", "259.10051", "260.10365", "261.10583", "262.10910", "258.0984315", "248.08655", "249.08780", "250.08756", "251.08894", "252.088967", "253.0905641", "254.090956", "255.093191", "256.0942829", "257.0968878", "258.09821", "259.10103", "260.10264", "261.10570", "262.10746", "263.11071", "264.11273", "259.10103", "251.09418", "252.09526", "253.09509", "254.09648", "255.096562", "256.098494", "257.099418", "258.10176", "259.102902", "260.10550", "261.10688", "262.10961", "263.11136", "264.11420", "265.11619", "266.11983", "266.11983", "253.10044", "254.10005", "255.10127", "256.101152", "257.102918", "258.103428", "259.105596", "260.10644", "261.108773", "262.10992", "263.11249", "264.11388", "265.11668", "266.11817", "267.12179", "268.12397", "267.12179", "255.10707", "256.10789", "257.10758", "258.10928", "259.109492", "260.11130", "261.11192", "262.11407", "263.11499", "264.11741", "265.11861", "266.12103", "267.12247", "268.12567", "269.12791", "270.13136", "268.12567", "258.11298", "259.11440", "260.114384", "261.115949", "262.116337", "263.11829", "264.11893", "265.12109", "266.12198", "267.12436", "268.12539", "269.12863", "270.13043", "271.13393", "272.13589", "273.13958", "271.13393", "260.12166", "261.12145", "262.12297", "263.12292", "264.12459", "265.12491", "266.12679", "267.12750", "268.12969", "269.13042", "270.13336", "271.13526", "272.13826", "273.14024", "274.14355", "275.14567", "270.13336", "263.12852", "264.128357", "265.129793", "266.130046", "267.13167", "268.13186", "269.13375", "270.13429", "271.13717", "272.13850", "273.14168", "274.14330", "275.14667", "276.14846", "277.15190", "269.13375", "265.13600", "266.13737", "267.13719", "268.13865", "269.13882", "270.14033", "271.14074", "272.14341", "273.14440", "274.14724", "275.14882", "276.15159", "277.15327", "278.15631", "279.15808", "278.15631", "267.14377", "268.14348", "269.144752", "270.144584", "271.14595", "272.14602", "273.14856", "274.14941", "275.15203", "276.15303", "277.15591", "278.15704", "279.16010", "280.16131", "281.16451", "281.16451", "272.15327", "273.15313", "274.15525", "275.15594", "276.15833", "277.15907", "278.16149", "279.16272", "280.16514", "281.16636", "282.16912", "283.17054", "282.16912", "276.16141", "277.16364", "278.16416", "279.16654", "280.16715", "281.16975", "282.17050", "283.17327", "284.17416", "285.17712", "285.17712", "278.17058", "279.17095", "280.17293", "281.17348", "282.17567", "283.17657", "284.17873", "285.17973", "286.18221", "287.18339", "286.18221", "285.18364", "286.18423", "287.18678", "288.18757", "289.19042", "289.19042", "287.19070", "288.19274", "289.19363", "290.19598", "291.19707", "289.19363", "289.19816", "290.19864", "291.20108", "292.20174", "293.20449", "293.20449", "291.20553", "292.20746", "293.20824", "294.21046", "294.21046"]}QCElemental-0.5.0/qcelemental/data/nist_2014_codata.py000066400000000000000000002212421351361252000223620ustar00rootroot00000000000000""" This is a automatically generated file from the 2014 NIST fundamental constants. Title: NIST-CODATA Internationally Recommended 2014 Values of the Fundamental Physical Constants - SRD 121 Date: 2014-01-01 DOI: 10.18434/T4WW24 URL: http://www.nist.gov/srd/srd_data/srd121_allascii_2014.json Access Date: 2018-09-26 22:11:02.928442 UTC File Authors: QCElemental Authors """ nist_2014_codata = { 'title': 'NIST-CODATA Internationally Recommended 2014 Values of the Fundamental Physical Constants - SRD 121', 'date': '2014-01-01', 'doi': '10.18434/T4WW24', 'url': 'http://www.nist.gov/srd/srd_data/srd121_allascii_2014.json', 'access_data': '2018-09-26 22:11:02.928442', 'constants': { '{220} lattice spacing of silicon': { 'quantity': '{220} lattice spacing of silicon', 'unit': 'm', 'value': '192.0155714e-12', 'uncertainty': '0.000 0032 e-12' }, 'alpha particle-electron mass ratio': { 'quantity': 'alpha particle-electron mass ratio', 'unit': '', 'value': '7294.29954136', 'uncertainty': '0.000 000 24' }, 'alpha particle mass': { 'quantity': 'alpha particle mass', 'unit': 'kg', 'value': '6.644657230e-27', 'uncertainty': '0.000 000 082 e-27' }, 'alpha particle mass energy equivalent': { 'quantity': 'alpha particle mass energy equivalent', 'unit': 'J', 'value': '5.971920097e-10', 'uncertainty': '0.000 000 073 e-10' }, 'alpha particle mass energy equivalent in mev': { 'quantity': 'alpha particle mass energy equivalent in MeV', 'unit': 'MeV', 'value': '3727.379378', 'uncertainty': '0.000 023' }, 'alpha particle mass in u': { 'quantity': 'alpha particle mass in u', 'unit': 'u', 'value': '4.001506179127', 'uncertainty': '0.000 000 000 063' }, 'alpha particle molar mass': { 'quantity': 'alpha particle molar mass', 'unit': 'kg mol^{-1}', 'value': '4.001506179127e-3', 'uncertainty': '0.000 000 000 063 e-3' }, 'alpha particle-proton mass ratio': { 'quantity': 'alpha particle-proton mass ratio', 'unit': '', 'value': '3.97259968907', 'uncertainty': '0.000 000 000 36' }, 'angstrom star': { 'quantity': 'Angstrom star', 'unit': 'm', 'value': '1.00001495e-10', 'uncertainty': '0.000 000 90 e-10' }, 'atomic mass constant': { 'quantity': 'atomic mass constant', 'unit': 'kg', 'value': '1.660539040e-27', 'uncertainty': '0.000 000 020 e-27' }, 'atomic mass constant energy equivalent': { 'quantity': 'atomic mass constant energy equivalent', 'unit': 'J', 'value': '1.492418062e-10', 'uncertainty': '0.000 000 018 e-10' }, 'atomic mass constant energy equivalent in mev': { 'quantity': 'atomic mass constant energy equivalent in MeV', 'unit': 'MeV', 'value': '931.4940954', 'uncertainty': '0.000 0057' }, 'atomic mass unit-electron volt relationship': { 'quantity': 'atomic mass unit-electron volt relationship', 'unit': 'eV', 'value': '931.4940954e6', 'uncertainty': '0.000 0057 e6' }, 'atomic mass unit-hartree relationship': { 'quantity': 'atomic mass unit-hartree relationship', 'unit': 'E_h', 'value': '3.4231776902e7', 'uncertainty': '0.000 000 0016 e7' }, 'atomic mass unit-hertz relationship': { 'quantity': 'atomic mass unit-hertz relationship', 'unit': 'Hz', 'value': '2.2523427206e23', 'uncertainty': '0.000 000 0010 e23' }, 'atomic mass unit-inverse meter relationship': { 'quantity': 'atomic mass unit-inverse meter relationship', 'unit': 'm^{-1}', 'value': '7.5130066166e14', 'uncertainty': '0.000 000 0034 e14' }, 'atomic mass unit-joule relationship': { 'quantity': 'atomic mass unit-joule relationship', 'unit': 'J', 'value': '1.492418062e-10', 'uncertainty': '0.000 000 018 e-10' }, 'atomic mass unit-kelvin relationship': { 'quantity': 'atomic mass unit-kelvin relationship', 'unit': 'K', 'value': '1.08095438e13', 'uncertainty': '0.000 000 62 e13' }, 'atomic mass unit-kilogram relationship': { 'quantity': 'atomic mass unit-kilogram relationship', 'unit': 'kg', 'value': '1.660539040e-27', 'uncertainty': '0.000 000 020 e-27' }, 'atomic unit of 1st hyperpolarizability': { 'quantity': 'atomic unit of 1st hyperpolarizability', 'unit': 'C^3 m^3 J^{-2}', 'value': '3.206361329e-53', 'uncertainty': '0.000 000 020 e-53' }, 'atomic unit of 2nd hyperpolarizability': { 'quantity': 'atomic unit of 2nd hyperpolarizability', 'unit': 'C^4 m^4 J^{-3}', 'value': '6.235380085e-65', 'uncertainty': '0.000 000 077 e-65' }, 'atomic unit of action': { 'quantity': 'atomic unit of action', 'unit': 'J s', 'value': '1.054571800e-34', 'uncertainty': '0.000 000 013 e-34' }, 'atomic unit of charge': { 'quantity': 'atomic unit of charge', 'unit': 'C', 'value': '1.6021766208e-19', 'uncertainty': '0.000 000 0098 e-19' }, 'atomic unit of charge density': { 'quantity': 'atomic unit of charge density', 'unit': 'C m^{-3}', 'value': '1.0812023770e12', 'uncertainty': '0.000 000 0067 e12' }, 'atomic unit of current': { 'quantity': 'atomic unit of current', 'unit': 'A', 'value': '6.623618183e-3', 'uncertainty': '0.000 000 041 e-3' }, 'atomic unit of electric dipole mom.': { 'quantity': 'atomic unit of electric dipole mom.', 'unit': 'C m', 'value': '8.478353552e-30', 'uncertainty': '0.000 000 052 e-30' }, 'atomic unit of electric field': { 'quantity': 'atomic unit of electric field', 'unit': 'V m^{-1}', 'value': '5.142206707e11', 'uncertainty': '0.000 000 032 e11' }, 'atomic unit of electric field gradient': { 'quantity': 'atomic unit of electric field gradient', 'unit': 'V m^{-2}', 'value': '9.717362356e21', 'uncertainty': '0.000 000 060 e21' }, 'atomic unit of electric polarizability': { 'quantity': 'atomic unit of electric polarizability', 'unit': 'C^2 m^2 J^{-1}', 'value': '1.6487772731e-41', 'uncertainty': '0.000 000 0011 e-41' }, 'atomic unit of electric potential': { 'quantity': 'atomic unit of electric potential', 'unit': 'V', 'value': '27.21138602', 'uncertainty': '0.000 000 17' }, 'atomic unit of electric quadrupole mom.': { 'quantity': 'atomic unit of electric quadrupole mom.', 'unit': 'C m^2', 'value': '4.486551484e-40', 'uncertainty': '0.000 000 028 e-40' }, 'atomic unit of energy': { 'quantity': 'atomic unit of energy', 'unit': 'J', 'value': '4.359744650e-18', 'uncertainty': '0.000 000 054 e-18' }, 'atomic unit of force': { 'quantity': 'atomic unit of force', 'unit': 'N', 'value': '8.23872336e-8', 'uncertainty': '0.000 000 10 e-8' }, 'atomic unit of length': { 'quantity': 'atomic unit of length', 'unit': 'm', 'value': '0.52917721067e-10', 'uncertainty': '0.000 000 000 12 e-10' }, 'atomic unit of mag. dipole mom.': { 'quantity': 'atomic unit of mag. dipole mom.', 'unit': 'J T^{-1}', 'value': '1.854801999e-23', 'uncertainty': '0.000 000 011 e-23' }, 'atomic unit of mag. flux density': { 'quantity': 'atomic unit of mag. flux density', 'unit': 'T', 'value': '2.350517550e5', 'uncertainty': '0.000 000 014 e5' }, 'atomic unit of magnetizability': { 'quantity': 'atomic unit of magnetizability', 'unit': 'J T^{-2}', 'value': '7.8910365886e-29', 'uncertainty': '0.000 000 0090 e-29' }, 'atomic unit of mass': { 'quantity': 'atomic unit of mass', 'unit': 'kg', 'value': '9.10938356e-31', 'uncertainty': '0.000 000 11 e-31' }, 'atomic unit of mom.um': { 'quantity': 'atomic unit of mom.um', 'unit': 'kg m s^{-1}', 'value': '1.992851882e-24', 'uncertainty': '0.000 000 024 e-24' }, 'atomic unit of permittivity': { 'quantity': 'atomic unit of permittivity', 'unit': 'F m^{-1}', 'value': '1.112650056e-10', 'uncertainty': '(exact)' }, 'atomic unit of time': { 'quantity': 'atomic unit of time', 'unit': 's', 'value': '2.418884326509e-17', 'uncertainty': '0.000 000 000 014 e-17' }, 'atomic unit of velocity': { 'quantity': 'atomic unit of velocity', 'unit': 'm s^{-1}', 'value': '2.18769126277e6', 'uncertainty': '0.000 000 000 50 e6' }, 'avogadro constant': { 'quantity': 'Avogadro constant', 'unit': 'mol^{-1}', 'value': '6.022140857e23', 'uncertainty': '0.000 000 074 e23' }, 'bohr magneton': { 'quantity': 'Bohr magneton', 'unit': 'J T^{-1}', 'value': '927.4009994e-26', 'uncertainty': '0.000 0057 e-26' }, 'bohr magneton in ev/t': { 'quantity': 'Bohr magneton in eV/T', 'unit': 'eV T^{-1}', 'value': '5.7883818012e-5', 'uncertainty': '0.000 000 0026 e-5' }, 'bohr magneton in hz/t': { 'quantity': 'Bohr magneton in Hz/T', 'unit': 'Hz T^{-1}', 'value': '13.996245042e9', 'uncertainty': '0.000 000 086 e9' }, 'bohr magneton in inverse meters per tesla': { 'quantity': 'Bohr magneton in inverse meters per tesla', 'unit': 'm^{-1} T^{-1}', 'value': '46.68644814', 'uncertainty': '0.000 000 29' }, 'bohr magneton in k/t': { 'quantity': 'Bohr magneton in K/T', 'unit': 'K T^{-1}', 'value': '0.67171405', 'uncertainty': '0.000 000 39' }, 'bohr radius': { 'quantity': 'Bohr radius', 'unit': 'm', 'value': '0.52917721067e-10', 'uncertainty': '0.000 000 000 12 e-10' }, 'boltzmann constant': { 'quantity': 'Boltzmann constant', 'unit': 'J K^{-1}', 'value': '1.38064852e-23', 'uncertainty': '0.000 000 79 e-23' }, 'boltzmann constant in ev/k': { 'quantity': 'Boltzmann constant in eV/K', 'unit': 'eV K^{-1}', 'value': '8.6173303e-5', 'uncertainty': '0.000 0050 e-5' }, 'boltzmann constant in hz/k': { 'quantity': 'Boltzmann constant in Hz/K', 'unit': 'Hz K^{-1}', 'value': '2.0836612e10', 'uncertainty': '0.000 0012 e10' }, 'boltzmann constant in inverse meters per kelvin': { 'quantity': 'Boltzmann constant in inverse meters per kelvin', 'unit': 'm^{-1} K^{-1}', 'value': '69.503457', 'uncertainty': '0.000 040' }, 'characteristic impedance of vacuum': { 'quantity': 'characteristic impedance of vacuum', 'unit': 'ohm', 'value': '376.730313461', 'uncertainty': '(exact)' }, 'classical electron radius': { 'quantity': 'classical electron radius', 'unit': 'm', 'value': '2.8179403227e-15', 'uncertainty': '0.000 000 0019 e-15' }, 'compton wavelength': { 'quantity': 'Compton wavelength', 'unit': 'm', 'value': '2.4263102367e-12', 'uncertainty': '0.000 000 0011 e-12' }, 'compton wavelength over 2 pi': { 'quantity': 'Compton wavelength over 2 pi', 'unit': 'm', 'value': '386.15926764e-15', 'uncertainty': '0.000 000 18 e-15' }, 'conductance quantum': { 'quantity': 'conductance quantum', 'unit': 'S', 'value': '7.7480917310e-5', 'uncertainty': '0.000 000 0018 e-5' }, 'conventional value of josephson constant': { 'quantity': 'conventional value of Josephson constant', 'unit': 'Hz V^{-1}', 'value': '483597.9e9', 'uncertainty': '(exact)' }, 'conventional value of von klitzing constant': { 'quantity': 'conventional value of von Klitzing constant', 'unit': 'ohm', 'value': '25812.807', 'uncertainty': '(exact)' }, 'cu x unit': { 'quantity': 'Cu x unit', 'unit': 'm', 'value': '1.00207697e-13', 'uncertainty': '0.000 000 28 e-13' }, 'deuteron-electron mag. mom. ratio': { 'quantity': 'deuteron-electron mag. mom. ratio', 'unit': '', 'value': '-4.664345535e-4', 'uncertainty': '0.000 000 026 e-4' }, 'deuteron-electron mass ratio': { 'quantity': 'deuteron-electron mass ratio', 'unit': '', 'value': '3670.48296785', 'uncertainty': '0.000 000 13' }, 'deuteron g factor': { 'quantity': 'deuteron g factor', 'unit': '', 'value': '0.8574382311', 'uncertainty': '0.000 000 0048' }, 'deuteron mag. mom.': { 'quantity': 'deuteron mag. mom.', 'unit': 'J T^{-1}', 'value': '0.4330735040e-26', 'uncertainty': '0.000 000 0036 e-26' }, 'deuteron mag. mom. to bohr magneton ratio': { 'quantity': 'deuteron mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '0.4669754554e-3', 'uncertainty': '0.000 000 0026 e-3' }, 'deuteron mag. mom. to nuclear magneton ratio': { 'quantity': 'deuteron mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '0.8574382311', 'uncertainty': '0.000 000 0048' }, 'deuteron mass': { 'quantity': 'deuteron mass', 'unit': 'kg', 'value': '3.343583719e-27', 'uncertainty': '0.000 000 041 e-27' }, 'deuteron mass energy equivalent': { 'quantity': 'deuteron mass energy equivalent', 'unit': 'J', 'value': '3.005063183e-10', 'uncertainty': '0.000 000 037 e-10' }, 'deuteron mass energy equivalent in mev': { 'quantity': 'deuteron mass energy equivalent in MeV', 'unit': 'MeV', 'value': '1875.612928', 'uncertainty': '0.000 012' }, 'deuteron mass in u': { 'quantity': 'deuteron mass in u', 'unit': 'u', 'value': '2.013553212745', 'uncertainty': '0.000 000 000 040' }, 'deuteron molar mass': { 'quantity': 'deuteron molar mass', 'unit': 'kg mol^{-1}', 'value': '2.013553212745e-3', 'uncertainty': '0.000 000 000 040 e-3' }, 'deuteron-neutron mag. mom. ratio': { 'quantity': 'deuteron-neutron mag. mom. ratio', 'unit': '', 'value': '-0.44820652', 'uncertainty': '0.000 000 11' }, 'deuteron-proton mag. mom. ratio': { 'quantity': 'deuteron-proton mag. mom. ratio', 'unit': '', 'value': '0.3070122077', 'uncertainty': '0.000 000 0015' }, 'deuteron-proton mass ratio': { 'quantity': 'deuteron-proton mass ratio', 'unit': '', 'value': '1.99900750087', 'uncertainty': '0.000 000 000 19' }, 'deuteron rms charge radius': { 'quantity': 'deuteron rms charge radius', 'unit': 'm', 'value': '2.1413e-15', 'uncertainty': '0.0025 e-15' }, 'electric constant': { 'quantity': 'electric constant', 'unit': 'F m^{-1}', 'value': '8.854187817e-12', 'uncertainty': '(exact)' }, 'electron charge to mass quotient': { 'quantity': 'electron charge to mass quotient', 'unit': 'C kg^{-1}', 'value': '-1.758820024e11', 'uncertainty': '0.000 000 011 e11' }, 'electron-deuteron mag. mom. ratio': { 'quantity': 'electron-deuteron mag. mom. ratio', 'unit': '', 'value': '-2143.923499', 'uncertainty': '0.000 012' }, 'electron-deuteron mass ratio': { 'quantity': 'electron-deuteron mass ratio', 'unit': '', 'value': '2.724437107484e-4', 'uncertainty': '0.000 000 000 096 e-4' }, 'electron g factor': { 'quantity': 'electron g factor', 'unit': '', 'value': '-2.00231930436182', 'uncertainty': '0.000 000 000 000 52' }, 'electron gyromag. ratio': { 'quantity': 'electron gyromag. ratio', 'unit': 's^{-1} T^{-1}', 'value': '1.760859644e11', 'uncertainty': '0.000 000 011 e11' }, 'electron gyromag. ratio over 2 pi': { 'quantity': 'electron gyromag. ratio over 2 pi', 'unit': 'MHz T^{-1}', 'value': '28024.95164', 'uncertainty': '0.000 17' }, 'electron-helion mass ratio': { 'quantity': 'electron-helion mass ratio', 'unit': '', 'value': '1.819543074854e-4', 'uncertainty': '0.000 000 000 088 e-4' }, 'electron mag. mom.': { 'quantity': 'electron mag. mom.', 'unit': 'J T^{-1}', 'value': '-928.4764620e-26', 'uncertainty': '0.000 0057 e-26' }, 'electron mag. mom. anomaly': { 'quantity': 'electron mag. mom. anomaly', 'unit': '', 'value': '1.15965218091e-3', 'uncertainty': '0.000 000 000 26 e-3' }, 'electron mag. mom. to bohr magneton ratio': { 'quantity': 'electron mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '-1.00115965218091', 'uncertainty': '0.000 000 000 000 26' }, 'electron mag. mom. to nuclear magneton ratio': { 'quantity': 'electron mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '-1838.28197234', 'uncertainty': '0.000 000 17' }, 'electron mass': { 'quantity': 'electron mass', 'unit': 'kg', 'value': '9.10938356e-31', 'uncertainty': '0.000 000 11 e-31' }, 'electron mass energy equivalent': { 'quantity': 'electron mass energy equivalent', 'unit': 'J', 'value': '8.18710565e-14', 'uncertainty': '0.000 000 10 e-14' }, 'electron mass energy equivalent in mev': { 'quantity': 'electron mass energy equivalent in MeV', 'unit': 'MeV', 'value': '0.5109989461', 'uncertainty': '0.000 000 0031' }, 'electron mass in u': { 'quantity': 'electron mass in u', 'unit': 'u', 'value': '5.48579909070e-4', 'uncertainty': '0.000 000 000 16 e-4' }, 'electron molar mass': { 'quantity': 'electron molar mass', 'unit': 'kg mol^{-1}', 'value': '5.48579909070e-7', 'uncertainty': '0.000 000 000 16 e-7' }, 'electron-muon mag. mom. ratio': { 'quantity': 'electron-muon mag. mom. ratio', 'unit': '', 'value': '206.7669880', 'uncertainty': '0.000 0046' }, 'electron-muon mass ratio': { 'quantity': 'electron-muon mass ratio', 'unit': '', 'value': '4.83633170e-3', 'uncertainty': '0.000 000 11 e-3' }, 'electron-neutron mag. mom. ratio': { 'quantity': 'electron-neutron mag. mom. ratio', 'unit': '', 'value': '960.92050', 'uncertainty': '0.000 23' }, 'electron-neutron mass ratio': { 'quantity': 'electron-neutron mass ratio', 'unit': '', 'value': '5.4386734428e-4', 'uncertainty': '0.000 000 0027 e-4' }, 'electron-proton mag. mom. ratio': { 'quantity': 'electron-proton mag. mom. ratio', 'unit': '', 'value': '-658.2106866', 'uncertainty': '0.000 0020' }, 'electron-proton mass ratio': { 'quantity': 'electron-proton mass ratio', 'unit': '', 'value': '5.44617021352e-4', 'uncertainty': '0.000 000 000 52 e-4' }, 'electron-tau mass ratio': { 'quantity': 'electron-tau mass ratio', 'unit': '', 'value': '2.87592e-4', 'uncertainty': '0.000 26 e-4' }, 'electron to alpha particle mass ratio': { 'quantity': 'electron to alpha particle mass ratio', 'unit': '', 'value': '1.370933554798e-4', 'uncertainty': '0.000 000 000 045 e-4' }, 'electron to shielded helion mag. mom. ratio': { 'quantity': 'electron to shielded helion mag. mom. ratio', 'unit': '', 'value': '864.058257', 'uncertainty': '0.000 010' }, 'electron to shielded proton mag. mom. ratio': { 'quantity': 'electron to shielded proton mag. mom. ratio', 'unit': '', 'value': '-658.2275971', 'uncertainty': '0.000 0072' }, 'electron-triton mass ratio': { 'quantity': 'electron-triton mass ratio', 'unit': '', 'value': '1.819200062203e-4', 'uncertainty': '0.000 000 000 084 e-4' }, 'electron volt': { 'quantity': 'electron volt', 'unit': 'J', 'value': '1.6021766208e-19', 'uncertainty': '0.000 000 0098 e-19' }, 'electron volt-atomic mass unit relationship': { 'quantity': 'electron volt-atomic mass unit relationship', 'unit': 'u', 'value': '1.0735441105e-9', 'uncertainty': '0.000 000 0066 e-9' }, 'electron volt-hartree relationship': { 'quantity': 'electron volt-hartree relationship', 'unit': 'E_h', 'value': '3.674932248e-2', 'uncertainty': '0.000 000 023 e-2' }, 'electron volt-hertz relationship': { 'quantity': 'electron volt-hertz relationship', 'unit': 'Hz', 'value': '2.417989262e14', 'uncertainty': '0.000 000 015 e14' }, 'electron volt-inverse meter relationship': { 'quantity': 'electron volt-inverse meter relationship', 'unit': 'm^{-1}', 'value': '8.065544005e5', 'uncertainty': '0.000 000 050 e5' }, 'electron volt-joule relationship': { 'quantity': 'electron volt-joule relationship', 'unit': 'J', 'value': '1.6021766208e-19', 'uncertainty': '0.000 000 0098 e-19' }, 'electron volt-kelvin relationship': { 'quantity': 'electron volt-kelvin relationship', 'unit': 'K', 'value': '1.16045221e4', 'uncertainty': '0.000 000 67 e4' }, 'electron volt-kilogram relationship': { 'quantity': 'electron volt-kilogram relationship', 'unit': 'kg', 'value': '1.782661907e-36', 'uncertainty': '0.000 000 011 e-36' }, 'elementary charge': { 'quantity': 'elementary charge', 'unit': 'C', 'value': '1.6021766208e-19', 'uncertainty': '0.000 000 0098 e-19' }, 'elementary charge over h': { 'quantity': 'elementary charge over h', 'unit': 'A J^{-1}', 'value': '2.417989262e14', 'uncertainty': '0.000 000 015 e14' }, 'faraday constant': { 'quantity': 'Faraday constant', 'unit': 'C mol^{-1}', 'value': '96485.33289', 'uncertainty': '0.000 59' }, 'faraday constant for conventional electric current': { 'quantity': 'Faraday constant for conventional electric current', 'unit': 'C_{90} mol^{-1}', 'value': '96485.3251', 'uncertainty': '0.0012' }, 'fermi coupling constant': { 'quantity': 'Fermi coupling constant', 'unit': 'GeV^{-2}', 'value': '1.1663787e-5', 'uncertainty': '0.000 0006 e-5' }, 'fine-structure constant': { 'quantity': 'fine-structure constant', 'unit': '', 'value': '7.2973525664e-3', 'uncertainty': '0.000 000 0017 e-3' }, 'first radiation constant': { 'quantity': 'first radiation constant', 'unit': 'W m^2', 'value': '3.741771790e-16', 'uncertainty': '0.000 000 046 e-16' }, 'first radiation constant for spectral radiance': { 'quantity': 'first radiation constant for spectral radiance', 'unit': 'W m^2 sr^{-1}', 'value': '1.191042953e-16', 'uncertainty': '0.000 000 015 e-16' }, 'hartree-atomic mass unit relationship': { 'quantity': 'hartree-atomic mass unit relationship', 'unit': 'u', 'value': '2.9212623197e-8', 'uncertainty': '0.000 000 0013 e-8' }, 'hartree-electron volt relationship': { 'quantity': 'hartree-electron volt relationship', 'unit': 'eV', 'value': '27.21138602', 'uncertainty': '0.000 000 17' }, 'hartree energy': { 'quantity': 'Hartree energy', 'unit': 'J', 'value': '4.359744650e-18', 'uncertainty': '0.000 000 054 e-18' }, 'hartree energy in ev': { 'quantity': 'Hartree energy in eV', 'unit': 'eV', 'value': '27.21138602', 'uncertainty': '0.000 000 17' }, 'hartree-hertz relationship': { 'quantity': 'hartree-hertz relationship', 'unit': 'Hz', 'value': '6.579683920711e15', 'uncertainty': '0.000 000 000 039 e15' }, 'hartree-inverse meter relationship': { 'quantity': 'hartree-inverse meter relationship', 'unit': 'm^{-1}', 'value': '2.194746313702e7', 'uncertainty': '0.000 000 000 013 e7' }, 'hartree-joule relationship': { 'quantity': 'hartree-joule relationship', 'unit': 'J', 'value': '4.359744650e-18', 'uncertainty': '0.000 000 054 e-18' }, 'hartree-kelvin relationship': { 'quantity': 'hartree-kelvin relationship', 'unit': 'K', 'value': '3.1577513e5', 'uncertainty': '0.000 0018 e5' }, 'hartree-kilogram relationship': { 'quantity': 'hartree-kilogram relationship', 'unit': 'kg', 'value': '4.850870129e-35', 'uncertainty': '0.000 000 060 e-35' }, 'helion-electron mass ratio': { 'quantity': 'helion-electron mass ratio', 'unit': '', 'value': '5495.88527922', 'uncertainty': '0.000 000 27' }, 'helion g factor': { 'quantity': 'helion g factor', 'unit': '', 'value': '-4.255250616', 'uncertainty': '0.000 000 050' }, 'helion mag. mom.': { 'quantity': 'helion mag. mom.', 'unit': 'J T^{-1}', 'value': '-1.074617522e-26', 'uncertainty': '0.000 000 014 e-26' }, 'helion mag. mom. to bohr magneton ratio': { 'quantity': 'helion mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '-1.158740958e-3', 'uncertainty': '0.000 000 014 e-3' }, 'helion mag. mom. to nuclear magneton ratio': { 'quantity': 'helion mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '-2.127625308', 'uncertainty': '0.000 000 025' }, 'helion mass': { 'quantity': 'helion mass', 'unit': 'kg', 'value': '5.006412700e-27', 'uncertainty': '0.000 000 062 e-27' }, 'helion mass energy equivalent': { 'quantity': 'helion mass energy equivalent', 'unit': 'J', 'value': '4.499539341e-10', 'uncertainty': '0.000 000 055 e-10' }, 'helion mass energy equivalent in mev': { 'quantity': 'helion mass energy equivalent in MeV', 'unit': 'MeV', 'value': '2808.391586', 'uncertainty': '0.000 017' }, 'helion mass in u': { 'quantity': 'helion mass in u', 'unit': 'u', 'value': '3.01493224673', 'uncertainty': '0.000 000 000 12' }, 'helion molar mass': { 'quantity': 'helion molar mass', 'unit': 'kg mol^{-1}', 'value': '3.01493224673e-3', 'uncertainty': '0.000 000 000 12 e-3' }, 'helion-proton mass ratio': { 'quantity': 'helion-proton mass ratio', 'unit': '', 'value': '2.99315267046', 'uncertainty': '0.000 000 000 29' }, 'hertz-atomic mass unit relationship': { 'quantity': 'hertz-atomic mass unit relationship', 'unit': 'u', 'value': '4.4398216616e-24', 'uncertainty': '0.000 000 0020 e-24' }, 'hertz-electron volt relationship': { 'quantity': 'hertz-electron volt relationship', 'unit': 'eV', 'value': '4.135667662e-15', 'uncertainty': '0.000 000 025 e-15' }, 'hertz-hartree relationship': { 'quantity': 'hertz-hartree relationship', 'unit': 'E_h', 'value': '1.5198298460088e-16', 'uncertainty': '0.000 000 000 0090 e-16' }, 'hertz-inverse meter relationship': { 'quantity': 'hertz-inverse meter relationship', 'unit': 'm^{-1}', 'value': '3.335640951e-9', 'uncertainty': '(exact)' }, 'hertz-joule relationship': { 'quantity': 'hertz-joule relationship', 'unit': 'J', 'value': '6.626070040e-34', 'uncertainty': '0.000 000 081 e-34' }, 'hertz-kelvin relationship': { 'quantity': 'hertz-kelvin relationship', 'unit': 'K', 'value': '4.7992447e-11', 'uncertainty': '0.000 0028 e-11' }, 'hertz-kilogram relationship': { 'quantity': 'hertz-kilogram relationship', 'unit': 'kg', 'value': '7.372497201e-51', 'uncertainty': '0.000 000 091 e-51' }, 'inverse fine-structure constant': { 'quantity': 'inverse fine-structure constant', 'unit': '', 'value': '137.035999139', 'uncertainty': '0.000 000 031' }, 'inverse meter-atomic mass unit relationship': { 'quantity': 'inverse meter-atomic mass unit relationship', 'unit': 'u', 'value': '1.33102504900e-15', 'uncertainty': '0.000 000 000 61 e-15' }, 'inverse meter-electron volt relationship': { 'quantity': 'inverse meter-electron volt relationship', 'unit': 'eV', 'value': '1.2398419739e-6', 'uncertainty': '0.000 000 0076 e-6' }, 'inverse meter-hartree relationship': { 'quantity': 'inverse meter-hartree relationship', 'unit': 'E_h', 'value': '4.556335252767e-8', 'uncertainty': '0.000 000 000 027 e-8' }, 'inverse meter-hertz relationship': { 'quantity': 'inverse meter-hertz relationship', 'unit': 'Hz', 'value': '299792458', 'uncertainty': '(exact)' }, 'inverse meter-joule relationship': { 'quantity': 'inverse meter-joule relationship', 'unit': 'J', 'value': '1.986445824e-25', 'uncertainty': '0.000 000 024 e-25' }, 'inverse meter-kelvin relationship': { 'quantity': 'inverse meter-kelvin relationship', 'unit': 'K', 'value': '1.43877736e-2', 'uncertainty': '0.000 000 83 e-2' }, 'inverse meter-kilogram relationship': { 'quantity': 'inverse meter-kilogram relationship', 'unit': 'kg', 'value': '2.210219057e-42', 'uncertainty': '0.000 000 027 e-42' }, 'inverse of conductance quantum': { 'quantity': 'inverse of conductance quantum', 'unit': 'ohm', 'value': '12906.4037278', 'uncertainty': '0.000 0029' }, 'josephson constant': { 'quantity': 'Josephson constant', 'unit': 'Hz V^{-1}', 'value': '483597.8525e9', 'uncertainty': '0.0030 e9' }, 'joule-atomic mass unit relationship': { 'quantity': 'joule-atomic mass unit relationship', 'unit': 'u', 'value': '6.700535363e9', 'uncertainty': '0.000 000 082 e9' }, 'joule-electron volt relationship': { 'quantity': 'joule-electron volt relationship', 'unit': 'eV', 'value': '6.241509126e18', 'uncertainty': '0.000 000 038 e18' }, 'joule-hartree relationship': { 'quantity': 'joule-hartree relationship', 'unit': 'E_h', 'value': '2.293712317e17', 'uncertainty': '0.000 000 028 e17' }, 'joule-hertz relationship': { 'quantity': 'joule-hertz relationship', 'unit': 'Hz', 'value': '1.509190205e33', 'uncertainty': '0.000 000 019 e33' }, 'joule-inverse meter relationship': { 'quantity': 'joule-inverse meter relationship', 'unit': 'm^{-1}', 'value': '5.034116651e24', 'uncertainty': '0.000 000 062 e24' }, 'joule-kelvin relationship': { 'quantity': 'joule-kelvin relationship', 'unit': 'K', 'value': '7.2429731e22', 'uncertainty': '0.000 0042 e22' }, 'joule-kilogram relationship': { 'quantity': 'joule-kilogram relationship', 'unit': 'kg', 'value': '1.112650056e-17', 'uncertainty': '(exact)' }, 'kelvin-atomic mass unit relationship': { 'quantity': 'kelvin-atomic mass unit relationship', 'unit': 'u', 'value': '9.2510842e-14', 'uncertainty': '0.000 0053 e-14' }, 'kelvin-electron volt relationship': { 'quantity': 'kelvin-electron volt relationship', 'unit': 'eV', 'value': '8.6173303e-5', 'uncertainty': '0.000 0050 e-5' }, 'kelvin-hartree relationship': { 'quantity': 'kelvin-hartree relationship', 'unit': 'E_h', 'value': '3.1668105e-6', 'uncertainty': '0.000 0018 e-6' }, 'kelvin-hertz relationship': { 'quantity': 'kelvin-hertz relationship', 'unit': 'Hz', 'value': '2.0836612e10', 'uncertainty': '0.000 0012 e10' }, 'kelvin-inverse meter relationship': { 'quantity': 'kelvin-inverse meter relationship', 'unit': 'm^{-1}', 'value': '69.503457', 'uncertainty': '0.000 040' }, 'kelvin-joule relationship': { 'quantity': 'kelvin-joule relationship', 'unit': 'J', 'value': '1.38064852e-23', 'uncertainty': '0.000 000 79 e-23' }, 'kelvin-kilogram relationship': { 'quantity': 'kelvin-kilogram relationship', 'unit': 'kg', 'value': '1.53617865e-40', 'uncertainty': '0.000 000 88 e-40' }, 'kilogram-atomic mass unit relationship': { 'quantity': 'kilogram-atomic mass unit relationship', 'unit': 'u', 'value': '6.022140857e26', 'uncertainty': '0.000 000 074 e26' }, 'kilogram-electron volt relationship': { 'quantity': 'kilogram-electron volt relationship', 'unit': 'eV', 'value': '5.609588650e35', 'uncertainty': '0.000 000 034 e35' }, 'kilogram-hartree relationship': { 'quantity': 'kilogram-hartree relationship', 'unit': 'E_h', 'value': '2.061485823e34', 'uncertainty': '0.000 000 025 e34' }, 'kilogram-hertz relationship': { 'quantity': 'kilogram-hertz relationship', 'unit': 'Hz', 'value': '1.356392512e50', 'uncertainty': '0.000 000 017 e50' }, 'kilogram-inverse meter relationship': { 'quantity': 'kilogram-inverse meter relationship', 'unit': 'm^{-1}', 'value': '4.524438411e41', 'uncertainty': '0.000 000 056 e41' }, 'kilogram-joule relationship': { 'quantity': 'kilogram-joule relationship', 'unit': 'J', 'value': '8.987551787e16', 'uncertainty': '(exact)' }, 'kilogram-kelvin relationship': { 'quantity': 'kilogram-kelvin relationship', 'unit': 'K', 'value': '6.5096595e39', 'uncertainty': '0.000 0037 e39' }, 'lattice parameter of silicon': { 'quantity': 'lattice parameter of silicon', 'unit': 'm', 'value': '543.1020504e-12', 'uncertainty': '0.000 0089 e-12' }, 'loschmidt constant (273.15 k, 100 kpa)': { 'quantity': 'Loschmidt constant (273.15 K, 100 kPa)', 'unit': 'm^{-3}', 'value': '2.6516467e25', 'uncertainty': '0.000 0015 e25' }, 'loschmidt constant (273.15 k, 101.325 kpa)': { 'quantity': 'Loschmidt constant (273.15 K, 101.325 kPa)', 'unit': 'm^{-3}', 'value': '2.6867811e25', 'uncertainty': '0.000 0015 e25' }, 'mag. constant': { 'quantity': 'mag. constant', 'unit': 'N A^{-2}', 'value': '12.566370614e-7', 'uncertainty': '(exact)' }, 'mag. flux quantum': { 'quantity': 'mag. flux quantum', 'unit': 'Wb', 'value': '2.067833831e-15', 'uncertainty': '0.000 000 013 e-15' }, 'molar gas constant': { 'quantity': 'molar gas constant', 'unit': 'J mol^{-1} K^{-1}', 'value': '8.3144598', 'uncertainty': '0.000 0048' }, 'molar mass constant': { 'quantity': 'molar mass constant', 'unit': 'kg mol^{-1}', 'value': '1e-3', 'uncertainty': '(exact)' }, 'molar mass of carbon-12': { 'quantity': 'molar mass of carbon-12', 'unit': 'kg mol^{-1}', 'value': '12e-3', 'uncertainty': '(exact)' }, 'molar planck constant': { 'quantity': 'molar Planck constant', 'unit': 'J s mol^{-1}', 'value': '3.9903127110e-10', 'uncertainty': '0.000 000 0018 e-10' }, 'molar planck constant times c': { 'quantity': 'molar Planck constant times c', 'unit': 'J m mol^{-1}', 'value': '0.119626565582', 'uncertainty': '0.000 000 000 054' }, 'molar volume of ideal gas (273.15 k, 100 kpa)': { 'quantity': 'molar volume of ideal gas (273.15 K, 100 kPa)', 'unit': 'm^3 mol^{-1}', 'value': '22.710947e-3', 'uncertainty': '0.000 013 e-3' }, 'molar volume of ideal gas (273.15 k, 101.325 kpa)': { 'quantity': 'molar volume of ideal gas (273.15 K, 101.325 kPa)', 'unit': 'm^3 mol^{-1}', 'value': '22.413962e-3', 'uncertainty': '0.000 013 e-3' }, 'molar volume of silicon': { 'quantity': 'molar volume of silicon', 'unit': 'm^3 mol^{-1}', 'value': '12.05883214e-6', 'uncertainty': '0.000 000 61 e-6' }, 'mo x unit': { 'quantity': 'Mo x unit', 'unit': 'm', 'value': '1.00209952e-13', 'uncertainty': '0.000 000 53 e-13' }, 'muon compton wavelength': { 'quantity': 'muon Compton wavelength', 'unit': 'm', 'value': '11.73444111e-15', 'uncertainty': '0.000 000 26 e-15' }, 'muon compton wavelength over 2 pi': { 'quantity': 'muon Compton wavelength over 2 pi', 'unit': 'm', 'value': '1.867594308e-15', 'uncertainty': '0.000 000 042 e-15' }, 'muon-electron mass ratio': { 'quantity': 'muon-electron mass ratio', 'unit': '', 'value': '206.7682826', 'uncertainty': '0.000 0046' }, 'muon g factor': { 'quantity': 'muon g factor', 'unit': '', 'value': '-2.0023318418', 'uncertainty': '0.000 000 0013' }, 'muon mag. mom.': { 'quantity': 'muon mag. mom.', 'unit': 'J T^{-1}', 'value': '-4.49044826e-26', 'uncertainty': '0.000 000 10 e-26' }, 'muon mag. mom. anomaly': { 'quantity': 'muon mag. mom. anomaly', 'unit': '', 'value': '1.16592089e-3', 'uncertainty': '0.000 000 63 e-3' }, 'muon mag. mom. to bohr magneton ratio': { 'quantity': 'muon mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '-4.84197048e-3', 'uncertainty': '0.000 000 11 e-3' }, 'muon mag. mom. to nuclear magneton ratio': { 'quantity': 'muon mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '-8.89059705', 'uncertainty': '0.000 000 20' }, 'muon mass': { 'quantity': 'muon mass', 'unit': 'kg', 'value': '1.883531594e-28', 'uncertainty': '0.000 000 048 e-28' }, 'muon mass energy equivalent': { 'quantity': 'muon mass energy equivalent', 'unit': 'J', 'value': '1.692833774e-11', 'uncertainty': '0.000 000 043 e-11' }, 'muon mass energy equivalent in mev': { 'quantity': 'muon mass energy equivalent in MeV', 'unit': 'MeV', 'value': '105.6583745', 'uncertainty': '0.000 0024' }, 'muon mass in u': { 'quantity': 'muon mass in u', 'unit': 'u', 'value': '0.1134289257', 'uncertainty': '0.000 000 0025' }, 'muon molar mass': { 'quantity': 'muon molar mass', 'unit': 'kg mol^{-1}', 'value': '0.1134289257e-3', 'uncertainty': '0.000 000 0025 e-3' }, 'muon-neutron mass ratio': { 'quantity': 'muon-neutron mass ratio', 'unit': '', 'value': '0.1124545167', 'uncertainty': '0.000 000 0025' }, 'muon-proton mag. mom. ratio': { 'quantity': 'muon-proton mag. mom. ratio', 'unit': '', 'value': '-3.183345142', 'uncertainty': '0.000 000 071' }, 'muon-proton mass ratio': { 'quantity': 'muon-proton mass ratio', 'unit': '', 'value': '0.1126095262', 'uncertainty': '0.000 000 0025' }, 'muon-tau mass ratio': { 'quantity': 'muon-tau mass ratio', 'unit': '', 'value': '5.94649e-2', 'uncertainty': '0.000 54 e-2' }, 'natural unit of action': { 'quantity': 'natural unit of action', 'unit': 'J s', 'value': '1.054571800e-34', 'uncertainty': '0.000 000 013 e-34' }, 'natural unit of action in ev s': { 'quantity': 'natural unit of action in eV s', 'unit': 'eV s', 'value': '6.582119514e-16', 'uncertainty': '0.000 000 040 e-16' }, 'natural unit of energy': { 'quantity': 'natural unit of energy', 'unit': 'J', 'value': '8.18710565e-14', 'uncertainty': '0.000 000 10 e-14' }, 'natural unit of energy in mev': { 'quantity': 'natural unit of energy in MeV', 'unit': 'MeV', 'value': '0.5109989461', 'uncertainty': '0.000 000 0031' }, 'natural unit of length': { 'quantity': 'natural unit of length', 'unit': 'm', 'value': '386.15926764e-15', 'uncertainty': '0.000 000 18 e-15' }, 'natural unit of mass': { 'quantity': 'natural unit of mass', 'unit': 'kg', 'value': '9.10938356e-31', 'uncertainty': '0.000 000 11 e-31' }, 'natural unit of mom.um': { 'quantity': 'natural unit of mom.um', 'unit': 'kg m s^{-1}', 'value': '2.730924488e-22', 'uncertainty': '0.000 000 034 e-22' }, 'natural unit of mom.um in mev/c': { 'quantity': 'natural unit of mom.um in MeV/c', 'unit': 'MeV/c', 'value': '0.5109989461', 'uncertainty': '0.000 000 0031' }, 'natural unit of time': { 'quantity': 'natural unit of time', 'unit': 's', 'value': '1.28808866712e-21', 'uncertainty': '0.000 000 000 58 e-21' }, 'natural unit of velocity': { 'quantity': 'natural unit of velocity', 'unit': 'm s^{-1}', 'value': '299792458', 'uncertainty': '(exact)' }, 'neutron compton wavelength': { 'quantity': 'neutron Compton wavelength', 'unit': 'm', 'value': '1.31959090481e-15', 'uncertainty': '0.000 000 000 88 e-15' }, 'neutron compton wavelength over 2 pi': { 'quantity': 'neutron Compton wavelength over 2 pi', 'unit': 'm', 'value': '0.21001941536e-15', 'uncertainty': '0.000 000 000 14 e-15' }, 'neutron-electron mag. mom. ratio': { 'quantity': 'neutron-electron mag. mom. ratio', 'unit': '', 'value': '1.04066882e-3', 'uncertainty': '0.000 000 25 e-3' }, 'neutron-electron mass ratio': { 'quantity': 'neutron-electron mass ratio', 'unit': '', 'value': '1838.68366158', 'uncertainty': '0.000 000 90' }, 'neutron g factor': { 'quantity': 'neutron g factor', 'unit': '', 'value': '-3.82608545', 'uncertainty': '0.000 000 90' }, 'neutron gyromag. ratio': { 'quantity': 'neutron gyromag. ratio', 'unit': 's^{-1} T^{-1}', 'value': '1.83247172e8', 'uncertainty': '0.000 000 43 e8' }, 'neutron gyromag. ratio over 2 pi': { 'quantity': 'neutron gyromag. ratio over 2 pi', 'unit': 'MHz T^{-1}', 'value': '29.1646933', 'uncertainty': '0.000 0069' }, 'neutron mag. mom.': { 'quantity': 'neutron mag. mom.', 'unit': 'J T^{-1}', 'value': '-0.96623650e-26', 'uncertainty': '0.000 000 23 e-26' }, 'neutron mag. mom. to bohr magneton ratio': { 'quantity': 'neutron mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '-1.04187563e-3', 'uncertainty': '0.000 000 25 e-3' }, 'neutron mag. mom. to nuclear magneton ratio': { 'quantity': 'neutron mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '-1.91304273', 'uncertainty': '0.000 000 45' }, 'neutron mass': { 'quantity': 'neutron mass', 'unit': 'kg', 'value': '1.674927471e-27', 'uncertainty': '0.000 000 021 e-27' }, 'neutron mass energy equivalent': { 'quantity': 'neutron mass energy equivalent', 'unit': 'J', 'value': '1.505349739e-10', 'uncertainty': '0.000 000 019 e-10' }, 'neutron mass energy equivalent in mev': { 'quantity': 'neutron mass energy equivalent in MeV', 'unit': 'MeV', 'value': '939.5654133', 'uncertainty': '0.000 0058' }, 'neutron mass in u': { 'quantity': 'neutron mass in u', 'unit': 'u', 'value': '1.00866491588', 'uncertainty': '0.000 000 000 49' }, 'neutron molar mass': { 'quantity': 'neutron molar mass', 'unit': 'kg mol^{-1}', 'value': '1.00866491588e-3', 'uncertainty': '0.000 000 000 49 e-3' }, 'neutron-muon mass ratio': { 'quantity': 'neutron-muon mass ratio', 'unit': '', 'value': '8.89248408', 'uncertainty': '0.000 000 20' }, 'neutron-proton mag. mom. ratio': { 'quantity': 'neutron-proton mag. mom. ratio', 'unit': '', 'value': '-0.68497934', 'uncertainty': '0.000 000 16' }, 'neutron-proton mass difference': { 'quantity': 'neutron-proton mass difference', 'unit': '', 'value': '2.30557377e-30', 'uncertainty': '0.000 000 85 e-30' }, 'neutron-proton mass difference energy equivalent': { 'quantity': 'neutron-proton mass difference energy equivalent', 'unit': '', 'value': '2.07214637e-13', 'uncertainty': '0.000 000 76 e-13' }, 'neutron-proton mass difference energy equivalent in mev': { 'quantity': 'neutron-proton mass difference energy equivalent in MeV', 'unit': '', 'value': '1.29333205', 'uncertainty': '0.000 000 48' }, 'neutron-proton mass difference in u': { 'quantity': 'neutron-proton mass difference in u', 'unit': '', 'value': '0.00138844900', 'uncertainty': '0.000 000 000 51' }, 'neutron-proton mass ratio': { 'quantity': 'neutron-proton mass ratio', 'unit': '', 'value': '1.00137841898', 'uncertainty': '0.000 000 000 51' }, 'neutron-tau mass ratio': { 'quantity': 'neutron-tau mass ratio', 'unit': '', 'value': '0.528790', 'uncertainty': '0.000 048' }, 'neutron to shielded proton mag. mom. ratio': { 'quantity': 'neutron to shielded proton mag. mom. ratio', 'unit': '', 'value': '-0.68499694', 'uncertainty': '0.000 000 16' }, 'newtonian constant of gravitation': { 'quantity': 'Newtonian constant of gravitation', 'unit': 'm^3 kg^{-1} s^{-2}', 'value': '6.67408e-11', 'uncertainty': '0.000 31 e-11' }, 'newtonian constant of gravitation over h-bar c': { 'quantity': 'Newtonian constant of gravitation over h-bar c', 'unit': '(GeV/c^2)^-2', 'value': '6.70861e-39', 'uncertainty': '0.000 31 e-39' }, 'nuclear magneton': { 'quantity': 'nuclear magneton', 'unit': 'J T^{-1}', 'value': '5.050783699e-27', 'uncertainty': '0.000 000 031 e-27' }, 'nuclear magneton in ev/t': { 'quantity': 'nuclear magneton in eV/T', 'unit': 'eV T^{-1}', 'value': '3.1524512550e-8', 'uncertainty': '0.000 000 0015 e-8' }, 'nuclear magneton in inverse meters per tesla': { 'quantity': 'nuclear magneton in inverse meters per tesla', 'unit': 'm^{-1} T^{-1}', 'value': '2.542623432e-2', 'uncertainty': '0.000 000 016 e-2' }, 'nuclear magneton in k/t': { 'quantity': 'nuclear magneton in K/T', 'unit': 'K T^{-1}', 'value': '3.6582690e-4', 'uncertainty': '0.000 0021 e-4' }, 'nuclear magneton in mhz/t': { 'quantity': 'nuclear magneton in MHz/T', 'unit': 'MHz T^{-1}', 'value': '7.622593285', 'uncertainty': '0.000 000 047' }, 'planck constant': { 'quantity': 'Planck constant', 'unit': 'J s', 'value': '6.626070040e-34', 'uncertainty': '0.000 000 081 e-34' }, 'planck constant in ev s': { 'quantity': 'Planck constant in eV s', 'unit': 'eV s', 'value': '4.135667662e-15', 'uncertainty': '0.000 000 025 e-15' }, 'planck constant over 2 pi': { 'quantity': 'Planck constant over 2 pi', 'unit': 'J s', 'value': '1.054571800e-34', 'uncertainty': '0.000 000 013 e-34' }, 'planck constant over 2 pi in ev s': { 'quantity': 'Planck constant over 2 pi in eV s', 'unit': 'eV s', 'value': '6.582119514e-16', 'uncertainty': '0.000 000 040 e-16' }, 'planck constant over 2 pi times c in mev fm': { 'quantity': 'Planck constant over 2 pi times c in MeV fm', 'unit': 'MeV fm', 'value': '197.3269788', 'uncertainty': '0.000 0012' }, 'planck length': { 'quantity': 'Planck length', 'unit': 'm', 'value': '1.616229e-35', 'uncertainty': '0.000 038 e-35' }, 'planck mass': { 'quantity': 'Planck mass', 'unit': 'kg', 'value': '2.176470e-8', 'uncertainty': '0.000 051 e-8' }, 'planck mass energy equivalent in gev': { 'quantity': 'Planck mass energy equivalent in GeV', 'unit': 'GeV', 'value': '1.220910e19', 'uncertainty': '0.000 029 e19' }, 'planck temperature': { 'quantity': 'Planck temperature', 'unit': 'K', 'value': '1.416808e32', 'uncertainty': '0.000 033 e32' }, 'planck time': { 'quantity': 'Planck time', 'unit': 's', 'value': '5.39116e-44', 'uncertainty': '0.000 13 e-44' }, 'proton charge to mass quotient': { 'quantity': 'proton charge to mass quotient', 'unit': 'C kg^{-1}', 'value': '9.578833226e7', 'uncertainty': '0.000 000 059 e7' }, 'proton compton wavelength': { 'quantity': 'proton Compton wavelength', 'unit': 'm', 'value': '1.32140985396e-15', 'uncertainty': '0.000 000 000 61 e-15' }, 'proton compton wavelength over 2 pi': { 'quantity': 'proton Compton wavelength over 2 pi', 'unit': 'm', 'value': '0.210308910109e-15', 'uncertainty': '0.000 000 000 097 e-15' }, 'proton-electron mass ratio': { 'quantity': 'proton-electron mass ratio', 'unit': '', 'value': '1836.15267389', 'uncertainty': '0.000 000 17' }, 'proton g factor': { 'quantity': 'proton g factor', 'unit': '', 'value': '5.585694702', 'uncertainty': '0.000 000 017' }, 'proton gyromag. ratio': { 'quantity': 'proton gyromag. ratio', 'unit': 's^{-1} T^{-1}', 'value': '2.675221900e8', 'uncertainty': '0.000 000 018 e8' }, 'proton gyromag. ratio over 2 pi': { 'quantity': 'proton gyromag. ratio over 2 pi', 'unit': 'MHz T^{-1}', 'value': '42.57747892', 'uncertainty': '0.000 000 29' }, 'proton mag. mom.': { 'quantity': 'proton mag. mom.', 'unit': 'J T^{-1}', 'value': '1.4106067873e-26', 'uncertainty': '0.000 000 0097 e-26' }, 'proton mag. mom. to bohr magneton ratio': { 'quantity': 'proton mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '1.5210322053e-3', 'uncertainty': '0.000 000 0046 e-3' }, 'proton mag. mom. to nuclear magneton ratio': { 'quantity': 'proton mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '2.7928473508', 'uncertainty': '0.000 000 0085' }, 'proton mag. shielding correction': { 'quantity': 'proton mag. shielding correction', 'unit': '', 'value': '25.691e-6', 'uncertainty': '0.011 e-6' }, 'proton mass': { 'quantity': 'proton mass', 'unit': 'kg', 'value': '1.672621898e-27', 'uncertainty': '0.000 000 021 e-27' }, 'proton mass energy equivalent': { 'quantity': 'proton mass energy equivalent', 'unit': 'J', 'value': '1.503277593e-10', 'uncertainty': '0.000 000 018 e-10' }, 'proton mass energy equivalent in mev': { 'quantity': 'proton mass energy equivalent in MeV', 'unit': 'MeV', 'value': '938.2720813', 'uncertainty': '0.000 0058' }, 'proton mass in u': { 'quantity': 'proton mass in u', 'unit': 'u', 'value': '1.007276466879', 'uncertainty': '0.000 000 000 091' }, 'proton molar mass': { 'quantity': 'proton molar mass', 'unit': 'kg mol^{-1}', 'value': '1.007276466879e-3', 'uncertainty': '0.000 000 000 091 e-3' }, 'proton-muon mass ratio': { 'quantity': 'proton-muon mass ratio', 'unit': '', 'value': '8.88024338', 'uncertainty': '0.000 000 20' }, 'proton-neutron mag. mom. ratio': { 'quantity': 'proton-neutron mag. mom. ratio', 'unit': '', 'value': '-1.45989805', 'uncertainty': '0.000 000 34' }, 'proton-neutron mass ratio': { 'quantity': 'proton-neutron mass ratio', 'unit': '', 'value': '0.99862347844', 'uncertainty': '0.000 000 000 51' }, 'proton rms charge radius': { 'quantity': 'proton rms charge radius', 'unit': 'm', 'value': '0.8751e-15', 'uncertainty': '0.0061 e-15' }, 'proton-tau mass ratio': { 'quantity': 'proton-tau mass ratio', 'unit': '', 'value': '0.528063', 'uncertainty': '0.000 048' }, 'quantum of circulation': { 'quantity': 'quantum of circulation', 'unit': 'm^2 s^{-1}', 'value': '3.6369475486e-4', 'uncertainty': '0.000 000 0017 e-4' }, 'quantum of circulation times 2': { 'quantity': 'quantum of circulation times 2', 'unit': 'm^2 s^{-1}', 'value': '7.2738950972e-4', 'uncertainty': '0.000 000 0033 e-4' }, 'rydberg constant': { 'quantity': 'Rydberg constant', 'unit': 'm^{-1}', 'value': '10973731.568508', 'uncertainty': '0.000 065' }, 'rydberg constant times c in hz': { 'quantity': 'Rydberg constant times c in Hz', 'unit': 'Hz', 'value': '3.289841960355e15', 'uncertainty': '0.000 000 000 019 e15' }, 'rydberg constant times hc in ev': { 'quantity': 'Rydberg constant times hc in eV', 'unit': 'eV', 'value': '13.605693009', 'uncertainty': '0.000 000 084' }, 'rydberg constant times hc in j': { 'quantity': 'Rydberg constant times hc in J', 'unit': 'J', 'value': '2.179872325e-18', 'uncertainty': '0.000 000 027 e-18' }, 'sackur-tetrode constant (1 k, 100 kpa)': { 'quantity': 'Sackur-Tetrode constant (1 K, 100 kPa)', 'unit': '', 'value': '-1.1517084', 'uncertainty': '0.000 0014' }, 'sackur-tetrode constant (1 k, 101.325 kpa)': { 'quantity': 'Sackur-Tetrode constant (1 K, 101.325 kPa)', 'unit': '', 'value': '-1.1648714', 'uncertainty': '0.000 0014' }, 'second radiation constant': { 'quantity': 'second radiation constant', 'unit': 'm K', 'value': '1.43877736e-2', 'uncertainty': '0.000 000 83 e-2' }, 'shielded helion gyromag. ratio': { 'quantity': 'shielded helion gyromag. ratio', 'unit': 's^{-1} T^{-1}', 'value': '2.037894585e8', 'uncertainty': '0.000 000 027 e8' }, 'shielded helion gyromag. ratio over 2 pi': { 'quantity': 'shielded helion gyromag. ratio over 2 pi', 'unit': 'MHz T^{-1}', 'value': '32.43409966', 'uncertainty': '0.000 000 43' }, 'shielded helion mag. mom.': { 'quantity': 'shielded helion mag. mom.', 'unit': 'J T^{-1}', 'value': '-1.074553080e-26', 'uncertainty': '0.000 000 014 e-26' }, 'shielded helion mag. mom. to bohr magneton ratio': { 'quantity': 'shielded helion mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '-1.158671471e-3', 'uncertainty': '0.000 000 014 e-3' }, 'shielded helion mag. mom. to nuclear magneton ratio': { 'quantity': 'shielded helion mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '-2.127497720', 'uncertainty': '0.000 000 025' }, 'shielded helion to proton mag. mom. ratio': { 'quantity': 'shielded helion to proton mag. mom. ratio', 'unit': '', 'value': '-0.7617665603', 'uncertainty': '0.000 000 0092' }, 'shielded helion to shielded proton mag. mom. ratio': { 'quantity': 'shielded helion to shielded proton mag. mom. ratio', 'unit': '', 'value': '-0.7617861313', 'uncertainty': '0.000 000 0033' }, 'shielded proton gyromag. ratio': { 'quantity': 'shielded proton gyromag. ratio', 'unit': 's^{-1} T^{-1}', 'value': '2.675153171e8', 'uncertainty': '0.000 000 033 e8' }, 'shielded proton gyromag. ratio over 2 pi': { 'quantity': 'shielded proton gyromag. ratio over 2 pi', 'unit': 'MHz T^{-1}', 'value': '42.57638507', 'uncertainty': '0.000 000 53' }, 'shielded proton mag. mom.': { 'quantity': 'shielded proton mag. mom.', 'unit': 'J T^{-1}', 'value': '1.410570547e-26', 'uncertainty': '0.000 000 018 e-26' }, 'shielded proton mag. mom. to bohr magneton ratio': { 'quantity': 'shielded proton mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '1.520993128e-3', 'uncertainty': '0.000 000 017 e-3' }, 'shielded proton mag. mom. to nuclear magneton ratio': { 'quantity': 'shielded proton mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '2.792775600', 'uncertainty': '0.000 000 030' }, 'speed of light in vacuum': { 'quantity': 'speed of light in vacuum', 'unit': 'm s^{-1}', 'value': '299792458', 'uncertainty': '(exact)' }, 'standard acceleration of gravity': { 'quantity': 'standard acceleration of gravity', 'unit': 'm s^{-2}', 'value': '9.80665', 'uncertainty': '(exact)' }, 'standard atmosphere': { 'quantity': 'standard atmosphere', 'unit': 'Pa', 'value': '101325', 'uncertainty': '(exact)' }, 'standard-state pressure': { 'quantity': 'standard-state pressure', 'unit': 'Pa', 'value': '100000', 'uncertainty': '(exact)' }, 'stefan-boltzmann constant': { 'quantity': 'Stefan-Boltzmann constant', 'unit': 'W m^{-2} K^{-4}', 'value': '5.670367e-8', 'uncertainty': '0.000 013 e-8' }, 'tau compton wavelength': { 'quantity': 'tau Compton wavelength', 'unit': 'm', 'value': '0.697787e-15', 'uncertainty': '0.000 063 e-15' }, 'tau compton wavelength over 2 pi': { 'quantity': 'tau Compton wavelength over 2 pi', 'unit': 'm', 'value': '0.111056e-15', 'uncertainty': '0.000 010 e-15' }, 'tau-electron mass ratio': { 'quantity': 'tau-electron mass ratio', 'unit': '', 'value': '3477.15', 'uncertainty': '0.31' }, 'tau mass': { 'quantity': 'tau mass', 'unit': 'kg', 'value': '3.16747e-27', 'uncertainty': '0.000 29 e-27' }, 'tau mass energy equivalent': { 'quantity': 'tau mass energy equivalent', 'unit': 'J', 'value': '2.84678e-10', 'uncertainty': '0.000 26 e-10' }, 'tau mass energy equivalent in mev': { 'quantity': 'tau mass energy equivalent in MeV', 'unit': 'MeV', 'value': '1776.82', 'uncertainty': '0.16' }, 'tau mass in u': { 'quantity': 'tau mass in u', 'unit': 'u', 'value': '1.90749', 'uncertainty': '0.000 17' }, 'tau molar mass': { 'quantity': 'tau molar mass', 'unit': 'kg mol^{-1}', 'value': '1.90749e-3', 'uncertainty': '0.000 17 e-3' }, 'tau-muon mass ratio': { 'quantity': 'tau-muon mass ratio', 'unit': '', 'value': '16.8167', 'uncertainty': '0.0015' }, 'tau-neutron mass ratio': { 'quantity': 'tau-neutron mass ratio', 'unit': '', 'value': '1.89111', 'uncertainty': '0.000 17' }, 'tau-proton mass ratio': { 'quantity': 'tau-proton mass ratio', 'unit': '', 'value': '1.89372', 'uncertainty': '0.000 17' }, 'thomson cross section': { 'quantity': 'Thomson cross section', 'unit': 'm^2', 'value': '0.66524587158e-28', 'uncertainty': '0.000 000 000 91 e-28' }, 'triton-electron mass ratio': { 'quantity': 'triton-electron mass ratio', 'unit': '', 'value': '5496.92153588', 'uncertainty': '0.000 000 26' }, 'triton g factor': { 'quantity': 'triton g factor', 'unit': '', 'value': '5.957924920', 'uncertainty': '0.000 000 028' }, 'triton mag. mom.': { 'quantity': 'triton mag. mom.', 'unit': 'J T^{-1}', 'value': '1.504609503e-26', 'uncertainty': '0.000 000 012 e-26' }, 'triton mag. mom. to bohr magneton ratio': { 'quantity': 'triton mag. mom. to Bohr magneton ratio', 'unit': '', 'value': '1.6223936616e-3', 'uncertainty': '0.000 000 0076 e-3' }, 'triton mag. mom. to nuclear magneton ratio': { 'quantity': 'triton mag. mom. to nuclear magneton ratio', 'unit': '', 'value': '2.978962460', 'uncertainty': '0.000 000 014' }, 'triton mass': { 'quantity': 'triton mass', 'unit': 'kg', 'value': '5.007356665e-27', 'uncertainty': '0.000 000 062 e-27' }, 'triton mass energy equivalent': { 'quantity': 'triton mass energy equivalent', 'unit': 'J', 'value': '4.500387735e-10', 'uncertainty': '0.000 000 055 e-10' }, 'triton mass energy equivalent in mev': { 'quantity': 'triton mass energy equivalent in MeV', 'unit': 'MeV', 'value': '2808.921112', 'uncertainty': '0.000 017' }, 'triton mass in u': { 'quantity': 'triton mass in u', 'unit': 'u', 'value': '3.01550071632', 'uncertainty': '0.000 000 000 11' }, 'triton molar mass': { 'quantity': 'triton molar mass', 'unit': 'kg mol^{-1}', 'value': '3.01550071632e-3', 'uncertainty': '0.000 000 000 11 e-3' }, 'triton-proton mass ratio': { 'quantity': 'triton-proton mass ratio', 'unit': '', 'value': '2.99371703348', 'uncertainty': '0.000 000 000 22' }, 'unified atomic mass unit': { 'quantity': 'unified atomic mass unit', 'unit': 'kg', 'value': '1.660539040e-27', 'uncertainty': '0.000 000 020 e-27' }, 'von klitzing constant': { 'quantity': 'von Klitzing constant', 'unit': 'ohm', 'value': '25812.8074555', 'uncertainty': '0.000 0059' }, 'weak mixing angle': { 'quantity': 'weak mixing angle', 'unit': '', 'value': '0.2223', 'uncertainty': '0.0021' }, 'wien frequency displacement law constant': { 'quantity': 'Wien frequency displacement law constant', 'unit': 'Hz K^{-1}', 'value': '5.8789238e10', 'uncertainty': '0.000 0034 e10' }, 'wien wavelength displacement law constant': { 'quantity': 'Wien wavelength displacement law constant', 'unit': 'm K', 'value': '2.8977729e-3', 'uncertainty': '0.000 0017 e-3' } } } # yapf: disable QCElemental-0.5.0/qcelemental/datum.py000066400000000000000000000147031351361252000176270ustar00rootroot00000000000000""" Datum Object Model """ from decimal import Decimal from typing import Any, Dict, Optional import numpy as np from pydantic import BaseModel, validator class Datum(BaseModel): """Facilitates the storage of quantum chemical results by labeling them with basic metadata. Attributes ---------- label : str Official label for `data`, often qcvar. May contain spaces. units : str ASCII, LaTeX-like representation of units, without square brackets. data : float or Decimal or or :py:class:`numpy.ndarray` Value for `label`. comment : str, optional Additional notes. doi : str, optional Literature citation or definition DOI link. glossary : str, optional Extended description or definition. numeric : bool, optional Whether `data` is numeric. Pass `True` to disable validating `data` as float/Decimal/np.ndarray. """ numeric: bool label: str units: str data: Any comment: str = '' doi: Optional[str] = None glossary: str = '' class Config: extra = "forbid" allow_mutation = False json_encoders = { np.ndarray: lambda v: v.flatten().tolist(), complex: lambda v: (v.real, v.imag), } def __init__(self, label, units, data, *, comment=None, doi=None, glossary=None, numeric=True): kwargs = {'label': label, 'units': units, 'data': data, 'numeric': numeric} if comment is not None: kwargs['comment'] = comment if doi is not None: kwargs['doi'] = doi if glossary is not None: kwargs['glossary'] = glossary super().__init__(**kwargs) @validator('data') def must_be_numerical(cls, v, values, **kwargs): try: 1.0 * v except TypeError: try: Decimal('1.0') * v except TypeError: if values['numeric']: raise ValueError(f'Datum data should be float, Decimal, or np.ndarray, not {type(v)}.') else: values['numeric'] = True else: values['numeric'] = True return v def __str__(self, label=''): width = 40 text = ['-' * width, '{:^{width}}'.format('Datum ' + self.label, width=width)] if label: text.append('{:^{width}}'.format(label, width=width)) text.append('-' * width) text.append('Data: {}'.format(self.data)) text.append('Units: [{}]'.format(self.units)) text.append('doi: {}'.format(self.doi)) text.append('Comment: {}'.format(self.comment)) text.append('Glossary: {}'.format(self.glossary)) text.append('-' * width) return '\n'.join(text) def dict(self, *args, **kwargs): return super().dict(*args, **{**kwargs, **{"skip_defaults": True}}) def to_units(self, units=None): from .physical_constants import constants to_unit = self.units if units is None else units factor = constants.conversion_factor(self.units, to_unit) if isinstance(self.data, Decimal): return factor * float(self.data) else: return factor * self.data def print_variables(qcvars: Dict[str, 'Datum']) -> str: """Form a printable representation of qcvariables. Parameters ---------- qcvars : dict of Datum Group of Datum objects to print. Returns ------- str Printable string representation of label, data, and unit in Datum-s. """ text = ['\n Variable Map:', ' ----------------------------------------------------------------------------'] if len(qcvars) == 0: text.append(' (none)') return '\n'.join(text) largest_key = max(len(k) for k in qcvars) + 2 # for quotation marks largest_characteristic = 8 for k, v in qcvars.items(): try: exp = int(str(v.data).split('E')[1]) except IndexError: pass else: largest_characteristic = max(exp, largest_characteristic) for k, qca in sorted(qcvars.items()): #if k != qca.lbl: # raise ValidationError('Huh? {} != {}'.format(k, qca.label)) if isinstance(qca.data, np.ndarray): data = np.array_str(qca.data, max_line_width=120, precision=8, suppress_small=True) data = '\n'.join(' ' + ln for ln in data.splitlines()) text.append(""" {:{keywidth}} => {:{width}} [{}]""".format('"' + k + '"', '', qca.units, keywidth=largest_key, width=largest_characteristic + 14)) text.append(data) elif isinstance(qca.data, Decimal): text.append(""" {:{keywidth}} => {:{width}} [{}]""".format('"' + k + '"', qca.data, qca.units, keywidth=largest_key, width=largest_characteristic + 14)) elif not qca.numeric: text.append(""" {:{keywidth}} => {:>{width}} [{}]""".format('"' + k + '"', str(qca.data), qca.units, keywidth=largest_key, width=largest_characteristic + 14)) else: text.append(""" {:{keywidth}} => {:{width}.{prec}f} [{}]""".format('"' + k + '"', qca.data, qca.units, keywidth=largest_key, width=largest_characteristic + 14, prec=12)) text.append('') return '\n'.join(text) QCElemental-0.5.0/qcelemental/exceptions.py000066400000000000000000000025651351361252000207010ustar00rootroot00000000000000""" Exceptions for QCElemental """ class NotAnElementError(Exception): """Error when element or nuclide can't be identified.""" def __init__(self, atom): self.message = 'Atom identifier ({}) uninterpretable as atomic number, element symbol, or nuclide symbol'.format( atom) class DataUnavailableError(Exception): """Error when dataset incomplete and otherwise valid query can't be fulfilled.""" def __init__(self, dataset, atom): self.message = 'Dataset ({}) missing value for key ({})'.format(dataset, atom) class MoleculeFormatError(Exception): """Error called when a molparse.from_string contains unparsable lines.""" def __init__(self, msg): self.message = 'Molecule line uninterpretable: {}'.format(msg) class ValidationError(Exception): """Error called for problems with syntax input file. Prints error message *msg* to standard output stream. """ def __init__(self, msg): self.message = 'Input Error: {}'.format(msg) class ChoicesError(Exception): """Error called for problems with syntax input file. Prints error message *msg* to standard output stream. Also attaches `choices` dictionary with options to proceed. """ def __init__(self, msg, choices=None): self.message = 'Input Error: {}'.format(msg) self.choices = {} if choices is None else choices QCElemental-0.5.0/qcelemental/extras.py000066400000000000000000000007411351361252000200200ustar00rootroot00000000000000""" Misc information and runtime information. """ from . import _version __all__ = ["get_information"] versions = _version.get_versions() __info = {"version": versions['version'], "git_revision": versions['full-revisionid']} def get_information(key: str): """ Obtains a variety of runtime information about QCElemental. """ key = key.lower() if key not in __info: raise KeyError(f"Information key '{key}' not understood.") return __info[key] QCElemental-0.5.0/qcelemental/models/000077500000000000000000000000001351361252000174215ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/models/__init__.py000066400000000000000000000007501351361252000215340ustar00rootroot00000000000000try: import pydantic except ImportError: # pragma: no cover raise ImportError("Python module pydantic not found. Solve by installing it: " "`conda install pydantic -c conda-forge` or `pip install pydantic`") from .molecule import Molecule from .results import Result, ResultInput, ResultProperties from .procedures import OptimizationInput, Optimization from .common_models import Provenance, ComputeError, FailedOperation from .align import AlignmentMill QCElemental-0.5.0/qcelemental/models/align.py000066400000000000000000000112471351361252000210720ustar00rootroot00000000000000import json import numpy as np from pydantic import BaseModel, validator from ..util import blockwise_expand, blockwise_contract from .common_models import (NDArray, NDArrayInt, ndarray_encoder) class AlignmentMill(BaseModel): """Facilitates the application of the simple transformation operations defined by namedtuple of arrays as recipe to the data structures describing Cartesian molecular coordinates. Attaches functions to transform the geometry, element list, gradient, etc. to the AlignmentRecipe. When `mirror` attribute (defaults to False) active, then molecular system can be substantively changed by procedure. """ shift: NDArray rotation: NDArray atommap: NDArrayInt mirror: bool = False class Config: json_encoders = {**ndarray_encoder} allow_mutation = False extra = "forbid" @validator('shift', whole=True) def must_be_3(cls, v, values, **kwargs): try: v = v.reshape(3) except (ValueError, AttributeError): raise ValueError("Shift must be castable to shape (3,)!") return v @validator('rotation', whole=True) def must_be_33(cls, v, values, **kwargs): try: v = v.reshape(3, 3) except (ValueError, AttributeError): raise ValueError("Rotation must be castable to shape (3, 3)!") return v def dict(self, *args, **kwargs): return super().dict(*args, **{**kwargs, **{"skip_defaults": False}}) def json_dict(self, *args, **kwargs): return json.loads(self.json(*args, **kwargs)) ### Non-Pydantic API functions def __str__(self, label: str = '') -> str: width = 40 text = [] text.append('-' * width) text.append('{:^{width}}'.format('AlignmentMill', width=width)) if label: text.append('{:^{width}}'.format(label, width=width)) text.append('-' * width) text.append('Mirror: {}'.format(self.mirror)) text.append('Atom Map: {}'.format(self.atommap)) text.append('Shift: {}'.format(self.shift)) text.append('Rotation:') text.append('{}'.format(self.rotation)) text.append('-' * width) return ('\n'.join(text)) def align_coordinates(self, geom, *, reverse=False) -> NDArray: """suitable for geometry or displaced geometry""" algeom = np.copy(geom) if reverse: algeom = algeom.dot(self.rotation) algeom = algeom + self.shift if self.mirror: algeom[:, 1] *= -1. else: if self.mirror: algeom[:, 1] *= -1. algeom = algeom - self.shift algeom = algeom.dot(self.rotation) algeom = algeom[self.atommap, :] # mirror-wise, rsm/msr == rms/msr return algeom def align_atoms(self, ats): """suitable for masses, symbols, Zs, etc.""" return ats[self.atommap] def align_vector(self, vec): """suitable for vector attached to molecule""" # sensible? TODO #alvec = np.copy(vec) #if self.mirror: # alvec[:, 1] *= -1 return vec.dot(self.rotation) def align_gradient(self, grad) -> NDArray: """suitable for vector system attached to atoms""" # sensible? TODO #algrad = np.copy(grad) #if self.mirror: # algrad[:, 1] *= -1 algrad = grad.dot(self.rotation) algrad = algrad[self.atommap] return algrad def align_hessian(self, hess) -> NDArray: blocked_hess = blockwise_expand(hess, (3, 3), False) alhess = np.zeros_like(blocked_hess) nat = blocked_hess.shape[0] for iat in range(nat): for jat in range(nat): alhess[iat, jat] = (self.rotation.T).dot(blocked_hess[iat, jat].dot(self.rotation)) alhess = alhess[np.ix_(self.atommap, self.atommap)] alhess = blockwise_contract(alhess) return alhess def align_system(self, geom, mass, elem, elez, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" nugeom = self.align_coordinates(geom, reverse=reverse) numass = self.align_atoms(mass) nuelem = self.align_atoms(elem) nuelez = self.align_atoms(elez) nuuniq = self.align_atoms(uniq) return nugeom, numass, nuelem, nuelez, nuuniq def align_mini_system(self, geom, uniq, *, reverse: bool = False): """For AlignmentRecipe `ar`, apply its translation, rotation, and atom map.""" nugeom = self.align_coordinates(geom, reverse=reverse) nuuniq = self.align_atoms(uniq) return nugeom, nuuniq QCElemental-0.5.0/qcelemental/models/common_models.py000066400000000000000000000045201351361252000226270ustar00rootroot00000000000000from enum import Enum from typing import Any, Dict, Optional import numpy as np from pydantic import BaseModel ndarray_encoder = {np.ndarray: lambda v: v.flatten().tolist()} class NDArray(np.ndarray): @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): try: v = np.array(v, dtype=np.double) except: raise RuntimeError("Could not cast {} to NumPy Array!".format(v)) return v class NDArrayInt(np.ndarray): @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): try: v = np.array(v, dtype=np.int) except: raise RuntimeError("Could not cast {} to NumPy Int Array!".format(v)) return v class Provenance(BaseModel): creator: str version: Optional[str] = None routine: Optional[str] = None class Config: extra = "allow" class Model(BaseModel): method: str basis: Optional[str] = None # basis_spec: BasisSpec = None # This should be exclusive with basis, but for now will be omitted class Config: allow_mutation = False extra = "allow" class DriverEnum(str, Enum): energy = 'energy' gradient = 'gradient' hessian = 'hessian' properties = 'properties' def derivative_int(self): egh = ['energy', 'gradient', 'hessian', 'third', 'fourth', 'fifth'] if self == 'properties': return 0 else: return egh.index(self) class ComputeError(BaseModel): """The type of error message raised""" error_type: str # Error enumeration not yet strict error_message: str extras: Optional[Dict[str, Any]] = None class Config: extra = "forbid" class FailedOperation(BaseModel): id: str = None input_data: Any = None success: bool = False error: ComputeError extras: Optional[Dict[str, Any]] = None class Config: extra = "forbid" allow_mutation = False json_encoders = {**ndarray_encoder} qcschema_input_default = "qcschema_input" qcschema_output_default = "qcschema_output" qcschema_optimization_input_default = "qcschema_optimization_input" qcschema_optimization_output_default = "qcschema_optimization_output" qcschema_molecule_default = "qcschema_molecule" QCElemental-0.5.0/qcelemental/models/molecule.py000066400000000000000000001203541351361252000216050ustar00rootroot00000000000000""" Molecule Object Model """ import collections import hashlib import json from pathlib import Path from typing import Any, Dict, List, Optional, Tuple, Union import numpy as np from pydantic import BaseModel, constr, validator from .common_models import NDArray, Provenance, ndarray_encoder, qcschema_molecule_default from ..molparse import from_arrays, from_schema, from_string, to_schema, to_string from ..periodic_table import periodictable from ..physical_constants import constants from ..testing import compare, compare_values from ..util import measure_coordinates, provenance_stamp, which_import # Rounding quantities for hashing GEOMETRY_NOISE = 8 MASS_NOISE = 6 CHARGE_NOISE = 4 _extension_map = { ".npy": "numpy", ".json": "json", ".xyz": "xyz", ".psimol": "psi4", ".psi4": "psi4", } def float_prep(array, around): """ Rounds floats to a common value and build positive zeros to prevent hash conflicts. """ if isinstance(array, (list, np.ndarray)): # Round array array = np.around(array, around) # Flip zeros array[np.abs(array) < 5**(-(around + 1))] = 0 elif isinstance(array, (float, int)): array = round(array, around) if array == -0.0: array = 0.0 else: raise TypeError("Type '{}' not recognized".format(type(array).__name__)) return array class Identifiers(BaseModel): """Canonical chemical identifiers""" molecule_hash: Optional[str] = None molecular_formula: Optional[str] = None smiles: Optional[str] = None inchi: Optional[str] = None inchikey: Optional[str] = None canonical_explicit_hydrogen_smiles: Optional[str] = None canonical_isomeric_explicit_hydrogen_mapped_smiles: Optional[str] = None canonical_isomeric_explicit_hydrogen_smiles: Optional[str] = None canonical_isomeric_smiles: Optional[str] = None canonical_smiles: Optional[str] = None class Config: allow_mutation = False extra = "forbid" def dict(self, *args, **kwargs): return super().dict(*args, **{**kwargs, **{"skip_defaults": True}}) class Molecule(BaseModel): # Required data schema_name: constr(strip_whitespace=True, regex=qcschema_molecule_default) = qcschema_molecule_default schema_version: int = 2 symbols: List[str] geometry: NDArray # Molecule data name: str = "" identifiers: Optional[Identifiers] = None comment: Optional[str] = None molecular_charge: float = 0.0 molecular_multiplicity: int = 1 # Atom data masses: List[float] real: List[bool] atom_labels: Optional[List[str]] = None atomic_numbers: Optional[List[int]] = None mass_numbers: Optional[List[int]] = None # Fragment and connection data connectivity: Optional[List[Tuple[int, int, float]]] = None fragments: List[List[int]] fragment_charges: List[float] fragment_multiplicities: List[int] # Orientation fix_com: bool = False fix_orientation: bool = False fix_symmetry: Optional[str] = None # Extra provenance: Provenance = provenance_stamp(__name__) id: Optional[Any] = None extras: Dict[str, Any] = None class Config: json_encoders = {**ndarray_encoder} allow_mutation = False extra = "forbid" def __init__(self, orient=False, validate=True, **kwargs): if validate: kwargs["schema_name"] = kwargs.pop("schema_name", "qcschema_molecule") kwargs["schema_version"] = kwargs.pop("schema_version", 2) # original_keys = set(kwargs.keys()) # revive when ready to revisit sparsity schema = to_schema(from_schema(kwargs), dtype=kwargs["schema_version"]) kwargs = {**kwargs, **schema} # Allow any extra fields super().__init__(**kwargs) # We are pulling out the values *explicitly* so that the pydantic skip_defaults works as expected # All attributes set bellow are equivalent to the default set. values = self.__values__ values["symbols"] = [s.title() for s in self.symbols] # Title case if values["masses"] is None: # Setup masses before fixing the orientation values["masses"] = [periodictable.to_mass(x) for x in values["symbols"]] if values["real"] is None: values["real"] = [True for _ in values["symbols"]] if orient: values["geometry"] = float_prep(self._orient_molecule_internal(), GEOMETRY_NOISE) else: values["geometry"] = float_prep(values["geometry"], GEOMETRY_NOISE) # Cleanup un-initialized variables (more complex than Pydantic Validators allow) if not values["fragments"]: natoms = values["geometry"].shape[0] values["fragments"] = [list(range(natoms))] values["fragment_charges"] = [values["molecular_charge"]] values["fragment_multiplicities"] = [values["molecular_multiplicity"]] else: if not values["fragment_charges"]: if np.isclose(values["molecular_charge"], 0.0): values["fragment_charges"] = [0 for _ in values["fragments"]] else: raise KeyError("Fragments passed in, but not fragment charges for a charged molecule.") if not values["fragment_multiplicities"]: if values["molecular_multiplicity"] == 1: values["fragment_multiplicities"] = [1 for _ in values["fragments"]] else: raise KeyError("Fragments passed in, but not fragment multiplicities for a non-singlet molecule.") @validator('geometry') def must_be_3n(cls, v, values, **kwargs): n = len(values['symbols']) try: v = v.reshape(n, 3) except (ValueError, AttributeError): raise ValueError("Geometry must be castable to shape (N,3)!") return v @validator('masses', 'real', whole=True) def must_be_n(cls, v, values, **kwargs): n = len(values['symbols']) if len(v) != n: raise ValueError("Masses and Real must be same number of entries as Symbols") return v @validator('real', whole=True) def populate_real(cls, v, values, **kwargs): # Can't use geometry here since its already been validated and not in values n = len(values['symbols']) if len(v) == 0: v = [True for _ in range(n)] return v @validator('fragment_charges', 'fragment_multiplicities', whole=True) def must_be_n_frag(cls, v, values, **kwargs): if 'fragments' in values: n = len(values['fragments']) if len(v) != n: raise ValueError("Fragment Charges and Fragment Multiplicities" " must be same number of entries as Fragments") else: raise ValueError("Cannot have Fragment Charges or Fragment Multiplicities " "without Fragments") return v @validator('connectivity') def min_zero(cls, v): if v < 0: raise ValueError("Connectivity entries must be greater than 0") return v @property def hash_fields(self): return [ "symbols", "masses", "molecular_charge", "molecular_multiplicity", "real", "geometry", "fragments", "fragment_charges", "fragment_multiplicities", "connectivity" ] def dict(self, *args, **kwargs): return super().dict(*args, **{**kwargs, **{"skip_defaults": True}}) def json_dict(self, *args, **kwargs): return json.loads(self.json(*args, **kwargs)) ### Non-Pydantic API functions def show(self, *, style: Union[str, Dict[str, Any]] = "ball_and_stick", canvas: Tuple[int, int] = (400, 400)) -> 'py3Dmol.view': """Creates a 3D representation of a moleucle that can be manipulated in Jupyter Notebooks and exported as images (`.png`). Parameters ---------- style : Union[str, Dict[str, Any]], optional Either 'ball_and_stick' or 'stick' style representations or a valid py3Dmol style dictionary. canvas : Tuple[int, int], optional The (width, height) of the display canvas in pixels Returns ------- py3Dmol.view A py3dMol view object of the molecule """ if not which_import("py3Dmol", return_bool=True): raise ModuleNotFoundError( f"Python module py3DMol not found. Solve by installing it: `conda install -c conda-forge py3dmol`" ) # pragma: no cover import py3Dmol if isinstance(style, dict): pass elif style == 'ball_and_stick': style = {'stick': {'radius': 0.2}, 'sphere': {'scale': 0.3}} elif style == 'stick': style = {'stick': {}} else: raise KeyError(f"Style '{style}' not recognized.") xyzview = py3Dmol.view(width=canvas[0], height=canvas[1]) xyzview.addModel(self.to_string("xyz", units="angstrom"), 'xyz') xyzview.setStyle(style) xyzview.zoomTo() return xyzview def measure(self, measurements: Union[List[int], List[List[int]]], *, degrees: bool = True) -> Union[float, List[float]]: """ Takes a measurement of the moleucle from the indicies provided. Parameters ---------- measurements : Union[List[int], List[List[int]]] Either a single list of indices or multiple. Return a distance, angle, or dihedral depending if 2, 3, or 4 indices is provided, respectively. Values are returned in Bohr (distance) or degree. degrees : bool, optional Returns degrees by default, radians otherwise. Returns ------- Union[float, List[float]] Either a value or list of the measured values. """ return measure_coordinates(self.geometry, measurements, degrees=degrees) def orient_molecule(self): """ Centers the molecule and orients via inertia tensor before returning a new Molecule """ return Molecule(orient=True, **self.dict()) def compare(self, other, bench=None): """ Checks if two molecules are identical. This is a molecular identity defined by scientific terms, and not programing terms, so it's less rigorous than a programmatic equality or a memory equivalent `is`. """ if isinstance(other, dict): other = Molecule(orient=False, **other) elif isinstance(other, Molecule): pass else: raise TypeError("Comparison molecule not understood of type '{}'.".format(type(other))) if bench is None: bench = self match = True match &= bench.symbols == other.symbols match &= np.allclose(bench.masses, other.masses, atol=MASS_NOISE) match &= np.equal(bench.real, other.real).all() match &= np.equal(bench.fragments, other.fragments).all() match &= np.allclose(bench.fragment_charges, other.fragment_charges, atol=CHARGE_NOISE) match &= np.equal(bench.fragment_multiplicities, other.fragment_multiplicities).all() match &= np.allclose(bench.molecular_charge, other.molecular_charge, atol=CHARGE_NOISE) match &= np.equal(bench.molecular_multiplicity, other.molecular_multiplicity).all() match &= np.allclose(bench.geometry, other.geometry, atol=GEOMETRY_NOISE) return match def pretty_print(self): """Print the molecule in Angstroms. Same as :py:func:`print_out` only always in Angstroms. (method name in libmints is print_in_angstrom) """ text = "" text += """ Geometry (in {0:s}), charge = {1:.1f}, multiplicity = {2:d}:\n\n""".format( 'Angstrom', self.molecular_charge, self.molecular_multiplicity) text += """ Center X Y Z \n""" text += """ ------------ ----------------- ----------------- -----------------\n""" for i in range(len(self.geometry)): text += """ {0:8s}{1:4s} """.format(self.symbols[i], "" if self.real[i] else "(Gh)") for j in range(3): text += """ {0:17.12f}""".format(self.geometry[i][j] * constants.conversion_factor("bohr", "angstroms")) text += "\n" # text += "\n" return text def get_fragment(self, real: Union[int, List], ghost: Optional[Union[int, List]] = None, orient: bool = False, group_fragments: bool = True) -> 'Molecule': """Get new Molecule with fragments preserved, dropped, or ghosted. Parameters ---------- real Fragment index or list of indices (0-indexed) to be real atoms in new Molecule. ghost Fragment index or list of indices (0-indexed) to be ghost atoms (basis fns only) in new Molecule. orient Whether or not to align (inertial frame) and phase geometry upon new Molecule instantiation (according to _orient_molecule_internal)? group_fragments Whether or not to group real fragments at the start of the atom list and ghost fragments toward the back. Previous to ``v0.5``, this was always effectively True. True is handy for finding duplicate (atom-order-independent) molecules by hash. False preserves fragment order (though collapsing gaps for absent fragments) like Psi4's ``extract_subsets``. False is handy for gradients where atom order of returned values matters. Returns ------- mol New ``py::class:qcelemental.model.Molecule`` with ``self``\ 's fragments present, ghosted, or absent. """ if isinstance(real, int): real = [real] if isinstance(ghost, int): ghost = [ghost] elif ghost is None: ghost = [] constructor_dict = {} ret_name = self.name + " (" + str(real) + "," + str(ghost) + ")" constructor_dict["name"] = ret_name # ret = Molecule(None, name=ret_name) if len(set(real) & set(ghost)): raise TypeError("Molecule:get_fragment: real and ghost sets are overlapping! ({0}, {1}).".format( str(real), str(ghost))) geom_blocks = [] symbols = [] masses = [] real_atoms = [] fragments = [] fragment_charges = [] fragment_multiplicities = [] atom_size = 0 if group_fragments: # Loop through the real blocks frag_start = 0 for frag in real: frag_size = len(self.fragments[frag]) geom_blocks.append(self.geometry[self.fragments[frag]]) for idx in self.fragments[frag]: symbols.append(self.symbols[idx]) real_atoms.append(True) masses.append(self.masses[idx]) fragments.append(list(range(frag_start, frag_start + frag_size))) frag_start += frag_size fragment_charges.append(float(self.fragment_charges[frag])) fragment_multiplicities.append(self.fragment_multiplicities[frag]) # Set charge and multiplicity constructor_dict["molecular_charge"] = sum(fragment_charges) constructor_dict["molecular_multiplicity"] = sum(x - 1 for x in fragment_multiplicities) + 1 # Loop through the ghost blocks for frag in ghost: frag_size = len(self.fragments[frag]) geom_blocks.append(self.geometry[self.fragments[frag]]) for idx in self.fragments[frag]: symbols.append(self.symbols[idx]) real_atoms.append(False) masses.append(self.masses[idx]) fragments.append(list(range(frag_start, frag_start + frag_size))) frag_start += frag_size fragment_charges.append(0) fragment_multiplicities.append(1) else: at2fr = [None] * len(self.symbols) for ifr, fr in enumerate(self.fragments): for iat in fr: at2fr[iat] = ifr at2at = [None] * len(self.symbols) for iat in range(len(self.symbols)): ifr = at2fr[iat] if ifr in real or ifr in ghost: geom_blocks.append(self.geometry[iat]) symbols.append(self.symbols[iat]) real_atoms.append(ifr in real) masses.append(self.masses[iat]) at2at[iat] = atom_size atom_size += 1 else: at2at[iat] = None for ifr, fr in enumerate(self.fragments): if ifr in real or ifr in ghost: fragments.append([at2at[iat] for iat in fr]) if ifr in real: fragment_charges.append(self.fragment_charges[ifr]) fragment_multiplicities.append(self.fragment_multiplicities[ifr]) elif ifr in ghost: fragment_charges.append(0) fragment_multiplicities.append(1) assert None not in fragments constructor_dict["fragments"] = fragments constructor_dict["fragment_charges"] = fragment_charges constructor_dict["fragment_multiplicities"] = fragment_multiplicities constructor_dict["symbols"] = symbols constructor_dict["geometry"] = np.vstack(geom_blocks) constructor_dict["real"] = real_atoms constructor_dict["masses"] = masses return Molecule(orient=orient, **constructor_dict) def to_string(self, dtype, units=None, *, atom_format=None, ghost_format=None, width=17, prec=12): """Returns a string that can be used by a variety of programs. Unclear if this will be removed or renamed to "to_psi4_string" in the future Suggest psi4 --> psi4frag and psi4 route to to_string """ molrec = from_schema(self.dict()) string = to_string(molrec, dtype=dtype, units=units, atom_format=atom_format, ghost_format=ghost_format, width=width, prec=prec) return string def get_hash(self): """ Returns the hash of the molecule. """ m = hashlib.sha1() concat = "" tmp_dict = super().dict() np.set_printoptions(precision=16) for field in self.hash_fields: data = tmp_dict[field] if field == "geometry": tmp_dict[field] = float_prep(data, GEOMETRY_NOISE).ravel().tolist() elif field == "fragment_charges": tmp_dict[field] = float_prep(data, CHARGE_NOISE).tolist() elif field == "molecular_charge": tmp_dict[field] = float_prep(data, CHARGE_NOISE) elif field == "masses": tmp_dict[field] = float_prep(data, MASS_NOISE).tolist() concat += json.dumps(tmp_dict[field]) # This should only be operating on Python types now m.update(concat.encode("utf-8")) return m.hexdigest() def get_molecular_formula(self): """ Returns the molecular formula for a molecule. Atom symbols are sorted from A-Z. Examples -------- >>> methane = qcelemental.models.Molecule(''' ... H 0.5288 0.1610 0.9359 ... C 0.0000 0.0000 0.0000 ... H 0.2051 0.8240 -0.6786 ... H 0.3345 -0.9314 -0.4496 ... H -1.0685 -0.0537 0.1921 ... ''') >>> methane.get_molecular_formula() CH4 >>> hcl = qcelemental.models.Molecule(''' ... H 0.0000 0.0000 0.0000 ... Cl 0.0000 0.0000 1.2000 ... ''') >>> hcl.get_molecular_formula() ClH """ count = collections.Counter(x.title() for x in self.symbols) ret = [] for k in sorted(count.keys()): c = count[k] ret.append(k) if c > 1: ret.append(str(c)) return "".join(ret) ### Constructors @classmethod def from_data(cls, data: Union[str, Dict[str, Any], np.array], dtype: Optional[str] = None, *, orient: bool = False, validate: bool = True, **kwargs: Dict[str, Any]) -> 'Molecule': """ Constructs a molecule object from a data structure. Parameters ---------- data : Union[str, Dict[str, Any], np.array] Data to construct Molecule from dtype : Optional[str], optional How to interpret the data, if not passed attempts to discover this based on input type. orient : bool, optional Orientates the molecule to a standard frame or not. validate : bool, optional Validates the molecule or not. **kwargs : Dict[str, Any] Additional kwargs to pass to the constructors. Returns ------- Molecule A constructed molecule class. """ if dtype is None: if isinstance(data, str): dtype = "string" elif isinstance(data, np.ndarray): dtype = "numpy" elif isinstance(data, dict): dtype = "dict" else: raise TypeError("Input type not understood, please supply the 'dtype' kwarg.") if dtype in ["string", "psi4", "psi4+", "xyz", "xyz+"]: input_dict = to_schema(from_string(data)["qm"], dtype=2) validate = False # Already validated, no need to do it twice elif dtype == "numpy": data = np.asarray(data) data = { "geom": data[:, 1:], "elez": data[:, 0], "units": kwargs.pop("units", "Angstrom"), "fragment_separators": kwargs.pop("frags", []) } input_dict = to_schema(from_arrays(**data), dtype=2) validate = False elif dtype == "json": input_dict = json.loads(data) elif dtype == "dict": input_dict = data else: raise KeyError("Dtype not understood '{}'.".format(dtype)) return cls(orient=orient, validate=validate, **input_dict) @classmethod def from_file(cls, filename: str, dtype: Optional[str] = None, *, orient: bool = False, **kwargs): """ Constructs a molecule object from a file. Parameters ---------- filename : str The filename to build dtype : Optional[str], optional The type of file to interpret. orient : bool, optional Orientates the molecule to a standard frame or not. **kwargs Any additional keywords to pass to the constructor Returns ------- Molecule A constructed molecule class. """ ext = Path(filename).suffix if dtype is None: if ext in _extension_map: dtype = _extension_map[ext] else: # Let `from_string` try to sort it dtype = "string" # Raw string type, read and pass through if dtype in ["string", "xyz", "psi4"]: with open(filename, "r") as infile: data = infile.read() elif dtype == "numpy": data = np.load(filename) elif dtype == "json": with open(filename, "r") as infile: data = json.load(infile) dtype = "dict" else: raise KeyError("Dtype not understood '{}'.".format(dtype)) return cls.from_data(data, dtype, orient=orient, **kwargs) def to_file(self, filename: str, dtype: Optional[str] = None) -> None: """Writes the Molecule to a file. Parameters ---------- filename : str The filename to write to dtype : Optional[str], optional The type of file to write, attempts to infer dtype from the filename if not provided. """ ext = Path(filename).suffix if dtype is None: if ext in _extension_map: dtype = _extension_map[ext] else: raise KeyError(f"Could not infer dtype from filename: `{filename}`") if dtype in ["xyz", "psi4"]: stringified = self.to_string(dtype) elif dtype in ["json"]: stringified = json.dumps(self.json_dict()) elif dtype in ["numpy"]: elements = np.array(self.atomic_numbers).reshape(-1, 1) npmol = np.hstack((elements, self.geometry)) np.save(filename, npmol) return else: raise KeyError(f"Dtype `{dtype}` is not valid") with open(filename, 'w') as handle: handle.write(stringified) ### Non-Pydantic internal functions def _orient_molecule_internal(self): """ Centers the molecule and orients via inertia tensor before returning a new set of the molecule geometry """ new_geometry = self.geometry.copy() # Ensure we get a copy # Get the mass as an array # Masses are needed for orientation np_mass = np.array(self.masses) # Center on Mass new_geometry -= np.average(new_geometry, axis=0, weights=np_mass) # Rotate into inertial frame tensor = self._inertial_tensor(new_geometry, weight=np_mass) _, evecs = np.linalg.eigh(tensor) new_geometry = np.dot(new_geometry, evecs) # Phases? Lets do the simplest thing and ensure the first atom in each column # that is not on a plane is positve phase_check = [False, False, False] geom_noise = 10**(-GEOMETRY_NOISE) for num in range(new_geometry.shape[0]): for x in range(3): if phase_check[x]: continue val = new_geometry[num, x] if abs(val) < geom_noise: continue phase_check[x] = True if val < 0: new_geometry[:, x] *= -1 if sum(phase_check) == 3: break return new_geometry def __str__(self): return self.pretty_print() def __repr__(self): return f"<{self.__class__.__name__}(name='{self.name}' formula='{self.get_molecular_formula()}' hash='{self.get_hash()[:7]}')>" def _repr_html_(self): try: return self.show()._repr_html_() except ModuleNotFoundError: return f"

{repr(self)[1:-1]}

" @staticmethod def _inertial_tensor(geom, *, weight): """ Compute the moment inertia tensor for a given geometry. """ # Build inertia tensor tensor = np.zeros((3, 3)) # Diagonal tensor[0][0] = np.sum(weight * (geom[:, 1]**2.0 + geom[:, 2]**2.0)) tensor[1][1] = np.sum(weight * (geom[:, 0]**2.0 + geom[:, 2]**2.0)) tensor[2][2] = np.sum(weight * (geom[:, 0]**2.0 + geom[:, 1]**2.0)) # I(alpha, beta) # Off diagonal tensor[1][0] = tensor[0][1] = -1.0 * np.sum(weight * geom[:, 0] * geom[:, 1]) tensor[2][0] = tensor[0][2] = -1.0 * np.sum(weight * geom[:, 0] * geom[:, 2]) tensor[2][1] = tensor[1][2] = -1.0 * np.sum(weight * geom[:, 1] * geom[:, 2]) return tensor def nuclear_repulsion_energy(self, ifr: int = None) -> float: """Nuclear repulsion energy. Parameters ---------- ifr : int, optional If not `None`, only compute for the `ifr`-th (0-indexed) fragment. Returns ------- Nuclear repulsion energy in entire molecule or in fragment. """ Zeff = [z * int(real) for z, real in zip(self.atomic_numbers, self.real)] atoms = list(range(self.geometry.shape[0])) if ifr is not None: atoms = self.fragments[ifr] nre = 0. for iat1, at1 in enumerate(atoms): for at2 in atoms[:iat1]: dist = np.linalg.norm(self.geometry[at1] - self.geometry[at2]) nre += Zeff[at1] * Zeff[at2] / dist return nre def nelectrons(self, ifr: int = None) -> int: """Number of electrons. Parameters ---------- ifr : int, optional If not `None`, only compute for the `ifr`-th (0-indexed) fragment. Returns ------- Number of electrons in entire molecule or in fragment. """ Zeff = [z * int(real) for z, real in zip(self.atomic_numbers, self.real)] if ifr is None: nel = sum(Zeff) - self.molecular_charge else: nel = sum([zf for iat, zf in enumerate(Zeff) if iat in self.fragments[ifr]]) - self.fragment_charges[ifr] return int(nel) def align(self, ref_mol, *, do_plot=False, verbose=0, atoms_map=False, run_resorting=False, mols_align=False, run_to_completion=False, uno_cutoff=1.e-3, run_mirror=False): """Finds shift, rotation, and atom reordering of `concern_mol` (self) that best aligns with `ref_mol`. Wraps :py:func:`qcel.molutil.B787` for :py:class:`qcel.models.Molecule`. Employs the Kabsch, Hungarian, and Uno algorithms to exhaustively locate the best alignment for non-oriented, non-ordered structures. Parameters ---------- concern_mol : qcel.models.Molecule Molecule of concern, to be shifted, rotated, and reordered into best coincidence with `ref_mol`. ref_mol : qcel.models.Molecule Molecule to match. atoms_map : bool, optional Whether atom1 of `ref_mol` corresponds to atom1 of `concern_mol`, etc. If true, specifying `True` can save much time. mols_align : bool, optional Whether `ref_mol` and `concern_mol` have identical geometries by eye (barring orientation or atom mapping) and expected final RMSD = 0. If `True`, procedure is truncated when RMSD condition met, saving time. do_plot : bool, optional Pops up a mpl plot showing before, after, and ref geometries. run_to_completion : bool, optional Run reorderings to completion (past RMSD = 0) even if unnecessary because `mols_align=True`. Used to test worst-case timings. run_resorting : bool, optional Run the resorting machinery even if unnecessary because `atoms_map=True`. uno_cutoff : float, optional TODO run_mirror : bool, optional Run alternate geometries potentially allowing best match to `ref_mol` from mirror image of `concern_mol`. Only run if system confirmed to be nonsuperimposable upon mirror reflection. verbose : int, optional Print level. Returns ------- Molecule, data Molecule is internal geometry of `self` optimally aligned and atom-ordered to `ref_mol`. Presently all fragment information is discarded. `data['rmsd']` is RMSD [A] between `ref_mol` and the optimally aligned geometry computed. `data['mill']` is a AlignmentMill namedtuple with fields (shift, rotation, atommap, mirror) that prescribe the transformation from `concern_mol` and the optimally aligned geometry. """ from ..molutil.align import B787 rgeom = np.array(ref_mol.geometry) runiq = np.asarray([ hashlib.sha1((sym + str(mas)).encode('utf-8')).hexdigest() for sym, mas in zip(ref_mol.symbols, ref_mol.masses) ]) concern_mol = self cgeom = np.array(concern_mol.geometry) cmass = np.array(concern_mol.masses) celem = np.array(concern_mol.symbols) celez = np.array(concern_mol.atomic_numbers) cuniq = np.asarray([ hashlib.sha1((sym + str(mas)).encode('utf-8')).hexdigest() for sym, mas in zip(concern_mol.symbols, concern_mol.masses) ]) rmsd, solution = B787(cgeom=cgeom, rgeom=rgeom, cuniq=cuniq, runiq=runiq, do_plot=do_plot, verbose=verbose, atoms_map=atoms_map, run_resorting=run_resorting, mols_align=mols_align, run_to_completion=run_to_completion, run_mirror=run_mirror, uno_cutoff=uno_cutoff) ageom, amass, aelem, aelez, _ = solution.align_system(cgeom, cmass, celem, celez, cuniq, reverse=False) adict = from_arrays(geom=ageom, mass=amass, elem=aelem, elez=aelez, units='Bohr', molecular_charge=concern_mol.molecular_charge, molecular_multiplicity=concern_mol.molecular_multiplicity, fix_com=True, fix_orientation=True) amol = Molecule(validate=False, **to_schema(adict, dtype=2)) # TODO -- can probably do more with fragments in amol now that # Mol is something with non-contig frags. frags now discarded. assert compare_values(concern_mol.nuclear_repulsion_energy(), amol.nuclear_repulsion_energy(), 'Q: concern_mol-->returned_mol NRE uncorrupted', atol=1.e-4, quiet=(verbose > 1)) if mols_align: assert compare_values(ref_mol.nuclear_repulsion_energy(), amol.nuclear_repulsion_energy(), 'Q: concern_mol-->returned_mol NRE matches ref_mol', atol=1.e-4, quiet=(verbose > 1)) assert compare(True, np.allclose(ref_mol.geometry, amol.geometry, atol=4), 'Q: concern_mol-->returned_mol geometry matches ref_mol', quiet=(verbose > 1)) return amol, {'rmsd': rmsd, 'mill': solution} def scramble(self, *, do_shift: bool = True, do_rotate=True, do_resort=True, deflection=1.0, do_mirror=False, do_plot=False, do_test=False, run_to_completion=False, run_resorting=False, verbose=0): """Generate a Molecule with random or directed translation, rotation, and atom shuffling. Optionally, check that the aligner returns the opposite transformation. Parameters ---------- ref_mol : qcel.models.Molecule Molecule to perturb. do_shift : bool or array-like, optional Whether to generate a random atom shift on interval [-3, 3) in each dimension (`True`) or leave at current origin. To shift by a specified vector, supply a 3-element list. do_rotate : bool or array-like, optional Whether to generate a random 3D rotation according to algorithm of Arvo. To rotate by a specified matrix, supply a 9-element list of lists. do_resort : bool or array-like, optional Whether to shuffle atoms (`True`) or leave 1st atom 1st, etc. (`False`). To specify shuffle, supply a nat-element list of indices. deflection : float, optional If `do_rotate`, how random a rotation: 0.0 is no change, 0.1 is small perturbation, 1.0 is completely random. do_mirror : bool, optional Whether to construct the mirror image structure by inverting y-axis. do_plot : bool, optional Pops up a mpl plot showing before, after, and ref geometries. do_test : bool, optional Additionally, run the aligner on the returned Molecule and check that opposite transformations obtained. run_to_completion : bool, optional By construction, scrambled systems are fully alignable (final RMSD=0). Even so, `True` turns off the mechanism to stop when RMSD reaches zero and instead proceed to worst possible time. run_resorting : bool, optional Even if atoms not shuffled, test the resorting machinery. verbose : int, optional Print level. Returns ------- Molecule, data Molecule is scrambled copy of `ref_mol` (self). `data['rmsd']` is RMSD [A] between `ref_mol` and the scrambled geometry. `data['mill']` is a AlignmentMill namedtuple with fields (shift, rotation, atommap, mirror) that prescribe the transformation from `ref_mol` to the returned geometry. Raises ------ AssertionError If `do_test=True` and aligner sanity check fails for any of the reverse transformations. """ from ..molutil.align import compute_scramble ref_mol = self rgeom = np.array(ref_mol.geometry) rmass = np.array(ref_mol.masses) relem = np.array(ref_mol.symbols) relez = np.array(ref_mol.atomic_numbers) runiq = np.asarray([ hashlib.sha1((sym + str(mas)).encode('utf-8')).hexdigest() for sym, mas in zip(ref_mol.symbols, ref_mol.masses) ]) nat = rgeom.shape[0] perturbation = compute_scramble(rgeom.shape[0], do_shift=do_shift, do_rotate=do_rotate, deflection=deflection, do_resort=do_resort, do_mirror=do_mirror) cgeom, cmass, celem, celez, cuniq = perturbation.align_system(rgeom, rmass, relem, relez, runiq, reverse=True) cmolrec = from_arrays( geom=cgeom, mass=cmass, elem=celem, elez=celez, units='Bohr', molecular_charge=ref_mol.molecular_charge, molecular_multiplicity=ref_mol.molecular_multiplicity, # copying fix_* vals rather than outright True. neither way great fix_com=ref_mol.fix_com, fix_orientation=ref_mol.fix_orientation) cmol = Molecule(validate=False, **to_schema(cmolrec, dtype=2)) rmsd = np.linalg.norm(cgeom - rgeom) * constants.bohr2angstroms / np.sqrt(nat) if verbose >= 1: print('Start RMSD = {:8.4f} [A]'.format(rmsd)) if do_test: _, data = cmol.align(ref_mol, do_plot=do_plot, atoms_map=(not do_resort), run_resorting=run_resorting, mols_align=True, run_to_completion=run_to_completion, run_mirror=do_mirror, verbose=verbose) solution = data['mill'] assert compare(True, np.allclose(solution.shift, perturbation.shift, atol=6), 'shifts equiv', quiet=(verbose > 1)) if not do_resort: assert compare(True, np.allclose(solution.rotation.T, perturbation.rotation), 'rotations transpose', quiet=(verbose > 1)) if solution.mirror: assert compare(True, do_mirror, 'mirror allowed', quiet=(verbose > 1)) return cmol, {'rmsd': rmsd, 'mill': perturbation} QCElemental-0.5.0/qcelemental/models/procedures.py000066400000000000000000000036221351361252000221510ustar00rootroot00000000000000import json from typing import Any, Dict, List, Optional from pydantic import BaseModel, constr from ..util import provenance_stamp from .common_models import (ComputeError, DriverEnum, Model, ndarray_encoder, qcschema_input_default, qcschema_optimization_input_default, qcschema_optimization_output_default, Provenance) from .molecule import Molecule from .results import Result class QCInputSpecification(BaseModel): schema_name: constr(strip_whitespace=True, regex=qcschema_input_default) = qcschema_input_default schema_version: int = 1 driver: DriverEnum model: Model keywords: Dict[str, Any] = {} extras: Dict[str, Any] = {} class Config: extra = "forbid" allow_mutation = False class OptimizationInput(BaseModel): id: Optional[str] = None hash_index: Optional[str] = None schema_name: constr( strip_whitespace=True, regex=qcschema_optimization_input_default) = qcschema_optimization_input_default schema_version: int = 1 keywords: Dict[str, Any] = {} extras: Dict[str, Any] = {} input_specification: QCInputSpecification initial_molecule: Molecule provenance: Provenance = provenance_stamp(__name__) class Config: extra = "forbid" allow_mutation = False json_encoders = {**ndarray_encoder} def json_dict(self, *args, **kwargs): return json.loads(self.json(*args, **kwargs)) class Optimization(OptimizationInput): schema_name: constr( strip_whitespace=True, regex=qcschema_optimization_output_default) = qcschema_optimization_output_default final_molecule: Optional[Molecule] trajectory: List[Result] energies: List[float] stdout: Optional[str] = None stderr: Optional[str] = None success: bool error: Optional[ComputeError] = None provenance: Provenance class Config(OptimizationInput.Config): pass QCElemental-0.5.0/qcelemental/models/results.py000066400000000000000000000076721351361252000215100ustar00rootroot00000000000000import json from typing import Any, Dict, List, Union, Optional from pydantic import BaseModel, constr, validator from ..util import provenance_stamp from .common_models import (ComputeError, DriverEnum, Model, Provenance, ndarray_encoder, qcschema_input_default, qcschema_output_default) from .molecule import Molecule class ResultProperties(BaseModel): # Calcinfo calcinfo_nbasis: Optional[int] = None calcinfo_nmo: Optional[int] = None calcinfo_nalpha: Optional[int] = None calcinfo_nbeta: Optional[int] = None calcinfo_natom: Optional[int] = None # Canonical nuclear_repulsion_energy: Optional[float] = None return_energy: Optional[float] = None # SCF Keywords scf_one_electron_energy: Optional[float] = None scf_two_electron_energy: Optional[float] = None scf_vv10_energy: Optional[float] = None scf_xc_energy: Optional[float] = None scf_dispersion_correction_energy: Optional[float] = None scf_dipole_moment: Optional[List[float]] = None scf_total_energy: Optional[float] = None scf_iterations: Optional[int] = None # MP2 Keywords mp2_same_spin_correlation_energy: Optional[float] = None mp2_opposite_spin_correlation_energy: Optional[float] = None mp2_singles_energy: Optional[float] = None mp2_doubles_energy: Optional[float] = None mp2_total_correlation_energy: Optional[float] = None # Old name, to be deprecated mp2_correlation_energy: Optional[float] = None mp2_total_energy: Optional[float] = None mp2_dipole_moment: Optional[List[float]] = None # CCSD Keywords ccsd_same_spin_correlation_energy: Optional[float] = None ccsd_opposite_spin_correlation_energy: Optional[float] = None ccsd_singles_energy: Optional[float] = None ccsd_doubles_energy: Optional[float] = None ccsd_correlation_energy: Optional[float] = None ccsd_total_energy: Optional[float] = None ccsd_dipole_moment: Optional[List[float]] = None ccsd_iterations: Optional[int] = None # CCSD(T) keywords ccsd_prt_pr_correlation_energy: Optional[float] = None ccsd_prt_pr_total_energy: Optional[float] = None ccsd_prt_pr_dipole_moment: Optional[List[float]] = None class Config: allow_mutation = False extra = "forbid" def dict(self, *args, **kwargs): return super().dict(*args, **{**kwargs, **{"skip_defaults": True}}) ### Primary models class ResultInput(BaseModel): """The MolSSI Quantum Chemistry Schema""" id: Optional[str] = None schema_name: constr(strip_whitespace=True, regex=qcschema_input_default) = qcschema_input_default schema_version: int = 1 molecule: Molecule driver: DriverEnum model: Model keywords: Dict[str, Any] = {} extras: Dict[str, Any] = {} provenance: Provenance = provenance_stamp(__name__) class Config: allow_mutation = False extra = "forbid" json_encoders = {**ndarray_encoder} def json_dict(self, *args, **kwargs): return json.loads(self.json(*args, **kwargs)) class Result(ResultInput): schema_name: constr(strip_whitespace=True, regex=qcschema_output_default) = qcschema_output_default properties: ResultProperties return_result: Union[float, List[float], Dict[str, Any]] stdout: Optional[str] = None stderr: Optional[str] = None success: bool error: Optional[ComputeError] = None provenance: Provenance class Config(ResultInput.Config): # Will carry other properties pass @validator("schema_name", pre=True) def input_to_output(cls, v): """If qcschema_input is passed in, cast it to output, otherwise no""" if v.lower().strip() in [qcschema_input_default, qcschema_output_default]: return qcschema_output_default raise ValueError("Only {0} or {1} is allowed for schema_name, " "which will be converted to {0}".format(qcschema_output_default, qcschema_input_default)) QCElemental-0.5.0/qcelemental/molparse/000077500000000000000000000000001351361252000177605ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/molparse/__init__.py000066400000000000000000000005201351361252000220660ustar00rootroot00000000000000from .from_arrays import from_arrays, from_input_arrays from .from_string import from_string from .nucleus import reconcile_nucleus, parse_nucleus_label from .chgmult import validate_and_fill_chgmult from .to_string import to_string from .to_schema import to_schema from .from_schema import from_schema, contiguize_from_fragment_patternQCElemental-0.5.0/qcelemental/molparse/chgmult.py000066400000000000000000000614161351361252000220050ustar00rootroot00000000000000import itertools from typing import Any, Dict, List, Union import numpy as np from ..exceptions import ValidationError from ..util import unique_everseen def _apply_default(llist, default): return [default if (c is None) else c for c in llist] def _high_spin_sum(mult_list): mm = 1 for m in mult_list: mm += m - 1 return mm def _mult_ok(m): return isinstance(m, (int, np.int64)) and m >= 1 def _sufficient_electrons_for_mult(z, c, m): """Require sufficient electrons in total: total mult ({}) - 1 > raw electrons ({}) - total chg ({})""" return m - 1 <= z - c def _parity_ok(z, c, m): """Check total electrons (neutral protons `z` and charge `c`) is (un)paired-compatible with multiplicity `m`""" return (m % 2) != ((z - c) % 2) #def _alpha_beta_allocator(z, c, m): # nbeta = (z - c - m + 1) // 2 # nalpha = nbeta + m - 1 # return nalpha, nbeta def validate_and_fill_chgmult(zeff, fragment_separators, molecular_charge: Union[float, None], fragment_charges, molecular_multiplicity: Union[int, None], fragment_multiplicities, zero_ghost_fragments: bool=False, verbose: int=1) -> Dict[str, Any]: """Forms molecular and fragment charge and multiplicity specification by completing and reconciling information from argument, supplemented by physical constraints and sensible defaults. Parameters ---------- zeff : ndarray of float (nat,) electron counts for neutral atoms, generally Z nuclear charge. 0 indicates ghosts such that a full fragment of 0s will be constained to `0 1` charge & multiplicity. fragment_separators : ndarray of int (nfr - 1, ) indices splitting `zeff` into nfr fragments. molecular_charge : float or None Total charge for molecular system. fragment_charges : list of float or None (nfr,) known fragment charges with `None` as placeholder for unknown. Expected pre-defaulted so even if nothing known, if `fragment_separators` breaks `zeff` into `nfr=2` fragments, input value should be ``fragment_charges=[None, None]``. molecular_multiplicity : int or None Total multiplicity for molecular system. fragment_multiplicity : list of int or None (nfr,) known fragment charges with `None` as placeholder for unknown. Expected pre-defaulted so even if nothing known, if `fragment_separators` breaks `zeff` into `nfr=2` fragments, input value should be ``fragment_multiplicities=[None, None]``. zero_ghost_fragments : bool, optional Fragments composed entirely of ghost atoms (Zeff=0) are required to have chgmult `0 1`. When `False`, violations of this will cause a ValidationError. When `True`, treat ghost fragments indicated by `zeff` to contain superior information over chgmult arguments that might still correspond to full-real molecule. Clears information from `molecular_charge` and `molecular_multiplicity` and sets ghost fragments to `0 1`, leaving other positions free to readjust. Unused (prefer to set up such manipulations outside function call) but works. verbose : int, optional Amount of printing. Returns ------- molecular_charge : float Total charge for molecular system. fragment_charges : list of float (nfr,) Charge on each fragment. molecular_multiplicity : int Total multiplicity for molecular system. fragment_multiplicities : list of int (nfr,) Multiplicity for each fragment. Raises ------ qcelemental.ValidationError When no solution to input arguments subject to the constraints below can be found. Notes ----- Returns combination of total & fragment charge & multiplicity among values of S1-7 that fulfill rules R1-9. A few derived implications in I1-3. * Constraints * R1 require all chg & mult exist * R2 require total charge to be the sum of frag chg * R3 require mult is positive int * R4 require sufficient tot electrons for mult: mult - 1 <= neut_el - chg * R5 require total parity consistent among tot electrons and mult: (mult % 2) != ((neut_el - chg) % 2) * R6 require chg match input argument values * R7 require mult match input argument values * R8 require that tot = sum(frag) mult follow high spin addition unless tot & frag mult fully specified * R9 require that ghost fragments (zeff all 0) be neutral singlet * Allowed values * S1 suggest input argument values for tot chg, frag chg, tot mult or frag mult * S2 suggest sum frag chg for tot chg, allowing for indiv frag chg defaulting to 0 * S3 suggest distributing unallocated chg onto frag chg * S4 suggest 0 default for frag chg * S5 suggest range of high-spin sum frag mult for tot mult, allowing for indiv frag mult defaulting to 1 or 2 * S6 suggest range of unallocated mult = tot - high_spin_sum(frag - 1), allowing for all indiv but self defaulting to 1 or 2. * S7 suggest 1 or 2 default for frag mult * Implications * I1 won't form an ion just to be closed shell (would require choosing +1 vs. -1) * I2 unallocated chg or mult lands on the first unspecified fragment able to bear it (enforced by returning first match encountered; subsequent matches distribute charge to later frags) * I3 missing chg or mult from tot - frags will always be allocated as a block, not distributed Examples -------- >>> validate_and_fill_chgmult(*sys('He'), 0, [0], 1, [1]) 0, [0], 1, [1] >>> validate_and_fill_chgmult(*sys('He'), None, [None], None, [None]) 0, [0], 1, [1] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], None, [None, None]) 0, [0, 0], 1, [1, 1]) >>> validate_and_fill_chgmult(*sys('He/He'), 2, [None, None], None, [None, None]) 2, [2, 0], 1, [1, 1]) >>> validate_and_fill_chgmult(*sys('He/He'), None, [2, None], None, [None, None]) 2, [2, 0], 1, [1, 1]) >>> validate_and_fill_chgmult(*sys('He/He'), 0, [2, None], None, [None, None]) 0, [2, -2], 1, [1, 1]) >>> validate_and_fill_chgmult(*sys('Ne/He/He'), -2, [None, 2, None], None, [None, None, None]) -2, [-4, 2, 0], 1, [1, 1, 1] >>> validate_and_fill_chgmult(*sys('Ne/He/He'), 2, [None, -2, None], None, [None, None, None]) 2, [4, -2, 0], 1, [1, 1, 1] # 9 - residual +4 distributes to first fragment able to wholly accept it (He+4 is no-go) >>> validate_and_fill_chgmult(*sys('He/He/Ne'), 2, [None, -2, None], None, [None, None, None]) 2, [0, -2, 4], 1, [1, 1, 1] # 10 - residual +4 unsuited for only open fragment, He, so irreconcilable >>> validate_and_fill_chgmult(*sys('He/He/Ne'), 2, [None, -2, 0], None, [None, None, None]) ValidationError # 11 - non-positive multiplicity >>> validate_and_fill_chgmult(*sys('He/He/Ne'), 2, [2, -2, None], None, [None, None, None]) 2, [2, -2, 2], 1, [1, 1, 1]) >>> validate_and_fill_chgmult(*sys('He/He'), None, [-2, 2], None, [None, None]) 0, [-2, 2], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, -2], None, [None, None]) -2, [0, -2], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('Ne/Ne'), 0, [None, 4], None, [None, None]) 0, [-4, 4], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('He/He/He'), 4, [2, None, None], None, [None, None, None]) 4, [2, 2, 0], 1, [1, 1, 1] >>> validate_and_fill_chgmult(*sys('He/He'), 0, [-2, 2], None, [None, None]) 0, [-2, 2], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('He/He'), 0, [-2, -2], None, [None, None]) ValidationError >>> validate_and_fill_chgmult(*sys('He'), None, [None], 0, [None]) ValidationError >>> validate_and_fill_chgmult(*sys('He'), None, [None], None, [1]) 0, [0], 1, [1] # 20 - doublet non consistent with closed-shell, neutral default charge >>> validate_and_fill_chgmult(*sys('He'), None, [None], None, [2]) ValidationError >>> validate_and_fill_chgmult(*sys('He'), None, [None], None, [3]) 0, [0], 3, [3] # 22 - insufficient electrons for pentuplet >>> validate_and_fill_chgmult(*sys('He'), None, [None], None, [5]) ValidationError >>> validate_and_fill_chgmult(*sys('He'), None, [-1], None, [2]) -1, [-1], 2, [2] # 24 - doublet not consistent with even charge >>> validate_and_fill_chgmult(*sys('He'), None, [-2], None, [2]) ValidationError >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], None, [1, 1]) 0, [0, 0], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], None, [3, 1]) 0, [0, 0], 3, [3, 1] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], None, [1, 3]) 0, [0, 0], 3, [1, 3] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], None, [3, 3]) 0, [0, 0], 5, [3, 3] >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], 3, [3, 3]) 0, [0, 0], 3, [3, 3] # 30 - bad parity btwn mult and total # electrons >>> validate_and_fill_chgmult(*sys('He/He'), None, [None, None], 2, [3, 3]) ValidationError >>> validate_and_fill_chgmult(*sys('H'), None, [None], None, [None]) 0, [0], 2, [2] >>> validate_and_fill_chgmult(*sys('H'), 1, [None], None, [None]) 1, [1], 1, [1] >>> validate_and_fill_chgmult(*sys('H'), None, [-1], None, [None]) -1, [-1], 1, [1] >>> validate_and_fill_chgmult(*sys('funnyH'), None, [None], None, [None]) 0, [0], 1, [1] # 35 - insufficient electrons >>> validate_and_fill_chgmult(*sys('funnierH'), None, [None], None, [None]) ValidationError >>> validate_and_fill_chgmult(*sys('H/H'), None, [None, None], None, [None, None]) 0, [0, 0], 3, [2, 2] >>> validate_and_fill_chgmult(*sys('H/He'), None, [None, None], None, [None, None]) 0, [0, 0], 2, [2, 1] >>> validate_and_fill_chgmult(*sys('H/He'), None, [1, 1], None, [None, None]) 2, [1, 1], 2, [1, 2] >>> validate_and_fill_chgmult(*sys('H/He'), -2, [-1, None], None, [None, None]) -2, [-1, -1], 2, [1, 2] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), None, [1, None, 1, None], None, [None, None, None, None]) 2, [1, 0, 1, 0], 1, [1, 1, 1, 1] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), None, [-1, None, 1, None], None, [None, None, None, None]) 0, [-1, 0, 1, 0], 1, [1, 1, 1, 1] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), 2, [None, None, 1, None], None, [None, None, None, None]) 2, [1, 0, 1, 0], 1, [1, 1, 1, 1] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), 3, [None, None, 1, None], None, [None, None, None, None]) 3, [0, 2, 1, 0], 2, [2, 1, 1, 1] >>> validate_and_fill_chgmult(*sys('H/He'), None, [1, None], None, [2, None]) ValidationError >>> validate_and_fill_chgmult(*sys('H/He'), None, [None, 0], None, [None, 2]) ValidationError >>> validate_and_fill_chgmult(*sys('H/He'), None, [None, -1], None, [None, 3]) ValidationError >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), None, [None, 1, 0, 1], None, [None, None, None, None]) 2, [0, 1, 0, 1], 5, [2, 2, 2, 2] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), None, [None, 1, 0, None], None, [None, None, None, None]) 1, [0, 1, 0, 0], 4, [2, 2, 2, 1] >>> validate_and_fill_chgmult(*sys('H/He/Na/Ne'), None, [None, 1, 0, None], None, [None, None, 4, None]) 1, [0, 1, 0, 0], 6, [2, 2, 4, 1] >>> validate_and_fill_chgmult(*sys('He/He/He'), 0, [None, None, 1], None, [1, None, 2]) 0, [0, -1, 1], 3, [1, 2, 2] >>> validate_and_fill_chgmult(*sys('N/N/N'), None, [1, 1, 1], 3, [None, 3, None]) 3, [1, 1, 1], 3, [1, 3, 1] >>> validate_and_fill_chgmult(*sys('N/N/N'), None, [1, 1, 1], 3, [None, None, None]) 3, [1, 1, 1], 3, [3, 1, 1] >>> validate_and_fill_chgmult(*sys('N/N/N'), None, [None, None, None], 3, [None, None, 2]) ValidationError >>> validate_and_fill_chgmult(*sys('N/N/N'), 1, [None, -1, None], 3, [None, None, 2]) 1, [2, -1, 0], 3, [2, 1, 2] # 55 - both (1, (1, 0.0, 0.0), 4, (1, 3, 2)) and (1, (0.0, 0.0, 1), 4, (2, 3, 1)) plausible >>> validate_and_fill_chgmult(*sys('N/Ne/N'), 1, [None, None, None], 4, [None, 3, None]) 1, [1, 0, 0], 4, [1, 3, 2] >>> validate_and_fill_chgmult(*sys('N/Ne/N'), None, [None, None, 1], 4, [None, 3, None]) 1, [0, 0, 1], 4, [2, 3, 1] >>> validate_and_fill_chgmult(*sys('He/He'), None, [-1, 1], None, [None, None]) 0, [-1, 1], 3, [2, 2] >>> validate_and_fill_chgmult(*sys('Gh'), 1, [None], None, [None]) ValidationError >>> validate_and_fill_chgmult(*sys('Gh'), -1, [None], None, [None]) ValidationError >>> validate_and_fill_chgmult(*sys('Gh'), None, [None], 3, [None]) ValidationError >>> validate_and_fill_chgmult(*sys('He/Gh'), None, [2, None], None, [None, None]) 2, [2, 0], 1, [1, 1] >>> validate_and_fill_chgmult(*sys('Gh/He'), None, [2, None], None, [None, None]) ValidationError >>> validate_and_fill_chgmult(*sys('Gh/He/Ne'), 2, [None, -2, None], None, [None, None, None]) 2, [0, -2, 4], 1, [1, 1, 1] >>> validate_and_fill_chgmult(*sys('Gh/He/Gh'), 1, [None, None, None], None, [None, None, None]) 1, [0, 1, 0], 2, [1, 2, 1] >>> sys = { 'He': (np.array([2]), np.array([])), 'He/He': (np.array([2, 2]), np.array([1])), 'Ne/He/He': (np.array([10, 2, 2]), np.array([1, 2])), 'He/He/Ne': (np.array([2, 2, 10]), np.array([1, 2])), 'Ne/Ne': (np.array([10, 10]), np.array([1])), 'He/He/He': (np.array([2, 2, 2]), np.array([1, 2])), 'H': (np.array([1]), np.array([])), 'funnyH': (np.array([0]), np.array([])), # has no electrons 'funnierH': (np.array([-1]), np.array([])), # has positron 'H/H': (np.array([1, 1]), np.array([1])), 'H/He': (np.array([1, 2]), np.array([1])), 'H/He/Na/Ne': (np.array([1, 2, 11, 10]), np.array([1, 2, 3])), 'N/N/N': (np.array([7, 7, 7]), np.array([1, 2])), 'N/Ne/N': (np.array([7, 10, 7]), np.array([1, 2])), 'He/Gh': (np.array([2, 0]), np.array([1])), 'Gh/He': (np.array([0, 2]), np.array([1])), 'Gh': (np.array([0, 0]), np.array([])), 'Gh/He/Ne': (np.array([0, 0, 2, 10]), np.array([2, 3])), 'Gh/He/Gh': (np.array([0, 2, 0]), np.array([1, 2]))} """ text = [] felez = np.split(zeff, fragment_separators) nfr = len(felez) text.append('felez: {}'.format(felez)) cgmp_exact_c = [] # exact_* are candidates for the final value cgmp_exact_fc: List[List[float]] = [[] for f in range(nfr)] cgmp_exact_m = [] cgmp_exact_fm: List[List[int]] = [[] for f in range(nfr)] cgmp_range = [] # tests that the final value must pass to be valid cgmp_rules = [] # key to what rules in cgmp_range are T/F real_fragments = np.array([not all(f == 0 for f in felez[ifr]) for ifr in range(nfr)]) all_fc_known = all(f is not None for f in fragment_charges) all_fm_known = all(f is not None for f in fragment_multiplicities) text.append('all_fc_known: {}'.format(all_fc_known)) text.append('all_fm_known: {}'.format(all_fm_known)) if zero_ghost_fragments and not all(real_fragments): print('possibly adjusting charges') molecular_charge = None fragment_charges = [(fr if real_fragments[ifr] else 0.0) for ifr, fr in enumerate(fragment_charges)] molecular_multiplicity = None fragment_multiplicities = [(fr if real_fragments[ifr] else 1) for ifr, fr in enumerate(fragment_multiplicities)] # <<< assert broad physical requirements # * (R1) require all chg & mult exist cgmp_range.append(lambda c, fc, m, fm: c is not None and all(f is not None for f in fc) and m is not None and all(f is not None for f in fm)) # yapf: disable cgmp_rules.append('1') # * (R2) require total charge to be the sum of fragment charges cgmp_range.append(lambda c, fc, m, fm: c == sum(fc)) cgmp_rules.append('2') # * (R3) require mult is positive int cgmp_range.append(lambda c, fc, m, fm: _mult_ok(m) and all(_mult_ok(f) for f in fm)) cgmp_rules.append('3') # <<< assert electron count requirements zel = np.sum(zeff) # note: number electrons in neutral species, not number total electrons fzel = [np.sum(f) for f in felez] text.append('zel: {}'.format(zel)) text.append('fzel: {}'.format(fzel)) # * (R4) require sufficient electrons for mult: mult - 1 <= neutral_electrons - chg cgmp_range.append(lambda c, fc, m, fm: _sufficient_electrons_for_mult(zel, c, m)) cgmp_rules.append('4') for ifr in range(nfr): cgmp_range.append(lambda c, fc, m, fm, ifr=ifr: _sufficient_electrons_for_mult(fzel[ifr], fc[ifr], fm[ifr])) cgmp_rules.append('4-' + str(ifr)) # * (R5) require total parity consistent among neutral_electrons, chg, and mult cgmp_range.append(lambda c, fc, m, fm: _parity_ok(zel, c, m)) cgmp_rules.append('5') for ifr in range(nfr): cgmp_range.append(lambda c, fc, m, fm, ifr=ifr: _parity_ok(fzel[ifr], fc[ifr], fm[ifr])) cgmp_rules.append('5-' + str(ifr)) # <<< (R6, R7, S1) assert & suggest input values if molecular_charge is not None: cgmp_exact_c.append(molecular_charge) cgmp_range.append(lambda c, fc, m, fm: c == molecular_charge) cgmp_rules.append('6') for ifr, chg in enumerate(fragment_charges): if chg is not None: cgmp_exact_fc[ifr].append(chg) cgmp_range.append(lambda c, fc, m, fm, ifr=ifr, chg=chg: fc[ifr] == chg) cgmp_rules.append('6-' + str(ifr)) if molecular_multiplicity is not None: cgmp_exact_m.append(molecular_multiplicity) cgmp_range.append(lambda c, fc, m, fm: m == molecular_multiplicity) cgmp_rules.append('7') for ifr, mult in enumerate(fragment_multiplicities): if mult is not None: cgmp_exact_fm[ifr].append(mult) cgmp_range.append(lambda c, fc, m, fm, ifr=ifr, mult=mult: fm[ifr] == mult) cgmp_rules.append('7-' + str(ifr)) # <<< assert high-spin-rule and suggest "missing quantity" and default values # * (S2) suggest net frag charge for total charge, allowing for indiv frag defaulting to 0 cgmp_exact_c.append(sum(filter(None, fragment_charges))) missing_frag_chg = 0. if molecular_charge is None else molecular_charge missing_frag_chg -= sum(filter(None, fragment_charges)) # * (S3) suggest distributing unallocated charge onto fragment # * (S4) suggest 0 default charge for fragment for ifr in range(nfr): if fragment_charges[ifr] is None: # unneeded, but shortens the exact lists cgmp_exact_fc[ifr].append(missing_frag_chg) cgmp_exact_fc[ifr].append(0.) # * (R8) require that frag mult follow high spin addition unless fully specified if molecular_multiplicity is None or any(f is None for f in fragment_multiplicities): cgmp_range.append(lambda c, fc, m, fm: m == _high_spin_sum(fm)) cgmp_rules.append('8') # * (S5) suggest range of net frag mult for total mult, allowing for indiv frag defaulting to 1 or 2. # many in range may be unphysical, but those will be caught by physical rules. if molecular_multiplicity is None: # unneeded, but shortens the exact lists frag_mult_hi = _high_spin_sum(_apply_default(fragment_multiplicities, 2)) frag_mult_lo = _high_spin_sum(_apply_default(fragment_multiplicities, 1)) for m in range(frag_mult_lo, frag_mult_hi + 1): cgmp_exact_m.append(m) # * (S6) suggest range of missing mult = tot - high_spin_sum(frag - 1), # allowing for all indiv but self defaulting to 1 or 2. Many in range # may be unphysical, but those will be caught by physical rules. # * (S7) suggest 1 or 2 default multiplicity for fragment if molecular_multiplicity is not None and any(f is None for f in fragment_multiplicities): frag_mult_less_one_none = fragment_multiplicities[:] frag_mult_less_one_none.remove(None) # "missing" slot to solve for frag_mult_hi = _high_spin_sum(_apply_default(frag_mult_less_one_none, 2)) frag_mult_lo = _high_spin_sum(_apply_default(frag_mult_less_one_none, 1)) missing_mult_hi = molecular_multiplicity - frag_mult_lo + 1 missing_mult_lo = molecular_multiplicity - frag_mult_hi + 1 else: missing_mult_hi = 0 missing_mult_lo = 0 for ifr in range(nfr): if fragment_multiplicities[ifr] is None: # unneeded, but shortens the exact lists for m in reversed(range(max(missing_mult_lo, 1), missing_mult_hi + 1)): cgmp_exact_fm[ifr].append(m) cgmp_exact_fm[ifr].append(1) cgmp_exact_fm[ifr].append(2) # * (R9) require that ghost fragments be neutral singlet for ifr in range(nfr): if all(f == 0 for f in felez[ifr]): cgmp_range.append(lambda c, fc, m, fm, ifr=ifr: fc[ifr] == 0 and fm[ifr] == 1) cgmp_rules.append('9-' + str(ifr)) # <<< reconcile and report def reconcile(exact_c, exact_fc, exact_m, exact_fm): """Returns a member from all combinations of `exact` that passes all tests in cgmp_range, else raises error.""" # remove duplicates uniq_c = unique_everseen(exact_c) uniq_fc = [unique_everseen(f) for f in exact_fc] uniq_m = unique_everseen(exact_m) uniq_fm = [unique_everseen(f) for f in exact_fm] text.append('c: {}'.format(list(exact_c))) for f in exact_fc: text.append('fc: {}'.format(list(f))) text.append('m: {}'.format(list(exact_m))) for f in exact_fm: text.append('fm: {}'.format(list(f))) header = True for candidate in itertools.product(*[uniq_c, itertools.product(*uniq_fc), uniq_m, itertools.product(*uniq_fm)]): # yapf: disable cc, cfc, cm, cfm = candidate if header: text.append("""Assess candidate {}: {}""".format(candidate, ' '.join( ('{:3}'.format(r) for r in cgmp_rules)))) header = False assessment = [fn(cc, cfc, cm, cfm) for fn in cgmp_range] sass = ['{:3}'.format('T' if b else '') for b in assessment] text.append("""Assess candidate {:}: {} --> {}""".format(candidate, ' '.join(sass), all(assessment))) if all(assessment): return candidate err = """Inconsistent or unspecified chg/mult: sys chg: {}, frag chg: {}, sys mult: {}, frag mult: {}""".format( molecular_charge, fragment_charges, molecular_multiplicity, fragment_multiplicities) if verbose > -1: print('\n\n' + '\n'.join(text)) raise ValidationError(err) def stringify(start, final): fcgmp = '{:^4}' return fcgmp.format(final) if final == start else fcgmp.format('(' + str(int(final)) + ')') # TODO could winnow down the exact_* lists a bit by ruling out # independent values. do this if many-frag molecular systems take too # long in the itertools.product c_final, fc_final, m_final, fm_final = reconcile(cgmp_exact_c, cgmp_exact_fc, cgmp_exact_m, cgmp_exact_fm) c_text = stringify(molecular_charge, c_final) fc_text = ', '.join((stringify(fs, ff) for fs, ff in zip(fragment_charges, fc_final))) m_text = stringify(molecular_multiplicity, m_final) fm_text = ', '.join((stringify(fs, ff) for fs, ff in zip(fragment_multiplicities, fm_final))) brief = [] brief.append(' {:26} {}'.format(' charge = ' + c_text, 'fragments = ' + fc_text)) brief.append(' {:26} {}'.format('multiplicity = ' + m_text, 'fragments = ' + fm_text)) been_defaulted = [] if c_text.count('(') + fc_text.count('(') > 1: been_defaulted.append('charge') if '(' in m_text or '(' in fm_text: been_defaulted.append('multiplicity') if been_defaulted: brief.append( ' Note: Default values have been applied for {}. Specify intentions in molecule input block'.format( ' and '.join(been_defaulted))) if m_final != _high_spin_sum(fm_final): brief.append( ' Warning: Total multiplicity is not high-spin sum of fragments; may be clobbered by psi4.core.Molecule.update_geometry().' ) if verbose >= 2: print('\n'.join(text)) if verbose >= 1: # TODO add back when printing worked out #print('\n'.join(brief)) pass return { 'molecular_charge': float(c_final), 'fragment_charges': [float(f) for f in fc_final], 'molecular_multiplicity': m_final, 'fragment_multiplicities': list(fm_final) } QCElemental-0.5.0/qcelemental/molparse/from_arrays.py000066400000000000000000000664141351361252000226710ustar00rootroot00000000000000import copy import pprint import re import numpy as np from ..exceptions import ValidationError from ..physical_constants import constants from ..util import distance_matrix, provenance_stamp, unnp, update_with_error from .chgmult import validate_and_fill_chgmult from .nucleus import reconcile_nucleus from .regex import VERSION_PATTERN def from_input_arrays( *, enable_qm=True, enable_efp=True, missing_enabled_return_qm='error', missing_enabled_return_efp='error', # qm geom=None, elea=None, elez=None, elem=None, mass=None, real=None, elbl=None, name=None, units='Angstrom', input_units_to_au=None, fix_com=None, fix_orientation=None, fix_symmetry=None, fragment_separators=None, fragment_charges=None, fragment_multiplicities=None, molecular_charge=None, molecular_multiplicity=None, # efp fragment_files=None, hint_types=None, geom_hints=None, # qm-vz geom_unsettled=None, variables=None, # processing details speclabel=True, tooclose=0.1, zero_ghost_fragments=False, nonphysical=False, mtol=1.e-3, verbose=1): """Compose a Molecule dict from unvalidated arrays and variables in multiple domains. Drives :py:func:`qcelemental.molparse.from_arrays` for sucessive domains and hooks them together (e.g., impose `fix_com` on "qm" when "efp" present. """ molinit = {} if enable_qm: molinit['qm'] = {} if enable_efp: molinit['efp'] = {} if enable_efp: processed = from_arrays( domain='efp', missing_enabled_return=missing_enabled_return_efp, units=units, input_units_to_au=input_units_to_au, fix_com=fix_com, fix_orientation=fix_orientation, fix_symmetry=fix_symmetry, fragment_files=fragment_files, hint_types=hint_types, geom_hints=geom_hints, # which other processing details needed? verbose=verbose) update_with_error(molinit, {'efp': processed}) if molinit['efp'] == {}: del molinit['efp'] efp_present = enable_efp and 'efp' in molinit and bool(len(molinit['efp']['geom_hints'])) if efp_present: fix_com = True fix_orientation = True fix_symmetry = 'c1' if enable_qm: dm = 'qmvz' if geom_unsettled else 'qm' processed = from_arrays( domain=dm, missing_enabled_return=missing_enabled_return_qm, geom=geom, elea=elea, elez=elez, elem=elem, mass=mass, real=real, elbl=elbl, name=name, units=units, input_units_to_au=input_units_to_au, fix_com=fix_com, fix_orientation=fix_orientation, fix_symmetry=fix_symmetry, fragment_separators=fragment_separators, fragment_charges=fragment_charges, fragment_multiplicities=fragment_multiplicities, molecular_charge=molecular_charge, molecular_multiplicity=molecular_multiplicity, geom_unsettled=geom_unsettled, variables=variables, # processing details speclabel=speclabel, tooclose=tooclose, zero_ghost_fragments=zero_ghost_fragments, nonphysical=nonphysical, mtol=mtol, verbose=1) update_with_error(molinit, {'qm': processed}) if molinit['qm'] == {}: del molinit['qm'] return molinit def from_arrays(*, geom=None, elea=None, elez=None, elem=None, mass=None, real=None, elbl=None, name=None, units='Angstrom', input_units_to_au=None, fix_com=None, fix_orientation=None, fix_symmetry=None, fragment_separators=None, fragment_charges=None, fragment_multiplicities=None, molecular_charge=None, molecular_multiplicity=None, comment=None, provenance=None, connectivity=None, fragment_files=None, hint_types=None, geom_hints=None, geom_unsettled=None, variables=None, domain='qm', missing_enabled_return='error', np_out=True, speclabel=True, tooclose=0.1, zero_ghost_fragments=False, nonphysical=False, mtol=1.e-3, verbose=1): """Compose a Molecule dict from unvalidated arrays and variables, returning dict. See fields of Return molrec below. Required parameters (for QM XYZ) are `geom` and one of `elem`, `elez`, `elbl` (`speclabel=True`) Parameters ---------- geom : array-like (nat, 3) or (3 * nat, ) ndarray or list o'lists of Cartesian coordinates. fragment_separators : array-like of int, optional (nfr - 1, ) list of atom indices at which to split `geom` into fragments. elbl : ndarray of str (nat, ) Label extending `elem` symbol, possibly conveying ghosting, isotope, mass, tagging information. tooclose : float, optional Interatom distance (native `geom` units) nearer than which atoms not allowed. nonphysical : bool, optional speclabel : bool, optional If `True`, interpret `elbl` as potentially full nucleus spec including ghosting, isotope, mass, tagging information, e.g., `@13C_mine` or `He4@4.01`. If `False`, interpret `elbl` as only the user/tagging extension to nucleus label, e.g. `_mine` or `4` in the previous examples. missing_enabled_return : {'minimal', 'none', 'error'} What to do when an enabled domain is of zero-length? Respectively, return a fully valid but empty molrec, return empty dictionary, or throw error. np_out : bool, optional When `True`, fields geom, elea, elez, elem, mass, real, elbl will be ndarray. Use `False` to get a json-able version. Returns ------- molrec : dict Molecule dictionary spec follows. Its principles are (1) contents are fully validated and defaulted - no error checking necessary, (2) contents may be mildly redundant - atomic numbers and element symbols present, (3) big system, nat-length single-type arrays, not small system, nat-number heterogeneous objects, (4) some fields are optional (e.g., fix_symmetry) but largely self-describing so units or fix_com must be present. (5) apart from some mild optional fields, _all_ fields will be present (corollary of "fully validated and defaulted") - no need to check for every key. in some cases like efp, keys will appear in blocks, so pre-handshake there will be a few hint keys and post-handshake they will be joined by full qm-like molrec. (6) molrec should be idempotent through this function (equiv to schema validator) but are not idempotent throughout its life. if fields permit, frame may be changed. Future? if fields permit, mol may be symmetrized. Coordinates and angles may change units or range if program returns them in only one form. name : str, optional Label for molecule; should be valid Python identifier. units : {'Angstrom', 'Bohr'} Units for `geom`. input_units_to_au : float, optional If `units='Angstrom'`, overrides consumer's value for [A]-->[a0] conversion. fix_com : bool Whether translation of `geom` is allowed or disallowed. fix_orientation : bool Whether rotation of `geom` is allowed or disallowed. fix_symmetry : str, optional Maximal point group symmetry which `geom` should be treated. Lowercase. geom : ndarray of float (3 * nat, ) Cartesian coordinates in `units`. elea : ndarray of int (nat, ) Mass number for atoms, if known isotope, else -1. elez : ndarray of int (nat, ) Number of protons, nuclear charge for atoms. elem : ndarray of str (nat, ) Element symbol for atoms. mass : ndarray of float (nat, ) Atomic mass [u] for atoms. real : ndarray of bool (nat, ) Real/ghostedness for atoms. elbl : ndarray of str (nat, ) Label with any tagging information from element spec. fragment_separators : list of int (nfr - 1, ) list of atom indices at which to split `geom` into fragments. fragment_charges : list of float (nfr, ) list of charge allocated to each fragment. fragment_multiplicities : list of int (nfr, ) list of multiplicity allocated to each fragment. molecular_charge : float total charge on system. molecular_multiplicity : int total multiplicity on system. comment : str, optional Additional comment for molecule. provenance : dict of str Accumulated history of molecule, with fields "creator", "version", "routine". connectivity : list of tuples of int, optional (nbond, 3) list of (0-indexed) (atomA, atomB, bond_order) (int, int, double) tuples EFP extension (this + units is minimal) fragment_files : list of str (nfr, ) lowercased names of efp meat fragment files. hint_types : {'xyzabc', 'points'} (nfr, ) type of fragment orientation hint. geom_hints : list of lists of float (nfr, ) inner lists have length 6 (xyzabc; to orient the center) or 9 (points; to orient the first three atoms) of the EFP fragment. QMVZ extension (geom_unsettled replaces geom) geom_unsettled : list of lists of str (nat, ) all-string Cartesian and/or zmat anchor and value contents mixing anchors, values, and variables. variables : list of pairs (nvar, 2) pairs of variables (str) and values (float). May be incomplete. Raises ------ qcelemental.ValidationError For most anything wrong. """ # << domain sorting >> available_domains = ['qm', 'efp', 'qmvz'] if domain not in available_domains: raise ValidationError('Topology domain {} not available for processing. Choose among {}'.format( domain, available_domains)) if domain == 'qm' and (geom is None or np.array(geom).size == 0): if missing_enabled_return == 'none': return {} elif missing_enabled_return == 'minimal': geom = [] else: raise ValidationError("""For domain 'qm', `geom` must be provided.""") if domain == 'efp' and (geom_hints is None or np.array(geom_hints).size == 0): if missing_enabled_return == 'none': return {} elif missing_enabled_return == 'minimal': geom_hints = [] fragment_files = [] hint_types = [] else: raise ValidationError("""For domain 'efp', `geom_hints` must be provided.""") molinit = {} extern = False processed = validate_and_fill_units( name=name, units=units, input_units_to_au=input_units_to_au, comment=comment, provenance=provenance, connectivity=connectivity, always_return_iutau=False) # yapf: disable processed['provenance'] = provenance_stamp(__name__) update_with_error(molinit, processed) if domain == 'efp': processed = validate_and_fill_efp( fragment_files=fragment_files, hint_types=hint_types, geom_hints=geom_hints) # yapf: disable update_with_error(molinit, processed) extern = bool(len(molinit['geom_hints'])) if domain == 'qm' or (domain == 'efp' and geom is not None) or domain == 'qmvz': if domain == 'qmvz': processed = validate_and_fill_unsettled_geometry( geom_unsettled=geom_unsettled, variables=variables) # yapf: disable update_with_error(molinit, processed) nat = len(molinit['geom_unsettled']) else: processed = validate_and_fill_geometry( geom=geom, tooclose=tooclose) # yapf: disable update_with_error(molinit, processed) nat = molinit['geom'].shape[0] // 3 processed = validate_and_fill_nuclei( nat, elea=elea, elez=elez, elem=elem, mass=mass, real=real, elbl=elbl, speclabel=speclabel, nonphysical=nonphysical, mtol=mtol, verbose=verbose) update_with_error(molinit, processed) processed = validate_and_fill_fragments( nat, fragment_separators=fragment_separators, fragment_charges=fragment_charges, fragment_multiplicities=fragment_multiplicities) update_with_error(molinit, processed) Z_available = molinit['elez'] * molinit['real'] * 1. processed = validate_and_fill_chgmult( zeff=Z_available, fragment_separators=molinit['fragment_separators'], molecular_charge=molecular_charge, fragment_charges=molinit['fragment_charges'], molecular_multiplicity=molecular_multiplicity, fragment_multiplicities=molinit['fragment_multiplicities'], zero_ghost_fragments=zero_ghost_fragments, verbose=verbose) del molinit['fragment_charges'] # sometimes safe update is too picky about overwriting v_a_f_fragments values del molinit['fragment_multiplicities'] update_with_error(molinit, processed) extern = (domain == 'efp') processed = validate_and_fill_frame( extern=extern, fix_com=fix_com, fix_orientation=fix_orientation, fix_symmetry=fix_symmetry) # yapf: disable update_with_error(molinit, processed) if verbose >= 2: print('RETURN FROM qcel.molparse.from_arrays(domain={})'.format(domain.upper())) pprint.pprint(molinit) if not np_out: molinit = unnp(molinit) return molinit def validate_and_fill_units(name=None, units='Angstrom', input_units_to_au=None, comment=None, provenance=None, connectivity=None, always_return_iutau=False): molinit = {} if name is not None: molinit['name'] = name if comment is not None: molinit['comment'] = comment def validate_provenance(dicary): expected_prov_keys = ['creator', 'routine', 'version'] try: prov_keys = sorted(dicary.keys()) except AttributeError: raise ValidationError("Provenance entry is not dictionary: {}".format(dicary)) if prov_keys == expected_prov_keys: if not isinstance(dicary['creator'], str): raise ValidationError( """Provenance key 'creator' should be string of creating program's name: {}""".format( dicary['creator'])) if not re.fullmatch(VERSION_PATTERN, dicary['version'], re.VERBOSE): raise ValidationError("""Provenance key 'version' should be a valid PEP 440 string: {}""".format( dicary['version'])) if not isinstance(dicary['routine'], str): raise ValidationError( """Provenance key 'routine' should be string of creating function's name: {}""".format( dicary['routine'])) return True else: raise ValidationError('Provenance keys ({}) incorrect: {}'.format(expected_prov_keys, prov_keys)) if provenance is None: molinit['provenance'] = {} else: if validate_provenance(provenance): molinit['provenance'] = copy.deepcopy(provenance) if connectivity is not None: conn = [] try: for (at1, at2, bondorder) in connectivity: if not (float(at1)).is_integer() or at1 < 0: # or at1 >= nat: raise ValidationError("""Connectivity first atom should be int [0, nat): {}""".format(at1)) if not (float(at2)).is_integer() or at2 < 0: # or at2 >= nat: raise ValidationError("""Connectivity second atom should be int [0, nat): {}""".format(at2)) if bondorder < 0 or bondorder > 5: raise ValidationError("""Connectivity bond order should be float [0, 5]: {}""".format(bondorder)) conn.append((int(min(at1, at2)), int(max(at1, at2)), float(bondorder))) conn.sort(key=lambda tup: tup[0]) molinit['connectivity'] = conn except ValueError: raise ValidationError( "Connectivity entry is not of form [(at1, at2, bondorder), ...]: {}".format(connectivity)) if units.capitalize() in ['Angstrom', 'Bohr']: molinit['units'] = units.capitalize() else: raise ValidationError('Invalid molecule geometry units: {}'.format(units)) if molinit['units'] == 'Bohr': iutau = 1. elif molinit['units'] == 'Angstrom': iutau = 1. / constants.bohr2angstroms if input_units_to_au is not None: if abs(input_units_to_au - iutau) < 0.05: iutau = input_units_to_au else: raise ValidationError("""No big perturbations to physical constants! {} !~= {}""".format( iutau, input_units_to_au)) if always_return_iutau or input_units_to_au is not None: molinit['input_units_to_au'] = iutau return molinit def validate_and_fill_frame(extern, fix_com=None, fix_orientation=None, fix_symmetry=None): if fix_com is True: com = True elif fix_com is False: if extern: raise ValidationError('Invalid fix_com ({}) with extern ({})'.format(fix_com, extern)) else: com = False elif fix_com is None: com = extern else: raise ValidationError('Invalid fix_com: {}'.format(fix_com)) if fix_orientation is True: orient = True elif fix_orientation is False: if extern: raise ValidationError('Invalid fix_orientation ({}) with extern ({})'.format(fix_orientation, extern)) else: orient = False elif fix_orientation is None: orient = extern else: raise ValidationError('Invalid fix_orientation: {}'.format(fix_orientation)) symm = None if extern: if fix_symmetry is None: symm = 'c1' elif fix_symmetry.lower() == 'c1': symm = 'c1' else: raise ValidationError('Invalid (non-C1) fix_symmetry ({}) with extern ({})'.format(fix_symmetry, extern)) else: if fix_symmetry is not None: symm = fix_symmetry.lower() molinit = {} molinit['fix_com'] = com molinit['fix_orientation'] = orient if symm: molinit['fix_symmetry'] = symm return molinit def validate_and_fill_efp(fragment_files=None, hint_types=None, geom_hints=None): if (fragment_files is None or hint_types is None or geom_hints is None or fragment_files == [None] or hint_types == [None] or geom_hints == [None] or not (len(fragment_files) == len(hint_types) == len(geom_hints))): raise ValidationError( """Missing or inconsistent length among efp quantities: fragment_files ({}), hint_types ({}), and geom_hints ({})""" .format(fragment_files, hint_types, geom_hints)) # NOTE: imposing case on file try: files = [f.lower() for f in fragment_files] except AttributeError: raise ValidationError("""fragment_files not strings: {}""".format(fragment_files)) if all(f in ['xyzabc', 'points', 'rotmat'] for f in hint_types): types = hint_types else: raise ValidationError("""hint_types not among 'xyzabc', 'points', 'rotmat': {}""".format(hint_types)) hints = [] hlen = {'xyzabc': 6, 'points': 9, 'rotmat': 12} for ifr, fr in enumerate(geom_hints): try: hint = [float(f) for f in fr] except (ValueError, TypeError): raise ValidationError("""Un float-able elements in geom_hints[{}]: {}""".format(ifr, fr)) htype = hint_types[ifr] if len(hint) == hlen[htype]: hints.append(hint) else: raise ValidationError("""EFP hint type {} not {} elements: {}""".format(htype, hlen[htype], hint)) return {'fragment_files': files, 'hint_types': types, 'geom_hints': hints} def validate_and_fill_geometry(geom=None, tooclose=0.1): """Check `geom` for overlapping atoms. Return flattened""" npgeom = np.array(geom, dtype=np.float).reshape((-1, 3)) dm = distance_matrix(npgeom, npgeom) iu = np.triu_indices(dm.shape[0]) dm[iu] = 10. tooclosem = np.where(dm < tooclose) if tooclosem[0].shape[0]: raise ValidationError("""Following atoms are too close: {}""".format( [(i, j, dm[i, j]) for i, j in zip(*tooclosem)])) return {'geom': npgeom.reshape((-1))} def validate_and_fill_nuclei( nat, elea=None, elez=None, elem=None, mass=None, real=None, elbl=None, # processing details speclabel=True, nonphysical=False, mtol=1.e-3, verbose=1): """Check the nuclear identity arrays for consistency and fill in knowable values.""" if elea is None: elea = np.asarray([None] * nat) else: # -1 equivalent to None elea = np.array([(None if at == -1 else at) for at in elea]) if elez is None: elez = np.asarray([None] * nat) else: elez = np.array(elez) if elem is None: elem = np.asarray([None] * nat) else: elem = np.array(elem) if mass is None: mass = np.asarray([None] * nat) else: mass = np.array(mass) if real is None: real = np.asarray([None] * nat) else: real = np.array(real) if elbl is None: elbl = np.asarray([None] * nat) else: elbl = np.array(elbl) if not ((nat, ) == elea.shape == elez.shape == elem.shape == mass.shape == real.shape == elbl.shape): raise ValidationError( """Dimension mismatch natom ({}) among A ({}), Z ({}), E ({}), mass ({}), real ({}), and elbl({})""". format((nat, ), elea.shape, elez.shape, elem.shape, mass.shape, real.shape, elbl.shape)) if nat: A, Z, E, mass, real, label = zip(*[ reconcile_nucleus( A=elea[at], Z=elez[at], E=elem[at], mass=mass[at], real=real[at], label=elbl[at], speclabel=speclabel, nonphysical=nonphysical, mtol=mtol, verbose=verbose) for at in range(nat) ]) else: A = Z = E = mass = real = label = [] return { 'elea': np.array(A, dtype=np.int), 'elez': np.array(Z, dtype=np.int), 'elem': np.array(E), 'mass': np.array(mass, dtype=np.float), 'real': np.array(real, dtype=np.bool), 'elbl': np.array(label) } def validate_and_fill_fragments(nat, fragment_separators=None, fragment_charges=None, fragment_multiplicities=None): """Check consistency of fragment specifiers wrt type and length. For charge & multiplicity, scientific defaults are not computed or applied; rather, missing slots are filled with `None` for later processing. """ if fragment_separators is None: if fragment_charges is None and fragment_multiplicities is None: frs = [] #np.array([], dtype=np.int) # if empty, needs to be both ndarray and int frc = [None] frm = [None] else: raise ValidationError( """Fragment quantities given without separation info: sep ({}), chg ({}), and mult ({})""".format( fragment_separators, fragment_charges, fragment_multiplicities)) else: trial_geom = np.zeros((nat, 3)) try: split_geom = np.split(trial_geom, fragment_separators, axis=0) except TypeError: raise ValidationError("""fragment_separators ({}) unable to perform trial np.split on geometry.""".format( fragment_separators)) if any(len(f) == 0 for f in split_geom): if nat != 0: raise ValidationError( """fragment_separators ({}) yields zero-length fragment(s) after trial np.split on geometry.""". format(split_geom)) if sum(len(f) for f in split_geom) != nat: raise ValidationError( """fragment_separators ({}) yields overlapping fragment(s) after trial np.split on geometry, possibly unsorted.""" .format(split_geom)) frs = fragment_separators nfr = len(split_geom) if fragment_charges is None: frc = [None] * nfr else: try: frc = [(f if f is None else float(f)) for f in fragment_charges] except TypeError: raise ValidationError("""fragment_charges not among None or float: {}""".format(fragment_charges)) if fragment_multiplicities is None: frm = [None] * nfr elif all(f is None or (isinstance(f, (int, np.int64)) and f >= 1) for f in fragment_multiplicities): frm = fragment_multiplicities else: raise ValidationError( """fragment_multiplicities not among None or positive integer: {}""".format(fragment_multiplicities)) if not (len(frc) == len(frm) == len(frs) + 1): raise ValidationError( """Dimension mismatch among fragment quantities: sep + 1 ({}), chg ({}), and mult({})""".format( len(frs) + 1, len(frc), len(frm))) return {'fragment_separators': list(frs), 'fragment_charges': frc, 'fragment_multiplicities': frm} def validate_and_fill_unsettled_geometry(geom_unsettled, variables): lgeom = [len(g) for g in geom_unsettled] if lgeom[0] not in [0, 3]: raise ValidationError("""First line must be Cartesian or single atom.""") if any(l == 3 for l in lgeom) and not all((l in [3, 6]) for l in lgeom): raise ValidationError( """Mixing Cartesian and Zmat formats must occur in just that order once absolute frame established.""") allowed_to_follow = {0: [2], 2: [4], 3: [3, 6], 4: [6], 6: [3, 6]} for il in range(len(lgeom) - 1): if lgeom[il + 1] not in allowed_to_follow[lgeom[il]]: raise ValidationError( """This is not how a Zmat works - aim for lower triangular. Line len ({}) may be followed by line len ({}), not ({}).""" .format(lgeom[il], allowed_to_follow[lgeom[il]], lgeom[il + 1])) if not all(len(v) == 2 for v in variables): raise ValidationError("""Variables should come in pairs: {}""".format(variables)) vvars = [[str(v[0]), float(v[1])] for v in variables] return {'geom_unsettled': geom_unsettled, 'variables': vvars} QCElemental-0.5.0/qcelemental/molparse/from_schema.py000066400000000000000000000136421351361252000226230ustar00rootroot00000000000000from typing import Dict import numpy as np from ..exceptions import ValidationError from ..util import provenance_stamp from .from_arrays import from_arrays def from_schema(molschema, *, verbose: int=1) -> Dict: """Construct molecule dictionary representation from non-Psi4 schema. Parameters ---------- molschema : dict Dictionary form of Molecule following known schema. verbose : int, optional Amount of printing. Returns ------- molrec : dict Dictionary representation of instance. """ if ((molschema.get('schema_name', '').startswith('qc_schema') or molschema.get('schema_name', '').startswith('qcschema')) and (molschema.get('schema_version', '') == 1)): ms = molschema['molecule'] elif molschema.get('schema_name', '').startswith('qcschema_molecule') and molschema.get('schema_version', '') == 2: ms = molschema else: raise ValidationError("""Schema not recognized, schema_name/schema_version: {}/{} """.format( molschema.get('schema_name', '(none)'), molschema.get('schema_version', '(none)'))) if 'fragments' in ms: frag_pattern = ms['fragments'] else: frag_pattern = [np.arange(len(ms['symbols']))] dcontig = contiguize_from_fragment_pattern( frag_pattern, geom=ms['geometry'], elea=ms.get('mass_numbers', None), elez=ms.get('atomic_numbers', None), elem=ms['symbols'], mass=ms.get('masses', None), real=ms.get('real', None), elbl=ms.get('atom_labels', None), throw_reorder=True) molrec = from_arrays( geom=dcontig['geom'], elea=dcontig['elea'], elez=dcontig['elez'], elem=dcontig['elem'], mass=dcontig['mass'], real=dcontig['real'], elbl=dcontig['elbl'], name=ms.get('name', None), units='Bohr', input_units_to_au=None, fix_com=ms.get('fix_com', None), fix_orientation=ms.get('fix_orientation', None), fix_symmetry=ms.get('fix_symmetry', None), fragment_separators=dcontig['fragment_separators'], fragment_charges=ms.get('fragment_charges', None), fragment_multiplicities=ms.get('fragment_multiplicities', None), molecular_charge=ms.get('molecular_charge', None), molecular_multiplicity=ms.get('molecular_multiplicity', None), comment=ms.get('comment', None), provenance=ms.get('provenance', None), connectivity=ms.get('connectivity', None), domain='qm', #missing_enabled_return=missing_enabled_return, speclabel=False, #tooclose=tooclose, #zero_ghost_fragments=zero_ghost_fragments, #nonphysical=nonphysical, #mtol=mtol, verbose=verbose) # replace from_arrays stamp with from_schema stamp molrec['provenance'] = provenance_stamp(__name__) return molrec def contiguize_from_fragment_pattern(frag_pattern, *, geom=None, verbose:int=1, throw_reorder:bool=False, **kwargs): """Take (nat, ?) array-like arrays and return with atoms arranged by (nfr, ?) `frag_pattern`. Parameters ---------- frag_pattern : list of lists of ints (nfr, ?) list of indices (0-indexed) grouping atoms into molecular fragments within the topology. geom : array-like, optional (nat, 3) or (3 * nat, ) ndarray or list o'lists of Cartesian coordinates, possibly with atoms belonging to the same fragment being dispersed in `geom`. throw_reorder : bool, optional Whether, when non-contiguous fragments detected, to raise ValidationError (``True``) or to proceed to reorder atoms to contiguize fragments (``False``). verbose : int, optional Quantity of printing kwargs : None or array-like Each additional array will be returned with ordering applied in the return dictionary. Returns ------- fragment_separators : array-like of int (nfr - 1, ) list of atom indices at which to split `geom` into fragments. geom : ndarray of float, optional (3 * nat, ) Cartesian coordinates with fragments contiguous. kwargs : None or ndarray, optional (nat, ) Each `kwargs` input array reordered for contiguous fragments. Raises ------ qcelemental.ValidationError When `frag_pattern` skips atoms or any array has inconsistent length. If `throw_reorder`, raises when non-contiguous fragments detected. """ vsplt = np.cumsum([len(fr) for fr in frag_pattern]) nat = vsplt[-1] fragment_separators = vsplt[:-1] do_reorder = False if not np.array_equal(np.sort(np.concatenate(frag_pattern)), np.arange(nat)): raise ValidationError("""Fragmentation pattern skips atoms: {}""".format(frag_pattern)) if not np.array_equal(np.concatenate(frag_pattern), np.arange(nat)): print("""Warning: QCElemental is reordering atoms to accommodate non-contiguous fragments""") do_reorder = True if do_reorder and throw_reorder: raise ValidationError( """Error: QCElemental would need to reorder atoms to accommodate non-contiguous fragments""") if geom is not None: ncgeom = np.array(geom).reshape(-1, 3) if nat != ncgeom.shape[0]: raise ValidationError("""dropped atoms! nat = {} != {}""".format(nat, ncgeom.shape[0])) geom = np.vstack([ncgeom[fr] for fr in frag_pattern]) geom = geom.reshape((-1)) def reorder(arr): if nat != len(arr): raise ValidationError("""wrong number of atoms in array: nat = {} != {}""".format(nat, len(arr))) return np.concatenate([np.array(arr)[fr] for fr in frag_pattern], axis=0) returns = {'fragment_separators': fragment_separators} if geom is not None: returns.update({'geom': geom}) extras = {k: (None if v is None else reorder(v)) for k, v in kwargs.items()} returns.update(extras) return returns QCElemental-0.5.0/qcelemental/molparse/from_string.py000066400000000000000000000701521351361252000226700ustar00rootroot00000000000000import pprint import re from typing import Dict, Tuple, Union from . import pubchem from ..exceptions import ChoicesError, MoleculeFormatError, ValidationError from ..util import filter_comments, provenance_stamp from .from_arrays import from_input_arrays from .regex import CARTXYZ, CHGMULT, ENDL, NUCLEUS, NUMBER, SEP __all__ = ['from_string'] def from_string(molstr, dtype=None, *, name=None, fix_com=None, fix_orientation=None, fix_symmetry=None, return_processed=False, enable_qm=True, enable_efp=True, missing_enabled_return_qm='none', missing_enabled_return_efp='none', verbose=1) -> Union[Dict, Tuple[Dict, Dict]]: """Construct a molecule dictionary from any recognized string format. Parameters ---------- molstr : str Multiline string specification of molecule in a recognized format. dtype : {'xyz', 'xyz+', 'psi4', 'psi4+'}, optional Molecule format name; see below for details. return_processed : bool, optional Additionally return intermediate dictionary. enable_qm : bool, optional Consider quantum mechanical domain in processing the string constants into the returned molrec. enable_efp: bool, optional Consider effective fragment potential domain in processing the string contents into the returned molrec. Only relevant if `dtype` supports EFP. missing_enabled_return_qm : {'minimal', 'none', 'error'} If `enable_qm=True`, what to do if it has no atoms/fragments? Respectively, return a fully valid but empty molrec, return empty dictionary, or throw error. missing_enabled_return_efp : {'minimal', 'none', 'error'} If `enable_efp=True`, what to do if it has no atoms/fragments? Respectively, return a fully valid but empty molrec, return empty dictionary, or throw error. name : str, optional Override `molstr` information for label for molecule; should be valid Python identifier. One of a very limited number of fields (three others follow) for trumping `molstr`. Provided for convenience, since the alternative would be collect the resulting molrec (discarding the Mol if called from class), editing it, then remaking the Mol. fix_com : bool, optional Override `molstr` information for whether translation of `geom` is allowed or disallowed. fix_orientation : bool, optional Override `molstr` information for whether rotation of `geom` is allowed or disallowed. fix_symmetry : str, optional Override `molstr` information for maximal point group symmetry which geometry should be treated. Returns ------- molrec : dict Molecule dictionary spec. See :py:func:`from_arrays`. molinit : dict, optional Intermediate "molrec"-like dictionary containing `molstr` info after parsing by this function but before the validation and defaulting of `from_arrays` that returns the proper `molrec`. Only provided if `return_processed` is True. Raises ------ qcelemental.MoleculeFormatError After processing of `molstr`, only an empty string should remain. Anything left is a syntax error. Notes ----- Several formats are interpretable :: xyz - Strict XYZ format ----------------------- String Layout ------------- comment line ... QM Domain --------- Specifiable: geom, elem/elez (element identity) Inaccessible: mass, real (vs. ghost), elbl (user label), name, units (assumed [A]), input_units_to_au, fix_com/orientation/symmetry, fragmentation, molecular_charge, molecular_multiplicity Notes ----- is pattern-matched but ignored. xyz+ - Enhanced XYZ format -------------------------- String Layout ------------- [] [ ] comment line ... QM Domain --------- Specifiable: geom, elem/elez (element identity), mass, real (vs. ghost), elbl (user label), units (defaults [A]), molecular_charge, molecular_multiplicity Inaccessible: name, input_units_to_au, fix_com/orientation/symmetry, fragmentation Notes ----- is pattern-matched but ignored. psi4 - Psi4 molecule {...} format --------------------------------- QM Domain --------- Specifiable: geom, elem/elez (element identity), mass, real (vs. ghost), elbl (user label), units (defaults [A]), fix_com/orientation/symmetry, fragment_separators, fragment_charges, fragment_multiplicities, molecular_charge, molecular_multiplicity Inaccessible: name, input_units_to_au PubChem ------- pubchem : [*] A string like the above searches the PubChem database and substitutes the below. Adding the wildcard searches for multiple matches and raises ChoicesError with matches for further consideration attached. Specifiable: geom, elem/elez (element identity), units (fixed [A]), molecular_charge, molecular_multiplicity (fixed singlet), name EFP Domain ---------- Specifiable: units, fix_com/orientation/symmetry, fragment_files, hint_types, geom_hints Inaccessible: anything atomic or fragment details -- geom, elem/elez (element identity), mass, real (vs. ghost), elbl (user label), fragment_separators, fragment_charges, fragment_multiplicities, molecular_charge, molecular_multiplicity psi4+ - Psi4 non-Cartesian molecule {...} format ------------------------------------------------ Like `dtype=psi4` (although combination with EFP not tested) except that instead of pure-Cartesian geometry, allow variables, zmatrix, and un-fully-specified geometries. *Not* MolSSI standard, but we're not dropping zmatrix yet. Note that in Psi4 internal coordinates defined through a zmatrix have no bearing on geometry optimization internals or constraints. """ if verbose >= 2: print('<<< FROM_STRING\n', molstr, '\n>>>') # << 1 >> str-->str -- discard comments molstr = filter_comments(molstr.strip()) def parse_as_xyz_ish(molstr, strict): molinit = {} # << 2 >> str-->dict -- process atoms, units[, chg, mult] molstr, processed = _filter_xyz(molstr, strict=strict) molinit.update(processed) if molstr: raise MoleculeFormatError("""Unprocessable Molecule remanents under {}:\n{}""".format(dtype, molstr)) return molstr, molinit def parse_as_psi4_ish(molstr, unsettled): molinit = {} # Notes # * *_filter functions must fill non-overlapping fields # * not recc but can add to downstream by appending to str # << 2.1 >> str-->str -- process pubchem into str for downfunction molstr, processed = _filter_pubchem(molstr) molinit.update(processed) # << 2.2 >> str-->dict -- process units, com, orient, symm molstr, processed = _filter_universals(molstr) molinit.update(processed) # << 2.3 >> str-->dict -- process efp frags molstr, processed = _filter_libefp(molstr) molinit.update(processed) # << 2.4 >> str-->dict -- process atoms, chg, mult, frags molstr, processed = _filter_mints(molstr, unsettled=unsettled) molinit.update(processed) if molstr: raise MoleculeFormatError("""Unprocessable Molecule remanents under {}:\n{}""".format(dtype, molstr)) return molstr, molinit if dtype == 'xyz': molstr, molinit = parse_as_xyz_ish(molstr, strict=True) elif dtype == 'xyz+': molstr, molinit = parse_as_xyz_ish(molstr, strict=False) elif dtype == 'psi4': molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False) elif dtype == 'psi4+': molstr, molinit = parse_as_psi4_ish(molstr, unsettled=True) elif dtype is None: try: molstr, molinit = parse_as_psi4_ish(molstr, unsettled=False) dtype = 'psi4' except MoleculeFormatError as err: try: molstr, molinit = parse_as_xyz_ish(molstr, strict=True) dtype = 'xyz' except MoleculeFormatError as err: try: molstr, molinit = parse_as_xyz_ish(molstr, strict=False) dtype = 'xyz+' except MoleculeFormatError as err: try: molstr, molinit = parse_as_psi4_ish(molstr, unsettled=True) dtype = 'psi4+' except MoleculeFormatError as err: raise MoleculeFormatError( """Unprocessable Molecule remanents under [psi4, xyz, xyz+, psi4+]:\n{}""".format(molstr)) else: raise KeyError("Molecule: dtype of %s not recognized.") # << 3 >> args-->dict -- process name, com, orient, symm from arguments processed = _filter_kwargs(name, fix_com, fix_orientation, fix_symmetry) molinit.update(processed) if verbose >= 2: print('\nFROM_STRING (', dtype, ') --> FROM_INPUT_ARRAYS <<<') pprint.pprint(molinit) print('>>>\n') # << 4 >> dict-->molspec molrec = from_input_arrays( speclabel=True, enable_qm=enable_qm, enable_efp=enable_efp, missing_enabled_return_qm=missing_enabled_return_qm, missing_enabled_return_efp=missing_enabled_return_efp, **molinit) # replace from_arrays stamp with from_string stamp if 'qm' in molrec and molrec['qm']: molrec['qm']['provenance'] = provenance_stamp(__name__) if 'efp' in molrec and molrec['efp']: molrec['efp']['provenance'] = provenance_stamp(__name__) if verbose >= 2: print('\nFROM_STRING MOLREC <<<', molrec, '>>>\n') if return_processed: return molrec, molinit else: return molrec # TODO maybe molrec needs a "fix_loose" flag to signal the reciever can symmetrize # pubchemerror = re.compile(r'^\s*PubchemError\s*$', re.IGNORECASE) # pubcheminput = re.compile(r'^\s*PubchemInput\s*$', re.IGNORECASE) # # N.B. Anything starting with PubchemError will be handled correctly by the molecule parser # # in libmints, which will just print the rest of the string and exit gracefully. pubchemre = re.compile(r'\Apubchem' + r'\s*:\s*' + r'(?P(([\S ]+)))\Z', re.IGNORECASE) def _filter_pubchem(string): """Find any "pubchem:" lines in `string`, make call to the pubchem database and return the XYZ results back to `string`. Author: @andysim """ def process_pubchem(matchobj): pubsearch = matchobj.group('pubsearch') # search pubchem for the provided string try: results = pubchem.get_pubchem_results(pubsearch) except Exception as e: raise ValidationError(e.message) if pubsearch.endswith('*'): pubsearch = pubsearch[:-1] if len(results) == 1: # There's only 1 result - use it xyz = results[0].get_molecule_string() processed['name'] = 'IUPAC {}'.format(results[0].name()) processed['molecular_charge'] = float(results[0].molecular_charge) if 'Input Error' in xyz: raise ValidationError(xyz) else: # There are multiple results -- print and exit # * formerly, this checked for (then used) any exact match, but now (LAB; Sep 2018), disabling that # since user explicitly added '*' char & "best match" (not available formerly) returned w/o '*' msg = "\tPubchemError\n" msg += "\tMultiple pubchem results were found. Replace\n\n\t\tpubchem:%s\n\n" % (pubsearch) msg += "\twith the Chemical ID number or exact name from one of the following and re-run.\n\n" msg += "\t Chemical ID IUPAC Name\n\n" ematches = {} for result in results: msg += "%s" % (result) ematches[result.cid] = result.iupac raise ChoicesError(msg, ematches) # remove PubchemInput first line and assert [A] xyz = xyz.replace('PubchemInput', 'units ang') return xyz reconstitute = [] processed = {} for line in string.split('\n'): line = re.sub(pubchemre, process_pubchem, line.strip()) if line: reconstitute.append(line) return '\n'.join(reconstitute), processed def _filter_kwargs(name, fix_com, fix_orientation, fix_symmetry): processed = {} if name is not None: processed['name'] = name if fix_com is not None: processed['fix_com'] = fix_com if fix_orientation is not None: processed['fix_orientation'] = fix_orientation if fix_symmetry is not None: processed['fix_symmetry'] = fix_symmetry return processed com = re.compile(r'\A(no_com|nocom)\Z', re.IGNORECASE) orient = re.compile(r'\A(no_reorient|noreorient)\Z', re.IGNORECASE) bohrang = re.compile(r'\Aunits?[\s=]+((?P(bohr|au|a.u.))|(?P(ang|angstrom)))\Z', re.IGNORECASE) symmetry = re.compile(r'\Asymmetry[\s=]+(?P\w+)\Z', re.IGNORECASE) def _filter_universals(string): """Process multiline `string` for fix_ and unit markers, returning a string of unprocessed `string` and a dictionary of processed fields. fix_com fix_orientation fix_symmetry #input_units_to_au (not settable) units """ def process_com(matchobj): processed['fix_com'] = True return '' def process_orient(matchobj): processed['fix_orientation'] = True return '' def process_bohrang(matchobj): if matchobj.group('uang'): processed['units'] = 'Angstrom' elif matchobj.group('ubohr'): processed['units'] = 'Bohr' return '' def process_symmetry(matchobj): processed['fix_symmetry'] = matchobj.group('pg').lower() return '' reconstitute = [] processed = {} com_found = False orient_found = False bohrang_found = False symmetry_found = False for line in string.split('\n'): line = line.strip() if not com_found: line, com_found = re.subn(com, process_com, line) if not orient_found: line, orient_found = re.subn(orient, process_orient, line) if not bohrang_found: line, bohrang_found = re.subn(bohrang, process_bohrang, line) if not symmetry_found: line, symmetry_found = re.subn(symmetry, process_symmetry, line) if line: reconstitute.append(line) return '\n'.join(reconstitute), processed fragment_marker = re.compile(r'^\s*--\s*$', re.MULTILINE) efpxyzabc = re.compile( r'\A' + r'efp' + SEP + r'(?P(\w+))' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + ENDL + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable efppoints = re.compile( r'\A' + r'efp' + SEP + r'(?P(\w+))' + ENDL + r'[\s,]*' + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + ENDL + r'[\s,]*' + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + ENDL + r'[\s,]*' + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + ENDL + r'\Z', re.IGNORECASE | re.MULTILINE | re.VERBOSE) # yapf: disable def _filter_libefp(string): def process_efpxyzabc(matchobj): processed['fragment_files'].append(matchobj.group('efpfile')) processed['hint_types'].append('xyzabc') processed['geom_hints'].append([ float(matchobj.group('x')), float(matchobj.group('y')), float(matchobj.group('z')), float(matchobj.group('a')), float(matchobj.group('b')), float(matchobj.group('c'))]) # yapf: disable return '' def process_efppoints(matchobj): processed['fragment_files'].append(matchobj.group('efpfile')) processed['hint_types'].append('points') processed['geom_hints'].append([ float(matchobj.group('x1')), float(matchobj.group('y1')), float(matchobj.group('z1')), float(matchobj.group('x2')), float(matchobj.group('y2')), float(matchobj.group('z2')), float(matchobj.group('x3')), float(matchobj.group('y3')), float(matchobj.group('z3'))]) # yapf: disable return '' reconstitute = [] processed = {} processed['fragment_files'] = [] processed['hint_types'] = [] processed['geom_hints'] = [] # handle `--`-demarcated blocks for frag in re.split(fragment_marker, string): frag = re.sub(efpxyzabc, process_efpxyzabc, frag.strip()) frag = re.sub(efppoints, process_efppoints, frag) if frag: reconstitute.append(frag) return '\n--\n'.join(reconstitute), processed fragment_marker = re.compile(r'^\s*--\s*$', re.MULTILINE) cgmp = re.compile(r'\A' + CHGMULT + r'\Z', re.VERBOSE) VAR = r'(-?[a-z][a-z0-9_]*)' # slight cheat to allow neg in `variable` NUCLABEL = r'([A-Z]{1,3}((_\w+)|(\d+))?)' ANCHORTO = r'((\d+)|' + NUCLABEL + r')' ANCHORVAL = r'(' + NUMBER + r'|' + VAR + ')' atom_cartesian = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + CARTXYZ + r'\Z', re.IGNORECASE | re.VERBOSE) atom_vcart = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + r'(?P' + ANCHORVAL + r')' + SEP + r'(?P' + ANCHORVAL + r')' + SEP + r'(?P' + ANCHORVAL + r')' + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable atom_zmat1 = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable atom_zmat2 = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable atom_zmat3 = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable atom_zmat4 = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + SEP + r'(?P' + ANCHORTO + r')' + SEP + r'(?P' + ANCHORVAL + r')' + r'\Z', re.IGNORECASE | re.VERBOSE) # yapf: disable variable = re.compile( r'\A' + r'(?P' + VAR + r')' + r'\s*=\s*' + r'(?P((tda)|(' + NUMBER + r')))' + r'\Z', re.IGNORECASE | re.VERBOSE) def _filter_mints(string, unsettled=False): """Handle extracting fragment, atom, and chg/mult lines from `string`. Returns ------- str, dict Returns first a subset (plus some fragment separation guidance) of `string` containing the unmatched contents. These are generally input violations unless handled by a subsequent processing function. Returns second a dictionary with processed extractions. Contains (some optional) the following keys. molecular_charge : float, optional molecular_multiplicity : int, optional geom elbl fragment_separators fragment_charges fragment_multiplicities unsettled : bool, optional Whether to allow variable entries and zmat structure, accumulating into geom_unsettled, rather than pure numerical Cartesian entries, accumulating into geom. """ def process_system_cgmp(matchobj): """Handles optional special first fragment with sole contents overall chg/mult.""" processed['molecular_charge'] = float(matchobj.group('chg')) processed['molecular_multiplicity'] = int(matchobj.group('mult')) return '' def filter_fragment(fstring): """Handles extraction from everything within a fragment marker "--" of a single chg/mult (or None/None) and multiple atom lines. """ def process_fragment_cgmp(matchobj): processed['fragment_charges'].append(float(matchobj.group('chg'))) processed['fragment_multiplicities'].append(int(matchobj.group('mult'))) return '' def process_atom_cartesian(matchobj): processed['elbl'].append(matchobj.group('nucleus')) processed['geom'].append(float(matchobj.group('x'))) processed['geom'].append(float(matchobj.group('y'))) processed['geom'].append(float(matchobj.group('z'))) return '' def process_atom_unsettled(matchobj): processed['elbl'].append(matchobj.group('nucleus')) geo = [] if 'Xval' in matchobj.groupdict(): geo.append(matchobj.group('Xval')) geo.append(matchobj.group('Yval')) geo.append(matchobj.group('Zval')) if 'Rval' in matchobj.groupdict(): geo.append(matchobj.group('Ridx')) geo.append(matchobj.group('Rval')) if 'Aval' in matchobj.groupdict(): geo.append(matchobj.group('Aidx')) geo.append(matchobj.group('Aval')) if 'Dval' in matchobj.groupdict(): geo.append(matchobj.group('Didx')) geo.append(matchobj.group('Dval')) processed['geom_unsettled'].append(geo) return '' def process_variable(matchobj): processed['variables'].append((matchobj.group('varname'), matchobj.group('varvalue'))) return '' freconstitute = [] start_atom = len(processed["elbl"]) if start_atom > 0: processed['fragment_separators'].append(start_atom) fcgmp_found = False for iln, line in enumerate(fstring.split('\n')): line = line.strip() if not fcgmp_found: line, fcgmp_found = re.subn(cgmp, process_fragment_cgmp, line) if unsettled: line = re.sub(atom_vcart, process_atom_unsettled, line) line = re.sub(atom_zmat1, process_atom_unsettled, line) line = re.sub(atom_zmat2, process_atom_unsettled, line) line = re.sub(atom_zmat3, process_atom_unsettled, line) line = re.sub(atom_zmat4, process_atom_unsettled, line) line = re.sub(variable, process_variable, line) else: line = re.sub(atom_cartesian, process_atom_cartesian, line) if line: freconstitute.append(line) if not fcgmp_found: processed['fragment_charges'].append(None) processed['fragment_multiplicities'].append(None) return '\n'.join(freconstitute), processed reconstitute = [] processed = {} processed['elbl'] = [] processed['fragment_separators'] = [] processed['fragment_charges'] = [] processed['fragment_multiplicities'] = [] if unsettled: processed['geom_unsettled'] = [] processed['variables'] = [] else: processed['geom'] = [] # handle `--`-demarcated blocks for ifr, frag in enumerate(re.split(fragment_marker, string)): frag = frag.strip() if ifr == 0 and cgmp.match(frag): frag, ntotch = re.subn(cgmp, process_system_cgmp, frag) else: frag, processed = filter_fragment(frag) if frag: reconstitute.append(frag) return '\n--\n'.join(reconstitute), processed xyz1strict = re.compile(r'\A' + r'(?P\d+)' + r'\Z') SIMPLENUCLEUS = r"""((?P[A-Z]{1,3})|(?P\d{1,3}))""" atom_cartesian_strict = re.compile(r'\A' + r'(?P' + SIMPLENUCLEUS + r')' + SEP + CARTXYZ + r'\Z', re.IGNORECASE | re.VERBOSE) xyz1 = re.compile(r'\A' + r'(?P\d+)' + r'[\s,]*' + r'((?P(bohr|au))|(?Pang))?' + r'\Z', re.IGNORECASE) xyz2 = re.compile(r'\A' + CHGMULT, re.VERBOSE) atom_cartesian = re.compile(r'\A' + r'(?P' + NUCLEUS + r')' + SEP + CARTXYZ + r'\Z', re.IGNORECASE | re.VERBOSE) def _filter_xyz(string, strict): """Handle extracting atom, units, and chg/mult lines from `string`. Parameters ---------- strict : bool Whether to enforce a strict XYZ file format or to allow units, chg/mult, and add'l atom info. Returns ------- str, dict Returns first a subset of `string` containing the unmatched contents. These are generally input violations unless handled by a subsequent processing function. Returns second a dictionary with processed extractions. Contains (some optional) the following keys. molecular_charge : float, optional (`strict=False` only) molecular_multiplicity : int, optional (`strict=False` only) geom elbl units : {'Angstrom', 'Bohr'} (`Bohr` `strict=False` only) """ def process_bohrang(matchobj): nat = matchobj.group('nat') # lgtm[py/unused-local-variable] if matchobj.group('uang'): processed['units'] = 'Angstrom' elif matchobj.group('ubohr'): processed['units'] = 'Bohr' return '' def process_system_cgmp(matchobj): processed['molecular_charge'] = float(matchobj.group('chg')) processed['molecular_multiplicity'] = int(matchobj.group('mult')) return '' def process_atom_cartesian(matchobj): processed['elbl'].append(matchobj.group('nucleus')) processed['geom'].append(float(matchobj.group('x'))) processed['geom'].append(float(matchobj.group('y'))) processed['geom'].append(float(matchobj.group('z'))) return '' #nat = 0 reconstitute = [] processed = {} processed['geom'] = [] processed['elbl'] = [] if strict: for iln, line in enumerate(string.split('\n')): line = line.strip() if iln == 0: line = re.sub(xyz1strict, '', line) elif iln == 1: continue else: line = re.sub(atom_cartesian_strict, process_atom_cartesian, line) if line: reconstitute.append(line) else: for iln, line in enumerate(string.split('\n')): line = line.strip() if iln == 0: line = re.sub(xyz1, process_bohrang, line) elif iln == 1: line = re.sub(xyz2, process_system_cgmp, line) else: line = re.sub(atom_cartesian, process_atom_cartesian, line) if line and iln != 1: reconstitute.append(line) if 'units' not in processed: processed['units'] = 'Angstrom' #if len(processed['geom']) != nat: # raise ValidationError processed['geom_hints'] = [] # no EFP return '\n'.join(reconstitute), processed QCElemental-0.5.0/qcelemental/molparse/nucleus.py000066400000000000000000000345351351361252000220220ustar00rootroot00000000000000import re from typing import List, Tuple from .regex import NUCLEUS from ..exceptions import NotAnElementError, ValidationError from ..periodic_table import periodictable _nucleus = re.compile(r'\A' + NUCLEUS + r'\Z', re.IGNORECASE | re.VERBOSE) def reconcile_nucleus(A:int=None, Z:int=None, E:str=None, mass:float=None, real:bool=None, label:str=None, speclabel:bool=True, nonphysical:bool=False, mtol:float=1.e-3, verbose:int=1) -> Tuple[int, int, str, float, bool, str]: """Forms consistent set of nucleus descriptors from all information from arguments, supplemented by the periodic table. At the least, must provide element identity somehow. Defaults to most-abundant isotope. Parameters ---------- A : int, optional Mass number, number of protons and neutrons. Z : int, optional Atomic number, number of protons. E : str, optional Element symbol from periodic table. mass : float, optional Atomic mass [u]. real : bool, optional Whether real or ghost/absent. label : str, optional Atom label according to :py:data:`qcelemental.molparse.regex.NUCLEUS`. speclabel : bool, optional If `True`, interpret `label` as potentially full nucleus spec including ghosting, isotope, mass, tagging information, e.g., ``@13C_mine`` or ``He4@4.01``. If `False`, interpret `label` as only the user/tagging extension to nucleus label, e.g. ``_mine`` or ``4`` in the previous examples. nonphysical : bool, optional When `True`, turns off sanity checking that prevents periodic table violations (e.g, light uranium: ``1U@1.007``). mtol : float, optional How different `mass` can be from a known nuclide mass and still merit the mass number assignment. Note that for elements dominated by a single isotope, the default may not be tight enough to prevent standard atomic weight (abundance-average of isotopes) from being labeled as the dominant isotope for A. verbose : int, optional Quantity of printing. Returns ------- A, Z, E, mass, real, userlabel : int, int, str, float, bool, str mass number, unless clues don't point to a known nuclide, in which case `-1`. atomic number. element symbol, capitalized. mass value [u]. real/ghost. user portion of `label` if present, else ''. Raises ------ qcelemental.NotAnElementError qcelemental.ValidationError Examples -------- >>> reconcile_nucleus(E='co') >>> reconcile_nucleus(Z=27) >>> reconcile_nucleus(A=59, Z=27) >>> reconcile_nucleus(E='cO', mass=58.933195048) >>> reconcile_nucleus(A=59, Z=27, E='CO') >>> reconcile_nucleus(A=59, E='cO', mass=58.933195048) >>> reconcile_nucleus(label='co') >>> reconcile_nucleus(label='59co') >>> reconcile_nucleus(label='co@58.933195048') >>> reconcile_nucleus(A=59, Z=27, E='cO', mass=58.933195048, label='co@58.933195048') >>> reconcile_nucleus(A=59, Z=27, E='cO', mass=58.933195048, label='27@58.933195048') >>> reconcile_nucleus(label='27') 59, 27, 'Co', 58.933195048, True, '' >>> reconcile_nucleus(label='co_miNe') >>> reconcile_nucleus(label='co_mIne@58.933195048') 59, 27, 'Co', 58.933195048, True, '_mine' >>> reconcile_nucleus(E='cO', mass=58.933) >>> reconcile_nucleus(label='cO@58.933') 59, 27, 'Co', 58.933, True, '' >>> assert 59, 27, 'Co', 58.933, True, '' == reconcile_nucleus(E='cO', mass=58.933, mtol=1.e-4)) AssertionError >>> reconcile_nucleus(E='Co', A=60) >>> reconcile_nucleus(Z=27, A=60, real=True) >>> reconcile_nucleus(E='Co', A=60) >>> reconcile_nucleus(Z=27, mass=59.933817059) >>> reconcile_nucleus(A=60, Z=27, mass=59.933817059) >>> reconcile_nucleus(label='60Co') >>> reconcile_nucleus(label='27', mass=59.933817059) >>> reconcile_nucleus(label='Co', mass=59.933817059) >>> reconcile_nucleus(A=60, label='Co') 60, 27, 'Co', 59.933817059, True, '' >>> reconcile_nucleus(E='Co', A=60, real=False)) >>> reconcile_nucleus(A=60, Z=27, mass=59.933817059, real=0)) >>> reconcile_nucleus(label='@60Co')) >>> reconcile_nucleus(label='Gh(27)', mass=59.933817059)) >>> reconcile_nucleus(label='@Co', mass=59.933817059)) >>> reconcile_nucleus(A=60, label='Gh(Co)')) 60, 27, 'Co', 59.933817059, False, '' >>> reconcile_nucleus(Z=27, mass=200, nonphysical=True) 60, 27, 'Co', 200.00000000, True, '' >>> reconcile_nucleus(mass=60.6, Z=27) >>> reconcile_nucleus(mass=60.6, E='Co') >>> reconcile_nucleus(mass=60.6, label='27') >>> reconcile_nucleus(label='Co@60.6') -1, 27, 'Co', 60.6, True, '' >>> reconcile_nucleus(mass=60.6, Z=27, A=61)) >>> reconcile_nucleus(A=80, Z=27) >>> reconcile_nucleus(Z=27, mass=200) >>> reconcile_nucleus(Z=27, mass=-200, nonphysical=True) >>> reconcile_nucleus(Z=-27, mass=200, nonphysical=True) >>> reconcile_nucleus(Z=1, label='he') >>> reconcile_nucleus(A=4, label='3he') >>> reconcile_nucleus(label='@U', real=True) >>> reconcile_nucleus(label='U', real=False) ValidationError """ # <<< define functions def reconcile(exact, tests, feature): """Returns a member from `exact` that passes all `tests`, else raises error for `feature`.""" for candidate in exact: assessment = [fn(candidate) for fn in tests] text.append("""Assess {} candidate {}: {} --> {}""".format(feature, candidate, assessment, all(assessment))) if all(assessment): return candidate err = """Inconsistent or unspecified {}: A: {}, Z: {}, E: {}, mass: {}, real: {}, label: {}""".format( feature, A, Z, E, mass, real, label) if verbose > -1: print('\n\n' + '\n'.join(text)) raise ValidationError(err) def offer_element_symbol(e): """Given an element, what can be suggested and asserted about Z, A, mass?""" _Z = periodictable.to_Z(e) offer_atomic_number(_Z) def offer_atomic_number(z): """Given an atomic number, what can be suggested and asserted about Z, A, mass?""" z = int(z) z_symbol = periodictable.to_E(z) z_mass = periodictable.to_mass(z) z_a = periodictable.to_A(z) z_a2mass = periodictable._el2a2mass[z_symbol] z_a2mass_min = min(z_a2mass.keys()) z_a2mass_max = max(z_a2mass.keys()) z_mass2a_min = min(z_a2mass.values()) z_mass2a_max = max(z_a2mass.values()) Z_exact.append(z) Z_range.append(lambda x, z=z: x == z) A_exact.append(z_a) if nonphysical: A_range.append(lambda x: x == -1 or x >= 1) text.append("""For A, input Z: {}, requires 1 < A or -1, nonphysical""".format(z)) else: A_range.append(lambda x, amin=z_a2mass_min, amax=z_a2mass_max: x == -1 or (x >= amin and x <= amax)) text.append( """For A, input Z: {} requires {} < A < {} or -1, the known mass number range for element""".format( z, z_a2mass_min, z_a2mass_max)) m_exact.append(z_mass) if nonphysical: m_range.append(lambda x: x > 0.5) text.append("""For mass, input Z: {}, requires 0.5 < mass, nonphysical""".format(z)) else: m_range.append(lambda x, mmin=z_mass2a_min, mmax=z_mass2a_max: x >= mmin - mmtol and x <= mmax + mmtol) text.append( """For mass, input Z: {} requires {} < mass < {} +/-{}, the known mass range for element""".format( z, z_mass2a_min, z_mass2a_max, mmtol)) def offer_mass_number(z, a): """Given a mass number and element, what can be suggested and asserted about A, mass?""" a = int(a) a_eliso = periodictable.to_E(z) + str(a) a_mass = periodictable.to_mass(a_eliso) A_exact.append(a) A_range.append(lambda x, a=a: x == a) text.append("""For A, inputs Z: {}, A: {} require A == {}.""".format(z, a, a)) m_exact.append(a_mass) m_range.append(lambda x, a_mass=a_mass: abs(x - a_mass) < mtol) text.append("""For mass, inputs Z: {}, A: {} require abs(mass - {}) < {}""".format(z, a, a_mass, mtol)) def offer_mass_value(z, m): """Given a mass and element, what can be suggested and asserted about A, mass?""" m = float(m) m_a = int(round(m, 0)) m_eliso = periodictable.to_E(z) + str(m_a) try: if abs(periodictable.to_mass(m_eliso) - m) > mtol: # only offer A if known nuclide. C@12.4 != 12C m_a = -1 except NotAnElementError: m_a = -1 A_exact.append(m_a) A_range.append(lambda x, m_a=m_a: x == m_a) text.append("""For A, inputs Z: {}, m: {} require A == {}""".format(z, m, m_a)) m_exact.append(m) m_range.append(lambda x, m=m: x == m) text.append("""For mass, inputs Z: {}, m: {} require m == {}""".format(z, m, m)) def offer_reality(rgh): r_exact.append(rgh) r_range.append(lambda x, rgh=rgh: x == rgh) text.append("""For real/ghost, input rgh: {} requires rgh == {}""".format(rgh, rgh)) def offer_user_label(lbl): lbl = str(lbl).lower() l_exact.append(lbl) l_range.append(lambda x, lbl=lbl: x == lbl) text.append("""For user label, input lbl: {} requires lbl == {}""".format(lbl, lbl)) # <<< initialize text = ['', """--> Inp: A={}, Z={}, E={}, mass={}, real={}, label={}""".format(A, Z, E, mass, real, label)] Z_exact: List = [] # *_exact are candidates for the final value Z_range: List = [] # *_range are tests that the final value must pass to be valid A_exact: List = [] A_range: List = [] m_exact: List = [] m_range: List = [] r_exact = [True] # default real/ghost is real r_range: List = [] l_exact = [''] # default user label is empty string l_range: List = [] mmtol = 0.5 # tolerance for mass outside known masses for element # <<< collect evidence for Z/A/m, then reconcile Z if Z is not None: offer_atomic_number(Z) if E is not None: offer_element_symbol(E) if label is not None and speclabel is True: lbl_A, lbl_Z, lbl_E, lbl_mass, lbl_real, lbl_user = parse_nucleus_label(label) if lbl_Z is not None: offer_atomic_number(lbl_Z) if lbl_E is not None: offer_element_symbol(lbl_E) Z_final = reconcile(Z_exact, Z_range, 'atomic number') E_final = periodictable.to_E(Z_final) # <<< collect more evidence for A/m, then reconcile them if A is not None: offer_mass_number(Z_final, A) if mass is not None: offer_mass_value(Z_final, mass) if real is not None: offer_reality(real) if label is not None: if speclabel: offer_reality(lbl_real) if lbl_A is not None: offer_mass_number(Z_final, lbl_A) if lbl_mass is not None: offer_mass_value(Z_final, lbl_mass) if lbl_user is not None: offer_user_label(lbl_user) else: offer_user_label(label) mass_final = reconcile(m_exact, m_range, 'mass') A_final = reconcile(A_exact, A_range, 'mass number') real_final = reconcile(r_exact, r_range, 'real/ghost') user_final = reconcile(l_exact, l_range, 'user label') text.append("""<-- Out: A={}, Z={}, E={}, mass={}, real={}, user={}""".format(A_final, Z_final, E_final, mass_final, real_final, user_final)) if verbose >= 2: print('\n'.join(text)) return (A_final, Z_final, E_final, mass_final, real_final, user_final) def parse_nucleus_label(label): """Separate molecule nucleus string into fields. Parameters ---------- label : str Conveys at least element and ghostedness and possibly isotope, mass, and user info in accordance with :py:data:`qcelemental.molparse.regex.NUCLEUS`. Returns ------- A, Z, E, mass, real, user : int or None, int or None, str or None, float or None, bool, str or None Field breakdown of `label`. Raises ------ qcelemental.ValidationError If `label` does not match NUCLEUS. Examples -------- >>> parse_nucleus_label('@ca_miNe') None, None, 'ca', None False, '_miNe' >>> parse_nucleus_label('Gh(Ca_mine)') None, None, 'Ca', None '_mine', False >>> parse_nucleus_label('@Ca_mine@1.07') None, None, 'Ca', 1.07 False, '_mine' >>> parse_nucleus_label('Gh(cA_MINE@1.07)') None, None, 'cA', 1.07 False, '_MINE' >>> parse_nucleus_label('@40Ca_mine@1.07') 40, None, 'Ca', 1.07 False, '_mine' >>> parse_nucleus_label('Gh(40Ca_mine@1.07)') 40, None, 'Ca', 1.07 False, '_mine' >>> parse_nucleus_label('444lu333@4.0') 444, None, 'lu', 4.0 True, '333' >>> parse_nucleus_label('@444lu333@4.4') 444, None, 'lu', 4.4 False, '333' >>> parse_nucleus_label('8i') 8, None, 'i', None True, None >>> parse_nucleus_label('53_mI4') None, 53, None, None True, '_mI4' >>> parse_nucleus_label('@5_MINEs3@4.4') None, 5, None, 4.4 False, '_MINEs3' >>> parse_nucleus_label('Gh(555_mines3@0.1)') None, 555, None, 0.1 False, '_mines3' """ matchobj = _nucleus.match(label) if matchobj: real = not (matchobj.group('gh1') or matchobj.group('gh2')) if matchobj.group('A'): A = int(matchobj.group('A')) else: A = None if matchobj.group('Z'): Z = int(matchobj.group('Z')) else: Z = None E = matchobj.group('E') if matchobj.group('user1'): user = matchobj.group('user1') elif matchobj.group('user2'): user = matchobj.group('user2') else: user = None if matchobj.group('mass'): mass = float(matchobj.group('mass')) else: mass = None else: raise ValidationError("""Nucleus label is not parseable: {}""".format(label)) return A, Z, E, mass, real, user QCElemental-0.5.0/qcelemental/molparse/pubchem.py000066400000000000000000000143241351361252000217610ustar00rootroot00000000000000"""Queries the PubChem database using a compound name (i.e. 1,3,5-hexatriene) to obtain a molecule string that can be passed to Molecule. :: results = getPubChemObj("1,3,5-hexatriene") Results is an array of results from PubChem matches to your query. for entry in results: entry["CID"] => PubChem compound identifer entry["IUPAC"] => IUPAC name for the resulting compound entry["PubChemObj"] => instance of PubChemObj for this compound entry["PubChemObj"].get_molecule_string() => returns a string compatible with Psi4's Molecule creation """ import json import re from ..exceptions import ValidationError from .regex import DECIMAL class PubChemObj(): def __init__(self, cid, mf, iupac, charge): self.url = 'http://pubchem.ncbi.nlm.nih.gov/summary/summary.cgi' self.cid = cid self.mf = mf self.iupac = iupac self.molecular_charge = charge self.natom = 0 self.dataSDF = '' def __str__(self): return "%17d %s\n" % (self.cid, self.iupac) def get_sdf(self): """Function to return the SDF (structure-data file) of the PubChem object.""" from urllib.request import urlopen, Request from urllib.parse import quote from urllib.error import URLError if (len(self.dataSDF) == 0): url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/SDF?record_type=3d'.format( quote(str(self.cid))) req = Request(url, headers={'Accept': 'chemical/x-mdl-sdfile'}) try: self.dataSDF = urlopen(req).read().decode('utf-8') except URLError as e: msg = "Unable to open\n\n%s\n\ndue to the error\n\n%s\n\n" % (url, e) msg += "It is possible that 3D information does not exist for this molecule in the PubChem database\n" print(msg) raise ValidationError(msg) return self.dataSDF def name(self): """Function to return the IUPAC name of the PubChem object.""" return self.iupac def get_cartesian(self): """Function to return a string of the atom symbol and XYZ coordinates of the PubChem object. """ try: sdf_text = self.get_sdf() except Exception as e: raise ValidationError(e.message) # Find # NA NB CONSTANT # 14 13 0 0 0 0 0 0 0999 V2000 m = re.search(r'^\s*(\d+)\s+(?:\d+\s+){8}V2000$', sdf_text, re.MULTILINE) self.natom = 0 if (m): self.natom = int(m.group(1)) if self.natom == 0: raise ValidationError("PubChem: Cannot find the number of atoms. 3D data doesn't appear\n" + "to be available for %s.\n" % self.iupac) lines = re.split('\n', sdf_text) # 3.7320 -0.2500 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 atom_re = re.compile(r'^\s*' + DECIMAL + r'\s+' + DECIMAL + r'\s+' + DECIMAL + r'\s*(\w+)(?:\s+\d+){12}', re.VERBOSE) molecule_string = "PubchemInput\n" atom_count = 0 for line in lines: atom_match = atom_re.match(line) if atom_match: x = float(atom_match.group(1)) y = float(atom_match.group(2)) z = float(atom_match.group(3)) sym = atom_match.group(4) atom_count = atom_count + 1 molecule_string += "%s %10.6f %10.6f %10.6f\n" % (sym, x, y, z) if (atom_count == self.natom): break return molecule_string def get_molecule_string(self): """Function to obtain a molecule string through get_cartesian() or fail. """ try: return self.get_cartesian() except Exception as e: return e.message def get_pubchem_results(name): """Function to query the PubChem database for molecules matching the input string. Builds a PubChemObj object if found. """ from urllib.request import urlopen from urllib.parse import quote from urllib.error import URLError if name.isdigit(): print("\tSearching PubChem database for CID {}".format(name)) url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{}/property/IUPACName,MolecularFormula,Charge/JSON'.format( quote(name)) else: if name.endswith('*'): name = name[:-1] loose = True else: loose = False print("\tSearching PubChem database for {} ({} returned)".format( name, 'all matches' if loose else 'single best match')) url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/{}/property/IUPACName,MolecularFormula,Charge/JSON?name_type={}'.format( quote(name), 'word' if loose else 'complete') try: response = urlopen(url) except URLError as e: # travis urllib.error.HTTPError: HTTP Error 503: Service Unavailable raise ValidationError( """\tPubchemError\n%s\n\treceived when trying to open\n\t%s\n\tCheck your internet connection, and the above URL, and try again.\n""" % (str(e), url)) from e data = json.loads(response.read().decode('utf-8')) results = [] for d in data['PropertyTable']['Properties']: if 'IUPACName' not in d: continue pubobj = PubChemObj(d['CID'], d['IUPACName'], d['IUPACName'], d['Charge']) results.append(pubobj) print("\tFound {} result(s)".format(len(results))) return results if __name__ == "__main__": # * comment "..exceptions" line above # * sulfonate below has no 3D structure available # * XYZ printing for tropolone* suppressed b/c too many and some have no 3D for inp in [ "1-methoxy-4-[(E)-prop-1-enyl]benzene", "4-[bis(4-hydroxyphenyl)methyl]phenol", "tropolone", "tropolone*", "sodium benzenesulfonate" ]: # pragma: no cover obj = get_pubchem_results(inp) for r in obj: print(r, end='') if inp != 'tropolone*': print(r.get_molecule_string()) QCElemental-0.5.0/qcelemental/molparse/regex.py000066400000000000000000000053561351361252000214550ustar00rootroot00000000000000# remember to use re.VERBOSE with DECIMAL, NUCLEUS, NUMBER, VERSION_PATTERN NUCLEUS = r"""(?: (?P@)|(?PGh\())? # optional ghost: @stuff or Gh(stuff) ... ( # mandatory element: AEuser or Zuser (?P (?P\d+)? # optional mass number, A (?P[A-Z]{1,3}) # mandatory atomic symbol, E (?P(_\w+)|(\d+))?) | # optional user label: Enumber or E_alphanum (?P (?P\d{1,3}) # mandatory atomic number, Z (?P(_\w+))?) # optional user label: Z_alphanum ) (?:@(?P\d+\.\d+))? # optional mass value [u] (?(gh2)\) # ... ghost )""" NUMBER = r"""( (?:[-+]?\d*\.\d+(?:[DdEe][-+]?\d+)?) | # .num with optional sign, exponent, wholenum (?:[-+]?\d+\.\d*(?:[DdEe][-+]?\d+)?) | # num. with optional sign, exponent, decimals (?:[-+]?\d+(?:[DdEe][-+]?\d+)?) # num with optional sign, exponent )""" DECIMAL = r"""( (?:[-+]?\d*\.\d+(?:[DdEe][-+]?\d+)?) | # .num with optional sign, exponent, wholenum (?:[-+]?\d+\.\d*(?:[DdEe][-+]?\d+)?) # num. with optional sign, exponent, decimals )""" SEP = r"""[\t ,]+""" ENDL = r"""[\t ,]*$""" CHGMULT = r"""(?P""" + NUMBER + r')' + SEP + r"""(?P\d+)""" CARTXYZ = r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' + SEP + r'(?P' + NUMBER + r')' # PEP 440 valid versions # * to avoid dependency on module "packaging", copied from https://github.com/pypa/packaging/blob/master/packaging/version.py#L182-L213 # * Deliberately not anchored to the start and end of the string, to make it easier for 3rd party code to reuse VERSION_PATTERN = r""" v? (?: (?:(?P[0-9]+)!)? # epoch (?P[0-9]+(?:\.[0-9]+)*) # release segment (?P
                                          # pre-release
            [-_\.]?
            (?P(a|b|c|rc|alpha|beta|pre|preview))
            [-_\.]?
            (?P[0-9]+)?
        )?
        (?P                                         # post release
            (?:-(?P[0-9]+))
            |
            (?:
                [-_\.]?
                (?Ppost|rev|r)
                [-_\.]?
                (?P[0-9]+)?
            )
        )?
        (?P                                          # dev release
            [-_\.]?
            (?Pdev)
            [-_\.]?
            (?P[0-9]+)?
        )?
    )
    (?:\+(?P[a-z0-9]+(?:[-_\.][a-z0-9]+)*))?       # local version
"""
QCElemental-0.5.0/qcelemental/molparse/to_schema.py000066400000000000000000000104111351361252000222710ustar00rootroot00000000000000import copy
from typing import Dict

import numpy as np

from ..exceptions import ValidationError
from ..physical_constants import constants
from ..util import unnp
from .to_string import formula_generator


def to_schema(molrec: Dict, dtype: str, units: str='Bohr', *, np_out: int=False) -> Dict:
    """Translate molparse internal Molecule spec into dictionary from other schemas.

    Parameters
    ----------
    molrec : dict
        Psi4 json Molecule spec.
    dtype : {'psi4', 1, 2}
        Molecule schema format.
        ``1`` is https://molssi-qc-schema.readthedocs.io/en/latest/auto_topology.html V1 + #44 + #53
        ``2`` is ``1`` with internal schema_name/version (https://github.com/MolSSI/QCSchema/pull/60)
    units : {'Bohr', 'Angstrom'}
        Units in which to write string. There is not an option to write in
        intrinsic/input units. Some `dtype` may not allow all units.
    np_out : bool, optional
        When `True`, fields originating from geom, elea, elez, elem, mass, real, elbl will be ndarray.
        Use `False` to get a json-able version.
    #return_type : {'json', 'yaml'} Serialization format string to return.

    Returns
    -------
    qcschema : dict
        Dictionary of the `dtype` repr of `molrec`.

    """
    qcschema: Dict = {}

    if molrec['units'] == 'Angstrom' and units == 'Bohr' and 'input_units_to_au' in molrec:
        factor = molrec['input_units_to_au']
    else:
        factor = constants.conversion_factor(molrec['units'], units)
    geom = np.array(molrec['geom']) * factor
    nat = geom.shape[0] // 3

    name = molrec.get('name', formula_generator(molrec['elem']))
    #    tagline = """auto-generated by qcdb from molecule {}""".format(name)

    if dtype == 'psi4':
        if units not in ['Angstrom', 'Bohr']:
            raise ValidationError("""Psi4 Schema {} allows only 'Bohr'/'Angstrom' coordinates, not {}.""".format(
                dtype, units))
        qcschema = copy.deepcopy(molrec)
        qcschema['geom'] = geom
        qcschema['units'] = units
        qcschema['name'] = name

    elif dtype in [1, 2]:
        if units != 'Bohr':
            raise ValidationError("""QC_JSON_Schema {} allows only 'Bohr' coordinates, not {}.""".format(dtype, units))

        molecule = {}
        molecule['symbols'] = np.array(molrec['elem'])
        molecule['geometry'] = geom
        molecule['masses'] = np.array(molrec['mass'])
        molecule['atomic_numbers'] = np.array(molrec['elez'])
        molecule['mass_numbers'] = np.array(molrec['elea'])
        molecule['atom_labels'] = np.array(molrec['elbl'])
        molecule['name'] = name
        if 'comment' in molrec:
            molecule['comment'] = molrec['comment']
        molecule['molecular_charge'] = molrec['molecular_charge']
        molecule['molecular_multiplicity'] = molrec['molecular_multiplicity']
        molecule['real'] = np.array(molrec['real'])
        fidx = np.split(np.arange(nat), molrec['fragment_separators'])
        molecule['fragments'] = [fr.tolist() for fr in fidx]
        molecule['fragment_charges'] = np.array(molrec['fragment_charges']).tolist()
        molecule['fragment_multiplicities'] = np.array(molrec['fragment_multiplicities']).tolist()
        molecule['fix_com'] = molrec['fix_com']
        molecule['fix_orientation'] = molrec['fix_orientation']
        if 'fix_symmetry' in molrec:
            molecule['fix_symmetry'] = molrec['fix_symmetry']
        molecule['provenance'] = copy.deepcopy(molrec['provenance'])
        if 'connectivity' in molrec:
            molecule['connectivity'] = copy.deepcopy(molrec['connectivity'])

        if dtype == 1:
            qcschema = {'schema_name': 'qcschema_input', 'schema_version': 1, 'molecule': molecule}
        elif dtype == 2:
            qcschema = molecule
            qcschema.update({'schema_name': 'qcschema_molecule', 'schema_version': 2})

    else:
        raise ValidationError("Schema dtype not understood, valid options are {{'psi4', 1, 2}}. Found {}.".format(dtype))

    if not np_out:
        qcschema = unnp(qcschema)

    return qcschema

    #if return_type == 'json':
    #    return json.dumps(qcschema)
    #elif return_type == 'yaml':
    #    import yaml
    #    return yaml.dump(qcschema)
    #else:
    #    raise ValidationError("""Return type ({}) not recognized.""".format(return_type))
QCElemental-0.5.0/qcelemental/molparse/to_string.py000066400000000000000000000257671351361252000223630ustar00rootroot00000000000000import collections
from typing import Dict

import numpy as np

from ..physical_constants import constants


def to_string(molrec: Dict,
              dtype: str,
              units: str = None,
              *,
              atom_format: str = None,
              ghost_format: str = None,
              width: int = 17,
              prec: int = 12,
              return_data: bool = False):
    """Format a string representation of QM molecule.

    Parameters
    ----------
    molrec : dict
        Psi4 json Molecule spec.
    dtype : {'xyz', 'cfour', 'nwchem', 'molpro'}
        Overall string format. Note that it's possible to request variations
        that don't fit the dtype spec so may not be re-readable (e.g., ghost
        and mass in nucleus label with ``'xyz'``).
        'cfour' forces nucleus label, ignoring atom_format, ghost_format
    units : str, optional
        Units in which to write string. Usually ``Angstrom`` or ``Bohr``
        but may be any length unit.  There is not an option to write in
        intrinsic/input units. For ``dtype='xyz', units='Bohr'`` where the
        format doesn't have a slot to specify units, "au" is added so that
        readable as ``dtype='xyz+'``.
    atom_format : str, optional
        General format is ``'{elem}'``. A format string that may contain fields
        'elea' (-1 will be ''), 'elez', 'elem', 'mass', 'elbl' in any
        arrangement. For example, if a format naturally uses element symbol
        and you want atomic number instead with mass info, too, pass
        ``'{elez}@{mass}'``. See `ghost_format` for handling field 'real'.
    ghost_format : str, optional
        General format is ``'@{elem}'``. Like `atom_format`, but this formatter
        is used when `real=False`. To suppress ghost atoms, use `ghost_format=''`.
    width : int, optional
        Field width for formatting coordinate float.
    prec : int, optional
        Number of decimal places for formatting coordinate float.
    return data : bool, optional
        Whether to return dictionary with additional info from the molrec that's
        not expressible in the string but may be of interest to the QC program.
        Note that field names are in QCSchema, not molrec, language.

    Returns
    -------
    str
        String representation of the molecule.
    str, dict
        When ``return_data=True`, return additionally a dictionary
            keywords: key, value pairs for processing molecule info into options
            fields: aspects of ``qcelemental.models.Molecule`` expressed into
                    string _or_ keywords.

    """

    #funits, fiutau = process_units(molrec)
    #molrec = self.to_dict(force_units=units, np_out=True)

    dtype = dtype.lower()

    default_units = {
        "xyz": "Angstrom",
        "cfour": "Bohr",
        "gamess": "Bohr",
        "molpro": "Bohr",
        "nwchem": "Bohr",
        "psi4": "Bohr",
        "terachem": "Bohr"
    }
    if dtype not in default_units:
        raise KeyError(f"dtype '{dtype}' not understood.")

    # Handle units
    if units is None:
        units = default_units[dtype]

    if molrec['units'] == 'Angstrom' and units.capitalize() == 'Angstrom':
        factor = 1.
    elif molrec['units'] == 'Angstrom' and units.capitalize() == 'Bohr':
        if 'input_units_to_au' in molrec:
            factor = molrec['input_units_to_au']
        else:
            factor = 1. / constants.bohr2angstroms
    elif molrec['units'] == 'Bohr' and units.capitalize() == 'Angstrom':
        factor = constants.bohr2angstroms
    elif molrec['units'] == 'Bohr' and units.capitalize() == 'Bohr':
        factor = 1.
    else:
        factor = constants.conversion_factor(molrec['units'], units)
    geom = np.array(molrec['geom']).reshape((-1, 3)) * factor

    name = molrec.get('name', formula_generator(molrec['elem']))
    tagline = """auto-generated by QCElemental from molecule {}""".format(name)
    data = {
        'fields': ['atomic_numbers', 'geometry', 'symbols'],
        'keywords': {},
    }

    if dtype == 'xyz':
        # Notes
        # * if units not in umap (e.g., nm), can't be read back in by from_string()

        atom_format = '{elem}' if atom_format is None else atom_format
        ghost_format = '@{elem}' if ghost_format is None else ghost_format
        umap = {'bohr': 'au', 'angstrom': ''}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)
        nat = len(atoms)

        first_line = """{} {}""".format(str(nat), umap.get(units.lower(), units.lower()))
        smol = [first_line.rstrip(), name]
        smol.extend(atoms)

    elif dtype == 'cfour':
        # Notes
        # * losing identity of ghost atoms. picked up again in basis formatting
        # * casting 'molecular_charge' to int
        # * no spaces at the beginning of 1st/comment line is important

        atom_format = '{elem}'
        ghost_format = 'GH'
        # TODO handle which units valid
        umap = {'bohr': 'bohr', 'angstrom': 'angstrom'}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        smol = [tagline]
        smol.extend(atoms)

        data['fields'].extend(['molecular_charge', 'molecular_multiplicity'])
        data['keywords'] = {
            'charge': int(molrec['molecular_charge']),
            'multiplicity': molrec['molecular_multiplicity'],
            'units': umap.get(units.lower()),
            'coordinates': 'cartesian',
        }

    elif dtype == 'molpro':

        atom_format = '{elem}'
        ghost_format = '{elem}'
        umap = {'bohr': 'bohr', 'angstrom': 'angstrom'}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        smol = []

        # Don't orient the molecule if asked to fix_com or fix_orientation
        if molrec['fix_orientation'] or molrec['fix_com']:
            smol.append('{orient,noorient}')

        # Have no symmetry if asked to fix_symmetry
        if 'fix_symmetry' in molrec.keys() and molrec['fix_symmetry'] == 'c1':
            smol.append('{symmetry,nosym}')
        elif 'fix_symmetry' not in molrec.keys():
            smol.append('{symmetry,auto}')

        smol.append('')

        units_line = f"""{{{umap.get(units.lower())}}}"""
        geom_line = """geometry={"""
        end_bracket = """}"""
        smol.append(units_line)
        smol.append(geom_line)
        smol.extend(atoms)
        smol.append(end_bracket)

        # Write ghost atom declarations in Molpro (using dummy card)
        if False in molrec['real']:
            ghost_line = 'dummy,' + ','.join([str(idx + 1) for idx, real in enumerate(molrec['real']) if not real])
            smol.append(ghost_line)

        smol.append(f"set,charge={molrec['molecular_charge']}")
        smol.append(f"set,multiplicity={molrec['molecular_multiplicity']}")

    elif dtype == 'nwchem':

        atom_format = '{elem}'
        ghost_format = 'GH'
        # TODO handle which units valid
        umap = {'bohr': 'bohr', 'angstrom': 'angstroms', 'nm': 'nanometers', 'pm': 'picometers'}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        first_line = f"""geometry units {umap.get(units.lower())}"""
        # noautosym nocenter  # no reorienting input geometry
        fix_symm = molrec.get('fix_symmetry', None)
        symm_line = ''
        if fix_symm:
            symm_line = 'symmetry {}'.format(fix_symm)  # not quite what Jiyoung had
        last_line = """end"""
        smol = [first_line]
        smol.extend(atoms)
        smol.append(symm_line)
        smol.append(last_line)

    elif dtype == 'gamess':
        # Untested by gamess itself

        atom_format = ' {elem}{elbl} {elez}'
        ghost_format = ' {BQ} -{elez}'

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        first_line = """ $data"""
        second_line = f""" {tagline}"""
        third_line = """ C1"""
        last_line = """ $end"""

        smol = [first_line, second_line, third_line]
        smol.extend(atoms)
        smol.append(last_line)

    elif dtype == 'terachem':

        atom_format = '{elem}'
        ghost_format = 'X{elem}'
        umap = {'bohr': 'au', 'angstrom': ''}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        first_line = f"""{len(atoms)} {umap[units.lower()]}"""
        smol = [first_line.rstrip(), name]
        smol.extend(atoms)

    elif dtype == 'psi4':

        atom_format = '{elem}'
        ghost_format = 'Gh({elem})'
        umap = {'bohr': 'bohr', 'angstrom': 'angstrom'}

        atoms = _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, 2)

        smol = [f"""{int(molrec['molecular_charge'])} {molrec['molecular_multiplicity']}"""]
        split_atoms = np.split(atoms, molrec["fragment_separators"])
        for ifr, fr in enumerate(split_atoms):
            smol.extend(['--', f"""{int(molrec['fragment_charges'][ifr])} {molrec['fragment_multiplicities'][ifr]}"""])
            smol.extend(fr.tolist())

        # append units and any other non-default molecule keywords
        smol.append(f"units {umap[units.lower()]}")
        if molrec["fix_com"]:
            smol.append("no_com")
        if molrec["fix_orientation"]:
            smol.append("no_reorient")

        data['fields'].extend([
            'molecular_charge', 'molecular_multiplicity', 'fragments', 'fragment_charges', 'fragment_multiplicities',
            'fix_com', 'fix_orientation', 'real',
        ])
        data['keywords'] = {}

    else:
        raise KeyError(f"dtype '{dtype}' not understood.")

    smol = '\n'.join(smol) + '\n'
    if return_data:
        return smol, data
    else:
        return smol


def _atoms_formatter(molrec, geom, atom_format, ghost_format, width, prec, sp):
    """Format a list of strings, one per atom from `molrec`."""

    #geom = molrec['geom'].reshape((-1, 3))
    nat = geom.shape[0]
    fxyz = """{:>{width}.{prec}f}"""
    sp = """{:{sp}}""".format('', sp=sp)

    atoms = []
    for iat in range(nat):
        atom = []
        atominfo = {
            'elea': '' if molrec['elea'][iat] == -1 else molrec['elea'][iat],
            'elez': molrec['elez'][iat],
            'elem': molrec['elem'][iat],
            'mass': molrec['mass'][iat],
            'elbl': molrec['elbl'][iat]
        }

        if molrec['real'][iat]:
            nuc = """{:{width}}""".format(atom_format.format(**atominfo), width=width)
            atom.append(nuc)
        else:
            if ghost_format == '':
                continue
            else:
                nuc = """{:{width}}""".format(ghost_format.format(**atominfo), width=width)
                atom.append(nuc)

        atom.extend([fxyz.format(x, width=width, prec=prec) for x in geom[iat]])
        atoms.append(sp.join(atom))

    return atoms


def formula_generator(elem):
    """Return simple chemical formula from element list `elem`.

    >>> formula_generator(['C', 'Ca', 'O', 'O', 'Ag']
    AgCCaO2

    """
    counted = collections.Counter(elem)
    return ''.join((el if cnt == 1 else (el + str(cnt))) for el, cnt in sorted(counted.items()))
QCElemental-0.5.0/qcelemental/molutil/000077500000000000000000000000001351361252000176235ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/molutil/__init__.py000066400000000000000000000000701351361252000217310ustar00rootroot00000000000000from .align import B787, kabsch_align, compute_scramble
QCElemental-0.5.0/qcelemental/molutil/align.py000066400000000000000000000614501351361252000212750ustar00rootroot00000000000000import time
import itertools
import collections

import numpy as np

from ..exceptions import ValidationError
from ..models import AlignmentMill
from ..physical_constants import constants
from ..testing import compare_values
from ..util import (distance_matrix, linear_sum_assignment, random_rotation_matrix, uno, which_import)


def _nre(Z, geom):
    """Nuclear repulsion energy"""

    nre = 0.
    for at1 in range(geom.shape[0]):
        for at2 in range(at1):
            dist = np.linalg.norm(geom[at1] - geom[at2])
            nre += Z[at1] * Z[at2] / dist
    return nre


def _pseudo_nre(Zhash, geom):
    """Pseudo nuclear repulsion energy where non-physical Z contrived from `Zhash`."""

    Zidx = list(set(sorted(Zhash)))
    pZ = [Zidx.index(z) for z in Zhash]
    return _nre(pZ, geom)


def B787(cgeom,
         rgeom,
         cuniq,
         runiq,
         do_plot=False,
         verbose=1,
         atoms_map=False,
         run_resorting=False,
         mols_align=False,
         run_to_completion=False,
         algorithm='hungarian_uno',
         uno_cutoff=1.e-3,
         run_mirror=False):
    """Use Kabsch algorithm to find best alignment of geometry `cgeom` onto
    `rgeom` while sampling atom mappings restricted by `runiq` and `cuniq`.

    Parameters
    ----------
    rgeom : ndarray of float
        (nat, 3) array of reference/target/unchanged geometry. Assumed [a0]
        for RMSD purposes.
    cgeom : ndarray of float
        (nat, 3) array of concern/changeable geometry. Assumed [a0] for RMSD
        purposes. Must have same nat, units, and atom content as rgeom.
    runiq : ndarray of str
        (nat,) array indicating which rows (atoms) in `rgeom` are shuffleable
        without changing the molecule. Generally hashes of element symbol and
        mass are used, but could be as simple as ['C', 'H', 'H', 'D', 'H'] for
        monodeuterated methane.
    cuniq : ndarray of str
        (nat,) array indicating which rows (atoms) in `cgeom` are shuffleable.
        See `runiq` for more details. Strings and count in `cuniq` must match
        `runiq`. That is, `sorted(cuniq) == sorted(runiq)`.
    do_plot : bool, optional
        Pops up a mpl plot showing before, after, and ref geometries.
    verbose : int, optional
        Quantity of printing. 0 to silence.
    atoms_map : bool, optional
        Whether atom1 of rgeom already corresponds to atom1 of cgeom and so on.
        If `True`, no resorting will be run, parameters `runiq` and `cuniq`
        may be passed as `None`, and much time will be saved.
    run_resorting : bool, optional
        Run the resorting machinery even if unnecessary because `atoms_map=True`.
    mols_align : bool or float, optional
        Whether ref_mol and concern_mol have identical geometries by eye
        (barring orientation or atom mapping) and expected final RMSD = 0.
        If `True`, procedure is truncated when RMSD condition met, saving time.
        If float, convcrit at which search for minimium truncates.
    run_to_completion : bool, optional
        Run reorderings to completion (past RMSD = 0) even if unnecessary because
        `mols_align=True`. Used to test worst-case timings.
    algorithm : {'hungarian_uno', 'permutative'}, optional
        When `atoms_map=False`, screening algorithm for plausible atom mappings.
        `permutative` suitable only for small systems.
    uno_cutoff : float, optional
        TODO
    run_mirror : bool, optional
        Run alternate geometries potentially allowing best match to `rgeom`
        from mirror image of `cgeom`. Only run if system confirmed to
        be nonsuperimposable upon mirror reflection.

    Returns
    -------
    float, tuple
        First item is RMSD [A] between `rgeom` and the optimally aligned
        geometry computed.
        Second item is a AlignmentMill namedtuple with fields
        (shift, rotation, atommap, mirror) that prescribe the transformation
        from `cgeom` and the optimally aligned geometry.

    """
    # validation
    if rgeom.shape != cgeom.shape or rgeom.shape[1] != 3:
        raise ValidationError("""natom doesn't match: {} != {}""".format(rgeom.shape, cgeom.shape))
    nat = rgeom.shape[0]
    if atoms_map and runiq is None and cuniq is None:
        runiq = np.array([''] * nat)
        cuniq = np.array([''] * nat)
    if sorted(runiq) != sorted(cuniq):
        raise ValidationError("""atom subclasses unequal:\n  {}\n  {}""".format(runiq, cuniq))

    if run_mirror:
        # use aligner to check if system and its (xz-plane) mirror image are
        #   superimposible and hence whether its worth doubling the number of Kabsch
        #   runs below to check for mirror-image matches
        mcgeom = np.copy(cgeom)
        mcgeom[:, 1] *= -1.
        exact = 1.e-6
        mrmsd, msolution = B787(mcgeom,
                                cgeom,
                                cuniq,
                                cuniq,
                                do_plot=False,
                                verbose=0,
                                atoms_map=False,
                                mols_align=exact,
                                run_mirror=False,
                                uno_cutoff=0.1)
        superimposable = mrmsd < exact
        if verbose >= 1 and superimposable:
            print(
                'Not testing for mirror-image matches (despite `run_mirror`) since system and its mirror are superimposable'
            )

    # initialization
    best_rmsd = 100.  # [A]
    ocount = 0
    hold_solution = None
    run_resorting = run_resorting or not atoms_map
    if mols_align is True:
        a_convergence = 1.e-3
    elif mols_align is False:
        a_convergence = 0.0
    else:
        a_convergence = mols_align

    # initial presentation
    atomfmt2 = """  {} {:16.8f} {:16.8f} {:16.8f}"""

    if verbose >= 2:
        print('<<<  Reference:')
        for at, _ in enumerate(runiq):
            print(atomfmt2.format(runiq[at][:6], *rgeom[at]))

        print('<<<  Concern:')
        for at, _ in enumerate(cuniq):
            print(atomfmt2.format(cuniq[at][:6], *cgeom[at]))

    # start_rmsd is nonsense if not atoms_map
    start_rmsd = np.linalg.norm(cgeom - rgeom) * constants.bohr2angstroms / np.sqrt(nat)
    if verbose >= 1:
        print('Start RMSD = {:8.4f} [A] (naive)'.format(start_rmsd))

    def _plausible_atom_orderings_wrapper(runiq,
                                          cuniq,
                                          rgeom,
                                          cgeom,
                                          run_resorting,
                                          algorithm='hungarian_uno',
                                          verbose=1,
                                          uno_cutoff=1.e-3):
        """Wrapper to _plausible_atom_orderings that bypasses it (`run_resorting=False`) when
        atoms of R & C known to be ordered. Easier to put logic here because _plausible is generator.

        """
        if run_resorting:
            return _plausible_atom_orderings(runiq,
                                             cuniq,
                                             rgeom,
                                             cgeom,
                                             algorithm=algorithm,
                                             verbose=verbose,
                                             uno_cutoff=uno_cutoff)
        else:
            return [np.arange(rgeom.shape[0])]

    t0 = time.time()
    tc = 0.
    for ordering in _plausible_atom_orderings_wrapper(runiq,
                                                      cuniq,
                                                      rgeom,
                                                      cgeom,
                                                      run_resorting,
                                                      algorithm=algorithm,
                                                      verbose=verbose,
                                                      uno_cutoff=uno_cutoff):
        t1 = time.time()
        ocount += 1
        npordd = np.asarray(ordering)
        _, RR, TT = kabsch_align(rgeom, cgeom[npordd, :], weight=None)

        temp_solution = AlignmentMill(shift=TT, rotation=RR, atommap=npordd, mirror=False)
        tgeom = temp_solution.align_coordinates(cgeom, reverse=False)
        if verbose >= 4:
            print('temp geom diff\n', tgeom - rgeom)
        temp_rmsd = np.linalg.norm(tgeom - rgeom) * constants.bohr2angstroms / np.sqrt(rgeom.shape[0])
        temp_rmsd = np.around(temp_rmsd, decimals=8)
        t2 = time.time()
        tc += t2 - t1

        if temp_rmsd < best_rmsd:
            best_rmsd = temp_rmsd
            hold_solution = temp_solution
            if verbose >= 1:
                print('<<<  trial {:8}  {} yields RMSD {}  >>>'.format(ocount, npordd, temp_rmsd))
            if not run_to_completion and best_rmsd < a_convergence:
                break
        else:
            if verbose >= 3:
                print('     trial {:8}  {} yields RMSD {}'.format(ocount, npordd, temp_rmsd))

        if run_mirror and not superimposable:
            t1 = time.time()
            ocount += 1
            icgeom = np.copy(cgeom)
            icgeom[:, 1] *= -1.
            _, RR, TT = kabsch_align(rgeom, icgeom[npordd, :], weight=None)

            temp_solution = AlignmentMill(shift=TT, rotation=RR, atommap=npordd, mirror=True)
            tgeom = temp_solution.align_coordinates(cgeom, reverse=False)
            if verbose >= 4:
                print('temp geom diff\n', tgeom - rgeom)
            temp_rmsd = np.linalg.norm(tgeom - rgeom) * constants.bohr2angstroms / np.sqrt(rgeom.shape[0])
            temp_rmsd = np.around(temp_rmsd, decimals=8)
            t2 = time.time()
            tc += t2 - t1

            if temp_rmsd < best_rmsd:
                best_rmsd = temp_rmsd
                hold_solution = temp_solution
                if verbose >= 1:
                    print('<<<  trial {:8}m {} yields RMSD {}  >>>'.format(ocount - 1, npordd, temp_rmsd))
                if not run_to_completion and best_rmsd < a_convergence:
                    break
            else:
                if verbose >= 3:
                    print('     trial {:8}m {} yields RMSD {}'.format(ocount - 1, npordd, temp_rmsd))

    t3 = time.time()
    if verbose >= 1:
        print('Total time [s] for {:6} iterations: {:.3}'.format(ocount, t3 - t0))
        print('Hungarian time [s] for atom ordering: {:.3}'.format(t3 - t0 - tc))
        print('Kabsch time [s] for mol alignment:    {:.3}'.format(tc))

    ageom, auniq = hold_solution.align_mini_system(cgeom, cuniq, reverse=False)
    final_rmsd = np.linalg.norm(ageom - rgeom) * constants.bohr2angstroms / np.sqrt(nat)
    assert (abs(best_rmsd - final_rmsd) < 1.e-3)

    if verbose >= 1:
        print('Final RMSD = {:8.4f} [A]'.format(final_rmsd))
        print('Mirror match:', hold_solution.mirror)
        print(hold_solution)

    # final presentation & plotting
    if verbose >= 2:
        print('<<<  Aligned:')
        for at, hsh in enumerate(auniq):
            print(atomfmt2.format(auniq[at][:6], *ageom[at]))
        print('<<<  Aligned Diff:')
        for at, hsh in enumerate(auniq):
            print(atomfmt2.format(auniq[at][:6], *[ageom[at][i] - rgeom[at][i] for i in range(3)]))

    if do_plot:
        plot_coord(ref=rgeom, cand=ageom, orig=cgeom, comment='Final RMSD = {:8.4f}'.format(final_rmsd))

    # sanity checks
    assert compare_values(_pseudo_nre(cuniq, cgeom),
                          _pseudo_nre(auniq, ageom),
                          'D: concern_mol-->returned_mol pNRE uncorrupted',
                          atol=1.e-4,
                          quiet=(verbose < 2))

    if mols_align is True:
        assert compare_values(_pseudo_nre(runiq, rgeom),
                              _pseudo_nre(auniq, ageom),
                              'D: concern_mol-->returned_mol pNRE matches ref_mol',
                              atol=1.e-4,
                              quiet=(verbose < 2))
        assert compare_values(rgeom,
                              ageom,
                              'D: concern_mol-->returned_mol geometry matches ref_mol',
                              atol=1.e-4,
                              quiet=(verbose < 2))
        assert compare_values(0., final_rmsd, 'D: null RMSD', atol=1.e-4, quiet=(verbose < 2))

    return final_rmsd, hold_solution


def _plausible_atom_orderings(ref, current, rgeom, cgeom, algorithm='hungarian_uno', verbose=1, uno_cutoff=1.e-3):
    """

    Parameters
    ----------
    ref : list
        Hashes encoding distinguishable non-coord characteristics of reference
        molecule. Namely, atomic symbol, mass, basis sets?.
    current : list
        Hashes encoding distinguishable non-coord characteristics of trial
        molecule. Namely, atomic symbol, mass, basis sets?.

    Returns
    -------
    iterator of tuples

    """
    if sorted(ref) != sorted(current):
        raise ValidationError("""ref and current can't map to each other.\n""" + 'R:  ' + str(ref) + '\nC:  ' +
                              str(current))

    where = collections.defaultdict(list)
    for iuq, uq in enumerate(ref):
        where[uq].append(iuq)

    cwhere = collections.defaultdict(list)
    for iuq, uq in enumerate(current):
        cwhere[uq].append(iuq)

    connect = collections.OrderedDict()
    for k in where:
        connect[tuple(where[k])] = tuple(cwhere[k])

    def filter_permutative(rgp, cgp):
        """Original atom ordering generator for like subset of atoms (e.g., all carbons).
        Relies on permutation. Filtering depends on similarity of structure (see `atol` parameter).
        Only suitable for total system size up to about 20 atoms.

        """
        if verbose >= 1:
            print("""Space:     {} <--> {}""".format(rgp, cgp))
        bnbn = [rrdistmat[first, second] for first, second in zip(rgp, rgp[1:])]
        for pm in itertools.permutations(cgp):
            cncn = [ccdistmat[first, second] for first, second in zip(pm, pm[1:])]
            if np.allclose(bnbn, cncn, atol=1.0):
                if verbose >= 1:
                    print('Candidate:', rgp, '<--', pm)
                yield pm

    def filter_hungarian_uno(rgp, cgp):
        """Hungarian algorithm on cost matrix based off headless (all Z same w/i space anyways) NRE.
        Having found _a_ solution and the reduced cost matrix, this still isn't likely to produce
        atom rearrangement fit for Kabsch b/c internal coordinate cost matrix doesn't nail down
        distance-equivalent atoms with different Cartesian coordinates like Cartesian-distance-matrix
        cost matrix does. So, form a bipartite graph from all essentially-zero connections between
        ref and concern and run Uno algorithm to enumerate them.

        """
        if verbose >= 1:
            print("""Space:     {} <--> {}""".format(rgp, cgp))

        # formulate cost matrix from internal (not Cartesian) layouts of R & C
        npcgp = np.array(cgp)
        submatCC = ccnremat[np.ix_(cgp, cgp)]
        submatRR = rrnremat[np.ix_(rgp, rgp)]
        sumCC = 100. * np.sum(submatCC, axis=0)  # cost mat small if not scaled, this way like Z=Neon
        sumRR = 100. * np.sum(submatRR, axis=0)
        cost = np.zeros((len(cgp), len(rgp)))
        for j in range(cost.shape[1]):
            for i in range(cost.shape[0]):
                cost[i, j] = (sumCC[i] - sumRR[j])**2
        if verbose >= 2:
            print('Cost:\n', cost)
        costcopy = np.copy(cost)  # other one gets manipulated by hungarian call

        # find _a_ best match btwn R & C atoms through Kuhn-Munkres (Hungarian) algorithm
        # * linear_sum_assigment call is exactly like `scipy.optimize.linear_sum_assignment(cost)` only with extra return
        t00 = time.time()
        (row_ind, col_ind), reducedcost = linear_sum_assignment(cost, return_cost=True)
        ptsCR = list(zip(row_ind, col_ind))
        ptsCR = sorted(ptsCR, key=lambda tup: tup[1])
        sumCR = costcopy[row_ind, col_ind].sum()
        t01 = time.time()
        if verbose >= 2:
            print('Reduced cost:\n', cost)
        if verbose >= 1:
            print('Hungarian time [s] for space:         {:.3}'.format(t01 - t00))

        # find _all_ best matches btwn R & C atoms through Uno algorithm, seeded from Hungarian sol'n
        edges = np.argwhere(reducedcost < uno_cutoff)
        gooduns = uno(edges, ptsCR)
        t02 = time.time()
        if verbose >= 1:
            print('Uno time [s] for space:               {:.3}'.format(t02 - t01))

        for gu in gooduns:
            gu2 = gu[:]
            gu2.sort(key=lambda x: x[1])  # resorts match into (r, c) = (info, range)
            subans = [p[0] for p in gu2]  # compacted to subans/lap format

            ans = tuple(npcgp[np.array(subans)])
            if verbose >= 3:
                print('Best Candidate ({:6.3}):'.format(sumCR), rgp, '<--', ans, '     from', cgp, subans)
            yield ans

    if algorithm == 'permutative':
        ccdistmat = distance_matrix(cgeom, cgeom)
        rrdistmat = distance_matrix(rgeom, rgeom)
        algofn = filter_permutative

    if algorithm == 'hungarian_uno':
        ccdistmat = distance_matrix(cgeom, cgeom)
        rrdistmat = distance_matrix(rgeom, rgeom)
        with np.errstate(divide='ignore'):
            ccnremat = np.reciprocal(ccdistmat)
            rrnremat = np.reciprocal(rrdistmat)
        ccnremat[ccnremat == np.inf] = 0.
        rrnremat[rrnremat == np.inf] = 0.
        algofn = filter_hungarian_uno

        # Ensure (optional dependency) networkx exists
        if not which_import('networkx', return_bool=True):
            raise ModuleNotFoundError(
                """Python module networkx not found. Solve by installing it: `conda install networkx` or `pip install networkx`"""
            )  # pragma: no cover

    # collect candidate atom orderings from algofn for each of the atom classes,
    #   recombine the classes with each other in every permutation (could maybe
    #   add Hungarian here, too) as generator back to permutation_kabsch
    for cpmut in itertools.product(*itertools.starmap(algofn, connect.items())):
        atpat = [None] * len(ref)
        for igp, group in enumerate(cpmut):
            for iidx, idx in enumerate(list(connect.keys())[igp]):
                atpat[idx] = group[iidx]
        yield atpat


def kabsch_align(rgeom, cgeom, weight=None):
    """Finds optimal translation and rotation to align `cgeom` onto `rgeom` via
    Kabsch algorithm by minimizing the norm of the residual, || R - U * C ||.

    Parameters
    ----------
    rgeom : ndarray of float
        (nat, 3) array of reference/target/unchanged geometry. Assumed [a0]
        for RMSD purposes.
    cgeom : ndarray of float
        (nat, 3) array of concern/changeable geometry. Assumed [a0] for RMSD
        purposes. Must have same Natom, units, and 1-to-1 atom ordering as rgeom.
    weight : ndarray of float
        (nat,) array of weights applied to `rgeom`. Note that definitions of
        weights (nothing to do with atom masses) are several, and I haven't
        seen one yet that can make centroid the center-of-mass and
        also make the RMSD match the usual mass-wtd-RMSD definition.
        Also, only one weight vector used rather than split btwn R & C,
        which may be invalid if not 1-to-1. Weighting is not recommended.

    Returns
    -------
    float, ndarray, ndarray
        First item is RMSD [A] between `rgeom` and the optimally aligned
        geometry computed.
        Second item is (3, 3) rotation matrix to optimal alignment.
        Third item is (3,) translation vector [a0] to optimal alignment.

    Sources
    -------
    Kabsch: Acta Cryst. (1978). A34, 827-828 http://journals.iucr.org/a/issues/1978/05/00/a15629/a15629.pdf
    C++ affine code: https://github.com/oleg-alexandrov/projects/blob/master/eigen/Kabsch.cpp
    weighted RMSD: http://www.amber.utah.edu/AMBER-workshop/London-2015/tutorial1/
    protein wRMSD code: https://pharmacy.umich.edu/sites/default/files/global_wrmsd_v8.3.py.txt
    quaternion: https://cnx.org/contents/HV-RsdwL@23/Molecular-Distance-Measures

    Author: dsirianni

    """
    if weight is None:
        w = np.ones((rgeom.shape[0]))
    elif isinstance(weight, (list, np.ndarray)):
        w = np.asarray(weight)
    else:
        raise ValidationError(f"""Unrecognized argument type {type(weight)} for kwarg 'weight'.""")

    R = rgeom
    C = cgeom
    N = rgeom.shape[0]
    if np.allclose(R, C):
        # can hit a mixed non-identity translation/rotation, so head off
        return 0., np.identity(3), np.zeros(3)

    Rcentroid = R.sum(axis=0) / N
    Ccentroid = C.sum(axis=0) / N
    R = np.subtract(R, Rcentroid)
    C = np.subtract(C, Ccentroid)

    R *= np.sqrt(w[:, None])
    C *= np.sqrt(w[:, None])

    RR = kabsch_quaternion(C.T, R.T)  # U
    TT = Ccentroid - RR.dot(Rcentroid)

    C = C.dot(RR)
    rmsd = np.linalg.norm(R - C) * constants.bohr2angstroms / np.sqrt(np.sum(w))

    return rmsd, RR, TT


def kabsch_quaternion(P, Q):
    """Computes the optimal rotation matrix U which mapping a set of points P
    onto the set of points Q according to the minimization of || Q - U * P ||,
    using the unit quaternion formulation of the Kabsch algorithm.

    Arguments:
     P := MxN array. M=dimension of space, N=number of points.
     Q := MxN array. M=dimension of space, N=number of points.

    Returns:
     U := Optimal MxM rotation matrix mapping P onto Q.

    Author: dsirianni

    """
    # Form covariance matrix
    cov = Q.dot(P.T)

    # Form the quaternion transformation matrix F
    F = np.zeros((4, 4))
    # diagonal
    F[0, 0] = cov[0, 0] + cov[1, 1] + cov[2, 2]
    F[1, 1] = cov[0, 0] - cov[1, 1] - cov[2, 2]
    F[2, 2] = -cov[0, 0] + cov[1, 1] - cov[2, 2]
    F[3, 3] = -cov[0, 0] - cov[1, 1] + cov[2, 2]
    # Upper & lower triangle
    F[1, 0] = F[0, 1] = cov[1, 2] - cov[2, 1]
    F[2, 0] = F[0, 2] = cov[2, 0] - cov[0, 2]
    F[3, 0] = F[0, 3] = cov[0, 1] - cov[1, 0]
    F[2, 1] = F[1, 2] = cov[0, 1] + cov[1, 0]
    F[3, 1] = F[1, 3] = cov[0, 2] + cov[2, 0]
    F[3, 2] = F[2, 3] = cov[1, 2] + cov[2, 1]

    # Compute ew, ev of F
    ew, ev = np.linalg.eigh(F)

    # Construct optimal rotation matrix from leading ev
    q = ev[:, -1]
    U = np.zeros((3, 3))

    U[0, 0] = q[0]**2 + q[1]**2 - q[2]**2 - q[3]**2
    U[0, 1] = 2 * (q[1] * q[2] - q[0] * q[3])
    U[0, 2] = 2 * (q[1] * q[3] + q[0] * q[2])
    U[1, 0] = 2 * (q[1] * q[2] + q[0] * q[3])
    U[1, 1] = q[0]**2 - q[1]**2 + q[2]**2 - q[3]**2
    U[1, 2] = 2 * (q[2] * q[3] - q[0] * q[1])
    U[2, 0] = 2 * (q[1] * q[3] - q[0] * q[2])
    U[2, 1] = 2 * (q[2] * q[3] + q[0] * q[1])
    U[2, 2] = q[0]**2 - q[1]**2 - q[2]**2 + q[3]**2

    return U


def compute_scramble(nat, do_resort=True, do_shift=True, do_rotate=True, deflection=1.0, do_mirror=False):
    """Generate a random or directed translation, rotation, and atom shuffling.

    Parameters
    ----------
    nat : int
        Number of atoms for which to prepare an atom mapping.
    do_resort : bool or array-like, optional
        Whether to randomly shuffle atoms (`True`) or leave 1st atom 1st, etc. (`False`)
        or shuffle according to specified (nat, ) indices (e.g., [2, 1, 0])
    do_shift : bool or array-like, optional
        Whether to generate a random atom shift on interval [-3, 3) in each
        dimension (`True`) or leave at current origin (`False`) or shift along
        specified (3, ) vector (e.g., np.array([0., 1., -1.])).
    do_rotate : bool or array-like, optional
        Whether to generate a random 3D rotation according to algorithm of Arvo (`True`)
        or leave at current orientation (`False`) or rotate with specified (3, 3) matrix.
    deflection : float, optional
        If `do_rotate`, how random a rotation: 0.0 is no change, 0.1 is small
        perturbation, 1.0 is completely random.
    do_mirror : bool, optional
        Whether to set mirror reflection instruction. Changes identity of
        molecule so off by default.

    Returns
    -------
    tuple
        AlignmentMill namedtuple with fields (shift, rotation, atommap, mirror)
        as requested: identity, random, or specified.

    """
    rand_elord = np.arange(nat)
    if do_resort is True:
        np.random.shuffle(rand_elord)
    elif do_resort is False:
        pass
    else:
        rand_elord = np.array(do_resort)
        assert (rand_elord.shape == (nat, ))

    if do_shift is True:
        rand_shift = 6 * np.random.random_sample((3, )) - 3
    elif do_shift is False:
        rand_shift = np.zeros((3, ))
    else:
        rand_shift = np.array(do_shift)
        assert (rand_shift.shape == (3, ))

    if do_rotate is True:
        rand_rot3d = random_rotation_matrix(deflection=deflection)
    elif do_rotate is False:
        rand_rot3d = np.identity(3)
    else:
        rand_rot3d = np.array(do_rotate)
        assert (rand_rot3d.shape == (3, 3))

    perturbation = AlignmentMill(shift=rand_shift, rotation=rand_rot3d, atommap=rand_elord, mirror=do_mirror)
    return perturbation
QCElemental-0.5.0/qcelemental/molutil/test_align.py000066400000000000000000000425751351361252000223430ustar00rootroot00000000000000import pytest
from ..tests.addons import using_networkx

import math
import pprint
pp = pprint.PrettyPrinter(width=120)

import numpy as np
import pydantic

import qcelemental as qcel
from qcelemental.testing import compare, compare_values, compare_recursive, compare_molrecs



ss22_12 = """
C    -1.2471894   -1.1718212   -0.6961388
C    -1.2471894   -1.1718212    0.6961388
N    -0.2589510   -1.7235771    1.4144796
C     0.7315327   -2.2652221    0.6967288
C     0.7315327   -2.2652221   -0.6967288
N    -0.2589510   -1.7235771   -1.4144796
H    -2.0634363   -0.7223199   -1.2472797
H    -2.0634363   -0.7223199    1.2472797
H     1.5488004   -2.7128282    1.2475604
H     1.5488004   -2.7128282   -1.2475604
C    -0.3380031    2.0800608    1.1300452
C     0.8540254    1.3593471    1.1306308
N     1.4701787    0.9907598    0.0000000
C     0.8540254    1.3593471   -1.1306308
C    -0.3380031    2.0800608   -1.1300452
N    -0.9523059    2.4528836    0.0000000
H    -0.8103758    2.3643033    2.0618643
H     1.3208583    1.0670610    2.0623986
H     1.3208583    1.0670610   -2.0623986
H    -0.8103758    2.3643033   -2.0618643
"""


@using_networkx
def test_scramble_descrambles_plain():
    s22_12 = qcel.models.Molecule.from_data(ss22_12)

    for trial in range(5):
        s22_12.scramble(do_shift=True, do_rotate=True, do_resort=True, do_plot=False, verbose=0, do_test=True)


def test_relative_geoms_align_free():
    s22_12 = qcel.models.Molecule.from_data(ss22_12)

    for trial in range(3):
        cmol, _ = s22_12.scramble(do_shift=True, do_rotate=True, do_resort=False, do_plot=False, verbose=2, do_test=True)

        rmolrec = qcel.molparse.from_schema(s22_12.dict())
        cmolrec = qcel.molparse.from_schema(cmol.dict())
        assert compare_molrecs(rmolrec, cmolrec, atol=1.e-4, relative_geoms='align')


def test_relative_geoms_align_fixed():
    s22_12 = qcel.models.Molecule.from_data(ss22_12 + 'nocom\nnoreorient\n')

    for trial in range(3):
        cmol, _ = s22_12.scramble(do_shift=False, do_rotate=False, do_resort=False, do_plot=False, verbose=2, do_test=True)

        rmolrec = qcel.molparse.from_schema(s22_12.dict())
        cmolrec = qcel.molparse.from_schema(cmol.dict())
        assert compare_molrecs(rmolrec, cmolrec, atol=1.e-4, relative_geoms='align')


chiral = qcel.models.Molecule.from_data("""
 C     0.000000     0.000000     0.000000
Br     0.000000     0.000000     1.949834
 F     1.261262     0.000000    -0.451181
Cl    -0.845465     1.497406    -0.341118
 H    -0.524489    -0.897662    -0.376047
""")


@using_networkx
def test_scramble_descrambles_chiral():
    chiral.scramble(do_shift=True, do_rotate=True, do_resort=True, do_plot=False, verbose=0, do_mirror=False, do_test=True)
    chiral.scramble(do_shift=True, do_rotate=True, do_resort=False, do_plot=False, verbose=1, do_mirror=False, do_test=True)
    for trial in range(5):
        chiral.scramble(do_shift=True, do_rotate=True, do_resort=True, do_plot=False, verbose=0, do_mirror=True, do_test=True)


soco10 = """
O  1.0 0.0 0.0
C  0.0 0.0 0.0
O -1.0 0.0 0.0
units ang
"""

sooc12 = """
O  1.2 4.0 0.0
O -1.2 4.0 0.0
C  0.0 4.0 0.0
units ang
"""

s18ooc12 = """
18O  1.2 4.0 0.0
O -1.2 4.0 0.0
C  0.0 4.0 0.0
units ang
"""

sooco12 = """
O  1.2 4.0 0.0
O -1.2 4.0 0.0
C  0.0 4.0 0.0
O  3.0 4.0 0.0
units ang
"""

soco12 = """
O  1.2 4.0 0.0
C  0.0 4.0 0.0
O -1.2 4.0 0.0
units ang
"""

ref_rmsd = math.sqrt(2. * 0.2 * 0.2 / 3.)  # RMSD always in Angstroms


@using_networkx
def test_error_bins_b787():
    oco10 = qcel.models.Molecule.from_data(soco10)
    oco12 = qcel.models.Molecule.from_data(s18ooc12)

    with pytest.raises(qcel.ValidationError) as e:
        oco12.align(oco10, verbose=0)

    assert 'atom subclasses unequal' in str(e.value)


@using_networkx
def test_error_nat_b787():
    oco10 = qcel.models.Molecule.from_data(soco10)
    oco12 = qcel.models.Molecule.from_data(sooco12)

    with pytest.raises(qcel.ValidationError) as e:
        oco12.align(oco10, verbose=0)

    assert "natom doesn't match" in str(e.value)


def test_mill_shift_error():
    with pytest.raises(pydantic.ValidationError) as e:
        qcel.models.AlignmentMill(shift=[0, 1])

    assert "Shift must be castable to shape" in str(e.value)


def test_mill_rot_error():
    with pytest.raises(pydantic.ValidationError) as e:
        qcel.models.AlignmentMill(rotation=[0, 1, 3])

    assert "Rotation must be castable to shape" in str(e.value)


@using_networkx
def test_b787():
    oco10 = qcel.molparse.from_string(soco10)
    oco12 = qcel.molparse.from_string(sooc12)

    oco10_geom_au = oco10['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms
    oco12_geom_au = oco12['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms

    rmsd, mill = qcel.molutil.B787(
        oco10_geom_au, oco12_geom_au, np.array(['O', 'C', 'O']), np.array(['O', 'O', 'C']), algorithm='permutative', verbose=4, do_plot=False)

    assert compare_values(ref_rmsd, rmsd, 'known rmsd B787', atol=1.e-6)


@using_networkx
def test_b787_atomsmap():
    oco10 = qcel.molparse.from_string(soco10)
    oco12 = qcel.molparse.from_string(soco12)

    oco10_geom_au = oco10['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms
    oco12_geom_au = oco12['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms

    rmsd, mill = qcel.molutil.B787(oco10_geom_au, oco12_geom_au, None, None, atoms_map=True)

    assert compare_values(ref_rmsd, rmsd, 'known rmsd B787', atol=1.e-6)


@using_networkx
def test_model_b787():
    oco10 = qcel.models.Molecule.from_data(soco10)
    oco12 = qcel.models.Molecule.from_data(sooc12)

    mol, data = oco12.align(oco10, verbose=4)

    assert compare_values(ref_rmsd, data['rmsd'], 'known rmsd qcel.models.Molecule.align', atol=1.e-6)


def test_error_kabsch():
    with pytest.raises(qcel.ValidationError) as e:
        qcel.molutil.kabsch_align([1, 2, 3], [4, 5, 6], weight=7)

    assert "for kwarg 'weight'" in str(e.value)


@using_networkx
def test_kabsch_identity():
    oco10 = qcel.molparse.from_string(soco10)
    oco12 = qcel.molparse.from_string(soco10)

    oco10_geom_au = oco10['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms
    oco12_geom_au = oco12['qm']['geom'].reshape((-1, 3)) / qcel.constants.bohr2angstroms

    rmsd, rot, shift = qcel.molutil.kabsch_align(oco10_geom_au, oco12_geom_au)

    assert compare_values(0., rmsd, 'identical')
    assert compare_values(np.identity(3), rot, 'identity rotation matrix')
    assert compare_values(np.zeros(3), shift, 'identical COM')


trop_cs = qcel.models.Molecule.from_data("""
     C        -3.19247825     2.43488661     0.00000000
     C        -4.39993972     0.13119097     0.00000000
     C        -3.25125097    -2.33609553     0.00000000
     C        -0.53296611     2.98441107     0.00000000
     C        -0.74683325    -3.02798473     0.00000000
     C         1.48688415     1.34759833     0.00000000
     H        -4.41324589     4.10714388     0.00000000
     H        -6.46804026     0.15889833     0.00000000
     H        -4.59260816    -3.91576186     0.00000000
     H        -0.00999373     4.98699344     0.00000000
     H        -0.30873683    -5.05056347     0.00000000
     C         1.53303555    -1.47231513     0.00000000
     O         3.67104984    -2.45774212     0.00000000
     O         3.84147141     2.33923482     0.00000000
     H         4.95785438     0.85953513     0.00000000
     units au
""")

trop_gs_c2v = qcel.models.Molecule.from_data("""
     C         2.38842439     0.00000000    -3.20779039
     C         0.00000000     0.00000000    -4.37431891
     C        -2.38842439     0.00000000    -3.20779039
     C         3.04548001     0.00000000    -0.63779964
     C        -3.04548001     0.00000000    -0.63779964
     C         1.40969252     0.00000000     1.46237865
     C        -1.40969252     0.00000000     1.46237865
     O         2.17618825     0.00000000     3.78161558
     O        -2.17618825     0.00000000     3.78161558
     H         0.00000000     0.00000000     4.59454571
     H         0.00000000     0.00000000    -6.44213321
     H         4.00103632     0.00000000    -4.50882987
     H        -4.00103632     0.00000000    -4.50882987
     H         5.05910161     0.00000000    -0.16572021
     H        -5.05910161     0.00000000    -0.16572021
     units au
""")


@using_networkx
def test_tropolone_b787():
    mol, data = trop_cs.align(trop_gs_c2v, do_plot=False, verbose=0, uno_cutoff=0.5)
    assert compare_values(0.1413, data['rmsd'], 'cs<-->c2v tropolones align', atol=1.e-2)


def test_scramble_identity():
    mill = qcel.molutil.compute_scramble(4, do_resort=False, do_shift=False, do_rotate=False, deflection=1.0, do_mirror=False)

    mill_str = """----------------------------------------
             AlignmentMill              
                  eye                   
----------------------------------------
Mirror:   False
Atom Map: [0 1 2 3]
Shift:    [0. 0. 0.]
Rotation:
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
----------------------------------------"""

    assert compare(mill_str, mill.__str__(label='eye'))

    mill_dict = {
        'shift': [0., 0., 0.],
        'rotation': [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]],
        'atommap': [0, 1, 2, 3],
        'mirror': False}

    assert compare_recursive(mill_dict, mill.dict())
    mill_dict['rotation'] = [1., 0., 0., 0., 1., 0., 0., 0., 1.]
    assert compare_recursive(mill_dict, mill.json_dict())


def test_scramble_specific():
    mill = qcel.molutil.compute_scramble(4,
                                          do_resort=[1, 2, 0, 3],
                                          do_shift=[-1.82564537, 2.25391838, -2.56591963],
                                          do_rotate=[[ 0.39078817, -0.9101616,  -0.13744259],
                                                     [ 0.36750838,  0.29117465, -0.88326379],
                                                     [ 0.84393258,  0.29465774,  0.44827962]])

    mill_str = """----------------------------------------
             AlignmentMill              
----------------------------------------
Mirror:   False
Atom Map: [1 2 0 3]
Shift:    [-1.82564537  2.25391838 -2.56591963]
Rotation:
[[ 0.39078817 -0.9101616  -0.13744259]
 [ 0.36750838  0.29117465 -0.88326379]
 [ 0.84393258  0.29465774  0.44827962]]
----------------------------------------"""

    assert compare(mill_str, mill.__str__())


def test_hessian_align():
    # from Psi4 test test_hessian_vs_cfour[HOOH_TS-H_analytic]

    rmill = """
----------------------------------------
             AlignmentMill              
----------------------------------------
Mirror:   False
Atom Map: [0 1 2 3]
Shift:    [0.00000000e+00 0.00000000e+00 1.32217718e-10]
Rotation:
[[ 9.99999870e-01 -5.08999836e-04 -0.00000000e+00]
 [ 5.08999836e-04  9.99999870e-01  0.00000000e+00]
 [ 0.00000000e+00 -0.00000000e+00  1.00000000e+00]]
----------------------------------------
"""

    p4_hooh_xyz = """
    units au
    H  1.8327917647 -1.5752960165 -0.0000055594
    O  1.3171390326  0.1388012713  0.0000003503
    O -1.3171390326 -0.1388012713  0.0000003503
    H -1.8327917647  1.5752960165 -0.0000055594
    """

    c4_hooh_xyz = """
         H                  1.83199008    -1.57622903    -0.00000556
         O                  1.31720978     0.13813086     0.00000035
         O                 -1.31720978    -0.13813086     0.00000035
         H                 -1.83199008     1.57622903    -0.00000556
         units au"""

    c4_hooh_hess = np.array(
    [[ 1.26389745e-01, -1.48044116e-01, -5.10600000e-07, -8.25705803e-02,
       8.94682153e-02,  3.59200000e-07, -2.97329883e-02,  6.20787276e-02,
       1.15100000e-07, -1.40861766e-02, -3.50282710e-03,  3.62000000e-08],
     [-1.48044116e-01,  5.70582596e-01,  1.97410000e-06,  1.70543201e-01,
      -5.85505592e-01, -2.01940000e-06, -1.89962579e-02,  1.41465336e-02,
       4.31000000e-08, -3.50282710e-03,  7.76462400e-04,  2.30000000e-09],
     [-5.10600000e-07,  1.97410000e-06, -1.39249540e-03,  5.48500000e-07,
      -2.04760000e-06,  1.39251280e-03, -1.70000000e-09,  7.57000000e-08,
       1.39261030e-03, -3.62000000e-08, -2.30000000e-09, -1.39262780e-03],
     [-8.25705803e-02,  1.70543201e-01,  5.48500000e-07,  4.71087328e-01,
      -1.32453772e-01, -3.97100000e-07, -3.58783760e-01, -1.90931709e-02,
      -1.53000000e-07, -2.97329883e-02, -1.89962579e-02,  1.70000000e-09],
     [ 8.94682153e-02, -5.85505592e-01, -2.04760000e-06, -1.32453772e-01,
       6.80349634e-01,  2.09300000e-06, -1.90931709e-02, -1.08990576e-01,
       3.04000000e-08,  6.20787276e-02,  1.41465336e-02, -7.57000000e-08],
     [ 3.59200000e-07, -2.01940000e-06,  1.39251280e-03, -3.97100000e-07,
       2.09300000e-06, -1.39226390e-03,  1.53000000e-07, -3.04000000e-08,
      -1.39285910e-03, -1.15100000e-07, -4.31000000e-08,  1.39261030e-03],
     [-2.97329883e-02, -1.89962579e-02, -1.70000000e-09, -3.58783760e-01,
      -1.90931709e-02,  1.53000000e-07,  4.71087328e-01, -1.32453772e-01,
       3.97100000e-07, -8.25705803e-02,  1.70543201e-01, -5.48500000e-07],
     [ 6.20787276e-02,  1.41465336e-02,  7.57000000e-08, -1.90931709e-02,
      -1.08990576e-01, -3.04000000e-08, -1.32453772e-01,  6.80349634e-01,
      -2.09300000e-06,  8.94682153e-02, -5.85505592e-01,  2.04760000e-06],
     [ 1.15100000e-07,  4.31000000e-08,  1.39261030e-03, -1.53000000e-07,
       3.04000000e-08, -1.39285910e-03,  3.97100000e-07, -2.09300000e-06,
      -1.39226390e-03, -3.59200000e-07,  2.01940000e-06,  1.39251280e-03],
     [-1.40861766e-02, -3.50282710e-03, -3.62000000e-08, -2.97329883e-02,
       6.20787276e-02, -1.15100000e-07, -8.25705803e-02,  8.94682153e-02,
      -3.59200000e-07,  1.26389745e-01, -1.48044116e-01,  5.10600000e-07],
     [-3.50282710e-03,  7.76462400e-04, -2.30000000e-09, -1.89962579e-02,
       1.41465336e-02, -4.31000000e-08,  1.70543201e-01, -5.85505592e-01,
       2.01940000e-06, -1.48044116e-01,  5.70582596e-01, -1.97410000e-06],
     [ 3.62000000e-08,  2.30000000e-09, -1.39262780e-03,  1.70000000e-09,
      -7.57000000e-08,  1.39261030e-03, -5.48500000e-07,  2.04760000e-06,
       1.39251280e-03,  5.10600000e-07, -1.97410000e-06, -1.39249540e-03]])

    # generated from native psi4 geometry before alignment to cfour geometry
    p4_hooh_hess_native = np.array(
    [[ 1.26540599e-01, -1.48270387e-01, -5.11580572e-07, -8.27030303e-02,
       8.97243491e-02,  3.60275814e-07, -2.97549532e-02,  6.20564277e-02,
       1.15085371e-07, -1.40826158e-02, -3.51038930e-03,  3.62193872e-08],
     [-1.48270387e-01,  5.70432494e-01,  1.97383511e-06,  1.70799401e-01,
      -5.85373844e-01, -2.01926658e-06, -1.90186246e-02,  1.41684555e-02,
       4.31889743e-08, -3.51038930e-03,  7.72894141e-04,  2.24249453e-09],
     [-5.11580572e-07,  1.97383511e-06, -1.39261744e-03,  5.49492724e-07,
      -2.04733779e-06,  1.39262576e-03, -1.69276446e-09,  7.57451701e-08,
       1.39262075e-03, -3.62193872e-08, -2.24249453e-09, -1.39262906e-03],
     [-8.27030303e-02,  1.70799401e-01,  5.49492724e-07,  4.71222858e-01,
      -1.32560453e-01, -3.98187966e-07, -3.58764874e-01, -1.92203240e-02,
      -1.52997522e-07, -2.97549532e-02, -1.90186246e-02,  1.69276446e-09],
     [ 8.97243491e-02, -5.85373844e-01, -2.04733779e-06, -1.32560453e-01,
       6.80215453e-01,  2.09276925e-06, -1.92203240e-02, -1.09010064e-01,
       3.03137013e-08,  6.20564277e-02,  1.41684555e-02, -7.57451701e-08],
     [ 3.60275814e-07, -2.01926658e-06,  1.39262576e-03, -3.98187966e-07,
       2.09276925e-06, -1.39245013e-03,  1.52997522e-07, -3.03137013e-08,
      -1.39279639e-03, -1.15085371e-07, -4.31889743e-08,  1.39262075e-03],
     [-2.97549532e-02, -1.90186246e-02, -1.69276446e-09, -3.58764874e-01,
      -1.92203240e-02,  1.52997522e-07,  4.71222858e-01, -1.32560453e-01,
       3.98187966e-07, -8.27030303e-02,  1.70799401e-01, -5.49492724e-07],
     [ 6.20564277e-02,  1.41684555e-02,  7.57451701e-08, -1.92203240e-02,
      -1.09010064e-01, -3.03137013e-08, -1.32560453e-01,  6.80215453e-01,
      -2.09276925e-06,  8.97243491e-02, -5.85373844e-01,  2.04733779e-06],
     [ 1.15085371e-07,  4.31889743e-08,  1.39262075e-03, -1.52997522e-07,
       3.03137013e-08, -1.39279639e-03,  3.98187966e-07, -2.09276925e-06,
      -1.39245013e-03, -3.60275814e-07,  2.01926658e-06,  1.39262576e-03],
     [-1.40826158e-02, -3.51038930e-03, -3.62193872e-08, -2.97549532e-02,
       6.20564277e-02, -1.15085371e-07, -8.27030303e-02,  8.97243491e-02,
      -3.60275814e-07,  1.26540599e-01, -1.48270387e-01,  5.11580572e-07],
     [-3.51038930e-03,  7.72894141e-04, -2.24249453e-09, -1.90186246e-02,
       1.41684555e-02, -4.31889743e-08,  1.70799401e-01, -5.85373844e-01,
       2.01926658e-06, -1.48270387e-01,  5.70432494e-01, -1.97383511e-06],
     [ 3.62193872e-08,  2.24249453e-09, -1.39262906e-03,  1.69276446e-09,
      -7.57451701e-08,  1.39262075e-03, -5.49492724e-07,  2.04733779e-06,
       1.39262576e-03,  5.11580572e-07, -1.97383511e-06, -1.39261744e-03]])

    p4mol = qcel.models.Molecule.from_data(p4_hooh_xyz)
    c4mol = qcel.models.Molecule.from_data(c4_hooh_xyz)
    aqmol, data = p4mol.align(c4mol, atoms_map=True, mols_align=True, verbose=4)
    mill = data['mill']

    assert compare([0, 1, 2, 3], mill.atommap)
    assert compare_values([
 [ 9.99999870e-01, -5.08999836e-04, -0.00000000e+00],
 [ 5.08999836e-04,  9.99999870e-01,  0.00000000e+00],
 [ 0.00000000e+00, -0.00000000e+00,  1.00000000e+00]],
        mill.rotation,
        atol=1.e-6)

    p2cgeom = mill.align_coordinates(p4mol.geometry)
    assert compare_values(c4mol.geometry, p2cgeom, atol=1.e-6)

    p2chess = mill.align_hessian(p4_hooh_hess_native)
    assert compare_values(c4_hooh_hess, p2chess, atol=1.e-4)
QCElemental-0.5.0/qcelemental/periodic_table.py000066400000000000000000000375631351361252000214730ustar00rootroot00000000000000"""
Periodic table class
"""

import collections
from decimal import Decimal
from typing import Union

from .exceptions import NotAnElementError


class PeriodicTable:
    """Nuclear and mass data about chemical elements from NIST.

    Parameters
    ----------
    None

    Attributes
    ----------
    A : list of int
        Mass number, number of protons and neutrons, starting with 0 for dummies.
    Z : list of int
        Atomic number, number of protons, starting with 0 for dummies.
    E : list of str
        Element symbol from periodic table, starting with "X" for dummies. "Fe" capitalization.
    EA : list of str
        Nuclide symbol in E + A form, e.g., "Li6".
        List `EA` is a superset of `E`; that is, both "Li6" and "Li" present.
        For hydrogen, "D" and "T" also included.
    mass : list of :py:class:`decimal.Decimal`
        Atomic mass [u].
        For nuclides (e.g., "Li6"), the reported mass.
        For stable elements (e.g., "Li"), the mass of the most abundant isotope ("Li7").
        For unstable elements (e.g., "Pu"), the mass of the longest-lived isotope ("Pu244").
    name : list of str
        Element name from periodic table, starting with "Dummy". "Iron" capitalization.

    """

    def __init__(self):

        from . import data

        # Of length number of elements
        self.Z = data.nist_2011_atomic_weights["Z"]
        self.E = data.nist_2011_atomic_weights["E"]
        self.name = data.nist_2011_atomic_weights["name"]

        self._el2z = dict(zip(self.E, self.Z))
        self._z2el = collections.OrderedDict(zip(self.Z, self.E))
        self._element2el = dict(zip(self.name, self.E))
        self._el2element = dict(zip(self.E, self.name))

        # Of length number of isotopes
        self._EE = data.nist_2011_atomic_weights["_EE"]
        self.EA = data.nist_2011_atomic_weights["EA"]
        self.A = data.nist_2011_atomic_weights["A"]
        self.mass = data.nist_2011_atomic_weights["mass"]

        self._eliso2mass = dict(zip(self.EA, self.mass))
        self._eliso2el = dict(zip(self.EA, self._EE))
        self._eliso2a = dict(zip(self.EA, self.A))
        self._el2a2mass = collections.defaultdict(dict)
        for EE, m, A in zip(self._EE, self.mass, self.A):
            self._el2a2mass[EE][A] = float(m)

    def _resolve_atom_to_key(self, atom: Union[int, str]) -> str:
        """Given `atom` as element name, element symbol, nuclide symbol, atomic number, or atomic number string,
        return valid `self._eliso2mass` key, regardless of case. Raises `NotAnElementError` if unidentifiable.

        """
        try:
            self._eliso2mass[atom.capitalize()]  # type: ignore
        except (KeyError, AttributeError):
            try:
                E = self._z2el[int(atom)]
            except (KeyError, ValueError):
                try:
                    E = self._element2el[atom.capitalize()]  # type: ignore
                except (KeyError, AttributeError):
                    raise NotAnElementError(atom)
                else:
                    return E
            else:
                return E
        else:
            assert isinstance(atom, str)
            return atom.capitalize()

    def to_mass(self, atom: Union[int, str], *, return_decimal:bool=False) -> Union[float, 'Decimal']:
        """Get atomic mass of `atom`.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.
        return_decimal : bool, optional
            Whether to preserve significant figures information by returning as Decimal (`True`) or to convert to float (`False`).

        Returns
        -------
        decimal.Decimal or float
            Atomic mass [u]. See above for type.
            If `atom` is nuclide (e.g., "Li6"), the reported mass.
            If `atom` is stable element (e.g., "Li"), the mass of the most abundant isotope, "Li7".
            If `atom` is unstable element (e.g., "Pu"), the mass of the longest-lived isotope, "Pu244".

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        identifier = self._resolve_atom_to_key(atom)
        mass = self._eliso2mass[identifier]

        if return_decimal:
            return Decimal(mass)
        else:
            return float(mass)

    def to_A(self, atom: Union[int, str]) -> int:
        """Get mass number of `atom`.

        Functions :py:func:`to_A` and :py:func:`to_mass_number` are aliases.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        int
            Mass number, number of protons and neutrons.
            If `atom` is nuclide (e.g., "Li6"), the corresponding mass number, 6.
            If `atom` is stable element (e.g., "Li"), the mass number of the most abundant isotope, 7.
            If `atom` is unstable element (e.g., "Pu"), the mass number of the longest-lived isotope, 244.

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        identifier = self._resolve_atom_to_key(atom)
        return self._eliso2a[identifier]

    def to_Z(self, atom: Union[int, str]) -> int:
        """Get atomic number of `atom`.

        Functions :py:func:`to_Z` and :py:func:`to_atomic_number` are aliases.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        int
            Atomic number, number of protons.

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        identifier = self._resolve_atom_to_key(atom)
        return self._el2z[self._eliso2el[identifier]]

    def to_E(self, atom: Union[int, str]) -> str:
        """Get element symbol of `atom`.

        Functions :py:func:`to_E` and :py:func:`to_symbol` are aliases.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        str
            Element symbol, capitalized.

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        identifier = self._resolve_atom_to_key(atom)
        return self._eliso2el[identifier]

    def to_element(self, atom: Union[int, str]) -> str:
        """Get element name of `atom`.

        Functions :py:func:`to_element` and :py:func:`to_name` are aliases.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        str
            Element name, capitalized.

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        identifier = self._resolve_atom_to_key(atom)
        return self._el2element[self._eliso2el[identifier]]

    to_mass_number = to_A
    to_atomic_number = to_Z
    to_symbol = to_E
    to_name = to_element

    def to_period(self, atom: Union[int, str]) -> int:
        """Get period (horizontal row in periodic table) of `atom`.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        int
            Period between 1 (e.g., `He`) and 7 (e.g., `U238`).

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        Z = self.to_Z(atom)

        if Z <= 2:
            return 1
        elif Z <= 10:
            return 2
        elif Z <= 18:
            return 3
        elif Z <= 36:
            return 4
        elif Z <= 54:
            return 5
        elif Z <= 86:
            return 6
        elif Z <= 118:
            return 7
        else:
            return 8

    def to_group(self, atom: Union[int, str]) -> Union[int, None]:
        """Get group (vertical column in periodic table) of `atom`.

        Parameters
        ----------
        atom : int or str
            Identifier for element or nuclide, e.g., `H`, `D`, `H2`, `He`, `hE4`.

        Returns
        -------
        int
            Group between 1 (e.g., `Li`) and 18 (e.g., `KR84`).
        None
            If one of the 30 Lanthanides (Z=57-71) or Actinides (Z=89-103).

        Raises
        ------
        NotAnElementError
            If `atom` cannot be resolved into an element or nuclide.

        """
        Z = self.to_Z(atom)

        # yapf: disable
        if Z in    [1, 3, 11, 19, 37, 55, 87]:
            return 1
        elif Z in     [4, 12, 20, 38, 56, 88]:
            return 2
        elif Z in            [21, 39]:
            return 3
        elif Z in            [22, 40, 72, 104]:
            return 4
        elif Z in            [23, 41, 73, 105]:
            return 5
        elif Z in            [24, 42, 74, 106]:
            return 6
        elif Z in            [25, 43, 75, 107]:
            return 7
        elif Z in            [26, 44, 76, 108]:
            return 8
        elif Z in            [27, 45, 77, 109]:
            return 9
        elif Z in            [28, 46, 78, 110]:
            return 10
        elif Z in            [29, 47, 79, 111]:
            return 11
        elif Z in            [30, 48, 80, 112]:
            return 12
        elif Z in     [5, 13, 31, 49, 81, 113]:
            return 13
        elif Z in     [6, 14, 32, 50, 82, 114]:
            return 14
        elif Z in     [7, 15, 33, 51, 83, 115]:
            return 15
        elif Z in     [8, 16, 34, 52, 84, 116]:
            return 16
        elif Z in     [9, 17, 35, 53, 85, 117]:
            return 17
        elif Z in [2, 10, 18, 36, 54, 86, 118]:
            return 18
        else:
            return None
        # yapf: enable

    def run_comparison(self):
        """Compare the existing element information for Psi4 and Cfour (in checkup_data folder) to `self`. Specialized use."""

        try:
            from . import checkup_data
        except ImportError:  # pragma: no cover
            print('Info for comparison (directory checkup_data) not installed. Run from source.')

        class bcolors:
            HEADER = '\033[95m'
            OKBLUE = '\033[94m'
            OKGREEN = '\033[92m'
            WARNING = '\033[93m'
            FAIL = '\033[91m'
            ENDC = '\033[0m'
            BOLD = '\033[1m'
            UNDERLINE = '\033[4m'

        #print(bcolors.OKBLUE + '\nChecking z2element vs. Psi4 ...' + bcolors.ENDC)
        #for zz in self._z2element:
        #    if zz > 107:
        #        break
        #    assert self._z2element[zz] == checkup_data.periodictable.z2element[
        #        zz].capitalize(), 'Element {} differs from {} for Z={}'.format(
        #            z_to_element[zz], checkup_data.periodictable.z2element[zz].capitalize(), zz)

        print(bcolors.OKBLUE + '\nChecking z2el vs. Psi4 ...' + bcolors.ENDC)
        for zz in self._z2el:
            if 0 < zz < 108:
                assert self._z2el[zz] == checkup_data.periodictable.z2el[zz].capitalize(
                ), 'Element {} differs from {} for Z={}'.format(self._z2el[zz],
                                                                checkup_data.periodictable.z2el[zz].capitalize(), zz)

        print(bcolors.OKBLUE + '\nChecking el2z vs. Psi4 ...' + bcolors.ENDC)
        for el in self._el2z:
            if self._el2z[el] > 107:
                break
            if el not in ['X', 'Gh']:
                assert self._el2z[el] == checkup_data.periodictable.el2z[
                    el.upper()], 'Element {} differs from {}'.format(self._el2z[el],
                                                                     checkup_data.periodictable.el2z[el.upper()])

        translate = {'UUB': 'Cn', 'UUT': 'Nh', 'UUQ': 'Fl', 'UUP': 'Mc', 'UUH': 'Lv', 'UUS': 'Ts', 'UUO': 'Og'}
        translate = {v: k for k, v in translate.items()}

        tol = 1.e-5
        print(bcolors.OKBLUE + '\nChecking ({}) el2mass vs. Psi4 ...'.format(tol))
        for el in self.E:
            ptel = translate.get(el, el.upper())
            if el not in ['X', 'Gh']:
                ref = self._eliso2mass[el]
                val = checkup_data.periodictable.el2mass[ptel]
                diff = abs(float(ref) - val)
                if diff > 1.e-2:
                    print(bcolors.FAIL +
                          'Element {} differs by {:12.8f}: {} (this) vs {} (psi)'.format(el, diff, ref, val) +
                          bcolors.ENDC)
                elif diff > tol:
                    print('Element {} differs by {:12.8f}: {} (this) vs {} (psi)'.format(el, diff, ref, val))

        tol = 1.e-5
        print(bcolors.OKBLUE + '\nChecking ({}) el2mass vs. Cfour ...'.format(tol) + bcolors.ENDC)
        for el in self.E:
            zz = self._el2z[el]
            if zz > 112:
                break
            if el not in ['X', 'Gh']:
                ref = self._eliso2mass[el]
                val = checkup_data.cfour_primary_masses[zz - 1]
                diff = abs(float(ref) - val)
                if diff > 1.e-2:
                    print(bcolors.FAIL +
                          'Element {} differs by {:12.8f}: {} (this) vs {} (cfour)'.format(el, diff, ref, val) +
                          bcolors.ENDC)
                elif diff > tol:
                    print('Element {} differs by {:12.8f}: {} (this) vs {} (cfour)'.format(el, diff, ref, val))

        tol = 1.e-3
        print(bcolors.OKBLUE + '\nChecking ({}) eliso2mass vs. Psi4 ...'.format(tol) + bcolors.ENDC)
        for el in self._eliso2mass:
            ptel = translate.get(el, el.upper())
            if el not in ['X', 'Gh']:
                if ptel not in checkup_data.periodictable.eliso2mass:
                    print('Element {:6} missing from Psi4'.format(el))
                    continue
                ref = self._eliso2mass[el]
                val = checkup_data.periodictable.eliso2mass[ptel]
                diff = abs(float(ref) - val)
                if diff > 1.e-2:
                    print(bcolors.FAIL +
                          'Element {:6} differs by {:12.8f}: {} (this) vs {} (psi)'.format(el, diff, ref, val) +
                          bcolors.ENDC)
                elif diff > tol:
                    print('Element {:6} differs by {:12.8f}: {} (this) vs {} (psi)'.format(el, diff, ref, val))

    def write_c_header(self, filename='masses.h'):
        """Write C header file defining arrays of mass and element information."""

        text = [
            '#ifndef _qcelemental_masses_h_', '#define _qcelemental_masses_h_', '',
            '/* This file is autogenerated from the QCElemental python module */', '',
            'static const char *atomic_labels[]={', '"' + '","'.join(e.upper() for e in self.E) + '"', '};', '',
            'static const double an2masses[]={', ','.join(str(self._eliso2mass[e]) for e in self.E), '};', '',
            'static const char *mass_labels[]={',
            '"' + '","'.join(e.upper() for e in self.EA if e not in ['Gh', 'X', 'X0']) + '"', '};', '',
            'static const double atomic_masses[]={',
            ','.join(str(self._eliso2mass[e]) for e in self.EA if e not in ['Gh', 'X', 'X0']), '};', '',
            '#endif /* header guard */', ''
        ] # yapf: disable

        with open(filename, 'w') as handle:
            handle.write('\n'.join(text))
        print('File written ({}). Remember to add license and clang-format it.'.format(filename))


#el2mass["GH"] = 0.  # note that ghost atoms in Cfour have mass 100.
#eliso2mass["GH"] = 0.  # note that ghost atoms in Cfour have mass 100.  # encompasses el2mass
#eliso2mass["X0"] = 0.  # probably needed, just checking
#el2z["GH"] = 0

# singleton
periodictable = PeriodicTable()
QCElemental-0.5.0/qcelemental/physical_constants/000077500000000000000000000000001351361252000220465ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/physical_constants/__init__.py000066400000000000000000000006011351361252000241540ustar00rootroot00000000000000"""
Units handlers
"""

# Ensure pint exists
from importlib.util import find_spec
spec = find_spec('pint')
if spec is None:
    raise ModuleNotFoundError(
        """Python module pint not found. Solve by installing it: `conda install pint -c conda-forge` or `pip install pint`"""
    )  # pragma: no cover
del spec, find_spec

from .context import constants, PhysicalConstantsContext
QCElemental-0.5.0/qcelemental/physical_constants/context.py000066400000000000000000000413301351361252000241050ustar00rootroot00000000000000"""
Contains relevant physical constants
"""

import collections
from decimal import Decimal
from typing import Union

from ..datum import Datum, print_variables
from .ureg import build_units_registry


class PhysicalConstantsContext:
    """CODATA 2014 physical constants set from NIST.

    Parameters
    ----------
    context : {'CODATA2014'}
        Origin of loaded data.

    Attributes
    ----------
    name : str
        The name of the context ('CODATA2014')
    pc : dict of Datum
        Each physical constant is an entry in `pc`, where key is the
        lowercased string of the NIST name (or any alias) and the
        value is a Datum object with `lbl` the exact NIST name string,
        `units`, `data` value as Decimal object, and any uncertainty
        in the `comment` field.
    year : int
        The year the context was created.

    """

    _transtable = str.maketrans(' -/{', '__p_', '.,()}')

    def __init__(self, context="CODATA2014"):
        self.pc = collections.OrderedDict()

        from ..data import nist_2014_codata

        if context == "CODATA2014":
            self.doi = nist_2014_codata["doi"]
            self.raw_codata = nist_2014_codata['constants']

            # physical constant loop
            for k, v in self.raw_codata.items():
                self.pc[k] = Datum(
                    v["quantity"],
                    v["unit"],
                    Decimal(v["value"]),
                    comment='uncertainty={}'.format(v["uncertainty"]),
                    doi=self.doi)
        else:
            raise KeyError("Context set as '{}', only contexts {'CODATA2014', } are currently supported")

        self.name = context
        self.year = int(context.replace("CODATA", ""))
        self._ureg = None

        # Extra relationships
        self.pc['calorie-joule relationship'] = Datum(
            'calorie-joule relationship', 'J', Decimal('4.184'), comment='uncertainty=(exact)')

        aliases = [
            ('h',                    'J',              self.pc['hertz-joule relationship'].data,                             'The Planck constant (Js)'),
            ('c',                    'Hz',             self.pc['inverse meter-hertz relationship'].data,                     'Speed of light (ms$^{-1}$)'),
            ('kb',                   'J',              self.pc['kelvin-joule relationship'].data,                            'The Boltzmann constant (JK$^{-1}$)'),
            ('R',                    'J mol^-1 K^-1',  self.pc['molar gas constant'].data,                                   'Universal gas constant (JK$^{-1}$mol$^{-1}$)'),
            ('bohr2angstroms',       'AA',             self.pc['bohr radius'].data * Decimal('1.E10'),                       'Bohr to Angstroms conversion factor'),
            ('bohr2m',               'm',              self.pc['bohr radius'].data,                                          'Bohr to meters conversion factor'),
            ('bohr2cm',              'cm',             self.pc['bohr radius'].data * Decimal('100'),                         'Bohr to centimeters conversion factor'),
            ('amu2g',                'g',              self.pc['atomic mass constant'].data * Decimal('1000'),               'Atomic mass units to grams conversion factor'),
            ('amu2kg',               'kg',             self.pc['atomic mass constant'].data,                                 'Atomic mass units to kg conversion factor' ),
            ('au2amu',               'u',              self.pc['electron mass in u'].data,                                   'Atomic units (m$@@e$) to atomic mass units conversion factor'),
            ('hartree2J',            'J',              self.pc['hartree energy'].data,                                       'Hartree to joule conversion factor'),
            ('hartree2aJ',           'aJ',             self.pc['hartree energy'].data * Decimal('1.E18'),                    'Hartree to attojoule (10$^{-18}$J) conversion factor'),
            ('cal2J',                'J',              self.pc['calorie-joule relationship'].data,                           'Calorie to joule conversion factor'),
            ('dipmom_au2si',         'C m',            self.pc['atomic unit of electric dipole mom.'].data,                  'Atomic units to SI units (Cm) conversion factor for dipoles'),
            ('dipmom_au2debye',      '???',            self.pc['atomic unit of electric dipole mom.'].data * Decimal('1.E21') / self.pc['hertz-inverse meter relationship'].data,
                                                                                                                             'Atomic units to Debye conversion factor for dipoles'),
            ('dipmom_debye2si',      '???',            self.pc['hertz-inverse meter relationship'].data * Decimal('1.E-21'), 'Debye to SI units (Cm) conversion factor for dipoles'),
            ('c_au',                 '',               self.pc['inverse fine-structure constant'].data,                      'Speed of light in atomic units'),
            ('hartree2ev',           'eV',             self.pc['hartree energy in ev'].data,                                 'Hartree to eV conversion factor'),
            ('hartree2wavenumbers',  'cm^-1',          self.pc['hartree-inverse meter relationship'].data * Decimal('0.01'), 'Hartree to cm$^{-1}$ conversion factor'),
            ('hartree2kcalmol',      'kcal mol^-1',    self.pc['hartree energy'].data * self.pc['avogadro constant'].data * Decimal('0.001') / self.pc['calorie-joule relationship'].data,
                                                                                                                             'Hartree to kcal mol$^{-1}$ conversion factor'),
            ('hartree2kJmol',        'kJ mol^-1',      self.pc['hartree energy'].data * self.pc['avogadro constant'].data * Decimal('0.001'), 'Hartree to kilojoule mol$^{-1}$ conversion factor'),
            ('hartree2MHz',          'MHz',            self.pc['hartree-hertz relationship'].data * Decimal('1.E-6'),        'Hartree to MHz conversion factor'),
            ('kcalmol2wavenumbers',  'kcal cm mol^-1', Decimal('10') * self.pc['calorie-joule relationship'].data / self.pc['molar planck constant times c'].data,
                                                                                                                             'kcal mol$^{-1}$ to cm$^{-1}$ conversion factor'),
            ('e0',                   'F m^-1',         self.pc['electric constant'].data,                                    'Vacuum permittivity (Fm$^{-1}$)'),
            ('na',                   'mol^-1',         self.pc['avogadro constant'].data,                                    "Avogadro's number"),
            ('me',                   'kg',             self.pc['electron mass'].data,                                        'Electron rest mass (in kg)'),
        ]  # yapf: disable

        # add alternate names for constants or derived values to help QC programs
        for alias in aliases:
            ident, units, value, comment = alias
            self.pc[ident.lower()] = Datum(ident, units, value, comment=comment)

        # add constants as directly callable member data
        for qca in self.pc.values():
            callname = qca.label.translate(self._transtable)
            setattr(self, callname, float(qca.data))

    def __str__(self):
        return "PhysicalConstantsContext(context='{}')".format(self.name)

    @property
    def ureg(self) -> 'UnitRegistry':
        """Returns the internal Pint units registry.

        Returns
        -------
        UnitRegistry
            The pint context
        """
        if self._ureg is None:
            self._ureg = build_units_registry(self)

        return self._ureg

    def get(self, physical_constant: str, return_tuple: bool=False) -> Union[float, 'Datum']:
        """Access a physical constant, `physical_constant`.

        Parameters
        ----------
        physical_constant : str
            Case-insensitive string of physical constant with NIST name.
        return_tuple : bool, optional
            See below.

        Returns
        -------
        Union[float, 'Datum']
            When ``return_tuple=False``, value of physical constant.
            When ``return_tuple=True``, Datum with units, description, uncertainty, and value of physical constant as Decimal.

        """
        qca = self.pc[physical_constant.lower()]

        if return_tuple:
            return qca
        else:
            return float(qca.data)

#       h                         'hertz-joule relationship'                  = 6.62606896E-34       # The Planck constant (Js)
#       c                         'inverse meter-hertz relationship'          = 2.99792458E8         # Speed of light (ms$^{-1}$)
#       kb                        'kelvin-joule relationship'                 = 1.3806504E-23        # The Boltzmann constant (JK$^{-1}$)
#       R                         'molar gas constant'                        = 8.314472             # Universal gas constant (JK$^{-1}$mol$^{-1}$)
#       bohr2angstroms            'Bohr radius' * 1.E10                       = 0.52917720859        # Bohr to Angstroms conversion factor
#       bohr2m                    'Bohr radius'                               = 0.52917720859E-10    # Bohr to meters conversion factor
#       bohr2cm                   'Bohr radius' * 100                         = 0.52917720859E-8     # Bohr to centimeters conversion factor
#       amu2kg                    'atomic mass constant'                      = 1.660538782E-27      # Atomic mass units to kg conversion factor
#       au2amu                    'electron mass in u'                        = 5.485799097E-4       # Atomic units (m$@@e$) to atomic mass units conversion factor
#       hartree2J                 'Hartree energy'                            = 4.359744E-18         # Hartree to joule conversion factor
#       hartree2aJ                'Hartree energy' * 1.E18                    = 4.359744             # Hartree to attojoule (10$^{-18}$J) conversion factor
#       cal2J                     = 4.184                # Calorie to joule conversion factor
#       dipmom_au2si              'atomic unit of electric dipole mom.'       = 8.47835281E-30       # Atomic units to SI units (Cm) conversion factor for dipoles
#       dipmom_au2debye           'atomic unit of electric dipole mom.' / ('hertz-inverse meter relationship' * 1.E-21)     = 2.54174623           # Atomic units to Debye conversion factor for dipoles
#       dipmom_debye2si           'hertz-inverse meter relationship' * 1.E-21 = 3.335640952E-30      # Debye to SI units (Cm) conversion factor for dipoles
#       c_au                      'inverse fine-structure constant'           = 137.035999679        # Speed of light in atomic units
#       hartree2ev                'Hartree energy in eV'                      = 27.21138             # Hartree to eV conversion factor
#       hartree2wavenumbers       'hartree-inverse meter relationship' * 0.01 = 219474.6             # Hartree to cm$^{-1}$ conversion factor
#       hartree2kcalmol           hartree2kJmol / cal2J                       = 627.5095             # Hartree to kcal mol$^{-1}$ conversion factor
#       hartree2kJmol             'Hartree energy'*'Avogadro constant'*0.001  = 2625.500             # Hartree to kilojoule mol$^{-1}$ conversion factor
#       hartree2MHz               'hartree-hertz relationship'                = 6.579684E9           # Hartree to MHz conversion factor
#       kcalmol2wavenumbers       10. / 'molar Planck constant times c'*4.184 = 349.7551             # kcal mol$^{-1}$ to cm$^{-1}$ conversion factor
#       e0                        'electric constant'                         = 8.854187817E-12      # Vacuum permittivity (Fm$^{-1}$)
#       na                        'Avogadro constant'                         = 6.02214179E23        # Avogadro's number
#       me                        'electron mass'                             = 9.10938215E-31       # Electron rest mass (in kg)

    def Quantity(self, data: str) -> 'Quantity':
        """Returns a Pint Quantity.
        """

        return self.ureg.Quantity(data)

    def conversion_factor(self, base_unit: Union[str, 'Quantity'], conv_unit: Union[str, 'Quantity']) -> float:
        """Provides the conversion factor from one unit to another.

        The conversion factor is based on the current contexts CODATA.

        Parameters
        ----------
        base_unit : Union[str, 'Quantity']
            The original units
        conv_unit : Union[str, 'Quantity']
            The units to convert to

        Examples
        --------

        >>> conversion_factor("meter", "picometer")
        1e-12

        >>> conversion_factor("feet", "meter")
        0.30479999999999996

        >>> conversion_factor(10 * ureg.feet, "meter")
        3.0479999999999996

        Returns
        -------
        float
            The requested conversion factor
        """

        # Add a little magic incase the incoming values have scalars
        import pint

        factor = 1.0

        # First make sure we either have Units or Quantities
        if isinstance(base_unit, str):
            base_unit = self.ureg.parse_expression(base_unit)

        if isinstance(conv_unit, str):
            conv_unit = self.ureg.parse_expression(conv_unit)

        # Need to play with prevector if we have Quantities
        if isinstance(base_unit, pint.quantity._Quantity):
            factor *= base_unit.magnitude
            base_unit = base_unit.units

        if isinstance(conv_unit, pint.quantity._Quantity):
            factor /= conv_unit.magnitude
            conv_unit = conv_unit.units

        return self.ureg.convert(factor, base_unit, conv_unit)

    def string_representation(self) -> str:
        """Print name, value, and units of all physical constants."""

        return print_variables(self.pc)

    def run_comparison(self):
        """Compare the existing physical constant information for Psi4 (in checkup_data folder) to `self`. Specialized use."""

        try:
            from .. import checkup_data
        except ImportError:  # pragma: no cover
            print('Info for comparison (directory checkup_data) not installed. Run from source.')

        class bcolors:
            HEADER = '\033[95m'
            OKBLUE = '\033[94m'
            OKGREEN = '\033[92m'
            WARNING = '\033[93m'
            FAIL = '\033[91m'
            ENDC = '\033[0m'
            BOLD = '\033[1m'
            UNDERLINE = '\033[4m'

        tol = 1.e-8
        print(bcolors.OKBLUE + '\nChecking ({}) physconst vs. Psi4 ...'.format(tol) + bcolors.ENDC)
        for pc in dir(checkup_data.physconst):
            if not pc.startswith('__'):
                ref = self.get(pc)
                val = getattr(checkup_data.physconst, pc)
                rat = abs(1.0 - float(ref) / val)
                if rat > 1.e-4:
                    print(bcolors.FAIL + 'Physical Constant {} ratio differs by {:12.8f}: {} (this) vs {} (psi)'.
                          format(pc, rat, ref, val) + bcolors.ENDC)
                if rat > tol:
                    print('Physical Constant {} ratio differs by {:12.8f}: {} (this) vs {} (psi)'.format(
                        pc, rat, ref, val))

    def _get_pi(self, from_scratch=False):
        """Get pi to 36 digits (or more with mpmath)."""

        if from_scratch:  # pragma: no cover
            from mpmath import mp
            mp.dps = 36
            return mp.pi
        else:
            return Decimal('3.14159265358979323846264338327950288')

    def write_c_header(self, filename='physconst.h'):
        """Write C header file defining physical constants and pi, all with ``pc_`` prefix."""

        pi = self._get_pi(from_scratch=False)
        tau = 2 * pi

        text = [
            '#ifndef _qcelemental_physconst_h_', '#define _qcelemental_physconst_h_', '',
            '/* This file is autogenerated from the QCElemental python module */', '', '/* clang-format off */',
            '#define pc_pi {}'.format(pi), '#define pc_twopi {}'.format(tau)
        ]

        for pc, qca in self.pc.items():
            callname = qca.label.translate(self._transtable)
            noncomment = '#define pc_{} {}'.format(callname, qca.data)
            text.append('{:80}  /*- {} [{}] {} -*/'.format(noncomment, qca.label, qca.units, qca.comment))
        text.append('/* clang-format on */')

        text.append('')
        text.append('/* For Cray X1 compilers */')
        text.append('#ifndef M_PI')
        text.append('#define M_PI 3.14159265358979323846')
        text.append('#endif')
        text.append('')

        text.append('#endif /* header guard */')
        text.append('')

        with open(filename, 'w') as handle:
            handle.write('\n'.join(text))
        print('File written ({}). Remember to add license and clang-format it.'.format(filename))


# singleton
constants = PhysicalConstantsContext("CODATA2014")
QCElemental-0.5.0/qcelemental/physical_constants/ureg.py000066400000000000000000000134611351361252000233670ustar00rootroot00000000000000"""
A wrapper for the pint ureg data
"""

# We only want the ureg builder exposed
__all__ = ["build_units_registry"]


def build_units_registry(context):
    """Builds a pint UnitRegistry based on a given PhysicalConstantsContext.

    Parameters
    ----------
    context : PhysicalConstantsContext
        The context to use for the values.
    """
    import pint

    phys_const = context.raw_codata
    ureg = pint.UnitRegistry(on_redefinition="ignore")

    # Explicitly update relevant 2014 codata

    # Definitions
    ureg.define("avogadro_constant = {} / mol = N_A".format(phys_const["avogadro constant"]["value"]))
    ureg.define("boltzmann_constant = {} * joule / kelvin".format(phys_const["boltzmann constant"]["value"]))
    ureg.define("speed_of_light = {} * meter / second".format(phys_const["speed of light in vacuum"]["value"]))
    ureg.define("hartree_inverse_meter = {} / hartree / m".format(
        phys_const["hartree-inverse meter relationship"]["value"]))

    # Energy
    ureg.define("hartree = {} * joule = E_h = hartree_energy".format(phys_const["hartree energy"]["value"]))
    ureg.define("electron_volt = {} * J = eV".format(phys_const["electron volt-joule relationship"]["value"]))

    # Constants
    ureg.define("electron_mass = {} * kg".format(phys_const["electron mass"]["value"]))
    ureg.define("elementary_charge = {} * coulomb = e".format(phys_const["elementary charge"]["value"]))
    ureg.define("plancks_constant = {} * joule * s".format(phys_const["planck constant"]["value"]))

    # Distance
    ureg.define("bohr = {} * meter = bohr_radius = Bohr".format(phys_const["bohr radius"]["value"]))
    ureg.define("wavenumber = 1 / centimeter")
    ureg.define("Angstrom = angstrom")

    # Masses
    ureg.define("atomic_mass_unit = {} * kilogram = u = amu = dalton = Da".format(
        phys_const["atomic mass constant"]["value"]))

    # Define relationships
    _const_rename = {
        "inverse meter": "inverse_meter",
        "atomic mass unit": "atomic_mass_unit",
        "electron volt": "electron_volt"
    }

    _nist_units = set()

    for k, v in phys_const.items():

        # Automatically builds the following:
        # electron_volt_to_kelvin = 1.16045221e4 / electron_volt * kelvin
        # hartree_to_atomic_mass_unit = 2.9212623197e-8 / hartree * atomic_mass_unit
        if not (("-" in k) and ("relationship" in k)): continue

        # Rename where needed
        left_unit, right_unit = k.split('-')
        left_unit = _const_rename.get(left_unit, left_unit)
        _nist_units.add(left_unit)

        right_unit = right_unit.replace(" relationship", "")
        right_unit = _const_rename.get(right_unit, right_unit)

        # Inverse is a special case

        if "inverse_meter" == left_unit:
            ratio1 = "* meter"
        else:
            ratio1 = "/ " + left_unit

        if "inverse_meter" == right_unit:
            ratio2 = "/ meter"
        else:
            ratio2 = "* " + right_unit

        definition = "{}_to_{} = {} {} {}".format(left_unit, right_unit, v["value"], ratio1, ratio2)
        ureg.define(definition)
        # print(definition)

    # Add contexts

    def _find_nist_unit(unit):
        """Converts pint datatypes to NIST datatypes
        """
        for value in unit.to_tuple()[1]:
            if value[1] < 1: continue
            if any(x in value[0] for x in _nist_units):
                return value[0]

        for value in unit.to_tuple()[1]:
            if (value[0] == "meter") and (value[1] == -1):
                return "inverse_meter"

        return None

    def build_transformer(right_unit, default):
        """Builds a transformer that attempts first to use the NIST values exactly and then falls back
        on to canonical Pint tech. The NIST values are not "exact" and will
        fail the triangle rule due to the inherent uncertainties of the values.

        Parameters
        ----------
        right_unit : str
            The NIST value to convert to
        default : str
            A fall back conversion rule to apply
        """

        def transformer(ureg, val):

            left_unit = _find_nist_unit(val)
            if left_unit is None:
                return val * ureg.parse_expression(default)
            else:
                return val * ureg.parse_expression("{}_to_{}".format(left_unit, right_unit))

        return transformer

    # Allows hartree <-> frequency
    c1 = pint.Context("energy_frequency")
    c1.add_transformation("[energy]", "[frequency]", build_transformer("hertz", "1 / plancks_constant"))
    c1.add_transformation("[frequency]", "[energy]", build_transformer("hartree", "plancks_constant"))

    # Allows hartree <-> inverse_length
    c2 = pint.Context("energy_inverse_length")
    c2.add_transformation("[energy]", "1 / [length]", build_transformer("inverse_meter", "hartree_to_inverse_meter"))
    c2.add_transformation("1 / [length]", "[energy]", build_transformer("hartree", "inverse_meter_to_hartree"))

    # Allows hartree <-> mass
    c3 = pint.Context("energy_mass")
    c3.add_transformation("[energy]", "[mass]", build_transformer("kilogram", "hartree_to_kilogram"))
    c3.add_transformation("[mass]", "[energy]", build_transformer("hartree", "kilogram_to_hartree"))

    # Allows hartree <-> temperature
    c4 = pint.Context("energy_temperature")
    c4.add_transformation("[energy]", "[temperature]", build_transformer("kelvin", "hartree_to_kelvin"))
    c4.add_transformation("[temperature]", "[energy]", build_transformer("hartree", "kelvin_to_hartree"))

    # Allows energy <-> energy / mol
    c5 = pint.Context("substance_relation")
    c5.add_transformation("[energy]", "[energy] / [substance]", lambda ureg, val: val * ureg.N_A)
    c5.add_transformation("[energy] / [substance]", "[energy]", lambda ureg, val: val / ureg.N_A)

    # Add the context
    ureg.enable_contexts(c1, c2, c3, c4, c5)

    return ureg
QCElemental-0.5.0/qcelemental/testing.py000066400000000000000000000436201351361252000201720ustar00rootroot00000000000000import collections
import copy
import logging
import math
import pprint
pp = pprint.PrettyPrinter(width=120)
import sys
from typing import Callable

import numpy as np


def _handle_return(passfail: bool, label: str, message: str, return_message: bool, quiet: bool = False):
    """Function to print a '*label*...PASSED' line to log.
    """

    if not quiet:
        if passfail:
            logging.info(f'    {label:.<53}PASSED')
        else:
            logging.error(f'    {label:.<53}FAILED')
            logging.error(f'    {message:.<53}')

    if return_message:
        return (passfail, message)
    else:
        return passfail


def tnm() -> str:
    """Returns the name of the calling function, usually name of test case.
    """

    return sys._getframe().f_back.f_code.co_name


def compare_values(expected,
                   computed,
                   label: str = None,
                   *,
                   atol: float = 1.e-6,
                   rtol: float = 1.e-16,
                   equal_nan: bool = False,
                   passnone: bool = False,
                   quiet: bool = False,
                   return_message: bool = False,
                   return_handler: Callable = None) -> bool:
    """Returns True if two floats or float arrays are element-wise equal within a tolerance.

    Parameters
    ----------
    expected : float or float array-like
        Reference value against which `computed` is compared.
    computed : float or float array-like
        Input value to compare against `expected`.
    atol : float, optional
        Absolute tolerance (see formula below).
    label : str, optional
        Label for passed and error messages. Defaults to calling function name.
    rtol : float, optional
        Relative tolerance (see formula below). By default set to zero so `atol` dominates.
    equal_nan : bool, optional
        Passed to np.isclose. Compare NaN's as equal.
    passnone : bool, optional
        Return True when both expected and computed are None.
    quiet : bool, optional
        Whether to log the return message.
    return_message : bool, optional
        Whether to return tuple. See below.

    Returns
    -------
    allclose : bool
        Returns True if `expected` and `computed` are equal within tolerance; False otherwise.
    message : str, optional
        When return_message=True, also return passed or error message.

    Other Parameters
    ----------------
    return_handler : function, optional
        Function to control printing, logging, raising, and returning.
        Specialized interception for interfacing testing systems.

    Notes
    -----
    * Akin to np.allclose.
    * For scalar float-comparable types and for arbitrary-dimension, np.ndarray-castable, uniform-type,
      float-comparable types. For mixed types, use :py:func:`compare_recursive`.
    * Sets rtol to zero to match expected Psi4 behaviour, otherwise measured as:

    .. code-block:: python

        absolute(computed - expected) <= (atol + rtol * absolute(expected))

    """
    label = label or sys._getframe().f_back.f_code.co_name
    pass_message = f'\t{label:.<66}PASSED'
    if return_handler is None:
        return_handler = _handle_return

    if passnone:
        if expected is None and computed is None:
            return return_handler(True, label, pass_message, return_message, quiet)

    try:
        xptd, cptd = np.array(expected, dtype=np.float), np.array(computed, dtype=np.float)
    except Exception:
        return return_handler(False, label, f"""\t{label}: inputs not cast-able to ndarray of np.float.""",
                              return_message, quiet)

    if xptd.shape != cptd.shape:
        return return_handler(False, label,
                              f"""\t{label}: computed shape ({cptd.shape}) does not match ({xptd.shape}).""",
                              return_message, quiet)

    digits1 = abs(int(np.log10(atol))) + 2
    digits_str = f'to atol={atol}'
    if rtol > 1.e-12:
        digits_str += f', rtol={rtol}'

    isclose = np.isclose(cptd, xptd, rtol=rtol, atol=atol, equal_nan=equal_nan)
    allclose = bool(np.all(isclose))

    if allclose:
        message = pass_message

    else:
        if xptd.shape == ():
            xptd_str = f'{float(xptd):.{digits1}f}'
        else:
            xptd_str = np.array_str(xptd, max_line_width=120, precision=12, suppress_small=True)
            xptd_str = '\n'.join('    ' + ln for ln in xptd_str.splitlines())

        if cptd.shape == ():
            cptd_str = f'{float(cptd):.{digits1}f}'
        else:
            cptd_str = np.array_str(cptd, max_line_width=120, precision=12, suppress_small=True)
            cptd_str = '\n'.join('    ' + ln for ln in cptd_str.splitlines())

        diff = cptd - xptd
        if xptd.shape == ():
            diff_str = f'{float(diff):.{digits1}f}'
            message = """\t{}: computed value ({}) does not match ({}) {} by difference ({}).""".format(
                label, cptd_str, xptd_str, digits_str, diff_str)
        else:
            diff[isclose] = 0.0
            diff_str = np.array_str(diff, max_line_width=120, precision=12, suppress_small=False)
            diff_str = '\n'.join('    ' + ln for ln in diff_str.splitlines())
            message = """\t{}: computed value does not match {}.\n  Expected:\n{}\n  Observed:\n{}\n  Difference (passed elements are zeroed):\n{}\n""".format(
                label, digits_str, xptd_str, cptd_str, diff_str)

    return return_handler(allclose, label, message, return_message, quiet)


def compare(expected,
            computed,
            label: str = None,
            *,
            quiet: bool = False,
            return_message: bool = False,
            return_handler: Callable = None) -> bool:
    """Returns True if two integers, strings, booleans, or integer arrays are element-wise equal.

    Parameters
    ----------
    expected : int, bool, str or int array-like
        Reference value against which `computed` is compared.
    computed : int, bool, str or int array-like
        Input value to compare against `expected`.
    label : str, optional
        Label for passed and error messages. Defaults to calling function name.

    Returns
    -------
    allclose : bool
        Returns True if `expected` and `computed` are equal; False otherwise.
    message : str, optional
        When return_message=True, also return passed or error message.

    Other Parameters
    ----------------
    return_handler : function, optional
        Function to control printing, logging, raising, and returning.
        Specialized interception for interfacing testing systems.

    Notes
    -----
    * Akin to np.array_equal.
    * For scalar exactly-comparable types and for arbitrary-dimension, np.ndarray-castable, uniform-type,
      exactly-comparable types. For mixed types, use :py:func:`compare_recursive`.

    """
    label = label or sys._getframe().f_back.f_code.co_name
    pass_message = f'\t{label:.<66}PASSED'
    if return_handler is None:
        return_handler = _handle_return

    try:
        xptd, cptd = np.array(expected), np.array(computed)
    except Exception:
        return return_handler(False, label, f"""\t{label}: inputs not cast-able to ndarray.""", return_message, quiet)

    if xptd.shape != cptd.shape:
        return return_handler(False, label,
                              f"""\t{label}: computed shape ({cptd.shape}) does not match ({xptd.shape}).""",
                              return_message, quiet)

    isclose = np.asarray(xptd == cptd)
    allclose = bool(isclose.all())

    if allclose:
        message = pass_message

    else:
        if xptd.shape == ():
            xptd_str = f'{xptd}'
        else:
            xptd_str = np.array_str(xptd, max_line_width=120, precision=12, suppress_small=True)
            xptd_str = '\n'.join('    ' + ln for ln in xptd_str.splitlines())

        if cptd.shape == ():
            cptd_str = f'{cptd}'
        else:
            cptd_str = np.array_str(cptd, max_line_width=120, precision=12, suppress_small=True)
            cptd_str = '\n'.join('    ' + ln for ln in cptd_str.splitlines())

        try:
            diff = cptd - xptd
        except TypeError:
            diff_str = '(n/a)'
        else:
            if xptd.shape == ():
                diff_str = f'{diff}'
            else:
                diff_str = np.array_str(diff, max_line_width=120, precision=12, suppress_small=False)
                diff_str = '\n'.join('    ' + ln for ln in diff_str.splitlines())

        if xptd.shape == ():
            message = """\t{}: computed value ({}) does not match ({}) by difference ({}).""".format(
                label, cptd_str, xptd_str, diff_str)
        else:
            message = """\t{}: computed value does not match.\n  Expected:\n{}\n  Observed:\n{}\n  Difference:\n{}\n""".format(
                label, xptd_str, cptd_str, diff_str)

    return return_handler(allclose, label, message, return_message, quiet)


def _compare_recursive(expected, computed, atol, rtol, _prefix=False):

    errors = []
    name = _prefix or "root"
    prefix = name + "."

    if isinstance(expected, (str, int, bool, complex)):
        if expected != computed:
            errors.append((name, "Value {} did not match {}.".format(expected, computed)))

    elif isinstance(expected, (list, tuple)):
        if len(expected) != len(computed):
            errors.append((name, "Iterable lengths did not match"))
        else:
            for i, item1, item2 in zip(range(len(expected)), expected, computed):
                errors.extend(_compare_recursive(item1, item2, _prefix=prefix + str(i), atol=atol, rtol=rtol))

    elif isinstance(expected, dict):
        expected_extra = computed.keys() - expected.keys()
        computed_extra = expected.keys() - computed.keys()
        if len(expected_extra):
            errors.append((name, "Found extra keys {}".format(expected_extra)))
        if len(computed_extra):
            errors.append((name, "Missing keys {}".format(computed_extra)))

        for k in expected.keys() & computed.keys():
            name = prefix + str(k)
            errors.extend(_compare_recursive(expected[k], computed[k], _prefix=name, atol=atol, rtol=rtol))

    elif isinstance(expected, float):
        passfail, msg = compare_values(expected, computed, atol=atol, rtol=rtol, return_message=True, quiet=True)
        if not passfail:
            errors.append((name, "Arrays differ." + msg))

    elif isinstance(expected, np.ndarray):
        if np.issubdtype(expected.dtype, np.floating):
            passfail, msg = compare_values(expected, computed, atol=atol, rtol=rtol, return_message=True, quiet=True)
        else:
            passfail, msg = compare(expected, computed, return_message=True, quiet=True)
        if not passfail:
            errors.append((name, "Arrays differ." + msg))

    elif isinstance(expected, type(None)):
        if expected is not computed:
            errors.append((name, "'None' does not match."))

    else:
        errors.append((name, f"Type {type(expected)} not understood -- stopping recursive compare."))

    return errors


def compare_recursive(expected,
                      computed,
                      label: str = None,
                      *,
                      atol: float = 1.e-6,
                      rtol: float = 1.e-16,
                      forgive: bool = None,
                      quiet: bool = False,
                      return_message: bool = False,
                      return_handler: Callable = None) -> bool:
    """
    Recursively compares nested structures such as dictionaries and lists.

    Parameters
    ----------
    expected : dict
        Reference value against which `computed` is compared.
        Dict may be of any depth but should contain Plain Old Data.
    computed : int, bool, str or int array-like
        Input value to compare against `expected`.
        Dict may be of any depth but should contain Plain Old Data.
    atol : int or float, optional
        Absolute tolerance (see formula below).
    label : str, optional
        Label for passed and error messages. Defaults to calling function name.
    rtol : float, optional
        Relative tolerance (see formula below). By default set to zero so `atol` dominates.
    forgive : list, optional
        Keys in top level which may change between `expected` and `computed` without triggering failure.

    Returns
    -------
    allclose : bool
        Returns True if `expected` and `computed` are equal within tolerance; False otherwise.
    message : str, optional
        When return_message=True, also return passed or error message.

    Notes
    -----

    .. code-block:: python

        absolute(computed - expected) <= (atol + rtol * absolute(expected))

    """
    label = label or sys._getframe().f_back.f_code.co_name
    if atol >= 1:
        raise ValueError(
            'Prior to v0.4.0, ``compare_recursive`` used to 10**-atol any atol >=1. That has ceased, so please express your atol literally.'
        )
    if return_handler is None:
        return_handler = _handle_return

    errors = _compare_recursive(expected, computed, atol=atol, rtol=rtol)

    if forgive is None:
        forgive = []
    else:
        forgive = [(fg if fg.startswith('root.') else 'root.' + fg) for fg in forgive]
    forgiven = []

    for nomatch in sorted(errors):
        for fg in (forgive or []):
            if nomatch[0].startswith(fg):
                forgiven.append(nomatch)
                errors.remove(nomatch)

    ## print if verbose >= 2 if these functions had that knob
    # forgiven_message = []
    # for e in sorted(forgiven):
    #     forgiven_message.append(e[0])
    #     forgiven_message.append("forgiven    " + e[1])
    # pprint.pprint(forgiven)

    message = []
    for e in sorted(errors):
        message.append(e[0])
        message.append("    " + e[1])

    message = "\n".join(message)

    return return_handler(len(message) == 0, label, message, return_message, quiet)


def compare_molrecs(expected,
                    computed,
                    label: str = None,
                    *,
                    atol: float = 1.e-6,
                    rtol: float = 1.e-16,
                    forgive=None,
                    verbose: int = 1,
                    relative_geoms='exact',
                    return_message: bool = False,
                    return_handler: Callable = None) -> bool:
    """Function to compare Molecule dictionaries. Prints
#    :py:func:`util.success` when elements of `computed` match elements of
#    `expected` to `tol` number of digits (for float arrays).

    """
    # Need to manipulate the dictionaries a bit, so hold values
    xptd = copy.deepcopy(expected)
    cptd = copy.deepcopy(computed)

    def massage_dicts(dicary):
        # if 'fix_symmetry' in dicary:
        #     dicary['fix_symmetry'] = str(dicary['fix_symmetry'])
        # if 'units' in dicary:
        #     dicary['units'] = str(dicary['units'])
        if 'fragment_files' in dicary:
            dicary['fragment_files'] = [str(f) for f in dicary['fragment_files']]
        # and about int vs long errors
        # if 'molecular_multiplicity' in dicary:
        #     dicary['molecular_multiplicity'] = int(dicary['molecular_multiplicity'])
        # if 'fragment_multiplicities' in dicary:
        #     dicary['fragment_multiplicities'] = [(m if m is None else int(m))
        #                                          for m in dicary['fragment_multiplicities']]
        if 'fragment_separators' in dicary:
            dicary['fragment_separators'] = [(s if s is None else int(s)) for s in dicary['fragment_separators']]
        # forgive generator version changes
        if 'provenance' in dicary:
            dicary['provenance'].pop('version')
        # regularize connectivity ordering
        if 'connectivity' in dicary:
            conn = [(min(at1, at2), max(at1, at2), bo) for (at1, at2, bo) in dicary['connectivity']]
            conn.sort(key=lambda tup: tup[0])
            dicary['connectivity'] = conn

        return dicary

    xptd = massage_dicts(xptd)
    cptd = massage_dicts(cptd)

    if relative_geoms == 'exact':
        pass
    elif relative_geoms == 'align':
        # can't just expect geometries to match, so we'll align them, check that
        #   they overlap and that the translation/rotation arrays jibe with
        #   fix_com/orientation, then attach the oriented geom to computed before the
        #   recursive dict comparison.
        from .molutil.align import B787
        cgeom = np.array(cptd['geom']).reshape((-1, 3))
        rgeom = np.array(xptd['geom']).reshape((-1, 3))
        rmsd, mill = B787(rgeom=rgeom,
                          cgeom=cgeom,
                          runiq=None,
                          cuniq=None,
                          atoms_map=True,
                          mols_align=True,
                          run_mirror=False,
                          verbose=0)
        if cptd['fix_com']:
            return compare(True,
                           np.allclose(np.zeros((3)), mill.shift, atol=atol),
                           'null shift',
                           quiet=(verbose == 0),
                           return_message=return_message,
                           return_handler=return_handler)
        if cptd['fix_orientation']:
            return compare(True,
                           np.allclose(np.identity(3), mill.rotation, atol=atol),
                           'null rotation',
                           quiet=(verbose == 0),
                           return_message=return_message,
                           return_handler=return_handler)
        ageom = mill.align_coordinates(cgeom)
        cptd['geom'] = ageom.reshape((-1))

    return compare_recursive(xptd,
                             cptd,
                             atol=atol,
                             rtol=rtol,
                             label=label,
                             forgive=forgive,
                             quiet=(verbose == 0),
                             return_message=return_message,
                             return_handler=return_handler)
QCElemental-0.5.0/qcelemental/tests/000077500000000000000000000000001351361252000173005ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/tests/__init__.py000066400000000000000000000000001351361252000213770ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/tests/addons.py000066400000000000000000000012001351361252000211130ustar00rootroot00000000000000import pytest

from qcelemental.util import which_import


using_networkx = pytest.mark.skipif(
    which_import('networkx', return_bool=True) is False,
    reason='Not detecting module networkx. Install package if necessary and add to envvar PYTHONPATH')

using_scipy = pytest.mark.skipif(
    which_import('scipy', return_bool=True) is False,
    reason='Not detecting module scipy. Install package if necessary and add to envvar PYTHONPATH')

using_py3dmol = pytest.mark.skipif(
    which_import('py3Dmol', return_bool=True) is False,
    reason='Not detecting module py3Dmol. Install package if necessary and add to envvar PYTHONPATH')
QCElemental-0.5.0/qcelemental/tests/test_constants.py000066400000000000000000000047271351361252000227370ustar00rootroot00000000000000import os
from decimal import Decimal

import pytest
import qcelemental


def test_access_1a():
    assert qcelemental.constants.c == 299792458


def test_access_1b():
    assert qcelemental.constants.speed_of_light_in_vacuum == 299792458


def test_access_1c():
    assert qcelemental.constants.pc['speed of light in vacuum'].data == 299792458


def test_access_1d():
    assert qcelemental.constants.get('speed of light in vacuum') == 299792458


def test_access_1e():
    qca = qcelemental.constants.get('speed of light in vacuum', return_tuple=True)

    assert qca.units == 'm s^{-1}'
    assert qca.comment == 'uncertainty=(exact)'
    assert qca.doi == '10.18434/T4WW24'
    assert qca.data == 299792458


def test_access_1f():
    assert qcelemental.constants.get('speed of LIGHT in vacuum') == 299792458


def test_access_2a():
    assert qcelemental.constants.Hartree_energy_in_eV == 27.21138602


def test_access_2b():
    assert qcelemental.constants.hartree2ev == 27.21138602


def test_access_2c():
    assert qcelemental.constants.pc['hartree energy in ev'].data == Decimal('27.21138602')


def test_access_2d():
    assert qcelemental.constants.get('hartree energy in ev') == 27.21138602


def test_access_2e():
    qca = qcelemental.constants.get('Hartree energy in eV', return_tuple=True)
    print(qca)

    assert qca.units == 'eV'
    assert qca.comment == 'uncertainty=0.000 000 17'
    assert qca.doi == '10.18434/T4WW24'
    assert qca.data == Decimal('27.21138602')


def test_access_2f():
    assert qcelemental.constants.get('hARTREE energy in eV') == 27.21138602


def test_access_2g():
    ref = {'label': 'Hartree energy in eV', 'units': 'eV', 'data': Decimal('27.21138602')}
    dqca = qcelemental.constants.get('Hartree energy in eV', return_tuple=True).dict()

    for itm in ref:
        assert ref[itm] == dqca[itm]


def test_c_header():
    qcelemental.constants.write_c_header("header.h")
    os.remove("header.h")


@pytest.mark.xfail(True, reason='comparison data not available for installed repository', run=True, strict=False)
def test_constants_comparison():
    qcelemental.constants.run_comparison()


def test_representation():
    qcelemental.constants.string_representation()


def test_str():
    assert "PhysicalConstantsContext(" in str(qcelemental.constants)


def test_codata2018():
    with pytest.raises(KeyError) as e:
        qcelemental.PhysicalConstantsContext("CODATA2018")

    assert "only contexts {'CODATA2014', } are currently supported" in str(e.value)
QCElemental-0.5.0/qcelemental/tests/test_covalentradii.py000066400000000000000000000041671351361252000235450ustar00rootroot00000000000000import os
from decimal import Decimal

import pytest
import qcelemental


@pytest.mark.parametrize("inp", ["He100", '-1', -1, -1.0, 'cat', 200, 'Cr_highspin'])
def test_id_resolution_error_bad_element(inp):
    with pytest.raises(qcelemental.NotAnElementError):
        ans = qcelemental.covalentradii.get(inp)


@pytest.mark.parametrize("inp", ['X', 'Bk', 100])
def test_id_resolution_error(inp):
    with pytest.raises(qcelemental.DataUnavailableError):
        qcelemental.covalentradii.get(inp)

    with pytest.raises(qcelemental.DataUnavailableError):
        qcelemental.covalentradii.get(inp, return_tuple=True)

    with pytest.raises(qcelemental.DataUnavailableError):
        qcelemental.covalentradii.get(inp, return_tuple=True, missing=3.0)

    assert qcelemental.covalentradii.get(inp, missing=4.0) == pytest.approx(4.0, 1.e-9)


a2b = 1. / qcelemental.constants.bohr2angstroms


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("KRYPTON", 1.16),
        ("kr", 1.16),
        ("kr84", 1.16),
        (36, 1.16),

        # aliases
        ("C", 0.76),
        ("C_sp", 0.69),
        ("MN", 1.61),
        ("Mn_lowspin", 1.39),

        # Deuterium
        ("D", 0.31),
        ("h2", 0.31),
    ])
def test_get(inp, expected):
    assert qcelemental.covalentradii.get(inp, units='angstrom') == pytest.approx(expected, 1.e-9)
    assert qcelemental.covalentradii.get(inp) == pytest.approx(a2b * expected, 1.e-9)


def test_get_tuple():
    ref = {'label': 'Mn', 'units': 'angstrom', 'data': Decimal('1.61')}
    dqca = qcelemental.covalentradii.get('manganese', return_tuple=True).dict()

    for itm in ref:
        assert ref[itm] == dqca[itm]


def test_c_header():
    qcelemental.covalentradii.write_c_header("header.h")
    os.remove("header.h")


def test_representation():
    qcelemental.covalentradii.string_representation()


def test_str():
    assert "CovalentRadii(" in str(qcelemental.covalentradii)


def test_covradmaker2018():
    with pytest.raises(KeyError) as e:
        qcelemental.CovalentRadii("COVRADMAKER2018")

    assert "only contexts {'ALVAREZ2008', } are currently supported" in str(e.value)
QCElemental-0.5.0/qcelemental/tests/test_datum.py000066400000000000000000000076021351361252000220300ustar00rootroot00000000000000from decimal import Decimal

import numpy as np
import pytest
import pydantic

import qcelemental as qcel
from qcelemental.testing import compare_recursive, compare_values


@pytest.fixture
def dataset():
    datums = {
        'decimal': qcel.Datum('a label', 'mdyn/angstrom', Decimal('4.4'), comment='force constant', doi='10.1000/182', numeric=False),
        'ndarray': qcel.Datum('an array', 'cm^-1', np.arange(4, dtype=np.float) * 4 / 3, comment='freqs'),
        'float': qcel.Datum('a float', 'kg', 4.4, doi='10.1000/182'),
        'string': qcel.Datum('ze lbl', 'ze unit', 'ze data', numeric=False),
        'lststr': qcel.Datum('ze lbl', 'ze unit', ['V', 'R', None], numeric=False),
    }  # yapf: disable

    return datums


def test_creation(dataset):
    datum1 = dataset['decimal']

    assert datum1.label == 'a label'
    assert datum1.units == 'mdyn/angstrom'
    assert datum1.data == Decimal('4.4')
    assert datum1.numeric is True  # checking that numeric got properly reset from input


def test_creation_nonnum(dataset):
    datum1 = dataset['string']

    assert datum1.label == 'ze lbl'
    assert datum1.units == 'ze unit'
    assert datum1.data == 'ze data'
    assert datum1.numeric is False


def test_creation_error():
    with pytest.raises(pydantic.ValidationError):
        qcel.Datum('ze lbl', 'ze unit', 'ze data')

    # assert 'Datum data should be float' in str(e)


@pytest.mark.parametrize("inp,expected", [
    (('decimal', None), 4.4),
    (('decimal', 'N/m'), 440),
    (('decimal', 'hartree/bohr/bohr'), 0.282614141011),
    (('ndarray', '1/m'), np.arange(4, dtype=np.float) * 400 / 3),
])
def test_units(dataset, inp, expected):
    assert compare_values(expected, dataset[inp[0]].to_units(inp[1]), atol=1.e-9)


def test_printing(dataset):
    datum1 = dataset['decimal']
    str1 = """----------------------------------------
             Datum a label
                 Pytest
----------------------------------------
Data:     4.4
Units:    [mdyn/angstrom]
doi:      10.1000/182
Comment:  force constant
Glossary:
----------------------------------------"""

    # Handle some odd spaces in the assert
    str2 = datum1.__str__(label='Pytest')
    assert all(x == y for x, y in zip(str1.split(), str2.split()))


def test_mass_printing_blank():
    pvnone = """
  Variable Map:
  ----------------------------------------------------------------------------
  (none)"""

    assert pvnone == qcel.datum.print_variables({})


def test_mass_printing(dataset):
    str1 = """
  Variable Map:
  ----------------------------------------------------------------------------
  "decimal" =>                    4.4 [mdyn/angstrom]
  "float"   =>         4.400000000000 [kg]
  "lststr"  =>       ['V', 'R', None] [ze unit]
  "ndarray" =>                        [cm^-1]
        [0.         1.33333333 2.66666667 4.        ]
  "string"  =>                ze data [ze unit]
"""

    assert str1 == qcel.datum.print_variables(dataset)


def test_to_dict(dataset):
    listans = [i * 4 / 3 for i in range(4)]
    ans = {'label': 'an array', 'units': 'cm^-1', 'data': listans, 'comment': 'freqs', 'numeric': True}

    dicary = dataset['ndarray'].dict()
    assert compare_recursive(ans, dicary, 9)


def test_complex_scalar():
    datum1 = qcel.Datum('complex scalar', '', complex(1, 2))
    ans = {'label': 'complex scalar', 'units': '', 'data': complex(1, 2), 'numeric': True}

    assert datum1.label == 'complex scalar'
    assert datum1.units == ''
    assert datum1.data.real == 1
    assert datum1.data.imag == 2

    dicary = datum1.dict()
    assert compare_recursive(ans, dicary, 9)


def test_complex_array():
    datum1 = qcel.Datum('complex array', '', np.arange(3, dtype=np.complex_) + 1j)
    ans = {
        'label': 'complex array',
        'units': '',
        'data': [complex(0, 1), complex(1, 1), complex(2, 1)],
        'numeric': True
    }

    dicary = datum1.dict()
    assert compare_recursive(ans, dicary, 9)
QCElemental-0.5.0/qcelemental/tests/test_importing.py000066400000000000000000000051011351361252000227160ustar00rootroot00000000000000import pytest

import os

import qcelemental as qcel


def test_which_import_t():
    ans = qcel.util.which_import('pint')
    assert ans.split(os.path.sep)[-1] == '__init__.py'


def test_which_import_t_bool():
    ans = qcel.util.which_import('pint', return_bool=True)
    assert ans is True


def test_which_import_f():
    ans = qcel.util.which_import('evilpint')
    assert ans is None


def test_which_import_f_bool():
    ans = qcel.util.which_import('evilpint', return_bool=True)
    assert ans is False


def test_which_import_f_raise():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which_import('evilpint', raise_error=True)

    assert str(e.value).endswith("Python module 'evilpint' not found in envvar PYTHONPATH.")


def test_which_import_f_raisemsg():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which_import('evilpint', raise_error=True, raise_msg='Install `evilpint`.')

    assert str(e.value).endswith("Python module 'evilpint' not found in envvar PYTHONPATH. Install `evilpint`.")


def test_which_t():
    ans = qcel.util.which('ls')
    assert ans.split(os.path.sep)[-1] == 'ls'


def test_which_t_bool():
    ans = qcel.util.which('ls', return_bool=True)
    assert ans is True


def test_which_f():
    ans = qcel.util.which('evills')
    assert ans is None


def test_which_f_bool():
    ans = qcel.util.which('evills', return_bool=True)
    assert ans is False


def test_which_f_raise():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which('evills', raise_error=True)

    assert str(e.value).endswith("Command 'evills' not found in envvar PATH.")


def test_which_f_raisemsg():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which('evills', raise_error=True, raise_msg='Install `evills`.')

    assert str(e.value).endswith("Command 'evills' not found in envvar PATH. Install `evills`.")


def test_which_f_raise():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which('evills', raise_error=True)

    assert str(e.value).endswith("Command 'evills' not found in envvar PATH.")


def test_which_f_raisemsg():
    with pytest.raises(ModuleNotFoundError) as e:
        qcel.util.which('evills', raise_error=True, raise_msg='Install `evills`.')

    assert str(e.value).endswith("Command 'evills' not found in envvar PATH. Install `evills`.")


def test_safe_version():
    assert 'v' + qcel.util.safe_version(qcel.__version__) == qcel.__version__


def test_parse_version():
    import pydantic
    assert qcel.util.parse_version(str(pydantic.VERSION)) >= qcel.util.parse_version("v0.20")
QCElemental-0.5.0/qcelemental/tests/test_model_serials.py000066400000000000000000000105631351361252000235400ustar00rootroot00000000000000import numpy as np
import pytest
from pydantic import ValidationError
from qcelemental.models import (ComputeError, FailedOperation, Molecule, Optimization, OptimizationInput, Result,
                                ResultInput)
from qcelemental.util import provenance_stamp


@pytest.fixture
def water():
    """Water dimer minima"""
    return Molecule.from_data(
        """
        0 1
        O  -1.551007  -0.114520   0.000000
        H  -1.934259   0.762503   0.000000
        H  -0.599677   0.040712   0.000000
        --
        O   1.350625   0.111469   0.000000
        H   1.680398  -0.373741  -0.758561
        H   1.680398  -0.373741   0.758561
        """,
        dtype="psi4",
        orient=True)


@pytest.fixture
def result_input():
    return {
        "id": "5c754f049642c7c861d67de5",
        "driver": "gradient",
        "model": {
            "method": "filler"
        },
    }


@pytest.fixture
def res_success():
    return {
        "success": True,
        "return_result": 536.2,
        "properties": {
            "scf_one_electron_energy": 5
        },
        "provenance": provenance_stamp("QCEl")
    }


@pytest.fixture
def res_failure(res_success):
    return {
        **res_success, "success": False,
        "error": {
            "error_type": "expected_testing_error",
            "error_message": "If you see this, its all good"
        }
    }


@pytest.fixture
def opti_input():
    return {"input_specification": {"driver": "gradient", "model": {"method": "filler"}}}


@pytest.fixture
def opti_success(water, result_input, res_success):
    res = Result(molecule=water, **result_input, **res_success)
    return {
        "success": True,
        "trajectory": [res] * 3,
        "final_molecule": water,
        "energies": [1.0, 2.0, 3.0],
        "provenance": provenance_stamp("QCEl")
    }


def test_driverenum_derivative_int(water, result_input):
    res = ResultInput(molecule=water, **result_input)

    assert res.driver == 'gradient'
    assert res.driver.derivative_int() == 1


def test_molecule_serialization(water):
    assert isinstance(water.dict(), dict)
    assert isinstance(water.json(), str)
    assert isinstance(water.json_dict(), dict)


def test_molecule_sparsity():
    m = Molecule(**{"symbols": ["He"], "geometry": [0, 0, 0], "identifiers": {"molecular_formula": "He"}})
    assert set(m.dict()["identifiers"].keys()) == {"molecular_formula"}
    assert set(m.identifiers.dict().keys()) == {"molecular_formula"}


def test_result_pass_serialization(water, result_input, res_success):
    res_in = ResultInput(molecule=water, **result_input)
    assert isinstance(res_in.dict(), dict)
    assert isinstance(res_in.json(), str)
    assert isinstance(res_in.json_dict(), dict)

    res_out = Result(molecule=water, **result_input, **res_success)
    assert isinstance(res_out.dict(), dict)
    assert isinstance(res_out.json(), str)
    assert isinstance(res_out.json_dict(), dict)


def test_result_sparsity(water, result_input, res_success):
    res_in = ResultInput(molecule=water, **result_input)
    assert set(res_in.dict()["model"].keys()) == {"method", "basis"}


def test_result_wrong_serialization(water, result_input, res_failure):
    res_out = Result(molecule=water, **result_input, **res_failure)
    assert isinstance(res_out.error, ComputeError)
    assert isinstance(res_out.dict(), dict)
    out_json = res_out.json()
    assert isinstance(out_json, str)
    assert 'its all good' in out_json


def test_optimization_pass_serialization(water, opti_input, opti_success):
    opti_in = OptimizationInput(initial_molecule=water, **opti_input)
    assert isinstance(opti_in.dict(), dict)
    assert isinstance(opti_in.json(), str)
    assert isinstance(opti_in.json_dict(), dict)

    opti_out = Optimization(initial_molecule=water, **opti_input, **opti_success)
    assert isinstance(opti_out.dict(), dict)
    assert isinstance(opti_out.json(), str)
    assert isinstance(opti_out.json_dict(), dict)


def test_failed_operation(water, result_input):
    failed = FailedOperation(
        extras={"garbage": water},
        input_data=result_input,
        error={"error_type": "expected_testing_error",
               "error_message": "If you see this, its all good"})
    assert isinstance(failed.error, ComputeError)
    assert isinstance(failed.dict(), dict)
    failed_json = failed.json()
    assert isinstance(failed_json, str)
    assert 'its all good' in failed_json
QCElemental-0.5.0/qcelemental/tests/test_molecule.py000066400000000000000000000410501351361252000225160ustar00rootroot00000000000000"""
Tests the imports and exports of the Molecule object.
"""

import numpy as np
import pytest
from qcelemental.models import Molecule
import qcelemental as qcel
from qcelemental.testing import compare, compare_values
from .addons import using_py3dmol

water_molecule = Molecule.from_data("""
    0 1
    O  -1.551007  -0.114520   0.000000
    H  -1.934259   0.762503   0.000000
    H  -0.599677   0.040712   0.000000
    """)

water_dimer_minima = Molecule.from_data(
    """
    0 1
    O  -1.551007  -0.114520   0.000000
    H  -1.934259   0.762503   0.000000
    H  -0.599677   0.040712   0.000000
    --
    O   1.350625   0.111469   0.000000
    H   1.680398  -0.373741  -0.758561
    H   1.680398  -0.373741   0.758561
    """,
    dtype="psi4",
    orient=True)


def test_molecule_data_constructor_numpy():
    water_psi = water_dimer_minima.copy()
    ele = np.array(water_psi.atomic_numbers).reshape(-1, 1)
    npwater = np.hstack((ele, water_psi.geometry))

    water_from_np = Molecule.from_data(npwater, name="water dimer", dtype="numpy", frags=[3])
    assert water_psi.compare(water_psi, water_from_np)

    water_from_np = Molecule.from_data(npwater, name="water dimer", frags=[3])
    assert water_psi.compare(water_psi, water_from_np)
    assert water_psi.get_molecular_formula() == "H4O2"


def test_molecule_data_constructor_dict():
    water_psi = water_dimer_minima.copy()

    # Check the JSON construct/deconstruct
    water_from_json = Molecule.from_data(water_psi.dict())
    assert water_psi.compare(water_psi, water_from_json)

    water_from_json = Molecule.from_data(water_psi.json(), "json")
    assert water_psi.compare(water_psi, water_from_json)
    assert water_psi.compare(Molecule.from_data(water_psi.to_string("psi4"), dtype="psi4"))

    assert water_psi.get_hash() == '3c4b98f515d64d1adc1648fe1fe1d6789e978d34'  # copied from schema_version=1
    assert water_psi.schema_version == 2
    assert water_psi.schema_name == 'qcschema_molecule'


def test_molecule_data_constructor_error():
    with pytest.raises(TypeError):
        Molecule.from_data([])

    with pytest.raises(KeyError):
        Molecule.from_data({}, dtype="bad")


def test_molecule_np_constructors():
    """
    Neon tetramer fun
    """
    ### Neon Tetramer
    neon_from_psi = Molecule.from_data(
        """
        Ne 0.000000 0.000000 0.000000
        --
        Ne 3.100000 0.000000 0.000000
        --
        Ne 0.000000 3.200000 0.000000
        --
        Ne 0.000000 0.000000 3.300000
        units bohr""",
        dtype="psi4")
    ele = np.array([10, 10, 10, 10]).reshape(-1, 1)
    npneon = np.hstack((ele, neon_from_psi.geometry))
    neon_from_np = Molecule.from_data(npneon, name="neon tetramer", dtype="numpy", frags=[1, 2, 3], units="bohr")

    assert neon_from_psi.compare(neon_from_psi, neon_from_np)

    # Check the JSON construct/deconstruct
    neon_from_json = Molecule.from_data(neon_from_psi.json(), dtype="json")
    assert neon_from_psi.compare(neon_from_psi, neon_from_json)
    assert neon_from_json.get_molecular_formula() == "Ne4"


def test_water_minima_data():
    # Give it a name
    mol_dict = water_dimer_minima.dict()
    mol_dict['name'] = "water dimer"
    mol = Molecule(orient=True, **mol_dict)

    assert len(str(mol)) == 661
    assert len(mol.to_string("psi4")) == 479

    assert sum(x == y for x, y in zip(mol.symbols, ['O', 'H', 'H', 'O', 'H', 'H'])) == mol.geometry.shape[0]
    assert mol.name == "water dimer"
    assert mol.molecular_charge == 0
    assert mol.molecular_multiplicity == 1
    assert np.sum(mol.real) == mol.geometry.shape[0]
    assert np.allclose(mol.fragments, [[0, 1, 2], [3, 4, 5]])
    assert np.allclose(mol.fragment_charges, [0, 0])
    assert np.allclose(mol.fragment_multiplicities, [1, 1])
    assert hasattr(mol, "provenance")
    assert np.allclose(mol.geometry, [[2.81211080, 0.1255717, 0.], [3.48216664, -1.55439981, 0.],
                                      [1.00578203, -0.1092573, 0.], [-2.6821528, -0.12325075, 0.],
                                      [-3.27523824, 0.81341093, 1.43347255], [-3.27523824, 0.81341093, -1.43347255]])
    assert mol.get_hash() == "3c4b98f515d64d1adc1648fe1fe1d6789e978d34"


def test_water_minima_fragment():

    mol = water_dimer_minima.copy()
    frag_0 = mol.get_fragment(0, orient=True)
    frag_1 = mol.get_fragment(1, orient=True)
    assert frag_0.get_hash() == "5f31757232a9a594c46073082534ca8a6806d367"
    assert frag_1.get_hash() == "bdc1f75bd1b7b999ff24783d7c1673452b91beb9"

    frag_0_1 = mol.get_fragment(0, 1)
    frag_1_0 = mol.get_fragment(1, 0)

    assert mol.symbols[:3] == frag_0.symbols
    assert np.allclose(mol.masses[:3], frag_0.masses)

    assert mol.symbols == frag_0_1.symbols
    assert np.allclose(mol.geometry, frag_0_1.geometry)

    assert mol.symbols[3:] + mol.symbols[:3] == frag_1_0.symbols
    assert np.allclose(mol.masses[3:] + mol.masses[:3], frag_1_0.masses)


def test_pretty_print():

    mol = water_dimer_minima.copy()
    assert isinstance(mol.pretty_print(), str)


def test_to_string():

    mol = water_dimer_minima.copy()
    assert isinstance(mol.to_string("psi4"), str)


@pytest.mark.parametrize("dtype, filext", [("json", "json"), ("xyz", "xyz"), ("numpy", "npy")])
def test_to_from_file_simple(tmp_path, dtype, filext):

    benchmol = Molecule.from_data("""
    O 0 0 0
    H 0 1.5 0
    H 0 0 1.5
    """)

    p = tmp_path / ("water." + filext)
    benchmol.to_file(p)

    mol = Molecule.from_file(p)

    assert mol.compare(benchmol)


@pytest.mark.parametrize("dtype", ["json", "psi4"])
def test_to_from_file_complex(tmp_path, dtype):

    p = tmp_path / ("water." + dtype)
    water_dimer_minima.to_file(p)

    mol = Molecule.from_file(p)
    assert mol.compare(water_dimer_minima)


def test_water_orient():
    # These are identical molecules, should find the correct results
    mol = Molecule.from_data("""
        O  -1.551007  -0.114520   0.000000
        H  -1.934259   0.762503   0.000000
        H  -0.599677   0.040712   0.000000
        --
        O  -0.114520  -1.551007  10.000000
        H   0.762503  -1.934259  10.000000
        H   0.040712  -0.599677  10.000000
        """)

    frag_0 = mol.get_fragment(0, orient=True)
    frag_1 = mol.get_fragment(1, orient=True)

    # Make sure the fragments match
    assert frag_0.get_hash() == frag_1.get_hash()

    # Make sure the complexes match
    frag_0_1 = mol.get_fragment(0, 1, orient=True)
    frag_1_0 = mol.get_fragment(1, 0, orient=True)

    assert frag_0_1.get_hash() == frag_1_0.get_hash()  # != if get_fragment(..., group_fragments=False)

    # These are identical molecules, but should be different with ghost
    mol = Molecule.from_data(
        """
        O  -1.551007  -0.114520   0.000000
        H  -1.934259   0.762503   0.000000
        H  -0.599677   0.040712   0.000000
        --
        O  -11.551007  -0.114520   0.000000
        H  -11.934259   0.762503   0.000000
        H  -10.599677   0.040712   0.000000
        """,
        dtype="psi4",
        orient=True)

    frag_0 = mol.get_fragment(0, orient=True)
    frag_1 = mol.get_fragment(1, orient=True)

    # Make sure the fragments match
    assert frag_0.molecular_multiplicity == 1
    assert frag_0.get_hash() == frag_1.get_hash()

    # Make sure the complexes match
    frag_0_1 = mol.get_fragment(0, 1, orient=True)
    frag_1_0 = mol.get_fragment(1, 0, orient=True)

    # Ghost fragments should prevent overlap
    assert frag_0_1.molecular_multiplicity == 1
    assert frag_0_1.get_hash() != frag_1_0.get_hash()


def test_molecule_errors_extra():
    data = water_dimer_minima.dict()
    data["whatever"] = 5
    with pytest.raises(Exception):
        Molecule(**data)


def test_molecule_errors_connectivity():
    data = water_molecule.dict()
    data["connectivity"] = [(-1, 5, 5)]
    with pytest.raises(Exception):
        Molecule(**data)


def test_molecule_errors_shape():
    data = water_molecule.dict()
    data["geometry"] = list(range(8))
    with pytest.raises(Exception):
        Molecule(**data)


def test_molecule_serialization():
    assert isinstance(water_dimer_minima.json(), str)

    assert isinstance(water_dimer_minima.json_dict()["geometry"], list)


def test_charged_fragment():
    mol = Molecule(
        symbols=["Li", "Li"],
        geometry=[0, 0, 0, 0, 0, 5],
        fragment_charges=[0.0, 0.0],
        fragment_multiplicities=[2, 2],
        fragments=[[0], [1]])
    assert mol.molecular_multiplicity == 3
    assert mol.molecular_charge == 0
    f1 = mol.get_fragment(0)
    assert f1.molecular_multiplicity == 2
    assert f1.fragment_multiplicities == [2]
    assert pytest.approx(f1.molecular_charge) == 0
    assert pytest.approx(f1.fragment_charges) == [0]


# someday, when we can have noncontig frags
#    mol = Molecule(**{
#        'fragments': [[1, 5, 6], [0], [2, 3, 4]],
#        'symbols': ["he", "o", "o", "h", "h", "h", "h"],
#        # same geom as test_water_orient but with He at origin
#        'geometry': [
#        0.0, 0.0, 0.0,
#        -1.551007,  -0.114520,   0.000000,
#        -0.114520,  -1.551007,  10.000000,
#         0.762503,  -1.934259,  10.000000,
#         0.040712,  -0.599677,  10.000000,
#        -1.934259,   0.762503,   0.000000,
#        -0.599677,   0.040712,   0.000000],
#    })


@pytest.mark.parametrize("group_fragments, orient", [
    (True, True),  # original
    (False, False),  # Psi4-like
])
def test_get_fragment(group_fragments, orient):
    mol = Molecule(**{
        'fragments': [[0], [1, 2, 3], [4, 5, 6]],
        'symbols': ["he", "o", "h", "h", "o", "h", "h"],
        # same geom as test_water_orient but with He at origin
        'geometry': np.array([
        0.0, 0.0, 0.0,
        -1.551007,  -0.114520,   0.000000,
        -1.934259,   0.762503,   0.000000,
        -0.599677,   0.040712,   0.000000,
        -0.114520,  -1.551007,  10.000000,
         0.762503,  -1.934259,  10.000000,
         0.040712,  -0.599677,  10.000000]) / qcel.constants.bohr2angstroms,
    })

    assert mol.nelectrons() == 22
    assert compare_values(32.25894779318589, mol.nuclear_repulsion_energy(), atol=1.e-5)

    monomers_nelectrons = [2, 10, 10]
    monomers_nre = [0.0, 9.163830150548483, 9.163830150548483]
    monomers = [mol.get_fragment(ifr, group_fragments=group_fragments, orient=orient) for ifr in range(3)]
    for fr in range(3):
        assert monomers[fr].nelectrons() == monomers_nelectrons[fr]
        assert compare_values(monomers[fr].nuclear_repulsion_energy(), monomers_nre[fr], 'monomer nre', atol=1.e-5)

    idimers = [(0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1)]
    dimers_nelectrons = [12, 12, 20, 12, 12, 20]
    dimers_nre = [16.8777971, 10.2097206, 23.4990904, 16.8777971, 10.2097206, 23.4990904]
    dimers = [mol.get_fragment(rl, group_fragments=group_fragments, orient=orient) for rl in idimers]
    for ifr in range(len(idimers)):
        # print('dd', ifr, idimers[ifr], dimers[ifr].nuclear_repulsion_energy(), dimers[ifr].get_hash())
        assert dimers[ifr].nelectrons() == dimers_nelectrons[ifr], 'dimer nelec'
        assert compare_values(dimers[ifr].nuclear_repulsion_energy(), dimers_nre[ifr], 'dimer nre', atol=1.e-5)
    if group_fragments and orient:
        assert dimers[0].get_hash() != dimers[3].get_hash()  # atoms out of order
        assert dimers[1].get_hash() != dimers[4].get_hash()  # atoms out of order
        assert dimers[2].get_hash() == dimers[5].get_hash()
    elif not group_fragments and not orient:
        assert dimers[0].get_hash() == dimers[3].get_hash()
        assert dimers[1].get_hash() == dimers[4].get_hash()
        assert dimers[2].get_hash() == dimers[5].get_hash()
    else:
        assert 0


    ghdimers_nelectrons = [2, 2, 10, 10, 10, 10]
    ghdimers_nre = [0.0, 0.0, 9.163830150548483, 9.163830150548483, 9.163830150548483, 9.163830150548483]
    ghdimers = [mol.get_fragment(rl, gh, group_fragments=group_fragments, orient=orient) for rl, gh in idimers]
    for ifr in range(len(idimers)):
        # print('gh', ifr, idimers[ifr], ghdimers[ifr].nuclear_repulsion_energy(), ghdimers[ifr].get_hash())
        assert ghdimers[ifr].nelectrons() == ghdimers_nelectrons[ifr], 'gh dimer nelec'
        assert compare_values(ghdimers[ifr].nuclear_repulsion_energy(), ghdimers_nre[ifr], 'gh dimer nre', atol=1.e-5)

    if group_fragments and orient:
        assert ghdimers[0].get_hash() != ghdimers[3].get_hash()  # diff atoms ghosted
        assert ghdimers[1].get_hash() != ghdimers[4].get_hash()  # diff atoms ghosted
        assert ghdimers[2].get_hash() == ghdimers[5].get_hash()
    elif not group_fragments and not orient:
        assert ghdimers[0].get_hash() != ghdimers[3].get_hash()  # diff atoms ghosted
        assert ghdimers[1].get_hash() != ghdimers[4].get_hash()  # diff atoms ghosted
        assert ghdimers[2].get_hash() != ghdimers[5].get_hash()  # real pattern different
        assert ghdimers[2].real != ghdimers[5].real
    else:
        assert 0


def test_molecule_repeated_hashing():

    mol = Molecule(**{
        'symbols': ['H', 'O', 'O', 'H'],
        'geometry': [
             1.7317,  1.2909,  1.037100000000001,
             1.3156, -0.0074, -0.2807,
            -1.3143,  0.0084, -0.2741,
            -1.7241, -1.3079,  1.0277
        ]
    }) # yapf: disable

    h1 = mol.get_hash()
    assert mol.get_molecular_formula() == "H2O2"

    mol2 = Molecule(orient=False, **mol.dict())
    assert h1 == mol2.get_hash()

    mol3 = Molecule(orient=False, **mol2.dict())
    assert h1 == mol3.get_hash()


@pytest.mark.parametrize("measure,result", [
    ([0, 1], 1.8086677572537304),
    ([0, 1, 2], 37.98890673587713),
    ([0, 1, 2, 3], 180.0),
    ([[0, 1, 2, 3]], [180.0]),
    ([[1, 3], [3, 1], [1, 2, 3]], [6.3282716, 6.3282716, 149.51606694803903]),
])
def test_measurements(measure, result):

    mol = Molecule(**{
        'symbols': ['H', 'O', 'O', 'H'],
        'geometry': [
             1.7317,  1.2909,  1.0371,
             1.3156, -0.0074, -0.2807,
            -1.3143,  0.0084, -0.2741,
            -1.7241, -1.3079,  1.0277
        ]
    }) # yapf: disable

    assert pytest.approx(water_dimer_minima.measure(measure)) == result


@pytest.mark.parametrize("f1c,f1m,f2c,f2m,tc,tm", [
    (0, 2, 0, 2, 0.0, 3),
    (0, 4, 0, 2, 0.0, 5),
    (1, 1, 1, 1, 2.0, 1),
    (1, 1, 0, 2, 1.0, 2),
    (0, 2, 1, 1, 1.0, 2),
    (-1, 1, 1, 1, 0.0, 1),
])
def test_fragment_charge_configurations(f1c, f1m, f2c, f2m, tc, tm):

    mol = Molecule.from_data("""
    {f1c} {f1m}
    Li 0 0 0
    --
    {f2c} {f2m}
    Li 0 0 5
    """.format(f1c=f1c, f1m=f1m, f2c=f2c, f2m=f2m))

    assert pytest.approx(mol.molecular_charge) == tc
    assert mol.molecular_multiplicity == tm

    # Test fragment1
    assert pytest.approx(mol.get_fragment(0).molecular_charge) == f1c
    assert mol.get_fragment(0).molecular_multiplicity == f1m

    assert pytest.approx(mol.get_fragment(0, 1).molecular_charge) == f1c
    assert mol.get_fragment(0, 1).molecular_multiplicity == f1m

    # Test fragment2
    assert pytest.approx(mol.get_fragment(1).molecular_charge) == f2c
    assert mol.get_fragment(1).molecular_multiplicity == f2m

    assert pytest.approx(mol.get_fragment([1], 0).molecular_charge) == f2c
    assert mol.get_fragment(1, [0]).molecular_multiplicity == f2m


def test_nuclearrepulsionenergy_nelectrons():

    mol = Molecule.from_data("""
    0 1
    --
    O          0.75119       -0.61395        0.00271
    H          1.70471       -0.34686        0.00009
    --
    1 1
    N         -2.77793        0.00179       -0.00054
    H         -2.10136        0.51768        0.60424
    H         -3.45559       -0.51904        0.60067
    H         -2.26004       -0.67356       -0.60592
    H         -3.29652        0.68076       -0.60124
    units ang
    """)

    assert compare_values(34.60370459, mol.nuclear_repulsion_energy(), 'D', atol=1.e-5)
    assert compare_values(4.275210518, mol.nuclear_repulsion_energy(ifr=0), 'M1', atol=1.e-5)
    assert compare_values(16.04859029, mol.nuclear_repulsion_energy(ifr=1), 'M2', atol=1.e-5)

    assert compare(20, mol.nelectrons(), 'D')
    assert compare(10, mol.nelectrons(ifr=0), 'M1')
    assert compare(10, mol.nelectrons(ifr=1), 'M2')

    mol = mol.get_fragment([1], 0, group_fragments=False)
    # Notice the 0th/1st fragments change if default group_fragments=True.
    ifr0 = 0
    ifr1 = 1
    assert compare_values(16.04859029, mol.nuclear_repulsion_energy(), 'D', atol=1.e-5)
    assert compare_values(0.0, mol.nuclear_repulsion_energy(ifr=ifr0), 'M1', atol=1.e-5)
    assert compare_values(16.04859029, mol.nuclear_repulsion_energy(ifr=ifr1), 'M2', atol=1.e-5)

    assert compare(10, mol.nelectrons(), 'D')
    assert compare(0, mol.nelectrons(ifr=ifr0), 'M1')
    assert compare(10, mol.nelectrons(ifr=ifr1), 'M2')


@using_py3dmol
def test_show():

    water_dimer_minima.show()
QCElemental-0.5.0/qcelemental/tests/test_molparse_align_chiral.py000066400000000000000000000442061351361252000252350ustar00rootroot00000000000000#! testing aligner on enantiomers based on Table 1 of 10.1021/ci100219f aka J Chem Inf Model 2010 50(12) 2129-2140

from .addons import using_networkx

import qcelemental as qcel
from qcelemental.testing import compare_values, compare

do_plot = False
verbose = 4
run_mirror = True
uno_cutoff = 0.1

simpleR = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -50.881170
 C     0.000000     0.000000     0.000000
Br     0.000000     0.000000     1.949834
 F     1.261262     0.000000    -0.451181
Cl    -0.845465     1.497406    -0.341118
 H    -0.524489    -0.897662    -0.376047
""")

simpleS = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -50.881200
 C     0.000000     0.000000     0.000000
Br     0.000000     0.000000     1.949804
 F     1.261275     0.000000    -0.451161
Cl    -0.845116    -1.497706    -0.341045
 H    -0.524793     0.897448    -0.376232
""")


@using_networkx()
def test_simpleS():
    mol, data = simpleS.align(
        simpleR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.093e-4, data['rmsd'], 'bromochlorofluoromethane R, S', atol=1.e-4)
    assert compare(True, data['mill'].mirror, 'bromochlorofluoromethane R, S enantiomers')


clbrbutRR = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -29.636550
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.509728
 C     1.394392     0.000000     2.083312
 C     1.460804     0.212794     3.561904
Cl    -0.805162    -1.495518     2.066383
Br     2.013324    -1.836057     1.828118
 H    -1.021157    -0.064219    -0.396135
 H     0.457357     0.913936    -0.400858
 H     0.566137    -0.857946    -0.390224
 H    -0.580825     0.865588     1.904836
 H     2.079174     0.666966     1.517655
 H     2.493301     0.125569     3.923171
 H     0.857400    -0.536748     4.093681
 H     1.087887     1.206566     3.844299
""")

clbrbutRS = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -30.277180
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.509142
 C     1.390374     0.000000     2.089915
 C     1.450794    -0.060529     3.582557
Cl    -0.831919    -1.494925     2.053243
Br     2.082342     1.783785     1.662513
 H    -1.023753    -0.036573    -0.393769
 H     0.478870     0.909080    -0.389803
 H     0.541746    -0.863633    -0.408767
 H    -0.578898     0.865555     1.907156
 H     2.057770    -0.738548     1.597517
 H     2.486863     0.018622     3.935397
 H     0.881502     0.759255     4.041367
 H     1.035280    -1.006910     3.957479
""")

clbrbutSR = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -30.275240
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.509155
 C     1.389920     0.000000     2.090729
 C     1.448916     0.051020     3.583897
Cl    -0.831642     1.495114     2.054639
Br     2.086426    -1.779337     1.653668
 H     0.548114     0.859605    -0.408848
 H     0.471909    -0.912597    -0.389913
 H    -1.023598     0.044124    -0.393419
 H    -0.579384    -0.865482     1.906833
 H     2.056087     0.742881     1.602705
 H     2.485550    -0.019639     3.936806
 H     0.888172    -0.777962     4.036680
 H     1.023018     0.990363     3.964880
""")

clbrbutSS = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -29.643460
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.509392
 C     1.393926     0.000000     2.083958
 C     1.460796    -0.214897     3.562526
Cl    -0.807585     1.492562     2.068948
Br     2.010793     1.836814     1.833496
 H     0.568886     0.856793    -0.388866
 H     0.454828    -0.914960    -0.401166
 H    -1.020876     0.067696    -0.396254
 H    -0.578058    -0.867227     1.905574
 H     2.080051    -0.665370     1.518052
 H     2.491742    -0.116029     3.925086
 H     0.847599     0.527095     4.093658
 H     1.098918    -1.213191     3.842777
""")


@using_networkx()
def test_clbrbutSS():
    mol, data = clbrbutSS.align(
        clbrbutRR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(5.411e-3, data['rmsd'], '2-chloro-3-bromobutane RR, SS', atol=1.e-3)
    assert compare(True, data['mill'].mirror, '2-chloro-3-bromobutane RR, SS enantiomers')


@using_networkx()
def test_clbrbutSR_vs_RR():
    mol, data = clbrbutSR.align(
        clbrbutRR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.095, data['rmsd'], '2-chloro-3-bromobutane RR, SR', atol=1.)


@using_networkx()
def test_clbrbutRS():
    mol, data = clbrbutRS.align(
        clbrbutRR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.092, data['rmsd'], '2-chloro-3-bromobutane RR, RS', atol=1.)


@using_networkx()
def test_clbrbutSR_vs_RS():
    mol, data = clbrbutSR.align(
        clbrbutRS, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(8.652e-3, data['rmsd'], '2-chloro-3-bromobutane RS, SR', atol=2.e-3)
    assert compare(True, data['mill'].mirror, '2-chloro-3-bromobutane RS, SR enantiomers')


dibromobutSS = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -22.937250
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.496279
 C     1.361987     0.000000     2.119416
 C     1.363587    -0.162563     3.607138
Br    -0.742941     1.740557     1.978536
Br     2.015868     1.817420     1.832045
 H     0.622501     0.819590    -0.386984
 H     0.389783    -0.942758    -0.406016
 H    -1.016978     0.140241    -0.387333
 H    -0.658640    -0.782496     1.930226
 H     2.059808    -0.696076     1.606819
 H     2.370436    -0.004470     4.013614
 H     0.693388     0.572465     4.075885
 H     1.030818    -1.164970     3.906985
""")

dibromobutSR = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -21.346970
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.495389
 C     1.354135     0.000000     2.127396
 C     1.351723    -0.024448     3.622684
Br    -0.736136     1.757120     1.966081
Br     2.112214    -1.739283     1.628669
 H     0.580028     0.840879    -0.404106
 H     0.435283    -0.928956    -0.395418
 H    -1.022843     0.087835    -0.387890
 H    -0.671001    -0.769427     1.932845
 H     2.015275     0.785568     1.703616
 H     2.375204    -0.088280     4.013274
 H     0.795144    -0.888367     4.010872
 H     0.887114     0.885089     4.029976
""")

dibromobutRS = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -21.346980
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.495412
 C     1.354107     0.000000     2.127461
 C     1.351518     0.024034     3.622752
Br    -0.735537    -1.757450     1.966030
Br     2.112747     1.739065     1.629148
 H    -1.023207    -0.082970    -0.387992
 H     0.575929    -0.843792    -0.403875
 H     0.439799     0.926712    -0.395760
 H    -0.671351     0.769073     1.933069
 H     2.015075    -0.785721     1.703686
 H     0.790548     0.884898     4.011423
 H     0.891569    -0.888103     4.029483
 H     2.374702     0.092797     4.013327
""")

dibromobutRR = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =   -22.930210
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.496210
 C     1.361649     0.000000     2.119588
 C     1.364606     0.173819     3.605897
Br    -0.746131    -1.738887     1.981479
Br     2.011720    -1.821637     1.845756
 H    -1.016792    -0.144232    -0.386401
 H     0.385594     0.944822    -0.405310
 H     0.625554    -0.816867    -0.387472
 H    -0.658290     0.782653     1.930960
 H     2.058559     0.690990     1.598667
 H     2.378222     0.050588     4.007472
 H     0.719551    -0.577247     4.084122
 H     1.002433     1.167985     3.899397
""")


@using_networkx()
def test_dibromobutRS_RR():
    mol, data = dibromobutRS.align(
        dibromobutRR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.562, data['rmsd'], '2,3-dibromobutane RR, RS', atol=1.e-1)


@using_networkx()
def test_dibromobutSS_RR():
    mol, data = dibromobutSS.align(
        dibromobutRR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.296e-2, data['rmsd'], '2,3-dibromobutane RR, SS', atol=1.e-3)
    assert compare(True, data['mill'].mirror, '2,3-dibromobutane RR, SS enantiomers')


@using_networkx()
def test_dibromobutRS_SS():
    mol, data = dibromobutRS.align(
        dibromobutSS, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
    assert compare_values(1.560, data['rmsd'], '2,3-dibromobutane SS, RS', atol=1.e-1)


@using_networkx()
def test_dibromobutRS_SR_nomirror():
    # Table satisfied by non-mirror identical, but 787 finds even better match
    mol, data = dibromobutRS.align(
        dibromobutSR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=False)
    assert compare_values(4.534e-2, data['rmsd'], '2,3-dibromobutane SR, RS (force non-mirror)', atol=2.e-2)
    assert compare(False, data['mill'].mirror, '2,3-dibromobutane SR, RS identical (force non-mirror)')


@using_networkx()
def test_dibromobutRS_SR():
    mol, data = dibromobutRS.align(
        dibromobutSR, do_plot=do_plot, verbose=verbose, uno_cutoff=uno_cutoff, run_mirror=True)
    assert compare_values(0.004, data['rmsd'], '2,3-dibromobutane SR, RS', atol=1.e-3)
    assert compare(True, data['mill'].mirror, '2,3-dibromobutane SR, RS identical')


chiralanem = qcel.models.Molecule.from_data("""
C 0.000000 0 0.000000
C 0.886800 -0.8868 0.886800
C 0.886800 0.8868 -0.886800
C -0.886800 -0.8868 -0.886800
C -0.886800 0.8868 0.886800
C 2.079500 1.2281 0.026100
C 2.079500 -1.2281 -0.026100
C -2.079500 1.2281 -0.026100
C -2.079500 -1.2281 0.026100
C 0.026100 -2.0795 -1.228100
C -0.026100 -2.0795 1.228100
C -0.026100 2.0795 -1.228100
C 0.026100 2.0795 1.228100
C -1.228100 -0.0261 2.079500
C 1.228100 0.0261 2.079500
C -1.228100 0.0261 -2.079500
C 1.228100 -0.0261 -2.079500
C -1.437000 1.437 -1.437000
C -1.437000 -1.437 1.437000
C 1.437000 1.437 1.437000
C 1.437000 -1.437 -1.437000
C 3.006300 0 0.000000
C -3.006300 0 0.000000
C 0.000000 -3.0063 0.000000
C 0.000000 3.0063 0.000000
C 0.000000 0 3.006300
C 0.000000 0 -3.006300
H 2.607600 2.1192 -0.300100
H 2.607600 -2.1192 0.300100
H -2.607600 2.1192 0.300100
H -2.607600 -2.1192 -0.300100
H -0.300100 -2.6076 -2.119200
H 0.300100 -2.6076 2.119200
H 0.300100 2.6076 -2.119200
H -0.300100 2.6076 2.119200
H -2.119200 0.3001 2.607600
H 2.119200 -0.3001 2.607600
H -2.119200 -0.3001 -2.607600
H 2.119200 0.3001 -2.607600
H -2.064300 2.0643 -2.064300
H -2.064300 -2.0643 2.064300
H 2.064300 2.0643 2.064300
H 2.064300 -2.0643 -2.064300
H 3.656500 0.0192 -0.869300
H 3.656500 -0.0192 0.869300
H -3.656500 0.0192 0.869300
H -3.656500 -0.0192 -0.869300
H 0.869300 -3.6565 0.019200
H -0.869300 -3.6565 -0.019200
H -0.869300 3.6565 0.019200
H 0.869300 3.6565 -0.019200
H -0.019200 0.8693 3.656500
H 0.019200 -0.8693 3.656500
H -0.019200 -0.8693 -3.656500
H 0.019200 0.8693 -3.656500
""")

chiralaneopt = qcel.models.Molecule.from_data("""
#FINAL HEAT OF FORMATION =    47.217140
 C     0.000000     0.000000     0.000000
 C     0.000000     0.000000     1.535668
 C     1.483667     0.000000     1.960298
 C     1.897323    -1.480934     1.794409
 C     1.182490    -2.080847     0.561287
 C     1.160139    -0.905526    -0.438483
 C     2.545861    -0.204414    -0.243922
 C     3.602821    -1.310924     0.084831
 C     3.428480    -1.569415     1.596218
 C     2.436544     0.740855     0.998744
 C     2.097384    -3.257873     0.162576
 C     3.269709    -2.638216    -0.611983
 C     1.732359     0.268505     3.459505
 C     3.048765    -0.514788     3.780718
 C     3.966870    -0.452217     2.514702
 C     2.669267    -2.013236     4.026184
 C     1.494657    -2.273549     3.059766
 C     3.776149     0.859977     1.740105
 C     2.563531    -3.866279     1.527159
 C     3.759779    -3.005446     2.054024
 C     1.383424    -3.724246     2.545368
 C     3.794577    -2.962180     3.588665
 C    -0.569013    -1.338608     2.113457
 C    -0.197642    -2.488310     1.118613
 C     0.156603    -1.623694     3.470578
 C     0.018490    -3.822007     1.848535
 C     0.524826    -0.323801     4.200672
 H     1.568811    -4.016806    -0.452686
 H     4.628802    -0.971302    -0.172183
 H    -0.455766    -2.286280     4.118621
 H     1.847273     1.350449     3.683628
 H     2.051322     1.740897     0.706352
 H     5.033032    -0.603860     2.787349
 H    -0.964496    -2.588982     0.321277
 H     1.469331    -4.472152     3.362241
 H     2.391506    -2.185584     5.087850
 H     4.725040    -3.370083     1.642575
 H    -0.555893     0.874898     1.935146
 H     1.028221    -1.243711    -1.488338
 H    -1.667421    -1.275180     2.255582
 H     3.561637    -0.084465     4.665344
 H     2.860156    -4.928614     1.408179
 H     2.834671     0.363982    -1.151800
 H     3.006241    -2.473585    -1.673645
 H     4.142926    -3.317268    -0.619310
 H     0.766661    -0.515569     5.262934
 H    -0.326977     0.381926     4.207412
 H     4.607699     1.031169     1.030954
 H     3.779340     1.728765     2.424868
 H    -0.791435    -4.010468     2.578027
 H    -0.006404    -4.673580     1.142980
 H     3.655972    -3.972633     4.016955
 H     4.776160    -2.609759     3.957486
 H     0.122734     1.023670    -0.400858
 H    -0.965759    -0.365759    -0.396401
""")


def toobig2():
    mol, data = chiralaneopt.align(
        chiralanem, do_plot=True, verbose=1, uno_cutoff=uno_cutoff, run_mirror=run_mirror)


water16a = qcel.models.Molecule.from_data("""
#Structure 1
   O    -0.084467    1.283579    2.178253  
   H     -0.214426    0.497331    1.648012 
   H      0.842088    1.497008    2.067913     
   O    -1.644378    1.004974   -1.335858      
   H     -0.936576    1.089986   -1.974624     
   H     -1.563482    1.782275   -0.783146     
   O    -4.082498    0.404970   -0.103848    
   H     -4.164661    1.230850    0.373019   
   H     -3.392342    0.566870   -0.747047  
   O     0.885759    1.313583   -2.471124    
   H      1.595634    1.495296   -3.086988   
   H      1.250364    0.664618   -1.869344  
   O     3.304318    1.849225   -3.705632    
   H      3.738185    1.225453   -3.123482   
   H      3.700488    1.693002   -4.562881  
   O     4.921608    2.257054   -0.014908  
   H      5.748722    2.636757    0.281636   
   H      4.573139    2.896392   -0.636236  
   O    -3.851472    2.654843    1.515734     
   H     -4.508222    3.193743    1.956752    
   H     -3.486279    2.105809    2.209583   
   O    -1.314041    3.016154    0.471117  
   H     -2.213369    3.112433    0.784438   
   H     -0.879917    2.492823    1.144833   
   O     1.934746   -0.298003   -0.539711  
   H      1.161422   -0.736328   -0.184644   
   H      2.126877    0.397022    0.089778  
   O     1.123490    3.460683   -0.812048   
   H      0.262457    3.600588   -0.417992  
   H      0.980427    2.774602   -1.464013    
   O    -2.652427    0.969173    3.240820   
   H     -2.811366    0.099257    2.874466  
   H     -1.710770    1.105316    3.136049   
   O     2.382627    1.887468    1.023049     
   H      3.321955    2.006903    0.882946    
   H      1.970184    2.527709    0.443210   
   O     4.359022    0.227060   -1.831784     
   H      3.618792   -0.204683   -1.405301    
   H      4.704801    0.822819   -1.167150   
   O     3.705281    3.849678   -1.814684    
   H      3.600618    3.297927   -2.589828   
   H      2.813674    3.983463   -1.493172  
   O    -3.045024   -1.310215    1.695293    
   H     -3.611478   -2.072473    1.814978   
   H     -3.495648   -0.776777    1.040608  
   O    -0.624923   -0.765966    0.467598    
   H     -1.374788   -1.163513    0.910194   
   H     -1.011241   -0.233905   -0.228031   
""")

water16b = qcel.models.Molecule.from_data("""
#molden generated tinker .xyz (Wales)
   O     0.274606    2.281294    0.941720    
   H     -0.279583    3.044112    0.776748   
   H     -0.172899    1.559531    0.500098  
   O     1.574315   -0.150067    3.907161     
   H      1.032872   -0.875394    3.595758    
   H      2.363067   -0.569656    4.250739   
   O     4.589079   -1.162818    1.739588     
   H      4.061988   -0.386694    1.549751    
   H      4.492536   -1.293636    2.682879     
   O     2.476901    0.649783    1.464892    
   H      2.208077    0.463249    2.364431   
   H      1.937491    1.395910    1.203042  
   O     0.107625   -2.118515    2.723094     
   H      0.419269   -1.965185    1.831129    
   H     -0.779279   -1.758594    2.732627    
   O    -3.158641    1.957245   -0.385051     
   H     -2.511036    1.264064   -0.512879    
   H     -3.696890    1.651169    0.344906    
   O    -4.289887    1.200334    2.041000     
   H     -5.190108    1.236977    2.364251    
   H     -3.852656    1.939202    2.464244    
   O     3.285123   -3.244798    0.634966     
   H      3.837248   -2.535976    0.965060    
   H      3.862595   -3.753709    0.065960    
   O     3.809297   -1.721168    4.350822     
   H      4.299371   -2.040094    5.108678    
   H      3.331724   -2.487801    4.033916   
   O    -2.803390    3.201522    3.061147     
   H     -2.026881    2.790362    3.440901    
   H     -2.475562    3.670771    2.293966   
   O     1.193599   -1.460875    0.313266  
   H      1.844128   -2.157387    0.224297   
   H      1.693307   -0.703184    0.617286  
   O    -2.051160   -0.368191    2.474788     
   H     -1.561920    0.321208    2.923793    
   H     -2.936251   -0.014906    2.385151   
   O    -1.813172    4.067794    0.610147  
   H     -1.980497    4.858988    0.098047     
   H     -2.324956    3.386739    0.173715    
   O     2.364312   -3.693786    3.221252    
   H      1.467289   -3.365569    3.159162   
   H      2.671276   -3.726141    2.315184  
   O    -1.079850    0.121664   -0.022351     
   H     -1.468450   -0.144272    0.811016    
   H     -0.382676   -0.515881   -0.176353   
   O    -0.513316    1.649229    3.471300  
   H      0.215824    1.180728    3.877618    
   H     -0.167536    1.948370    2.630358   
""")


def toobig():
    mol, data = water16a.align(water16b, do_plot=True, verbose=1, uno_cutoff=uno_cutoff, run_mirror=run_mirror)
QCElemental-0.5.0/qcelemental/tests/test_molparse_from_schema.py000066400000000000000000000113501351361252000250760ustar00rootroot00000000000000import copy

import numpy as np
import pytest
import qcelemental as qcel
from qcelemental.testing import compare_molrecs

_schema_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_schema'}


@pytest.mark.parametrize("inp,expected", [
    ({
        'frag_pattern': [[0], [1]],
        'geom': [0., 0., 0., 1., 0., 0.],
        'elbl': ['O', 'H']
    }, {
        'fragment_separators': np.array([1]),
        'geom': np.array([0., 0., 0., 1., 0., 0.]),
        'elbl': np.array(['O', 'H'])
    }),
    ({
        'frag_pattern': [[2, 0], [1]],
        'geom': np.array([[0., 0., 1.], [0., 0., 2.], [0., 0., 0.]]),
        'elem': np.array(['Li', 'H', 'He'])
    }, {
        'fragment_separators': np.array([2]),
        'geom': np.array([0., 0., 0., 0., 0., 1., 0., 0., 2.]),
        'elem': np.array(['He', 'Li', 'H'])
    }),
    ({
        'frag_pattern': [[2, 0], [1]],
        'elez': [3, 1, 2]
    }, {
        'fragment_separators': np.array([2]),
        'elez': np.array([2, 3, 1])
    }),
])
def test_contiguize_from_fragment_pattern(inp, expected):
    ans = qcel.molparse.contiguize_from_fragment_pattern(**inp)

    # compare_molrecs instead of compare_dicts handles some fragment_separators types issues
    assert compare_molrecs(expected, ans, atol=1.e-6)


@pytest.mark.parametrize("inp,expected", [
    ({
        'frag_pattern': [[2, 0], [1, 3]],
        'geom': np.array([[0., 0., 1.], [0., 0., 2.], [0., 0., 0.]]),
        'elem': np.array(['Li', 'H', 'He'])
    }, 'dropped atoms'),
    ({
        'frag_pattern': [[2, 0], [1, 4]]
    }, 'Fragmentation pattern skips atoms'),
    ({
        'frag_pattern': [[2, 0], [1, 3]],
        'elem': np.array(['U', 'Li', 'H', 'He']),
        'elbl': np.array(['Li', 'H', 'He'])
    }, 'wrong number of atoms in array'),
    ({
        'frag_pattern': [[2, 0], [1]],
        'elez': [3, 1, 2],
        'throw_reorder': True
    }, 'reorder atoms to accommodate non-contiguous fragments'),
])
def test_contiguize_from_fragment_pattern_error(inp, expected):
    with pytest.raises(qcel.ValidationError) as e:
        qcel.molparse.contiguize_from_fragment_pattern(**inp)

    assert expected in str(e.value)


schema14_1 = {
    "geometry": [0.0, 0.0, -5.0, 0.0, 0.0, 5.0],
    "symbols": ["He", "He"],
    'fragments': [[0], [1]],
    'fragment_charges': [0.0, 0.0],
    'fragment_multiplicities': [3, 1],
    'masses': [4.00260325413, 4.00260325413],
    'name': 'He2',
    'fix_com': False,
    'fix_orientation': False,
    'molecular_charge': 0.0,
    "molecular_multiplicity": 3,
    "real": [True, False]
}

schema14_psi4_np = {
    "geom": np.array([0.0, 0.0, -5.0, 0.0, 0.0, 5.0]),
    "elem": np.array(["He", "He"]),
    'elea': np.array([4, 4]),
    'elez': np.array([2, 2]),
    'fragment_charges': [0.0, 0.0],
    'fragment_multiplicities': [3, 1],
    'mass': np.array([4.00260325413, 4.00260325413]),
    'name': 'He2',
    'fix_com': False,
    'fix_orientation': False,
    'molecular_charge': 0.0,
    "molecular_multiplicity": 3,
    'units': 'Bohr',
    'fragment_separators': [1],
    'elbl': np.array(['', '']),
    "real": np.array([True, False]),
    "provenance": _schema_prov_stamp,
}


def test_from_schema_1_14e():
    schema = {"schema_name": "qc_schema", "schema_version": 1, "molecule": copy.deepcopy(schema14_1)}

    ans = qcel.molparse.from_schema(schema)
    assert compare_molrecs(schema14_psi4_np, ans, 4)


def test_from_schema_1p5_14e():
    # this is the oddball case where passing code has internally a dtype=2 molecule
    #   but it's still passing the outer data structure
    schema = {"schema_name": "qc_schema", "schema_version": 1, "molecule": copy.deepcopy(schema14_1)}
    schema['molecule'].update({"schema_name": "qcschema_molecule", "schema_version": 2})

    ans = qcel.molparse.from_schema(schema)
    assert compare_molrecs(schema14_psi4_np, ans, 4)


def test_from_schema_2_14e():
    schema = copy.deepcopy(schema14_1)
    schema.update({"schema_name": "qcschema_molecule", "schema_version": 2})

    ans = qcel.molparse.from_schema(schema)
    assert compare_molrecs(schema14_psi4_np, ans, 4)


def test_from_schema_error_f():
    schema = {"schema_name": "private_schema", "schema_version": 1, "molecule": copy.deepcopy(schema14_1)}

    with pytest.raises(qcel.ValidationError) as e:
        qcel.molparse.from_schema(schema)

    assert 'Schema not recognized' in str(e.value)


def test_from_schema_1_nfr_error_14g():
    schema = {"schema_name": "qc_schema", "schema_version": 1, "molecule": copy.deepcopy(schema14_1)}
    schema['molecule'].pop('fragments')

    with pytest.raises(qcel.ValidationError) as e:
        ans = qcel.molparse.from_schema(schema)

    assert 'Dimension mismatch among fragment quantities: sep + 1 (1), chg (2), and mult(2)' in str(e.value)
QCElemental-0.5.0/qcelemental/tests/test_molparse_from_string.py000066400000000000000000001676031351361252000251610ustar00rootroot00000000000000import copy
import sys

import numpy as np
import pytest
import qcelemental
from qcelemental.testing import compare, compare_molrecs, compare_recursive, tnm

_arrays_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_arrays'}
_string_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_string'}

subject1 = """O 0 0   0
no_com

H 1 ,, 0 \t  0 # stuff-n-nonsense"""

ans1 = {
    'geom': [0., 0., 0., 1., 0., 0.],
    'elbl': ['O', 'H'],
    'fix_com': True,
    'fragment_separators': [],
    'fragment_charges': [None],
    'fragment_multiplicities': [None],
    'fragment_files': [],
    'geom_hints': [],
    'hint_types': [],
}

fullans1a = {
    'geom': np.array([0., 0., 0., 1., 0., 0.]),
    'elea': np.array([16, 1]),
    'elez': np.array([8, 1]),
    'elem': np.array(['O', 'H']),
    'mass': np.array([15.99491462, 1.00782503]),
    'real': np.array([True, True]),
    'elbl': np.array(['', '']),
    'units': 'Angstrom',
    'fix_com': True,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [0.0],
    'fragment_multiplicities': [2],
    'molecular_charge': 0.0,
    'molecular_multiplicity': 2,
}
fullans1c = copy.deepcopy(fullans1a)
fullans1c.update({
    'fragment_charges': [1.],
    'fragment_multiplicities': [1],
    'molecular_charge': 1.,
    'molecular_multiplicity': 1
})


def test_psi4_qm_1a():
    subject = subject1
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans1, intermed, atol=1.e-4)
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_1ab():
    subject = subject1
    ans = copy.deepcopy(ans1)
    ans['fix_orientation'] = False
    ans['fix_com'] = False
    fullans = copy.deepcopy(fullans1a)
    fullans['fix_com'] = False
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(
        subject, return_processed=True, fix_orientation=False, fix_com=False)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_1b():
    subject = '\n' + '\t' + subject1 + '\n\n'
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans1, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_1c():
    subject = '1 1\n  -- \n' + subject1
    ans = copy.deepcopy(ans1)
    ans.update({'molecular_charge': 1., 'molecular_multiplicity': 1})
    fullans = copy.deepcopy(fullans1c)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_1d():
    subject = subject1 + '\n1 1'
    ans = copy.deepcopy(ans1)
    ans.update({'fragment_charges': [1.], 'fragment_multiplicities': [1]})
    fullans = copy.deepcopy(fullans1c)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_1e():
    """duplicate com"""
    subject = subject1 + '\n  nocom'

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_qm_1f():

    final = qcelemental.molparse.from_arrays(
        geom=np.array([0., 0., 0., 1., 0., 0.]),
        elez=np.array([8, 1]),
        units='Angstrom',
        fix_com=True,
        fix_orientation=False)


def test_psi4_qm_iutautoobig_error_1g():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=np.array([0., 0., 0., 1., 0., 0.]),
            elez=np.array([8, 1]),
            input_units_to_au=1.1 / 0.52917721067,
            units='Angstrom',
            fix_com=True,
            fix_orientation=False)

    assert 'No big perturbations to physical constants' in str(e.value)


def test_psi4_qm_iutau_1h():
    fullans = copy.deepcopy(fullans1a)
    iutau = 1.01 / 0.52917721067
    fullans['input_units_to_au'] = iutau
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        geom=np.array([0., 0., 0., 1., 0., 0.]),
        elez=np.array([8, 1]),
        input_units_to_au=iutau,
        units='Angstrom',
        fix_com=True,
        fix_orientation=False)

    assert compare_molrecs(fullans, final, tnm() + ': full')

    smol = qcelemental.molparse.to_string(final, dtype='xyz', units='Bohr')
    rsmol = """2 au
HO
O                     0.000000000000     0.000000000000     0.000000000000
H                     1.908623386712     0.000000000000     0.000000000000
"""
    assert compare(rsmol, smol, tnm() + ': str')


def test_psi4_qm_iutau_1i():
    fullans = copy.deepcopy(fullans1a)
    iutau = 1.01 / 0.52917721067
    fullans['input_units_to_au'] = iutau
    fullans['fix_symmetry'] = 'cs'
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        geom=np.array([0., 0., 0., 1., 0., 0.]),
        elez=np.array([8, 1]),
        input_units_to_au=iutau,
        units='Angstrom',
        fix_symmetry="CS",
        fix_com=True,
        fix_orientation=False)

    assert compare_molrecs(fullans, final, tnm() + ': full')

    kmol = qcelemental.molparse.to_schema(final, dtype=1, units='Bohr')
    schema14_1_iutau = {
        "schema_name": "qc_schema_input",
        "schema_version": 1,
        "molecule": {
            "geometry": [0.0, 0.0, 0.0, 1.908623386712, 0.0, 0.0],
            "symbols": ["O", "H"],
            "atomic_numbers": [8, 1],
            "mass_numbers": [16, 1],
            "atom_labels": ["", ""],
            'fragments': [[0, 1]],
            'fragment_charges': [0.0],
            'fragment_multiplicities': [2],
            'masses': [15.99491462, 1.00782503],
            'name': 'HO',
            'fix_com': True,
            'fix_orientation': False,
            'fix_symmetry': 'cs',
            'molecular_charge': 0.0,
            "molecular_multiplicity": 2,
            "real": [True, True],
            "provenance": _arrays_prov_stamp
        }
    }

    assert compare_molrecs(schema14_1_iutau["molecule"], kmol["molecule"], tnm() + ': sch', atol=1.e-8)


subject2 = [
    """
6Li 0.0 0.0 0.0
  units  a.u.
H_specIAL@2.014101  100 0 0""", """@Ne 2 4 6""", """h .0,1,2
Gh(he3) 0 1 3
noreorient"""
]

ans2 = {
    'geom': [0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.],
    'elbl': ['6Li', 'H_specIAL@2.014101', '@Ne', 'h', 'Gh(he3)'],
    'units': 'Bohr',
    'fix_orientation': True,
    'fragment_separators': [2, 3],
    'fragment_charges': [None, None, None],
    'fragment_multiplicities': [None, None, None],
    'fragment_files': [],
    'geom_hints': [],
    'hint_types': [],
}

fullans2 = {
    'geom': np.array([0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.]),
    'elea': np.array([6, 2, 20, 1, 4]),
    'elez': np.array([3, 1, 10, 1, 2]),
    'elem': np.array(['Li', 'H', 'Ne', 'H', 'He']),
    'mass': np.array([6.015122794, 2.014101, 19.99244017542, 1.00782503, 4.00260325415]),
    'real': np.array([True, True, False, True, False]),
    'elbl': np.array(['', '_special', '', '', '3']),
    'units': 'Bohr',
    'fix_com': False,
    'fix_orientation': True,
    'fragment_separators': [2, 3],
}
fullans2_unnp = copy.deepcopy(fullans2)
fullans2_unnp.update({
    'geom': [0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.],
    'elea': [6, 2, 20, 1, 4],
    'elez': [3, 1, 10, 1, 2],
    'elem': ['Li', 'H', 'Ne', 'H', 'He'],
    'mass': [6.015122794, 2.014101, 19.99244017542, 1.00782503, 4.00260325415],
    'real': [True, True, False, True, False],
    'elbl': ['', '_special', '', '', '3'],
})


def test_psi4_qm_2a():
    subject = '\n--\n'.join(subject2)
    fullans = copy.deepcopy(fullans2)
    fullans_unnp = copy.deepcopy(fullans2_unnp)
    ud = {
        'molecular_charge': 0.,
        'molecular_multiplicity': 2,
        'fragment_charges': [0., 0., 0.],
        'fragment_multiplicities': [1, 1, 2]
    }
    fullans.update(ud)
    fullans_unnp.update(ud)
    fullans['provenance'] = _string_prov_stamp
    fullans_unnp['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans2, intermed, tnm() + ': intermediate')
    final_unnp = qcelemental.util.unnp(final['qm'])
    assert compare_molrecs(fullans_unnp, final_unnp, tnm() + ': full unnp')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_2b():
    subject = copy.deepcopy(subject2)
    subject.insert(0, '1 3')
    subject = '\n--\n'.join(subject)
    ans = copy.deepcopy(ans2)
    ans.update({'molecular_charge': 1., 'molecular_multiplicity': 3})
    fullans = copy.deepcopy(fullans2)
    fullans.update({
        'molecular_charge': 1.,
        'molecular_multiplicity': 3,
        'fragment_charges': [1., 0., 0.],
        'fragment_multiplicities': [2, 1, 2]
    })
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_psi4_qm_2c():
    """double overall chg/mult spec"""
    subject = copy.deepcopy(subject2)
    subject.insert(0, '1 3\n1 3')
    subject = '\n--\n'.join(subject)

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_qm_2d():
    """trailing comma"""
    subject = copy.deepcopy(subject2)
    subject.insert(0, 'H 10,10,10,')
    subject = '\n--\n'.join(subject)

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


#def test_psi4_qm_2e():
#    """empty fragment"""
#    subject = copy.deepcopy(subject2)
#    subject.insert(2, '\n')
#    subject = '\n--\n'.join(subject)
#
#    with pytest.raises(qcelemental.MoleculeFormatError):
#        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_qm_2f():
    """double frag chgmult"""
    subject = copy.deepcopy(subject2)
    subject[1] += '\n 1 2\n 5 6'
    subject = '\n--\n'.join(subject)

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_qm_2g():
    """illegal chars in nucleus"""
    subject = copy.deepcopy(subject2)
    subject[1] = """@Ne_{CN}_O 2 4 6"""
    subject = '\n--\n'.join(subject)

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_qm_3():
    """psi4/psi4#731"""
    subject = """0 1
Mg 0 0"""

    with pytest.raises(qcelemental.ValidationError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


subject5 = """
efp C6H6 -0.30448173 -2.24210052 -0.29383131 -0.642499 7.817407 -0.568147  # second to last equiv to 1.534222
--
efp C6H6 -0.60075437  1.36443336  0.78647823  3.137879 1.557344 -2.568550
"""

ans5 = {
    'fragment_files': ['C6H6', 'C6H6'],
    'hint_types': ['xyzabc', 'xyzabc'],
    'geom_hints': [[-0.30448173, -2.24210052, -0.29383131, -0.642499, 7.817407, -0.568147],
                   [-0.60075437, 1.36443336, 0.78647823, 3.137879, 1.557344, -2.568550]],
    'geom': [],
    'elbl': [],
    'fragment_charges': [None],
    'fragment_multiplicities': [None],
    'fragment_separators': [],
}

fullans5b = {'efp': {}}
fullans5b['efp']['hint_types'] = ans5['hint_types']
fullans5b['efp']['geom_hints'] = ans5['geom_hints']
fullans5b['efp']['units'] = 'Bohr'
fullans5b['efp']['fix_com'] = True
fullans5b['efp']['fix_orientation'] = True
fullans5b['efp']['fix_symmetry'] = 'c1'
fullans5b['efp']['fragment_files'] = ['c6h6', 'c6h6']


def test_psi4_efp_5a():
    subject = subject5

    hintsans = [[
        (val / qcelemental.constants.bohr2angstroms if i < 3 else val) for i, val in enumerate(ans5['geom_hints'][0])
    ], [(val / qcelemental.constants.bohr2angstroms if i < 3 else val) for i, val in enumerate(ans5['geom_hints'][1])]]
    hintsans[0][4] = 1.534222
    fullans = copy.deepcopy(fullans5b)
    fullans['efp']['units'] = 'Angstrom'
    fullans['efp']['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans5, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': final efp')

    hintsstd = qcelemental.util.standardize_efp_angles_units('Angstrom', final['efp']['geom_hints'])
    final['efp']['geom_hints'] = hintsstd
    fullans['efp']['geom_hints'] = hintsans
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': final efp standardized')


def test_psi4_efp_5b():
    subject = subject5 + '\nunits bohr'

    ans = copy.deepcopy(ans5)
    ans['units'] = 'Bohr'
    fullans = copy.deepcopy(fullans5b)
    fullans['efp']['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': final efp')


def test_psi4_efp_5c():
    """fix_orientation not mol kw"""
    subject = subject5 + '\nno_com\nfix_orientation\nsymmetry c1'

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_psi4_efp_5d():
    subject = subject5 + '\nno_com\nno_reorient\nsymmetry c1\nunits a.u.'

    ans = copy.deepcopy(ans5)
    ans['units'] = 'Bohr'
    ans['fix_com'] = True
    ans['fix_orientation'] = True
    ans['fix_symmetry'] = 'c1'
    fullans = copy.deepcopy(fullans5b)
    fullans['efp']['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': final')


def test_psi4_efp_5e():
    """symmetry w/efp"""
    subject = subject5 + 'symmetry cs\nunits a.u.'

    with pytest.raises(qcelemental.ValidationError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


subject6 = """
    0 1
    O1    0         0     0.118720
    h2   -0.753299, 0.0, -0.474880

    H3    0.753299, 0.0, -0.474880

    --
    efp h2O -2.12417561  1.22597097 -0.95332054 -2.902133 -4.5481863 -1.953647  # second to last equiv to 1.734999
 --
efp ammoniA
     0.98792    1.87681    2.85174
units au
     1.68798    1.18856    3.09517

     1.45873    2.55904    2.27226

"""

ans6 = {
    'units':
    'Bohr',
    'geom': [0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
    'elbl': ['O1', 'h2', 'H3'],
    'fragment_charges': [0.],
    'fragment_multiplicities': [1],
    'fragment_separators': [],
    'fragment_files': ['h2O', 'ammoniA'],
    'geom_hints': [[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                   [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
    'hint_types': ['xyzabc', 'points'],
}

fullans6 = {
    'qm': {
        'geom': np.array([0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880]),
        'elea': np.array([16, 1, 1]),
        'elez': np.array([8, 1, 1]),
        'elem': np.array(['O', 'H', 'H']),
        'mass': np.array([15.99491462, 1.00782503, 1.00782503]),
        'real': np.array([True, True, True]),
        'elbl': np.array(['1', '2', '3']),
        'units': 'Bohr',
        'fix_com': True,
        'fix_orientation': True,
        'fix_symmetry': 'c1',
        'fragment_charges': [0.],
        'fragment_multiplicities': [1],
        'fragment_separators': [],
        'molecular_charge': 0.,
        'molecular_multiplicity': 1
    },
    'efp': {
        'fragment_files': ['h2o', 'ammonia'],
        'geom_hints': [[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                       [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
        'hint_types': ['xyzabc', 'points'],
        'units':
        'Bohr',
        'fix_com':
        True,
        'fix_orientation':
        True,
        'fix_symmetry':
        'c1',
    }
}


def test_psi4_qmefp_6a():
    subject = subject6
    fullans = copy.deepcopy(fullans6)
    fullans['qm']['provenance'] = _string_prov_stamp
    fullans['efp']['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans6, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')

    hintsstd = qcelemental.util.standardize_efp_angles_units('Bohr', final['efp']['geom_hints'])
    final['efp']['geom_hints'] = hintsstd
    fullans['efp']['geom_hints'][0][4] = 1.734999
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': final efp standardized')


def test_psi4_qmefp_6b():
    subject = subject6.replace('au', 'ang')

    ans = copy.deepcopy(ans6)
    ans['units'] = 'Angstrom'

    fullans = copy.deepcopy(fullans6)
    fullans['qm']['units'] = 'Angstrom'
    fullans['efp']['units'] = 'Angstrom'
    fullans['qm']['provenance'] = _string_prov_stamp
    fullans['efp']['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')


def test_psi4_qmefpformat_error_6c():
    """try to give chgmult to an efp"""

    subject = subject6.replace('    efp h2O', '0 1\n    efp h2O')

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_qmefp_array_6d():

    fullans = copy.deepcopy(fullans6)
    fullans['qm']['provenance'] = _arrays_prov_stamp
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(
        units='Bohr',
        geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
        elbl=['O1', 'h2', 'H3'],
        fragment_files=['h2O', 'ammoniA'],
        geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                    [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
        hint_types=['xyzabc', 'points'])

    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')


def test_qmefp_badhint_error_6e():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'efp1'])

    assert "hint_types not among 'xyzabc', 'points', 'rotmat'" in str(e.value)


def test_qmefp_badefpgeom_error_6f():

    with pytest.raises(qcelemental.ValidationError) as e:
        final = qcelemental.molparse.from_input_arrays(
            units='Bohr',
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, None, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'points'])

    assert "Un float-able elements in geom_hints" in str(e.value)


def test_qmefp_badhintgeom_error_6g():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['points', 'xyzabc'])

    assert 'EFP hint type points not 9 elements' in str(e.value)


def test_qmefp_badfragfile_error_6h():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 5],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'points'])

    assert 'fragment_files not strings' in str(e.value)


def test_qmefp_hintlen_error_6i():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'points', 'points'])

    assert 'Missing or inconsistent length among efp quantities' in str(e.value)


def test_qmefp_fixcom_error_6j():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            fix_com=False,
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'points'])

    assert 'Invalid fix_com (False) with extern (True)' in str(e.value)


def test_qmefp_fixori_error_6k():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_input_arrays(
            units='Bohr',
            fix_orientation=False,
            geom=[0., 0., 0.118720, -0.753299, 0.0, -0.474880, 0.753299, 0.0, -0.474880],
            elbl=['O1', 'h2', 'H3'],
            fragment_files=['h2O', 'ammoniA'],
            geom_hints=[[-2.12417561, 1.22597097, -0.95332054, -2.902133, -4.5481863, -1.953647],
                        [0.98792, 1.87681, 2.85174, 1.68798, 1.18856, 3.09517, 1.45873, 2.55904, 2.27226]],
            hint_types=['xyzabc', 'points'])

    assert 'Invalid fix_orientation (False) with extern (True)' in str(e.value)


#QCEL@using_pylibefp
#QCELdef test_psi4_qmefp_6d():
#QCEL    subject = subject6
#QCEL
#QCEL    fullans = copy.deepcopy(fullans6)
#QCEL    fullans['efp']['geom'] = np.array([-2.22978429,  1.19270015, -0.99721732, -1.85344873,  1.5734809 ,
#QCEL        0.69660583, -0.71881655,  1.40649303, -1.90657336,  0.98792   ,
#QCEL        1.87681   ,  2.85174   ,  2.31084386,  0.57620385,  3.31175679,
#QCEL        1.87761143,  3.16604791,  1.75667803,  0.55253064,  2.78087794,
#QCEL        4.47837555])
#QCEL    fullans['efp']['elea'] = np.array([16, 1, 1, 14, 1, 1, 1])
#QCEL    fullans['efp']['elez'] = np.array([8, 1, 1, 7, 1, 1, 1])
#QCEL    fullans['efp']['elem'] = np.array(['O', 'H', 'H', 'N', 'H', 'H', 'H'])
#QCEL    fullans['efp']['mass'] = np.array([15.99491462, 1.00782503, 1.00782503, 14.00307400478, 1.00782503, 1.00782503, 1.00782503])
#QCEL    fullans['efp']['real'] = np.array([True, True, True, True, True, True, True])
#QCEL    fullans['efp']['elbl'] = np.array(['_a01o1', '_a02h2', '_a03h3', '_a01n1', '_a02h2', '_a03h3', '_a04h4'])
#QCEL    fullans['efp']['fragment_separators'] = [3]
#QCEL    fullans['efp']['fragment_charges'] = [0., 0.]
#QCEL    fullans['efp']['fragment_multiplicities'] = [1, 1]
#QCEL    fullans['efp']['molecular_charge'] = 0.
#QCEL    fullans['efp']['molecular_multiplicity'] = 1
#QCEL    fullans['efp']['hint_types'] = ['xyzabc', 'xyzabc']
#QCEL    fullans['efp']['geom_hints'][1] = [1.093116487139866, 1.9296501432128303, 2.9104336205167156, -1.1053108079381473, 2.0333070957565544, -1.488586877218809]
#QCEL
#QCEL    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
#QCEL
#QCEL    import pylibefp
#QCEL    efpobj = pylibefp.from_dict(final['efp'])
#QCEL    efpfinal = efpobj.to_dict()
#QCEL    efpfinal = qcelemental.molparse.from_arrays(speclabel=False, domain='efp', **efpfinal)
#QCEL
#QCEL    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
#QCEL    assert compare_molrecs(fullans['efp'], efpfinal, tnm() + ': full efp')

subject7 = """\
5
   stuffs
6Li 0.0 0.0 0.0
H_specIAL@2.014101  100 0 0
@Ne 2 4 6
h .0,1,2
Gh(he3) 0 1 3
"""

ans7 = {
    'geom': [0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.],
    'elbl': ['6Li', 'H_specIAL@2.014101', '@Ne', 'h', 'Gh(he3)'],
    'units': 'Angstrom',
    'geom_hints': [],  # shouldn't be needed
}

fullans7 = {
    'geom': np.array([0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.]),
    'elea': np.array([6, 2, 20, 1, 4]),
    'elez': np.array([3, 1, 10, 1, 2]),
    'elem': np.array(['Li', 'H', 'Ne', 'H', 'He']),
    'mass': np.array([6.015122794, 2.014101, 19.99244017542, 1.00782503, 4.00260325415]),
    'real': np.array([True, True, False, True, False]),
    'elbl': np.array(['', '_special', '', '', '3']),
    'units': 'Angstrom',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [0.],
    'fragment_multiplicities': [2],
    'molecular_charge': 0.,
    'molecular_multiplicity': 2,
}


def test_xyzp_qm_7a():
    """XYZ doesn't fit into psi4 string"""
    subject = subject7

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='psi4')


def test_xyzp_qm_7b():
    """XYZ doesn't fit into strict xyz string"""
    subject = subject7

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='xyz')


def test_xyzp_qm_7c():
    subject = subject7
    fullans = copy.deepcopy(fullans7)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='xyz+')
    assert compare_recursive(ans7, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full qm')


def test_xyzp_qm_7d():
    subject = subject7.replace('5', '5 au ')
    subject = subject.replace('stuff', '-1 3 slkdjfl2 32#$^& ')

    ans = copy.deepcopy(ans7)
    ans['units'] = 'Bohr'
    ans['molecular_charge'] = -1.
    ans['molecular_multiplicity'] = 3

    fullans = copy.deepcopy(fullans7)
    fullans['units'] = 'Bohr'
    fullans['fragment_charges'] = [-1.]
    fullans['fragment_multiplicities'] = [3]
    fullans['molecular_charge'] = -1.
    fullans['molecular_multiplicity'] = 3
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='xyz+')
    assert compare_recursive(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full qm')


def test_xyzp_qm_7e():
    subject = subject7.replace('5', '5 ang')
    fullans = copy.deepcopy(fullans7)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='xyz+')
    assert compare_recursive(ans7, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full qm')


subject8 = """\
3
   stuffs
Li 0.0 0.0 0.0
1  100 0 0
Ne 2 4 6
h .0,1,2
 2 0 1 3
"""

ans8 = {
    'geom': [0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.],
    'elbl': ['Li', '1', 'Ne', 'h', '2'],
    'units': 'Angstrom',
    'geom_hints': [],  # shouldn't be needed
}

fullans8 = {
    'geom': np.array([0., 0., 0., 100., 0., 0., 2., 4., 6., 0., 1., 2., 0., 1., 3.]),
    'elea': np.array([7, 1, 20, 1, 4]),
    'elez': np.array([3, 1, 10, 1, 2]),
    'elem': np.array(['Li', 'H', 'Ne', 'H', 'He']),
    'mass': np.array([7.016004548, 1.00782503, 19.99244017542, 1.00782503, 4.00260325415]),
    'real': np.array([True, True, True, True, True]),
    'elbl': np.array(['', '', '', '', '']),
    'units': 'Angstrom',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [0.],
    'fragment_multiplicities': [2],
    'molecular_charge': 0.,
    'molecular_multiplicity': 2,
}


def test_xyzp_qm_8a():
    subject = subject8
    fullans = copy.deepcopy(fullans8)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, dtype='xyz+')
    assert compare_recursive(ans8, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full qm', atol=1.e-4)


fullans10qm = {
    'geom': np.array([0., 0., 0.]),
    'elea': np.array([12]),
    'elez': np.array([6]),
    'elem': np.array(['C']),
    'mass': np.array([12.]),
    'real': np.array([True]),
    'elbl': np.array(['']),
    'units': 'Angstrom',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [0.],
    'fragment_multiplicities': [1],
    'molecular_charge': 0.,
    'molecular_multiplicity': 1
}
fullans10efp = {
    'fragment_files': ['cl2'],
    'hint_types': ['xyzabc'],
    'geom_hints': [[0., 0., 0., 0., 0., 0.]],
    'units': 'Angstrom',
    'fix_com': True,
    'fix_orientation': True,
    'fix_symmetry': 'c1'
}
blankqm = {
    'geom': np.array([]),
    'elea': np.array([]),
    'elez': np.array([]),
    'elem': np.array([]),
    'mass': np.array([]),
    'real': np.array([]),
    'elbl': np.array([]),
    'units': 'Angstrom',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [0.],
    'fragment_multiplicities': [1],
    'molecular_charge': 0.,
    'molecular_multiplicity': 1
}
blankefp = {
    'fragment_files': [],
    'hint_types': [],
    'geom_hints': [],
    'units': 'Angstrom',
    'fix_com': True,
    'fix_orientation': True,
    'fix_symmetry': 'c1'
}


def test_arrays_10a():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': True
    }

    fullans = {'qm': copy.deepcopy(fullans10qm), 'efp': copy.deepcopy(fullans10efp)}
    fullans['qm']['fix_com'] = True
    fullans['qm']['fix_orientation'] = True
    fullans['qm']['fix_symmetry'] = 'c1'
    fullans['qm']['provenance'] = _arrays_prov_stamp
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10b():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': False,
        'enable_efp': True
    }

    fullans = {'efp': fullans10efp}
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10c():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': False
    }

    fullans = {'qm': fullans10qm}
    fullans['qm']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10d():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_efp': 'none'
    }

    fullans = {'qm': fullans10qm}
    fullans['qm']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10e():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_efp': 'minimal'
    }

    fullans = {'qm': fullans10qm, 'efp': blankefp}
    fullans['qm']['provenance'] = _arrays_prov_stamp
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10f():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_efp': 'error'
    }

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_input_arrays(**subject)


def test_arrays_10g():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': False,
        'enable_efp': True,
        'missing_enabled_return_efp': 'none'
    }

    fullans = {}

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10h():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': False,
        'enable_efp': True,
        'missing_enabled_return_efp': 'minimal'
    }

    fullans = {'efp': blankefp}
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10i():
    subject = {
        'geom': [0, 0, 0],
        'elem': ['C'],
        'enable_qm': False,
        'enable_efp': True,
        'missing_enabled_return_efp': 'error'
    }

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_input_arrays(**subject)


def test_arrays_10j():
    subject = {'geom': [0, 0, 0], 'elem': ['C'], 'enable_qm': True, 'enable_efp': False}

    fullans = {'qm': fullans10qm}
    fullans['qm']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10k():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_qm': 'none'
    }

    fullans = {'efp': fullans10efp}
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10l():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_qm': 'minimal'
    }

    fullans = {'qm': copy.deepcopy(blankqm), 'efp': fullans10efp}
    fullans['qm']['fix_com'] = True
    fullans['qm']['fix_orientation'] = True
    fullans['qm']['fix_symmetry'] = 'c1'
    fullans['qm']['provenance'] = _arrays_prov_stamp
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10m():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': True,
        'missing_enabled_return_qm': 'error'
    }

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_input_arrays(**subject)


def test_arrays_10n():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': False,
        'enable_efp': True
    }

    fullans = {'efp': fullans10efp}
    fullans['efp']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_arrays_10o():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': False,
        'missing_enabled_return_qm': 'none'
    }

    fullans = {}

    final = qcelemental.molparse.from_input_arrays(**subject)
    with pytest.raises(KeyError):
        final['qm']
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10p():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': False,
        'missing_enabled_return_qm': 'minimal'
    }

    fullans = {'qm': blankqm}
    fullans['qm']['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_input_arrays(**subject)
    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    with pytest.raises(KeyError):
        final['efp']


def test_arrays_10q():
    subject = {
        'fragment_files': ['cl2'],
        'hint_types': ['xyzabc'],
        'geom_hints': [[0, 0, 0, 0, 0, 0]],
        'enable_qm': True,
        'enable_efp': False,
        'missing_enabled_return_qm': 'error'
    }

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_input_arrays(**subject)


def test_strings_10r():
    subject = ''

    final = qcelemental.molparse.from_string(
        subject, enable_qm=True, enable_efp=True, missing_enabled_return_qm='none', missing_enabled_return_efp='none')

    print('final', final)
    with pytest.raises(KeyError):
        final['qm']
    with pytest.raises(KeyError):
        final['efp']


def test_strings_10s():
    subject = ''

    final = qcelemental.molparse.from_string(
        subject,
        enable_qm=True,
        enable_efp=True,
        missing_enabled_return_qm='minimal',
        missing_enabled_return_efp='minimal')

    fullans = {'qm': blankqm, 'efp': blankefp}
    fullans['qm']['provenance'] = _string_prov_stamp
    fullans['efp']['provenance'] = _string_prov_stamp

    assert compare_molrecs(fullans['qm'], final['qm'], tnm() + ': full qm')
    assert compare_molrecs(fullans['efp'], final['efp'], tnm() + ': full efp')


def test_strings_10t():
    subject = ''

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_string(
            subject,
            enable_qm=True,
            enable_efp=True,
            missing_enabled_return_qm='error',
            missing_enabled_return_efp='error')


def test_qmol_11c():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""nocom\n8 0 0 0\n1 1 0 0""", dtype='psi4')
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11d():
    fullans = copy.deepcopy(fullans1a)
    fullans.update({
        'variables': [],
        'geom_unsettled': [['0', '0', '0'], ['1', '0', '0']],
    })
    fullans.pop('geom')
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""nocom\n8 0 0 0\n1 1 0 0""", dtype='psi4+')
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11e():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""2\n\nO 0 0 0 \n1 1 0 0 """, dtype='xyz', fix_com=True)
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11g():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _arrays_prov_stamp

    asdf = qcelemental.molparse.from_arrays(geom=[0., 0., 0., 1., 0., 0.], elez=[8, 1], fix_com=True, verbose=2)
    assert compare_molrecs(fullans, asdf, 4)


def test_qmol_11h():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""nocom\n8 0 0 0\n1 1 0 0""")
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11i():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""nocom\n8 0 0 0\n1 1 0 0""")
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11j():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _string_prov_stamp

    asdf = qcelemental.molparse.from_string("""2\n\nO 0 0 0 \n1 1 0 0 """, fix_com=True)
    assert compare_molrecs(fullans, asdf['qm'], 4)


def test_qmol_11p():
    fullans = copy.deepcopy(fullans1a)
    fullans['provenance'] = _arrays_prov_stamp

    asdf = qcelemental.molparse.from_arrays(geom=[0., 0., 0., 1., 0., 0.], elez=[8, 1], fix_com=True, units='AngSTRom')
    assert compare_molrecs(fullans, asdf, 4)


def test_qmol_11q():
    with pytest.raises(KeyError):
        qcelemental.molparse.from_string("""2\n\nO 0 0 0 \n1 1 0 0 """, fix_com=True, dtype='psi3')


#QCELdef test_qmol_12():
#QCEL    asdf = qcdb.Molecule(geom=[ 0.,  0.,  0.,  1.,  0.,  0.], elez=[8, 1], fix_com=True)
#QCEL    assess_mol_11(asdf, 'qcdb.Molecule(geom, elez)')
#QCEL
#QCEL    import json
#QCEL    smol = json.dumps(asdf.to_dict(np_out=False))
#QCEL    dmol = json.loads(smol)
#QCEL
#QCEL    asdf2 = qcdb.Molecule(dmol)
#QCEL    assess_mol_11(asdf, 'qcdb.Molecule(jsondict)')

subject12 = """
 0 1
 1
 8 1 0.95
 O 2 1.40 1 A
 H 3 0.95 2 A 1 120.0

A = 105.0
"""

fullans12 = {
    'elbl': np.array(['', '', '', '']),
    'elea': np.array([1, 16, 16, 1]),
    'elem': np.array(['H', 'O', 'O', 'H']),
    'elez': np.array([1, 8, 8, 1]),
    'fix_com': False,
    'fix_orientation': False,
    'fragment_charges': [0.0],
    'fragment_multiplicities': [1],
    'fragment_separators': [],
    'geom_unsettled': [[], ['1', '0.95'], ['2', '1.40', '1', 'A'], ['3', '0.95', '2', 'A', '1', '120.0']],
    'mass': np.array([1.00782503, 15.99491462, 15.99491462, 1.00782503]),
    'molecular_charge': 0.0,
    'molecular_multiplicity': 1,
    'real': np.array([True, True, True, True]),
    'units': 'Angstrom',
    'variables': [['A', 105.0]],
    'fix_symmetry': 'c1'
}
ans12 = {
    'elbl': ['1', '8', 'O', 'H'],
    'fragment_charges': [0.0],
    'fragment_files': [],
    'fragment_multiplicities': [1],
    'fragment_separators': [],
    'geom_hints': [],
    'geom_unsettled': [[], ['1', '0.95'], ['2', '1.40', '1', 'A'], ['3', '0.95', '2', 'A', '1', '120.0']],
    'hint_types': [],
    'variables': [('A', '105.0')],
    'fix_symmetry': 'c1'
}


def test_psi4_qm_12a():
    subject = subject12
    fullans = copy.deepcopy(fullans12)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, fix_symmetry='c1')
    assert compare_recursive(ans12, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_tooclose_error():
    subject = """2 -1 -1 -1\n2 -1 -1 -1.05"""

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_string(subject)

    assert 'too close' in str(e.value)


def test_cartbeforezmat_error():
    subject = """He 0 0 0\nHe 1 2"""

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_string(subject)

    assert 'Mixing Cartesian and Zmat' in str(e.value)


def test_jumbledzmat_error():
    subject = """He\nHe 1 2. 2 100. 3 35.\nHe 1 2."""

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_string(subject)

    assert 'aim for lower triangular' in str(e.value)


def test_steepzmat_error():
    subject = """He\nHe 1 2.\nHe 1 2. 2 100. 3 35."""

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_string(subject)

    assert 'aim for lower triangular' in str(e.value)


def test_zmatvar_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            elem=['Rn', 'Rn'],
            variables=[['bond', 2.0, 'badextra']],
            geom_unsettled=[[], ['1', 'bond']])

    assert 'Variables should come in pairs' in str(e.value)


def test_toomanyfrag_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['ar1', '42AR2'],
            fragment_multiplicities=[3, 3],
            fragment_separators=[1, 2],
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'zero-length fragment' in str(e.value)


def test_fragsep_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['ar1', '42AR2'],
            fragment_multiplicities=[3, 3],
            fragment_separators=np.array(['1']),
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'unable to perform trial np.split on geometry' in str(e.value)


def test_cartzmatcart():
    subject = """1 1
# This part is just a normal Cartesian geometry specification for benzene
C          0.710500000000    -0.794637665924    -1.230622098778
C          1.421000000000    -0.794637665924     0.000000000000
C          0.710500000000    -0.794637665924     1.230622098778
C         -0.710500000000    -0.794637665924     1.230622098778
H          1.254500000000    -0.794637665924    -2.172857738095
H         -1.254500000000    -0.794637665924     2.172857738095
C         -0.710500000000    -0.794637665924    -1.230622098778
C         -1.421000000000    -0.794637665924     0.000000000000
H          2.509000000000    -0.794637665924     0.000000000000
H          1.254500000000    -0.794637665924     2.172857738095
H         -1.254500000000    -0.794637665924    -2.172857738095
H         -2.509000000000    -0.794637665924     0.000000000000
# And the hydronium part is specified using a zmatrix, referencing the benzene coordinates
X  1  CC  3  30   2  A2
O  13 R   1  90   2  90
H  14 OH  13 TDA  1  0
H  14 OH  15 TDA  13 A1
H  14 OH  15 TDA  13 -A1
He         3.710500000000    -0.794637665924    -1.230622098778

CC    = 1.421
CH    = 1.088
A1    = 120.0
A2    = 180.0
OH    = 1.05
R     = 4.0
"""

    qcelemental.molparse.from_string(subject)


def test_fixcom_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(elez=[3], molecular_charge=1, geom=[0, 0, 0], fix_com='thanks!')

    assert 'Invalid fix_com' in str(e.value)


def test_fixori_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(elez=[3], molecular_charge=1, geom=[0, 0, 0], fix_orientation=-1)

    assert 'Invalid fix_orientation' in str(e.value)


def test_units_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(elez=[3], molecular_charge=1, geom=[0, 0, 0], units='furlong')

    assert 'Invalid molecule geometry units' in str(e.value)


def test_domain_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(domain='kitten')

    assert 'Topology domain kitten not available' in str(e.value)


def test_natom_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(elem=['C'], elea=[12, 13], geom=[0, 0, 0])

    assert 'Dimension mismatch natom' in str(e.value)


def test_incompletefrag_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['ar1', '42AR2'],
            fragment_multiplicities=[3, 3],
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'Fragment quantities given without separation info' in str(e.value)


def test_badmult_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['ar1', '42AR2'],
            fragment_multiplicities=[-3, 3],
            fragment_separators=np.array([1]),
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'fragment_multiplicities not among None or positive integer' in str(e.value)


def test_badchg_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['ar1', '42AR2'],
            fragment_charges=[[], {}],
            fragment_separators=np.array([1]),
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'fragment_charges not among None or float' in str(e.value)


def test_fraglen_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            domain='qmvz',
            speclabel=True,
            elbl=['na', 'cl'],
            fragment_charges=[1, -1, 0],
            fragment_separators=np.array([1]),
            geom_unsettled=[[], ['1', 'bond']],
            hint_types=[],
            units='Bohr',
            variables=[('bond', '3')])

    assert 'mismatch among fragment quantities' in str(e.value)


def test_zmatfragarr_14a():
    fullans = copy.deepcopy(fullans14)
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        domain='qmvz',
        speclabel=True,
        elbl=['ar1', '42AR2'],
        fragment_multiplicities=[3, 3],
        fragment_separators=[1],
        geom_unsettled=[[], ['1', 'bond']],
        hint_types=[],
        units='Bohr',
        variables=[('bond', '3')])

    assert compare_molrecs(fullans, final, tnm() + ': full')


def test_zmatfragarr_14b():
    fullans = copy.deepcopy(fullans14)
    fullans['elbl'] = ['', '']
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        domain='qmvz',
        speclabel=False,
        elez=[18, 18],
        elea=np.array([40, 42]),
        real=[True, True],
        fragment_multiplicities=[3, 3],
        fragment_separators=[1],
        geom_unsettled=[[], ['1', 'bond']],
        hint_types=[],
        units='Bohr',
        variables=[('bond', '3')])

    assert compare_molrecs(fullans, final, tnm() + ': full')


def test_zmatfragarr_14c():
    fullans = copy.deepcopy(fullans14)
    fullans['elbl'] = ['', '']
    fullans['fix_com'] = True
    fullans['fix_orientation'] = True
    fullans['mass'] = fullans['mass'].tolist()  # other np vs. list diffs are hidden by compare_molrecs
    fullans['real'] = fullans['real'].tolist()
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        np_out=False,
        domain='qmvz',
        speclabel=False,
        elez=[18, 18],
        elea=[40, None],
        mass=[None, 41.96304574],
        real=[True, True],
        fragment_multiplicities=[3, 3],
        fragment_separators=[1],
        geom_unsettled=[[], ['1', 'bond']],
        hint_types=[],
        units='Bohr',
        fix_com=True,
        fix_orientation=True,
        variables=[('bond', '3')])

    assert compare_molrecs(fullans, final, tnm() + ': full')


subject14 = """
        0 3
        ar1
        --
        0 3
        42AR2 1 bond
    units a.u.
        bond =3.0
        """

fullans14 = {
    'elbl': np.array(['1', '2']),
    'elea': np.array([40, 42]),
    'elem': np.array(['Ar', 'Ar']),
    'elez': np.array([18, 18]),
    'fix_com': False,
    'fix_orientation': False,
    'fragment_charges': [0.0, 0.0],
    'fragment_multiplicities': [3, 3],
    'fragment_separators': [1],
    'geom_unsettled': [[], ['1', 'bond']],
    'mass': np.array([39.96238312, 41.96304574]),
    'molecular_charge': 0.0,
    'molecular_multiplicity': 5,
    'real': np.array([True, True]),
    'units': 'Bohr',
    'variables': [['bond', 3.0]]
}


def test_zmatfragstr_14d():
    subject = subject14
    fullans = copy.deepcopy(fullans14)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, verbose=2)
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_badprov0_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(geom=[1, 2, 3], elez=[4], provenance='mine')

    assert 'Provenance entry is not dictionary' in str(e.value)


def test_badprov1_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=[1, 2, 3], elez=[4], provenance={
                'creator': ('psi', 'tuple'),
                'routine': 'buggy',
                'version': '0.1b'
            })

    assert """Provenance key 'creator' should be string of creating program's name:""" in str(e.value)


def test_badprov2_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=[1, 2, 3],
            elez=[4],
            provenance={
                'creator': '',
                'routine': 'buggy',
                'version': 'my.vanity.version.13'
            })

    assert """Provenance key 'version' should be a valid PEP 440 string:""" in str(e.value)


def test_badprov3_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=[1, 2, 3], elez=[4], provenance={
                'creator': '',
                'routine': 5,
                'version': '0.1b'
            })

    assert """Provenance key 'routine' should be string of creating function's name:""" in str(e.value)


def test_badprov4_error():
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=[1, 2, 3], elez=[4], provenance={
                'creators': '',
                'routine': 'buggy',
                'version': '0.1b'
            })

    assert """Provenance keys (['creator', 'routine', 'version']) incorrect:""" in str(e.value)


fullans17 = {
    'geom': np.array([0., 1., 2., 3., 4., 5., 6., 7., 8.]),
    'elea': np.array([1, 32, 1]),
    'elez': np.array([1, 16, 1]),
    'elem': np.array(['H', 'S', 'H']),
    'mass': np.array([1.00782503, 31.9720711744, 1.00782503]),
    'real': np.array([False, True, True]),
    'elbl': np.array(['', '', '']),
    'units': 'Bohr',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'fragment_charges': [-1.0],
    'fragment_multiplicities': [1],
    'molecular_charge': -1.0,
    'molecular_multiplicity': 1,
    'connectivity': [
        (0, 1, 1.0),
        (1, 2, 1.0),
    ],
}


def test_connectivity_17a():
    fullans = copy.deepcopy(fullans17)
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        geom=np.arange(9),
        units='Bohr',
        elez=[1, 16, 1],
        molecular_charge=-1,
        real=[False, True, True],
        connectivity=[(0, 1, 1), (1, 2, 1)],
    )

    assert compare_molrecs(fullans, final, tnm() + ': full')


def test_connectivity_17b():
    fullans = copy.deepcopy(fullans17)
    fullans['provenance'] = _arrays_prov_stamp

    final = qcelemental.molparse.from_arrays(
        geom=np.arange(9),
        units='Bohr',
        elez=[1, 16, 1],
        molecular_charge=-1,
        real=[False, True, True],
        connectivity=[(2.0, 1, 1), (1, 0, 1)],
    )

    assert compare_molrecs(fullans, final, tnm() + ': full')


def test_connectivity_atindex_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=np.arange(9),
            units='Bohr',
            elez=[1, 16, 1],
            molecular_charge=-1,
            real=[False, True, True],
            connectivity=[(2.1, 1, 1), (1, 0, 1)],
        )

    assert "Connectivity first atom should be int" in str(e.value)


def test_connectivity_atrange_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=np.arange(9),
            units='Bohr',
            elez=[1, 16, 1],
            molecular_charge=-1,
            real=[False, True, True],
            connectivity=[(2, 1, 1), (1, -1, 1)],
        )

    assert "Connectivity second atom should be int" in str(e.value)


def test_connectivity_bondorder_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=np.arange(9),
            units='Bohr',
            elez=[1, 16, 1],
            molecular_charge=-1,
            real=[False, True, True],
            connectivity=[(2, 1, 1), (1, 0, 6)],
        )

    assert "Connectivity bond order should be float" in str(e.value)


def test_connectivity_type_error():

    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.from_arrays(
            geom=np.arange(9),
            units='Bohr',
            elez=[1, 16, 1],
            molecular_charge=-1,
            real=[False, True, True],
            connectivity='wire',
        )

    assert "Connectivity entry is not of form" in str(e.value)


#'geom_unsettled': [[], ['1', '2.'], ['1', '2.', '2', '100.', '3', '35.']],

#final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, verbose=2)
#import pprint
#pprint.pprint(final)
#pprint.pprint(intermed)

#assert False
QCElemental-0.5.0/qcelemental/tests/test_molparse_parse_nucleus_label.py000066400000000000000000000041101351361252000266160ustar00rootroot00000000000000import pytest
import qcelemental
from qcelemental.testing import compare, compare_values


@pytest.mark.parametrize("inp,expected", [
    ('@ca_miNe', {'E': 'ca', 'Z': None, 'user': '_miNe', 'A': None, 'real': False, 'mass': None}),
    ('Gh(Ca_mine)', {'E': 'Ca', 'Z': None, 'user': '_mine', 'A': None, 'real': False, 'mass': None}),
    ('@Ca_mine@1.07', {'E': 'Ca', 'Z': None, 'user': '_mine', 'A': None, 'real': False, 'mass': 1.07}),
    ('Gh(cA_MINE@1.07)', {'E': 'cA', 'Z': None, 'user': '_MINE', 'A': None, 'real': False, 'mass': 1.07}),
    ('@40Ca_mine@1.07', {'E': 'Ca', 'Z': None, 'user': '_mine', 'A': 40, 'real': False, 'mass': 1.07}),
    ('Gh(40Ca_mine@1.07)', {'E': 'Ca', 'Z': None, 'user': '_mine', 'A': 40, 'real': False, 'mass': 1.07}),
    ('444lu333@4.0', {'E': 'lu', 'Z': None, 'user': '333', 'A': 444, 'real': True, 'mass': 4.0}),
    ('@444lu333@4.4', {'E': 'lu', 'Z': None, 'user': '333', 'A': 444, 'real': False, 'mass': 4.4}),
    ('8i', {'E': 'i', 'Z': None, 'user': None, 'A': 8, 'real': True, 'mass': None}),
    ('53_mI4', {'Z': 53, 'E': None, 'user': '_mI4', 'A': None, 'real': True, 'mass': None}),
    ('@5_MINEs3@4.4', {'Z': 5, 'E': None, 'user': '_MINEs3', 'A': None, 'real': False, 'mass': 4.4}),
    ('Gh(555_mines3@0.1)', {'Z': 555, 'E': None, 'user': '_mines3', 'A': None, 'real': False, 'mass': 0.1}),
])  # yapf: disable
def test_parse_nucleus_label(inp, expected):
    lbl_A, lbl_Z, lbl_E, lbl_mass, lbl_real, lbl_user = qcelemental.molparse.nucleus.parse_nucleus_label(inp)

    assert compare(expected['real'], lbl_real, inp + " real")
    assert compare(expected['A'], lbl_A, inp + " A")
    assert compare(expected['Z'], lbl_Z, inp + " Z")
    assert compare(expected['E'], lbl_E, inp + " symbol")
    assert compare(expected['user'], lbl_user, inp + " user")
    assert compare_values(expected['mass'], lbl_mass, inp + " mass", passnone=True, atol=1.e-6)


@pytest.mark.parametrize("inp", [
    '1L1A1B1',
])
def test_parse_nucleus_label_error(inp):
    with pytest.raises(qcelemental.ValidationError):
        ans = qcelemental.molparse.nucleus.parse_nucleus_label(inp)
QCElemental-0.5.0/qcelemental/tests/test_molparse_pubchem.py000066400000000000000000000150271351361252000242430ustar00rootroot00000000000000import copy

import numpy as np
import pytest
import qcelemental
from qcelemental.testing import compare_molrecs, tnm

_string_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_string'}

subject4 = """pubchem:benzene"""

ans4 = {
    'geom': [
        -1.213100, -0.688400, 0.000000, -1.202800, 0.706400, 0.000100, -0.010300, -1.394800, 0.000000, 0.010400,
        1.394800, -0.000100, 1.202800, -0.706300, 0.000000, 1.213100, 0.688400, 0.000000, -2.157700, -1.224400,
        0.000000, -2.139300, 1.256400, 0.000100, -0.018400, -2.480900, -0.000100, 0.018400, 2.480800, 0.000000,
        2.139400, -1.256300, 0.000100, 2.157700, 1.224500, 0.000000
    ],
    'elbl': ['C', 'C', 'C', 'C', 'C', 'C', 'H', 'H', 'H', 'H', 'H', 'H'],
    'units': 'Angstrom',
    'molecular_charge': 0.0,
    'fragment_separators': [],
    'fragment_charges': [None],
    'fragment_multiplicities': [None],
    'fragment_files': [],
    'geom_hints': [],
    'hint_types': [],
    'name': 'IUPAC benzene'
}  # yapf: disable

fullans4 = {
    'geom': np.array([
        -1.213100, -0.688400, 0.000000, -1.202800, 0.706400, 0.000100, -0.010300, -1.394800, 0.000000, 0.010400,
        1.394800, -0.000100, 1.202800, -0.706300, 0.000000, 1.213100, 0.688400, 0.000000, -2.157700, -1.224400,
        0.000000, -2.139300, 1.256400, 0.000100, -0.018400, -2.480900, -0.000100, 0.018400, 2.480800, 0.000000,
        2.139400, -1.256300, 0.000100, 2.157700, 1.224500, 0.000000
    ]),
    'elbl': np.array(['C', 'C', 'C', 'C', 'C', 'C', 'H', 'H', 'H', 'H', 'H', 'H']),
    'elea': np.array([12, 12, 12, 12, 12, 12, 1, 1, 1, 1, 1, 1]),
    'elez': np.array([6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1]),
    'elem': np.array(['C', 'C', 'C', 'C', 'C', 'C', 'H', 'H', 'H', 'H', 'H', 'H']),
    'mass': np.array([12., 12., 12., 12., 12., 12., 1.00782503, 1.00782503, 1.00782503, 1.00782503, 1.00782503, 1.00782503]),
    'real': np.array([True, True, True, True, True, True, True, True, True, True, True, True]),
    'elbl': np.array(['', '', '', '', '', '', '', '', '', '', '', '']),
    'units': 'Angstrom',
    'fix_com': False,
    'fix_orientation': False,
    'fragment_separators': [],
    'molecular_charge': 0.,
    'molecular_multiplicity': 1,
    'fragment_charges': [0.],
    'fragment_multiplicities': [1],
    'name': 'IUPAC benzene'
}  # yapf: disable


def test_pubchem_4a():
    subject = subject4
    fullans = copy.deepcopy(fullans4)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_molrecs(ans4, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_pubchem_4b():
    """user units potentially contradicting pubchem units"""
    subject = subject4 + '\nunits au'

    with pytest.raises(qcelemental.MoleculeFormatError):
        final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)


def test_pubchem_4c():
    subject = """
pubchem  : 241
"""
    ans = copy.deepcopy(ans4)
    ans['name'] = 'benzene'
    fullans = copy.deepcopy(fullans4)
    fullans['name'] = 'benzene'
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True, name='benzene', verbose=2)
    assert compare_molrecs(ans, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_pubchem_error_d():
    subject = """
    pubchem:-55
"""

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_string(subject, return_processed=True)


def test_pubchem_error_e():
    # no 3D structure available
    subject = """
pubchem : sodium benzenesulfonate

"""

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_string(subject)


def test_pubchem_error_f():
    subject = """
    pubchem: 100000000000000
"""

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.from_string(subject, return_processed=True)


def test_pubchem_multiout_g():
    subject = """
    #pubchem: gobbledegook
    #pubchem: c6h12o
    #pubchem: formaldehyde*
    pubchem: tropolone*
"""

    with pytest.raises(qcelemental.ChoicesError) as e:
        qcelemental.molparse.from_string(subject, return_processed=True)

    try:
        qcelemental.molparse.from_string(subject, return_processed=True)
    except qcelemental.ChoicesError as e:
        assert e.choices[10789] == '2-hydroxycyclohepta-2,4,6-trien-1-one'
        assert e.choices[193687] == '2-hydroxy-3-iodo-6-propan-2-ylcyclohepta-2,4,6-trien-1-one'


subject13 = """pubchem :ammonium\n"""

ans13 = {
    'name': 'IUPAC azanium',
    'molecular_charge': 1.0,
    'units': 'Angstrom',
    'fragment_files': [],
    'hint_types': [],
    'geom_hints': [],
    'elbl': ['N', 'H', 'H', 'H', 'H'],
    'fragment_separators': [],
    'fragment_charges': [None],
    'fragment_multiplicities': [None],
    'geom': [
        0.0, 0.0, 0.0, 0.9645, 0.2796, 0.2138, 0.0075, -0.886, -0.5188, -0.5235, -0.1202, 0.8751, -0.4486, 0.7266,
        -0.5701
    ]
}  # yapf: disable

fullans13 = {
    'name': 'IUPAC azanium',
    'units': 'Angstrom',
    'geom': np.array([0., 0., 0., 0.9645, 0.2796, 0.2138, 0.0075, -0.886, -0.5188, -0.5235, -0.1202, 0.8751, -0.4486, 0.7266, -0.5701]),
    'elea': np.array([14, 1, 1, 1, 1]),
    'elez': np.array([7, 1, 1, 1, 1]),
    'elem': np.array(['N', 'H', 'H', 'H', 'H']),
    'mass': np.array([14.003074, 1.00782503, 1.00782503, 1.00782503, 1.00782503]),
    'real': np.array([True, True, True, True, True]),
    'elbl': np.array(['', '', '', '', '']),
    'fragment_separators': [],
    'molecular_charge': 1.0,
    'fragment_charges': [1.0],
    'molecular_multiplicity': 1,
    'fragment_multiplicities': [1],
    'fix_com': False,
    'fix_orientation': False
}  # yapf: disable


def test_pubchem_13h():
    subject = subject13
    fullans = copy.deepcopy(fullans13)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_molrecs(ans13, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')


def test_pubchem_13i():
    subject = "PubChem:223"
    fullans = copy.deepcopy(fullans13)
    fullans['provenance'] = _string_prov_stamp

    final, intermed = qcelemental.molparse.from_string(subject, return_processed=True)
    assert compare_molrecs(ans13, intermed, tnm() + ': intermediate')
    assert compare_molrecs(fullans, final['qm'], tnm() + ': full')
QCElemental-0.5.0/qcelemental/tests/test_molparse_reconcile_nucleus.py000066400000000000000000000071601351361252000263200ustar00rootroot00000000000000import pytest
import qcelemental

co_dominant = (59, 27, 'Co', 58.93319429, True, '')
co_dominant_mine = (59, 27, 'Co', 58.93319429, True, '_mine')
co_dominant_shortmass = (59, 27, 'Co', 58.933, True, '')
co60 = (60, 27, 'Co', 59.93381630, True, '')
co60_mine = (60, 27, 'Co', 59.93381630, True, '_mine')
co60ghost = (60, 27, 'Co', 59.93381630, False, '')
co_unspecified = (-1, 27, 'Co', 60.6, True, '')


@pytest.mark.parametrize("inp,expected", [
    ({'E': 'co'}, co_dominant),
    ({'Z': 27}, co_dominant),
    ({'A': 59, 'Z': 27}, co_dominant),
    ({'E': 'cO', 'mass': 58.93319429}, co_dominant),
    ({'A': 59, 'Z': 27, 'E': 'CO'}, co_dominant),
    ({'A': 59, 'E': 'cO', 'mass': 58.93319429}, co_dominant),
    ({'label': 'co', 'verbose': 2}, co_dominant),
    ({'label': '59co'}, co_dominant),
    ({'label': 'co@58.93319429'}, co_dominant),
    ({'A': 59, 'Z': 27, 'E': 'cO', 'mass': 58.93319429, 'label': 'co@58.93319429'}, co_dominant),
    ({'A': 59, 'Z': 27, 'E': 'cO', 'mass': 58.93319429, 'label': '27@58.93319429'}, co_dominant),
    ({'label': '27'}, co_dominant),
    ({'label': 'co_miNe'}, co_dominant_mine),
    ({'label': 'co_mIne@58.93319429'}, co_dominant_mine),
    ({'E': 'cO', 'mass': 58.933}, co_dominant_shortmass),
    ({'label': 'cO@58.933'}, co_dominant_shortmass),
    ({'E': 'Co', 'A': 60}, co60),
    ({'Z': 27, 'A': 60, 'real': True}, co60),
    ({'E': 'Co', 'A': 60}, co60),
    ({'Z': 27, 'mass': 59.93381630}, co60),
    ({'A': 60, 'Z': 27, 'mass': 59.93381630}, co60),
    ({'label': '60Co' }, co60),
    ({'label': '27', 'mass': 59.93381630}, co60),
    ({'label': 'Co', 'mass': 59.93381630}, co60),
    ({'A': 60, 'label': 'Co'}, co60),
    ({'mass': 60.6, 'Z': 27}, co_unspecified),
    ({'mass': 60.6, 'E': 'Co'}, co_unspecified),
    ({'mass': 60.6, 'label': '27'}, co_unspecified),
    ({'label': 'Co@60.6'}, co_unspecified),
    ({'E': 'Co', 'A': 60, 'real': False}, co60ghost),
    ({'A': 60, 'Z': 27, 'mass': 59.93381630, 'real': 0}, co60ghost),
    ({'label': '@60Co'}, co60ghost),
    ({'label': 'Gh(27)', 'mass': 59.93381630}, co60ghost),
    ({'label': '@Co', 'mass': 59.93381630}, co60ghost),
    ({'A': 60, 'label': 'Gh(Co)'}, co60ghost),
    ({'label': '60co_miNe'}, co60_mine),
    ({'label': '_miNe', 'A': 59, 'E': 'Co', 'speclabel': False}, co_dominant_mine),
])  # yapf: disable
def test_reconcile_nucleus(inp, expected):
    assert expected == qcelemental.molparse.reconcile_nucleus(**inp)


@pytest.mark.parametrize("inp", [
    {'E': 'cO', 'mass': 58.933, 'mtol': 1.e-4},
    {'label': '27@58.933', 'mtol': 1.e-4},
])  # yapf: disable
def test_reconcile_nucleus_assertionerror(inp):
    with pytest.raises(AssertionError):
        assert co_dominant_shortmass == qcelemental.molparse.reconcile_nucleus(**inp)


@pytest.mark.parametrize("inp", [
    {'A': 80, 'Z': 27 },
    {'Z': -27, 'mass': 200, 'nonphysical': True},
])  # yapf: disable
def test_reconcile_nucleus_notanelementerror(inp):
    with pytest.raises(qcelemental.NotAnElementError):
        qcelemental.molparse.reconcile_nucleus(**inp)


def test_reconcile_nucleus_41():
    qcelemental.molparse.reconcile_nucleus(Z=27, mass=200, nonphysical=True)


@pytest.mark.parametrize("inp", [
    {'mass': 60.6, 'Z': 27, 'A': 61},
    {'Z': 27, 'mass': 200 },
    {'Z': 27, 'mass': -200, 'nonphysical': True},
    {'Z': 1, 'label': 'he'},
    {'A': 4, 'label': '3he'},
    {'label': '@U', 'real': True},
    {'label': 'U', 'real': False},
    {'label': '_miNe', 'A': 59, 'E': 'Co', 'speclabel': True},
])  # yapf: disable
def test_reconcile_nucleus_validationerror(inp):
    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.reconcile_nucleus(**inp)
QCElemental-0.5.0/qcelemental/tests/test_molparse_to_schema.py000066400000000000000000000244171351361252000245650ustar00rootroot00000000000000import copy

import numpy as np
import pytest
import qcelemental
from qcelemental.testing import compare_molrecs

_string_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_string'}
_schema_prov_stamp = {'creator': 'QCElemental', 'version': '1.0', 'routine': 'qcelemental.molparse.from_schema'}

subject14 = """0 3\n--\nHe 0 0 -5\n--\n@He 0 0 5\nunits au"""

schema14_1 = {
    "schema_name": "qc_schema_input",
    "schema_version": 1,
    "molecule": {
        "geometry": [0.0, 0.0, -5.0, 0.0, 0.0, 5.0],
        "symbols": ["He", "He"],
        "atomic_numbers": [2, 2],
        "mass_numbers": [4, 4],
        "atom_labels": ['', ''],
        'fragments': [[0], [1]],
        'fragment_charges': [0.0, 0.0],
        'fragment_multiplicities': [3, 1],
        'masses': [4.00260325413, 4.00260325413],
        'name': 'He2',
        'fix_com': False,
        'fix_orientation': False,
        'molecular_charge': 0.0,
        "molecular_multiplicity": 3,
        "real": [True, False]
    }
}

schema14_2 = {
    'schema_name': 'qcschema_molecule',
    'schema_version': 2
}
schema14_2.update(schema14_1['molecule'])

schema14_psi4 = {
    "geom": [0.0, 0.0, -5.0, 0.0, 0.0, 5.0],
    "elem": ["He", "He"],
    'elea': [4, 4],
    'elez': [2, 2],
    'fragment_charges': [0.0, 0.0],
    'fragment_multiplicities': [3, 1],
    'mass': [4.00260325413, 4.00260325413],
    'name': 'He2',
    'fix_com': False,
    'fix_orientation': False,
    'molecular_charge': 0.0,
    "molecular_multiplicity": 3,
    'units': 'Bohr',
    'fragment_separators': [1],
    'elbl': ['', ''],
    "real": [True, False]
}


def test_1_14a():
    fullans = copy.deepcopy(schema14_1)
    fullans['molecule']['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject14)
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype=1)
    assert compare_molrecs(fullans['molecule'], kmol['molecule'])

    fullans = copy.deepcopy(schema14_psi4)
    fullans['provenance'] = _schema_prov_stamp

    molrec = qcelemental.molparse.from_schema(kmol)
    molrec = qcelemental.util.unnp(molrec)
    assert compare_molrecs(fullans, molrec)


def test_2_14b():
    fullans = copy.deepcopy(schema14_2)
    fullans['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject14)
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype=2)
    assert compare_molrecs(fullans, kmol)

    fullans = copy.deepcopy(schema14_psi4)
    fullans['provenance'] = _schema_prov_stamp

    molrec = qcelemental.molparse.from_schema(kmol)
    molrec = qcelemental.util.unnp(molrec)
    assert compare_molrecs(fullans, molrec)


def test_psi4_14c():
    fullans = copy.deepcopy(schema14_psi4)
    fullans['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject14)
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype='psi4')
    assert compare_molrecs(fullans, kmol)


def test_dtype_error():

    final = qcelemental.molparse.from_string(subject14)
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.to_schema(final['qm'], dtype='xkcd927')

    assert "Schema dtype not understood" in str(e.value)


@pytest.mark.parametrize("dtype", [
    1,
    2,
])
def test_qcschema_ang_error(dtype):

    final = qcelemental.molparse.from_string(subject14)
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.to_schema(final['qm'], dtype=dtype, units='Angstrom')

    assert f"QC_JSON_Schema {dtype} allows only 'Bohr' coordinates" in str(e.value)


def test_psi4_nm_error():

    final = qcelemental.molparse.from_string(subject14)
    with pytest.raises(qcelemental.ValidationError) as e:
        qcelemental.molparse.to_schema(final['qm'], dtype='psi4', units='nm')

    assert "Psi4 Schema psi4 allows only 'Bohr'/'Angstrom' coordinates, not nm" in str(e.value)


twobohrinang = 2.0 * qcelemental.constants.conversion_factor("bohr", "angstrom")
subject15 = """symmetry cS\nH 0 0 {twobohrinang}\nO 0 0 0\n2H_deut {twobohrinang} 0 0\nno_com\nno_reorient""".format(
    twobohrinang=twobohrinang)

schema15_1 = {
    "schema_name": "qc_schema_input",
    "schema_version": 1,
    "molecule": {
        "geometry": [0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0],
        "symbols": ["H", "O", "H"],
        "atomic_numbers": [1, 8, 1],
        "mass_numbers": [1, 16, 2],
        "atom_labels": ['', '', '_deut'],
        'fragments': [[0, 1, 2]],
        'fragment_charges': [0.0],
        'fragment_multiplicities': [1],
        'masses': [1.00782503223, 15.99491461957, 2.01410177812],
        'name': 'H2O',
        'comment': 'I has a comment',
        'fix_com': True,
        'fix_orientation': True,
        'fix_symmetry': 'cs',
        'molecular_charge': 0.0,
        "molecular_multiplicity": 1,
        "real": [True, True, True]
    }
}

schema15_2 = {
    'schema_name': 'qcschema_molecule',
    'schema_version': 2
}
schema15_2.update(schema15_1['molecule'])

schema15_psi4 = {
    "geom": [0.0, 0.0, twobohrinang, 0.0, 0.0, 0.0, twobohrinang, 0.0, 0.0],
    "elem": ["H", "O", "H"],
    "elez": [1, 8, 1],
    "elea": [1, 16, 2],
    "elbl": ['', '', '_deut'],
    'fragment_charges': [0.0],
    'fragment_multiplicities': [1],
    'mass': [1.00782503223, 15.99491461957, 2.01410177812],
    'name': 'H2O',
    'comment': 'I has a comment',
    'fix_com': True,
    'fix_orientation': True,
    'fix_symmetry': 'cs',
    'molecular_charge': 0.0,
    "molecular_multiplicity": 1,
    'units': 'Angstrom',
    'fragment_separators': [],
    'elbl': ['', '', '_deut'],
    "real": [True, True, True]
}


def test_1_15a():
    fullans = copy.deepcopy(schema15_1)
    fullans['molecule']['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject15)
    final['qm']['comment'] = 'I has a comment'
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype=1)
    assert compare_molrecs(fullans['molecule'], kmol['molecule'])

    fullans = copy.deepcopy(schema15_psi4)
    fullans['units'] = 'Bohr'
    fullans['geom'] = [0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0]
    fullans['provenance'] = _schema_prov_stamp

    molrec = qcelemental.molparse.from_schema(kmol)
    molrec = qcelemental.util.unnp(molrec)
    assert compare_molrecs(fullans, molrec)


def test_2_15b():
    fullans = copy.deepcopy(schema15_2)
    fullans['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject15)
    final['qm']['comment'] = 'I has a comment'
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype=2)
    assert compare_molrecs(fullans, kmol)

    fullans = copy.deepcopy(schema15_psi4)
    fullans['units'] = 'Bohr'
    fullans['geom'] = [0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0]
    fullans['provenance'] = _schema_prov_stamp

    molrec = qcelemental.molparse.from_schema(kmol)
    molrec = qcelemental.util.unnp(molrec)
    assert compare_molrecs(fullans, molrec)


def test_psi4_15c():
    fullans = copy.deepcopy(schema15_psi4)
    fullans['provenance'] = _string_prov_stamp

    final = qcelemental.molparse.from_string(subject15)
    final['qm']['comment'] = 'I has a comment'
    kmol = qcelemental.molparse.to_schema(final['qm'], dtype='psi4', units='Angstrom')
    assert compare_molrecs(fullans, kmol)


schema16_1 = {
    'schema_name': 'qc_schema_input',
    'schema_version': 1,
    'molecule': {
        'geometry': [2., 2., 3.],
        'symbols': ['C'],
        'masses': [12.0],
        'atom_labels': [''],
        'atomic_numbers': [6],
        'mass_numbers': [12],
        'real': [True],
        'name': 'C',
        'molecular_charge': 0.,
        'molecular_multiplicity': 1,
        'fragments': [[0]],
        'fragment_charges': [0.],
        'fragment_multiplicities': [1],
        'fix_com': False,
        'fix_orientation': False,
        'provenance': {
            'creator': 'Mystery Program',
            'version': '2018.3',
            'routine': 'molecule builder',
        },
        'connectivity': [(0, 0, 0.0)],
    },
}

schema16_2 = {
    'schema_name': 'qcschema_molecule',
    'schema_version': 2
}
schema16_2.update(schema16_1['molecule'])

schema16_psi4 = {
    'units': 'Bohr',
    'geom': np.array([2., 2., 3.]),
    'elem': np.array(['C']),
    'mass': np.array([12.0]),
    'elbl': np.array(['']),
    'elez': np.array([6]),
    'elea': np.array([12]),
    'real': np.array([True]),
    'name': 'C',
    'molecular_charge': 0.,
    'molecular_multiplicity': 1,
    'fragment_separators': [],
    'fragment_charges': [0.],
    'fragment_multiplicities': [1],
    'fix_com': False,
    'fix_orientation': False,
    'provenance': {
        'creator': 'Mystery Program',
        'version': '2018.3',
        'routine': 'molecule builder',
    },
    'connectivity': [(0, 0, 0.0)],
}


def test_froto_1_16a():
    basic = {
        'schema_name': 'qc_schema_output',
        'schema_version': 1,
        'molecule': {
            'geometry': [2, 2, 3],
            'symbols': ['C'],
            'connectivity': [(0.0, -0.0, 0)],
            'provenance': {
                'creator': 'Mystery Program',
                'version': '2018.3',
                'routine': 'molecule builder',
            },
        },
    }

    fullans = copy.deepcopy(schema16_1)
    fullans['molecule']['provenance'] = _schema_prov_stamp

    roundtrip = qcelemental.molparse.to_schema(qcelemental.molparse.from_schema(basic), dtype=1)
    assert compare_molrecs(fullans['molecule'], roundtrip['molecule'])


def test_froto_2_16a():
    basic = {
        'schema_name': 'qcschema_molecule',
        'schema_version': 2,
        'geometry': [2, 2, 3],
        'symbols': ['C'],
        'connectivity': [(0.0, -0.0, 0)],
        'provenance': {
            'creator': 'Mystery Program',
            'version': '2018.3',
            'routine': 'molecule builder',
        },
    }

    fullans = copy.deepcopy(schema16_2)
    fullans['provenance'] = _schema_prov_stamp

    roundtrip = qcelemental.molparse.to_schema(qcelemental.molparse.from_schema(basic), dtype=2)
    assert compare_molrecs(fullans, roundtrip)


@pytest.mark.parametrize("dtype", [
    1,
    2,
])
def test_tofro_16b(dtype):

    fullans = copy.deepcopy(schema16_psi4)
    fullans['provenance'] = _schema_prov_stamp

    roundtrip = qcelemental.molparse.from_schema(qcelemental.molparse.to_schema(schema16_psi4, dtype=dtype))
    assert compare_molrecs(fullans, roundtrip)
QCElemental-0.5.0/qcelemental/tests/test_molparse_to_string.py000066400000000000000000000134131351361252000246250ustar00rootroot00000000000000import pytest
import qcelemental
from qcelemental.testing import compare

_results = {
"subject1": """
3 au

Co 0 0 0
H  2 0 0
h_OTher -2 0 0
""",

"ans1_au": """3 au
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
H                     2.000000000000     0.000000000000     0.000000000000
H                    -2.000000000000     0.000000000000     0.000000000000
""",

"ans1_ang": """3
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
H                     1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
""",

"ans1c_ang": """3
CoH2
59Co                      0.00000000         0.00000000         0.00000000
1H                        1.05835442         0.00000000         0.00000000
1H_other                 -1.05835442         0.00000000         0.00000000
""",

"ans1c_nm": """3 nm
CoH2
59Co                      0.00000000         0.00000000         0.00000000
1H                        0.10583544         0.00000000         0.00000000
1H_other                 -0.10583544         0.00000000         0.00000000
""",

"subject2": """
Co 0 0 0
no_reorient
--
@H  1.05835442134 0 0
h_OTher -1.05835442134 0 0
""",

"ans2_au": """3 au
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
@H                    2.000000000000     0.000000000000     0.000000000000
H                    -2.000000000000     0.000000000000     0.000000000000
""",

"ans2_ang": """3
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
Gh(1)                 1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
""",

"ans2c_ang": """2
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
""",

"ans2_cfour_ang": """auto-generated by QCElemental from molecule CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
GH                    1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
""",

"ans2_nwchem_ang": """geometry units angstroms
Co                    0.000000000000     0.000000000000     0.000000000000
GH                    1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000

end
""",

"ans2_terachem_au": """3 au
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
XH                    2.000000000000     0.000000000000     0.000000000000
H                    -2.000000000000     0.000000000000     0.000000000000
""",

"ans2_terachem_ang": """3
CoH2
Co                    0.000000000000     0.000000000000     0.000000000000
XH                    1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
""",

"ans2_psi4_au": """0 3
--
0 2
Co                    0.000000000000     0.000000000000     0.000000000000
--
0 2
Gh(H)                 2.000000000000     0.000000000000     0.000000000000
H                    -2.000000000000     0.000000000000     0.000000000000
units bohr
no_reorient
""",

"ans2_molpro_au": """{orient,noorient}
{symmetry,auto}

{bohr}
geometry={
Co                    0.000000000000     0.000000000000     0.000000000000
H                     2.000000000000     0.000000000000     0.000000000000
H                    -2.000000000000     0.000000000000     0.000000000000
}
dummy,2
set,charge=0.0
set,multiplicity=3
""",

"ans2_molpro_ang": """{orient,noorient}
{symmetry,auto}

{angstrom}
geometry={
Co                    0.000000000000     0.000000000000     0.000000000000
H                     1.058354421340     0.000000000000     0.000000000000
H                    -1.058354421340     0.000000000000     0.000000000000
}
dummy,2
set,charge=0.0
set,multiplicity=3
""",

}  # yapf: disable


@pytest.mark.parametrize("inp,expected", [
    (("subject1", {'dtype': 'xyz', 'units': 'Bohr'}), "ans1_au"),
    (("subject1", {'dtype': 'xyz', 'units': 'Angstrom'}), "ans1_ang"),
    (("subject1", {'dtype': 'xyz', 'prec': 8, 'atom_format': '{elea}{elem}{elbl}'}), "ans1c_ang"),
    (("subject2", {'dtype': 'xyz', 'units': 'Bohr'}), "ans2_au"),
    (("subject2", {'dtype': 'xyz', 'units': 'Angstrom', 'ghost_format': 'Gh({elez})'}), "ans2_ang"),
    (("subject2", {'dtype': 'xyz', 'units': 'angstrom', 'ghost_format': ''}), "ans2c_ang"),
    (("subject2", {'dtype': 'cfour', 'units': 'angstrom'}), "ans2_cfour_ang"),
    (("subject2", {'dtype': 'nwchem', 'units': 'angstrom'}), "ans2_nwchem_ang"),
    (("subject1", {'dtype': 'xyz', 'units': 'nm', 'prec': 8, 'atom_format': '{elea}{elem}{elbl}'}), "ans1c_nm"),
    (("subject2", {'dtype': 'terachem', 'units': 'angstrom'}), "ans2_terachem_ang"),
    (("subject2", {'dtype': 'terachem'}), "ans2_terachem_au"),
    (("subject2", {'dtype': 'psi4', 'units': 'bohr'}), "ans2_psi4_au"),
    (("subject2", {'dtype': 'molpro', 'units': 'bohr'}), "ans2_molpro_au"),
    (("subject2", {'dtype': 'molpro', 'units': 'angstrom'}), "ans2_molpro_ang"),
])  # yapf: disable
def test_to_string_xyz(inp, expected):
    molrec = qcelemental.molparse.from_string(_results[inp[0]])
    smol = qcelemental.molparse.to_string(molrec['qm'], **inp[1])
    print(smol)

    assert compare(_results[expected], smol)


@pytest.mark.parametrize("inp", [
    ("subject1", {'dtype': 'xyz', 'units': 'kg', 'prec': 8, 'atom_format': '{elea}{elem}{elbl}'}),
])  # yapf: disable
def test_to_string_error(inp):
    import pint
    molrec = qcelemental.molparse.from_string(_results[inp[0]])

    with pytest.raises(pint.errors.DimensionalityError):
        qcelemental.molparse.to_string(molrec['qm'], **inp[1])
QCElemental-0.5.0/qcelemental/tests/test_molparse_validate_and_fill_chgmult.py000066400000000000000000000205531351361252000277640ustar00rootroot00000000000000import numpy as np
import pytest
import qcelemental
from qcelemental.testing import compare

# (system-shorthand, tot-chg, frag-chg, tot-mult, frag-mult), (expected_final_tot-chg, frag-chg, tot-mult, frag-mult)


@pytest.mark.parametrize(
    "inp,expected",
    [
        (('He', 0, [0], 1, [1]), (0, [0], 1, [1])),  # 1
        (('He', None, [None], None, [None]), (0, [0], 1, [1])),  # 2
        (('He/He', None, [None, None], None, [None, None]), (0, [0, 0], 1, [1, 1])),  # 3
        (('He/He', 2, [None, None], None, [None, None]), (2, [2, 0], 1, [1, 1])),  # 4
        (('He/He', None, [2, None], None, [None, None]), (2, [2, 0], 1, [1, 1])),  # 5
        (('He/He', 0, [2, None], None, [None, None]), (0, [2, -2], 1, [1, 1])),  # 6
        (('Ne/He/He', -2, [None, 2, None], None, [None, None, None]), (-2, [-4, 2, 0], 1, [1, 1, 1])),  # 7
        (('Ne/He/He', 2, [None, -2, None], None, [None, None, None]), (2, [4, -2, 0], 1, [1, 1, 1])),  # 8
        (('He/He/Ne', 2, [None, -2, None], None, [None, None, None]), (2, [0, -2, 4], 1, [1, 1, 1])),  # 9
        (('He/He/Ne', 2, [2, -2, None], None, [None, None, None]), (2, [2, -2, 2], 1, [1, 1, 1])),  # 11
        (('He/He', None, [-2, 2], None, [None, None]), (0, [-2, 2], 1, [1, 1])),  # 12
        (('He/He', None, [None, -2], None, [None, None]), (-2, [0, -2], 1, [1, 1])),  # 13
        (('Ne/Ne', 0, [None, 4], None, [None, None]), (0, [-4, 4], 1, [1, 1])),  # 14
        (('He/He/He', 4, [2, None, None], None, [None, None, None]), (4, [2, 2, 0], 1, [1, 1, 1])),  # 15
        (('He/He', 0, [-2, 2], None, [None, None]), (0, [-2, 2], 1, [1, 1])),  # 16
        (('He', None, [None], None, [1]), (0, [0], 1, [1])),  # 19
        (('He', None, [None], None, [3]), (0, [0], 3, [3])),  # 21
        (('He', None, [-1], None, [2]), (-1, [-1], 2, [2])),  # 23
        (('He/He', None, [None, None], None, [1, 1]), (0, [0, 0], 1, [1, 1])),  # 25
        (('He/He', None, [None, None], None, [3, 1]), (0, [0, 0], 3, [3, 1])),  # 26
        (('He/He', None, [None, None], None, [1, 3]), (0, [0, 0], 3, [1, 3])),  # 27
        (('He/He', None, [None, None], None, [3, 3]), (0, [0, 0], 5, [3, 3])),  # 28
        (('He/He', None, [None, None], 3, [3, 3]), (0, [0, 0], 3, [3, 3])),  # 29
        (('H', None, [None], None, [None]), (0, [0], 2, [2])),  # 31
        (('H', 1, [None], None, [None]), (1, [1], 1, [1])),  # 32
        (('H', None, [-1], None, [None]), (-1, [-1], 1, [1])),  # 33
        (('funnyH', None, [None], None, [None]), (0, [0], 1, [1])),  # 34
        (('H/H', None, [None, None], None, [None, None]), (0, [0, 0], 3, [2, 2])),  # 36
        (('H/He', None, [None, None], None, [None, None]), (0, [0, 0], 2, [2, 1])),  # 37
        (('H/He', None, [1, 1], None, [None, None]), (2, [1, 1], 2, [1, 2])),  # 38
        (('H/He', -2, [-1, None], None, [None, None]), (-2, [-1, -1], 2, [1, 2])),  # 39
        (('H/He/Na/Ne', None, [1, None, 1, None], None, [None, None, None, None]),
         (2, [1, 0, 1, 0], 1, [1, 1, 1, 1])),  # 40
        (('H/He/Na/Ne', None, [-1, None, 1, None], None, [None, None, None, None]),
         (0, [-1, 0, 1, 0], 1, [1, 1, 1, 1])),  # 41
        (('H/He/Na/Ne', 2, [None, None, 1, None], None, [None, None, None, None]),
         (2, [1, 0, 1, 0], 1, [1, 1, 1, 1])),  # 42
        (('H/He/Na/Ne', 3, [None, None, 1, None], None, [None, None, None, None]),
         (3, [0, 2, 1, 0], 2, [2, 1, 1, 1])),  # 43
        (('H/He/Na/Ne', None, [None, 1, 0, 1], None, [None, None, None, None]),
         (2, [0, 1, 0, 1], 5, [2, 2, 2, 2])),  # 47
        (('H/He/Na/Ne', None, [None, 1, 0, None], None, [None, None, None, None]),
         (1, [0, 1, 0, 0], 4, [2, 2, 2, 1])),  # 48
        (('H/He/Na/Ne', None, [None, 1, 0, None], None, [None, None, 4, None]),
         (1, [0, 1, 0, 0], 6, [2, 2, 4, 1])),  # 49
        (('He/He/He', 0, [None, None, 1], None, [1, None, 2]), (0, [0, -1, 1], 3, [1, 2, 2])),  # 50
        (('N/N/N', None, [1, 1, 1], 3, [None, 3, None]), (3, [1, 1, 1], 3, [1, 3, 1])),  # 51
        (('N/N/N', None, [1, 1, 1], 3, [None, None, None]), (3, [1, 1, 1], 3, [3, 1, 1])),  # 52
        (('N/N/N', 1, [None, -1, None], 3, [None, None, 2]), (1, [2, -1, 0], 3, [2, 1, 2])),  # 54
        (('N/Ne/N', 1, [None, None, None], 4, [None, 3, None]), (1, [1, 0, 0], 4, [1, 3, 2])),  # 55
        (('N/Ne/N', None, [None, None, 1], 4, [None, 3, None]), (1, [0, 0, 1], 4, [2, 3, 1])),  # 56
        (('He/He', None, [-1, 1], None, [None, None]), (0, [-1, 1], 3, [2, 2])),  # 57
        (('He/Gh', None, [2, None], None, [None, None], {'verbose': 2}), (2, [2, 0], 1, [1, 1])),  # 61
        (('Gh/He/Ne', 2, [None, -2, None], None, [None, None, None]), (2, [0, -2, 4], 1, [1, 1, 1])),  # 63
        (('Gh/He/Gh', 1, [None, None, None], None, [None, None, None]), (1, [0, 1, 0], 2, [1, 2, 1])),  # 64
        (('Ne/Ne', 2, [-2, None], None, [None, None]), (2, [-2, 4], 1, [1, 1])),  # 65a
        (('Gh/Ne', 2, [-2, None], None, [None, None], {'zero_ghost_fragments': True}), (0, [0, 0], 1, [1, 1])),  # 65c
    ]) # yapf: disable
def test_validate_and_fill_chgmult(inp, expected):
    system = _systemtranslator[inp[0]]
    kwargs = inp[5] if len(inp) > 5 else {}

    ans = qcelemental.molparse.validate_and_fill_chgmult(system[0], system[1], inp[1], inp[2], inp[3], inp[4],
                                                         **kwargs)
    assert compare(1, ans == dict(zip(_keys, expected)), """{}: {}, {}, {}, {} --> {}""".format(*inp, expected))


@pytest.mark.parametrize(
    "inp",
    [
        ('He/He/Ne', 2, [None, -2, 0], None, [None, None, None]),  # 10
        ('He/He', 0, [-2, -2], None, [None, None]),  # 17
        ('He', None, [None], 0, [None]),  # 18
        ('He', None, [None], None, [2]),  # 20
        ('He', None, [None], None, [5]),  # 22
        ('He', None, [-2], None, [2]),  # 24
        ('He/He', None, [None, None], 2, [3, 3]),  # 30
        ('funnierH', None, [None], None, [None]),  # 35
        ('H/He', None, [1, None], None, [2, None]),  # 44
        ('H/He', None, [None, 0], None, [None, 2]),  # 45
        ('H/He', None, [None, -1], None, [None, 3]),  # 46
        ('N/N/N', None, [None, None, None], 3, [None, None, 2]),  # 53
        ('Gh', 1, [None], None, [None]),  # 58
        ('Gh', -1, [None], None, [None]),  # 59
        ('Gh', None, [None], 3, [None]),  # 60
        ('Gh/He', None, [2, None], None, [None, None]),  # 62
        ('Gh/Ne', 2, [-2, None], None, [None, None]),  # 65b
    ]) # yapf: disable
def test_validate_and_fill_chgmult_irreconcilable(inp):
    system = _systemtranslator[inp[0]]

    with pytest.raises(qcelemental.ValidationError):
        qcelemental.molparse.validate_and_fill_chgmult(system[0], system[1], inp[1], inp[2], inp[3], inp[4], verbose=0)


# Notes
#  9 - residual +4 distributes to first fragment able to wholly accept it (He+4 is no-go)
# 10 - residual +4 unsuited for only open fragment, He, so irreconcilable
# 11 - non-positive multiplicity
# 20 - doublet non consistent with closed-shell, neutral default charge
# 22 - insufficient electrons for pentuplet
# 24 - doublet not consistent with even charge
# 30 - bad parity btwn mult and total # electrons
# 35 - insufficient electrons
# 55 - both (1, (1, 0.0, 0.0), 4, (1, 3, 2)) and (1, (0.0, 0.0, 1), 4, (2, 3, 1)) plausible
# 65 - non-0/1 on Gh fragment errors normally but reset by zero_ghost_fragments

_keys = ['molecular_charge', 'fragment_charges', 'molecular_multiplicity', 'fragment_multiplicities']
_systemtranslator = {
    'He': (np.array([2]), np.array([])),
    'He/He': (np.array([2, 2]), np.array([1])),
    'Ne/He/He': (np.array([10, 2, 2]), np.array([1, 2])),
    'He/He/Ne': (np.array([2, 2, 10]), np.array([1, 2])),
    'Ne/Ne': (np.array([10, 10]), np.array([1])),
    'He/He/He': (np.array([2, 2, 2]), np.array([1, 2])),
    'H': (np.array([1]), np.array([])),
    'funnyH': (np.array([0]), np.array([])),  # has no electrons
    'funnierH': (np.array([-1]), np.array([])),  # has positron
    'H/H': (np.array([1, 1]), np.array([1])),
    'H/He': (np.array([1, 2]), np.array([1])),
    'H/He/Na/Ne': (np.array([1, 2, 11, 10]), np.array([1, 2, 3])),
    'N/N/N': (np.array([7, 7, 7]), np.array([1, 2])),
    'N/Ne/N': (np.array([7, 10, 7]), np.array([1, 2])),
    'He/Gh': (np.array([2, 0]), np.array([1])),
    'Gh/He': (np.array([0, 2]), np.array([1])),
    'Gh': (np.array([0, 0]), np.array([])),
    'Gh/He/Ne': (np.array([0, 0, 2, 10]), np.array([2, 3])),
    'Gh/He/Gh': (np.array([0, 2, 0]), np.array([1, 2])),
    'Gh/Ne': (np.array([0, 10]), np.array([1])),
}
QCElemental-0.5.0/qcelemental/tests/test_periodictable.py000066400000000000000000000073421351361252000235250ustar00rootroot00000000000000import os
from decimal import Decimal

import pytest
import qcelemental


@pytest.mark.parametrize("inp,expected", [
    ("He", "He"),
    ("He", "He"),
    ("He4", "He"),
    ("he", "He"),
    ("2", "He"),
    (2, "He"),
    (2.0, "He"),
])
def test_id_resolution(inp, expected):
    assert qcelemental.periodictable._resolve_atom_to_key('He') == 'He'


@pytest.mark.parametrize("inp", ["He100", '-1', -1, -1.0, 'cat', 200])
def test_id_resolution_error(inp):
    with pytest.raises(qcelemental.exceptions.NotAnElementError):
        qcelemental.periodictable._resolve_atom_to_key(inp)


# TODO test ghost


def test_to_mass_krypton_decimal():
    assert qcelemental.periodictable.to_mass('kr', return_decimal=True) == Decimal('83.9114977282')


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("KRYPTON", 83.9114977282),
        ("kr", 83.9114977282),
        ("kr84", 83.9114977282),
        (36, 83.9114977282),

        # Kr 86
        ("kr86", 85.9106106269),

        # Helium
        ("D", 2.01410177812),
        ("h2", 2.01410177812),
    ])
def test_to_mass(inp, expected):
    assert qcelemental.periodictable.to_mass(inp) == pytest.approx(expected, 1.e-9)


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("kr", 84),
        ("KRYPTON", 84),
        ("kr84", 84),
        (36, 84),

        # Kr 86
        ("kr86", 86),

        # Helium
        ("D", 2),
        ("h2", 2),
    ])
def test_to_mass_number(inp, expected):
    assert qcelemental.periodictable.to_A(inp) == expected


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("kr", 36),
        ("KRYPTON", 36),
        ("kr84", 36),
        (36, 36),

        # Kr 86
        ("kr86", 36),

        # Deuterium
        ("D", 1),
        ("h2", 1),
    ])
def test_to_atomic_number(inp, expected):
    assert qcelemental.periodictable.to_Z(inp) == expected


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("kr", "Kr"),
        ("KRYPTON", "Kr"),
        ("kr84", "Kr"),
        (36, "Kr"),

        # Kr 86
        ("kr86", "Kr"),

        # Deuterium
        ("D", "H"),
        ("h2", "H"),
    ])
def test_to_symbol(inp, expected):
    assert qcelemental.periodictable.to_E(inp) == expected


@pytest.mark.parametrize(
    "inp,expected",
    [
        # Kr 84
        ("kr", "Krypton"),
        ("KRYPTON", "Krypton"),
        ("kr84", "Krypton"),
        (36, "Krypton"),

        # Kr 86
        ("kr86", "Krypton"),

        # Deuterium
        ("D", "Hydrogen"),
        ("h2", "Hydrogen"),
    ])
def test_to_element(inp, expected):
    assert qcelemental.periodictable.to_element(inp) == expected


@pytest.mark.parametrize("inp,expected", [('HE', 1), ('carbon', 2), ('cl35', 3), (36, 4), (37.0, 5), ('mercury', 6),
                                          ('Ts', 7)])
def test_to_period(inp, expected):
    assert qcelemental.periodictable.to_period(inp) == expected


@pytest.mark.parametrize("inp,expected", [
    ('D', 1),
    ('Ba', 2),
    ('yttrium', 3),
    ('hf179', 4),
    (23, 5),
    ('w', 6),
    (43.0, 7),
    (26.0, 8),
    ('meitnerium', 9),
    ('pt', 10),
    ('gold', 11),
    ('cd', 12),
    (5.0, 13),
    (14, 14),
    ('phosphorus', 15),
    ('SE', 16),
    ('i', 17),
    (54, 18),
    ('La', None),
    (89.0, None),
    ('lutetium', None),
    (103.0, None),
    ('u238', None),
])
def test_to_group(inp, expected):
    assert qcelemental.periodictable.to_group(inp) == expected


def test_c_header():
    qcelemental.periodictable.write_c_header("header.h")
    os.remove("header.h")


@pytest.mark.xfail(True, reason='comparison data not available for installed repository', run=True, strict=False)
def test_periodic_table_comparison():
    qcelemental.periodictable.run_comparison()
QCElemental-0.5.0/qcelemental/tests/test_testing.py000066400000000000000000000216201351361252000223670ustar00rootroot00000000000000from decimal import Decimal

import numpy as np
import pytest
import qcelemental as qcel

_arrs = {
    'a1234_14': np.arange(4),
    'blip14': np.arange(4) + [0., 0.02, 0.005, 0.02],
    'a1234_22': np.arange(4).reshape((2, 2)),
    'blip22': (np.arange(4) + [0., 0.02, 0.005, 0.02]).reshape((2, 2)),
    'iblip14': np.arange(4) + [0, 1, 0, 1],
    'iblip22': (np.arange(4) + [0, 1, 0, 1]).reshape((2, 2)),
}

_dcts = {
    'ell': {'a': _arrs['a1234_14'], 'b': {'ba': _arrs['a1234_14'], 'bb': _arrs['a1234_22']}},
    'elll': {'a': _arrs['a1234_14'], 'b': {'ba': _arrs['a1234_14'], 'bb': _arrs['a1234_22'], 'bc': 4}},
    'ellnone': {'a': _arrs['a1234_14'], 'b': {'ba': _arrs['a1234_14'], 'bb': _arrs['a1234_22'], 'bc': None}},
    'ellshort': {'a': np.arange(3), 'b': {'ba': _arrs['a1234_14'], 'bb': _arrs['a1234_22']}},
    'blipell': {'a': _arrs['blip14'], 'b': {'ba': _arrs['a1234_14'], 'bb': _arrs['blip22']}},
}  # yapf: disable

_pass_message = '\t{:.<66}PASSED'


@pytest.mark.parametrize("ref,cpd,tol,kw,boool,msg", [
    (2., 2.02, 1.e-1, {'label': 'asdf'}, True, (None,
        _pass_message.format('asdf'))),

    (2., 2.02, 1.e-2, {'label': 'asdf'}, False, (None,
        'asdf: computed value (2.0200) does not match (2.0000) to atol=0.01 by difference (0.0200).')),

    (2., Decimal("2.02"), 1.e-1, {'label': 'asdf'}, True, (None,
        _pass_message.format('asdf'))),

    (2., Decimal("2.02"), 1.e-2, {'label': 'asdf'}, False, (None,
        'asdf: computed value (2.0200) does not match (2.0000) to atol=0.01 by difference (0.0200).')),

    (2., 2.000000002, 1.e-9, {}, False, (None,
        'test_compare_values: computed value (2.00000000200) does not match (2.00000000000) to atol=1e-09 by difference (0.00000000200).')),

    (2., 2.05, 1.e-3, {}, False, (None,
        'test_compare_values: computed value (2.05000) does not match (2.00000) to atol=0.001 by difference (0.05000).')),

    (_arrs['a1234_14'], _arrs['blip14'], 1.e-1, {}, True, (None,
        _pass_message.format('test_compare_values'))),

    (_arrs['a1234_14'], _arrs['blip14'], 1.e-2, {}, False, (None,
        """test_compare_values: computed value does not match to atol=0.01.
  Expected:
    [0. 1. 2. 3.]
  Observed:
    [0.    1.02  2.005 3.02 ]
  Difference (passed elements are zeroed):
    [0.   0.02 0.   0.02]""")),

    (_arrs['a1234_22'], _arrs['blip22'], 1.e-1, {}, True, (None,
        _pass_message.format('test_compare_values'))),

    (_arrs['a1234_22'], _arrs['blip22'], 1.e-2, {}, False, (None,
        """test_compare_values: computed value does not match to atol=0.01.
  Expected:
    [[0. 1.]
     [2. 3.]]
  Observed:
    [[0.    1.02 ]
     [2.005 3.02 ]]
  Difference (passed elements are zeroed):
    [[0.   0.02]
     [0.   0.02]]""")),

    (_arrs['a1234_22'], _arrs['blip14'], 1.e-2, {}, False, (None,
        """test_compare_values: computed shape ((4,)) does not match ((2, 2)).""")),

    (None, None, 1.e-4, {'passnone': True}, True, (None,
        _pass_message.format('test_compare_values'))),

    (None, None, 1.e-4, {}, False, (None,
        """test_compare_values: computed value (nan) does not match (nan) to atol=0.0001 by difference (nan).""")),

])  # yapf: disable
def test_compare_values(ref, cpd, tol, kw, boool, msg):
    res, mstr = qcel.testing.compare_values(ref, cpd, **kw, atol=tol, return_message=True)
    assert res is boool
    assert mstr.strip() == msg[1].strip()


@pytest.mark.parametrize("ref,cpd,kw,boool,msg", [
    (2, 2, {'label': 'asdf'}, True, (None,
        _pass_message.format('asdf'))),

    (2, -2, {'label': 'asdf'}, False, (None,
        'asdf: computed value (-2) does not match (2) by difference (-4).')),

    (2, Decimal("2"), {'label': 'asdf'}, True, (None,
        _pass_message.format('asdf'))),

    (2, Decimal("3"), {'label': 'asdf'}, False, (None,
        'asdf: computed value (3) does not match (2) by difference (1).')),

    (True, True, {}, True, (None,
        _pass_message.format('test_compare'))),

    (False, False, {}, True, (None,
        _pass_message.format('test_compare'))),

    (None, None, {}, True, (None,
        _pass_message.format('test_compare'))),

    (True, None, {}, False, (None,
        'test_compare: computed value (None) does not match (True) by difference ((n/a)).')),

    (True, False, {}, False, (None,
        'test_compare: computed value (False) does not match (True) by difference ((n/a)).')),

    (False, None, {}, False, (None,
        'test_compare: computed value (None) does not match (False) by difference ((n/a)).')),

    (False, True, {}, False, (None,
        'test_compare: computed value (True) does not match (False) by difference ((n/a)).')),

    (None, False, {}, False, (None,
        'test_compare: computed value (False) does not match (None) by difference ((n/a)).')),

    (None, True, {}, False, (None,
        'test_compare: computed value (True) does not match (None) by difference ((n/a)).')),

    ('cat', 'cat', {}, True, (None,
        _pass_message.format('test_compare'))),

    ('cat', 'mouse', {}, False, (None,
        'test_compare: computed value (mouse) does not match (cat) by difference ((n/a)).')),

    (_arrs['a1234_14'], _arrs['a1234_14'], {}, True, (None,
        _pass_message.format('test_compare'))),

    (_arrs['a1234_14'], _arrs['iblip14'], {}, False, (None,
        """ test_compare: computed value does not match.
  Expected:
    [0 1 2 3]
  Observed:
    [0 2 2 4]
  Difference:
    [0 1 0 1]""")),

    (_arrs['a1234_22'], _arrs['a1234_22'], {}, True, (None,
        _pass_message.format('test_compare'))),

    (_arrs['a1234_22'], _arrs['iblip22'], {}, False, (None,
        """test_compare: computed value does not match.
  Expected:
    [[0 1]
     [2 3]]
  Observed:
    [[0 2]
     [2 4]]
  Difference:
    [[0 1]
     [0 1]]""")),

    (_arrs['a1234_22'], _arrs['iblip14'], {}, False, (None,
        """test_compare: computed shape ((4,)) does not match ((2, 2)).""")),

    (1, np.ones(1), {}, False, (None,
        """test_compare: computed shape ((1,)) does not match (()).""")),

    (1, np.array(1), {}, True, (None,
        _pass_message.format('test_compare'))),

    (1, np.array([1]), {}, False, (None,
        """test_compare: computed shape ((1,)) does not match (()).""")),
])  # yapf: disable
def test_compare(ref, cpd, kw, boool, msg):
    res, mstr = qcel.testing.compare(ref, cpd, **kw, return_message=True)
    assert res is boool
    assert mstr.strip() == msg[1].strip()


@pytest.mark.parametrize("ref,cpd,kw,boool,msg", [
    (_dcts['ell'], _dcts['ell'], {}, True, (None, '')),

    (_dcts['elll'], _dcts['ell'], {}, False, (None,
        """root.b
    Missing keys {'bc'}""")),

    (_dcts['ell'], _dcts['elll'], {}, False, (None,
        """root.b
    Found extra keys {'bc'}""")),

    (_dcts['ellnone'], _dcts['elll'], {}, False, (None,
        """root.b.bc
    'None' does not match.""")),

    (_dcts['ell'], _dcts['ellshort'], {}, False, (None,
        """root.a
    Arrays differ.\t_compare_recursive: computed shape ((3,)) does not match ((4,)).""")),

    (qcel.util.unnp(_dcts['ell']), qcel.util.unnp(_dcts['ellshort']), {}, False, (None,
        """root.a
    Iterable lengths did not match""")),

    (_dcts['ell'], _dcts['blipell'], {}, False, (None,
        """root.a
    Arrays differ.\t_compare_recursive: computed value does not match.
  Expected:
    [0 1 2 3]
  Observed:
    [0.    1.02  2.005 3.02 ]
  Difference:
    [0.    0.02  0.005 0.02 ]

root.b.bb
    Arrays differ.\t_compare_recursive: computed value does not match.
  Expected:
    [[0 1]
     [2 3]]
  Observed:
    [[0.    1.02 ]
     [2.005 3.02 ]]
  Difference:
    [[0.    0.02 ]
     [0.005 0.02 ]]""")),

    ({'a': [1, 2], 'b': {'ba':[1, 2, 3], 'bb': [1, 2, 3]}}, {'a': [1, 3], 'b': {'ba':[1, 4, 4], 'bb':[1, 2, 4]}},
        {}, False, (None,
        """root.a.1
    Value 2 did not match 3.
root.b.ba.1
    Value 2 did not match 4.
root.b.ba.2
    Value 3 did not match 4.
root.b.bb.2
    Value 3 did not match 4.""")),

    (_dcts['elll'], _dcts['ell'], {'forgive': ['root.b']}, True, (None, '')),

    (_dcts['ell'], _dcts['elll'], {'forgive': ['b']}, True, (None, '')),

    (_dcts['ellnone'], _dcts['elll'], {'forgive': ['b']}, True, (None, '')),

    (_dcts['ellnone'], _dcts['elll'], {'forgive': ['b.bc']}, True, (None, '')),

    (_dcts['ell'], _dcts['blipell'], {'forgive': ['b']}, False, (None,
        """root.a
    Arrays differ.\t_compare_recursive: computed value does not match.
  Expected:
    [0 1 2 3]
  Observed:
    [0.    1.02  2.005 3.02 ]
  Difference:
    [0.    0.02  0.005 0.02 ]""")),

    ({'a': [1, 2], 'b': {'ba':[1, 2, 3], 'bb': [1, 2, 3]}}, {'a': [1, 3], 'b': {'ba':[1, 4, 4], 'bb':[1, 2, 4]}},
        {'forgive': ['root.a', 'b.bb.2']}, False, (None,
        """root.b.ba.1
    Value 2 did not match 4.
root.b.ba.2
    Value 3 did not match 4.""")),
])  # yapf: disable
def test_compare_recursive(ref, cpd, kw, boool, msg):
    res, mstr = qcel.testing.compare_recursive(ref, cpd, **kw, return_message=True)
    assert res is boool
    assert mstr.strip() == msg[1].strip()
QCElemental-0.5.0/qcelemental/tests/test_units.py000066400000000000000000000053261351361252000220610ustar00rootroot00000000000000import os
from decimal import Decimal

import pytest
import qcelemental


# 2014 CODATA values
@pytest.mark.parametrize("from_unit, to_unit, expected", [

    # First check the 7 canonical NIST conversions
    ("hartree", "Hz", "6.579683920711e15"),
    ("amu", "hartree", "3.4231776902e7"),
    ("hartree", "kilogram", "4.850870129e-35"),
    ("hartree", "J/mol", "2625499.638"),
    ("hartree", "eV", "27.21138602"),
    ("hartree", "wavenumber", "2.194746313702e5"),
    ("hartree", "kelvin", "3.1577513e5"),

    # Check other values
    ("millihartree", "Hz", "6.579683920711e9"),
    ("mhartree", "Hz", "6.579683920711e9"),
    ("hartree", "microgram", "4.850870129e-26"),
    ("microhartree", "wavenumber", "2.194746313702e-7"),
    ("uhartree", "wavenumber", "2.194746313702e-7"),
    ("kilohartree", "kiloeV", "27.21138602"),
    ("hartree", "kiloeV", "0.02721138602"),
    ("millihartree", "J/mol", "2625.499638"),
    ("hartree", "kJ/mol", "2625.499638"),
    ("hartree", "J", "4.359744650e-18"),
    ("1/m", "hartree", "4.556335e-8"),
]) # yapf: disable
def test_unit_conversion_nist(from_unit, to_unit, expected):

    # Build values and quantize to the tolerance
    expected = Decimal(expected)
    from_to_value = Decimal(qcelemental.constants.conversion_factor(from_unit, to_unit)).quantize(expected)
    assert from_to_value == expected

@pytest.mark.parametrize("from_unit, to_unit, expected", [
    ("hartree", "kcal/mol", "627.509474"),
    ("hartree", "kJ/mol", "2625.499638"),
    ("bohr", "angstrom", "0.52917721067"),
    ("bohr", "nanometer", "5.2917721067e-2"),
    ("bohr", "cm", "5.2917721067e-9"),
    ("bohr", "miles", "3.288154743E-14"),
    ("amu", "kg", "1.660539040e-27"),
    ("amu", "g", "1.660539040e-24"),
    ("Bohr", "bohr", "1.0"),
    ("Angstrom", "Angstrom", "1.0"),
]) # yapf: disable
def test_unit_conversion_other(from_unit, to_unit, expected):

    # Build values and quantize to the tolerance
    expected = Decimal(expected)
    from_to_value = Decimal(qcelemental.constants.conversion_factor(from_unit, to_unit)).quantize(expected)
    assert from_to_value == expected

    # Build inverse
    inv_expected = 1 / Decimal(expected)
    to_from_value = Decimal(qcelemental.constants.conversion_factor(to_unit, from_unit))

    # Expected to a relative tolerance as the number of digits plus two for rounding
    # Using float comparisons as we are taking an (1 / float) inverse in the conversion code
    rel_tol = float("10e-{}".format(len(expected.as_tuple().digits) + 2))
    assert pytest.approx(float(inv_expected), rel_tol) == float(to_from_value)

def test_quantities_smoke():
    """
    Smoke test to ensure Quantities are correctly returned
    """
    assert 5 == qcelemental.constants.Quantity("5 kcal").magnitudeQCElemental-0.5.0/qcelemental/tests/test_utils.py000066400000000000000000000141261351361252000220550ustar00rootroot00000000000000import numpy as np
import pytest
import qcelemental
from qcelemental.testing import compare_recursive, compare_values


@pytest.mark.parametrize("inp,expected", [
    (['AAAABBBCCDAABBB'], 'ABCD'),
    (['ABBCcAD', str.lower], 'ABCD'),
])
def test_unique_everseen(inp, expected):
    ue = qcelemental.util.unique_everseen(*inp)
    assert list(ue) == list(expected)

@pytest.mark.parametrize("inp,expected", [
    (({1:{"a":"A"},2:{"b":"B"}}, {2:{"c":"C"},3:{"d":"D"}}), {1:{"a":"A"},2:{"b":"B","c":"C"},3:{"d":"D"}}),
    (({1:{"a":"A"},2:{"b":"B","c":None}}, {2:{"c":"C"},3:{"d":"D"}}), {1:{"a":"A"},2:{"b":"B","c":"C"},3:{"d":"D"}}),
    (({1: [None, 1]}, {1: [2, 1],3:{"d":"D"}}), {1:[2, 1], 3:{"d":"D"}})
]) # yapf: disable
def test_updatewitherror(inp, expected):
    assert compare_recursive(expected, qcelemental.util.update_with_error(inp[0], inp[1]))

@pytest.mark.parametrize("inp", [
    ({1: {"a": "A"}, 2: {"b": "B"}}, {1: {"a": "A"}, 2: {"b": "C"}}),
    ({1: {"a": "A"}, 2: {"b": "B"}}, {1: {"a": "A"}, 2: {"b": None}}),
    ({1: [None, 1]}, {1: [2, 2], 3: {"d": "D"}}),
]) # yapf: disable
def test_updatewitherror_error(inp):
    with pytest.raises(KeyError):
        qcelemental.util.update_with_error(inp[0], inp[1])

@pytest.mark.parametrize("inp,expected", [
    ({'dicary': {"a":"A", "b":"B"}}, {"a":"A", "b":"B"}),
    ({'dicary': {"a":np.arange(2), "b":[1, 2]}}, {"a":[0, 1], "b":[1, 2]}),
    ({'dicary': {"c":{"a":np.arange(2), "b":[1, 2]}}}, {"c":{"a":[0, 1], "b":[1, 2]}}),
    ({'dicary': {"c":{"a":np.arange(2), "b":[1, 2]}}, 'flat': True}, {"c":{"a":[0, 1], "b":[1, 2]}}),
    ({'dicary': {"c":{"a":np.arange(2), "b":[1, 2]}, "d":np.arange(6).reshape((2, 3))}}, {"c":{"a":[0, 1], "b":[1, 2]}, "d":[[0, 1, 2], [3, 4, 5]]}),
    ({'dicary': {"c":{"a":np.arange(2), "b":[1, 2]}, "d":np.arange(6).reshape((2, 3))}, 'flat': True}, {"c":{"a":[0, 1], "b":[1, 2]}, "d":[0, 1, 2, 3, 4, 5]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", np.arange(4).reshape(2, 2)]}}, {"a": [0, 1], "e": ["mouse", [[0, 1], [2, 3]]]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", {"f": np.arange(4).reshape(2, 2)}]}}, {"a": [0, 1], "e": ["mouse", {"f": [[0, 1], [2, 3]]}]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", [np.arange(4).reshape(2, 2), {"f": np.arange(6).reshape(2, 3), "g": [[11], [12]]}]]}}, {"a": [0, 1], "e": ["mouse", [[[0, 1], [2, 3]], {"f": [[0, 1, 2], [3, 4, 5]], "g": [[11], [12]]}]]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", np.arange(4).reshape(2, 2)]}, 'flat': True}, {"a": [0, 1], "e": ["mouse", [0, 1, 2, 3]]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", {"f": np.arange(4).reshape(2, 2)}]}, 'flat': True}, {"a": [0, 1], "e": ["mouse", {"f": [0, 1, 2, 3]}]}),
    ({'dicary': {"a": np.arange(2), "e": ["mouse", [np.arange(4).reshape(2, 2), {"f": np.arange(6).reshape(2, 3), "g": [[11], [12]]}]]}, 'flat': True}, {"a": [0, 1], "e": ["mouse", [[0, 1, 2, 3], {"f": [0, 1, 2, 3, 4, 5], "g": [[11], [12]]}]]}),
]) # yapf: disable
def test_unnp(inp, expected):
    assert compare_recursive(expected, qcelemental.util.unnp(**inp), atol=1.e-4)


def test_distance():
    def _test_distance(p1, p2, value):
        tmp = qcelemental.util.compute_distance(p1, p2)
        assert compare_values(value, float(tmp))

    _test_distance([0, 0, 0], [0, 0, 1], 1.0)
    _test_distance([0, 0, 0], [0, 0, 0], 0.0)

    tmp1 = np.random.rand(20, 3) * 4
    tmp2 = np.random.rand(20, 3) * 4
    np_dist = np.linalg.norm(tmp1 - tmp2, axis=1)
    ee_dist = qcelemental.util.compute_distance(tmp1, tmp2)
    assert np.allclose(np_dist, ee_dist)


def test_angle():
    def _test_angle(p1, p2, p3, value, degrees=True):
        tmp = qcelemental.util.compute_angle(p1, p2, p3, degrees=degrees)
        assert compare_values(value, float(tmp))

    # Check all 90 degree domains
    p1 = [5, 0, 0]
    p2 = [0, 0, 0]
    p3 = [0, 2, 0]
    p4 = [0, 0, 4]
    _test_angle(p1, p2, p3, 90)
    _test_angle(p3, p2, p1, 90)

    _test_angle(p1, p2, p4, 90)
    _test_angle(p4, p2, p1, 90)

    _test_angle(p3, p2, p4, 90)
    _test_angle(p4, p2, p3, 90)
    _test_angle(p4, p2, p3, np.pi / 2, degrees=False)

    # Zero angle
    p5 = [6, 0, 0]
    _test_angle(p1, p2, p1, 0)
    _test_angle(p1, p2, p5, 0)
    _test_angle(p1, p2, p5, 0, degrees=False)

    # Linear
    p6 = [-5, 0, 0]
    p7 = [-4, 0, 0]
    _test_angle(p1, p2, p6, 180)
    _test_angle(p1, p2, p6, 180)
    _test_angle(p1, p2, p7, np.pi, degrees=False)


def test_dihedral1():
    def _test_dihedral(p1, p2, p3, p4, value, degrees=True):
        tmp = qcelemental.util.compute_dihedral(p1, p2, p3, p4, degrees=degrees)
        assert compare_values(value, float(tmp), label="test_dihedral1")

    p1 = [0, 0, 0]
    p2 = [0, 2, 0]
    p3 = [2, 2, 0]
    p4 = [2, 0, 0]
    p5 = [2, 4, 0]

    # Cis check
    _test_dihedral(p1, p2, p3, p4, 0)

    # Trans check
    _test_dihedral(p1, p2, p3, p5, 180)

    # 90 phase checks
    p6 = [2, 2, -2]
    p7 = [2, 2, 2]
    _test_dihedral(p1, p2, p3, p6, 90)
    _test_dihedral(p1, p2, p3, p7, -90)

    p8 = [0, 4, 0]
    _test_dihedral(p8, p2, p3, p6, -90)
    _test_dihedral(p8, p2, p3, p7, 90)

    # Linear checks
    _test_dihedral(p1, p2, p3, [3, 2, 0], 0)
    _test_dihedral(p1, p2, p3, [3, 2 + 1.e-14, 0], 180)
    _test_dihedral(p1, p2, p3, [3, 2 - 1.e-14, 0], 0)
    _test_dihedral(p1, p2, p3, [3, 2, 0 + 1.e-14], -90)
    _test_dihedral(p1, p2, p3, [3, 2, 0 - 1.e-14], 90)


def test_dihedral2():
    # FROM: https://stackoverflow.com/questions/20305272/

    def _test_dihedral(p1, p2, p3, p4, value, degrees=True):
        tmp = qcelemental.util.compute_dihedral(p1, p2, p3, p4, degrees=degrees)
        assert compare_values(value, float(tmp), label="test_dihedral1")

    p0 = [24.969, 13.428, 30.692]
    p1 = [24.044, 12.661, 29.808]
    p2 = [22.785, 13.482, 29.543]
    p3 = [21.951, 13.670, 30.431]
    p4 = [23.672, 11.328, 30.466]
    p5 = [22.881, 10.326, 29.620]
    p6 = [23.691, 9.935, 28.389]
    p7 = [22.557, 9.096, 30.459]

    _test_dihedral(p0, p1, p2, p3, -71.21515114671394)
    _test_dihedral(p0, p1, p4, p5, -171.94319947953642)
    _test_dihedral(p1, p4, p5, p6, 60.82226735264638)
    _test_dihedral(p1, p4, p5, p7, -177.63641151521261)
QCElemental-0.5.0/qcelemental/util/000077500000000000000000000000001351361252000171135ustar00rootroot00000000000000QCElemental-0.5.0/qcelemental/util/__init__.py000066400000000000000000000011001351361252000212140ustar00rootroot00000000000000from .np_blockwise import blockwise_expand, blockwise_contract
from .np_rand3drot import random_rotation_matrix
from .scipy_hungarian import linear_sum_assignment
from .gph_uno_bipartite import uno
#from .mpl import plot_coord
from .misc import (distance_matrix, update_with_error, standardize_efp_angles_units, filter_comments, unnp,
                   compute_distance, compute_angle, compute_dihedral, measure_coordinates)
from .internal import provenance_stamp
from .itertools import unique_everseen
from .importing import parse_version, safe_version, which, which_import
QCElemental-0.5.0/qcelemental/util/gph_uno_bipartite.py000066400000000000000000000375631351361252000232050ustar00rootroot00000000000000"""Functions to enumerate all perfect and maximum matchings in bipartite graph.

Implemented following the algorithms in the paper "Algorithms for Enumerating
All Perfect, Maximum and Maximal Matchings in Bipartite Graphs" by Takeaki Uno,
using numpy and networkx modules of python.

NOTICE: optimization needed.

Author: guangzhi XU (xugzhi1987@gmail.com; guangzhi.xu@outlook.com)
Update time: 2017-06-29 14:41:56.

Copied Dec 2017 LAB Adapted from https://github.com/Xunius/bipartite_matching
Updated Dec 2017 LAB for pep8, py3, more tests, starter_match, and simpler interface

"""
import numpy as np


# commented as untested [Apr 2019]
#def _plotGraph(graph):
#    """Plot graph using nodes as position number."""
#    import networkx as nx
#
#    import matplotlib.pyplot as plt
#    fig = plt.figure()
#    ax = fig.add_subplot(111)
#
#    pos = [(ii[1], ii[0]) for ii in graph.nodes()]
#    pos_dict = dict(zip(graph.nodes(), pos))
#    nx.draw(graph, pos=pos_dict, ax=ax, with_labels=True)
#    plt.show(block=False)
#    return


def _formDirected(g, match):
    """Form directed graph D from G and matching M.

    Parameters
    ----------
    g : 
        Undirected bipartite graph. Nodes are separated by their
        'bipartite' attribute.
    match : 
        List of edges forming a matching of `g`. 
    
    Returns
    -------
    networkx.DiGraph
	    Directed graph, with edges in `match` pointing from set-0
	    (bipartite attribute==0) to set-1 (bipartite attrbiute==1), and
	    the other edges in `g` but not in `match` pointing from set-1 to
	    set-0.

    """
    import networkx as nx

    d = nx.DiGraph()

    for ee in g.edges():
        if ee in match or (ee[1], ee[0]) in match:
            if g.node[ee[0]]['bipartite'] == 0:
                d.add_edge(ee[0], ee[1])
            else:
                d.add_edge(ee[1], ee[0])
        else:
            if g.node[ee[0]]['bipartite'] == 0:
                d.add_edge(ee[1], ee[0])
            else:
                d.add_edge(ee[0], ee[1])

    return d


def _enumMaximumMatching(g, starter_match=None):
    """Find all maximum matchings in an undirected bipartite graph `g`.

    Parameters
    ----------
    g : networkx.Graph
        Undirected bipartite graph. Nodes are separated by their
        'bipartite' attribute.
    starter_match : dict, optional
        Single perfect match to inaugurate Uno's algorithm.

    Returns
    -------
    list
        Each is a list of edges forming a maximum matching of `g`. 

    Author
    ------
    guangzhi XU (xugzhi1987@gmail.com; guangzhi.xu@outlook.com)
    Update time: 2017-05-21 20:04:51.

    """
    import networkx as nx
    all_matches = []

    #----------------Find one matching M----------------
    if starter_match is None:
        match = nx.bipartite.hopcroft_karp_matching(g)
    else:
        match = starter_match

    #---------------Re-orient match arcs---------------
    match2 = []
    for kk, vv in match.items():
        if g.node[kk]['bipartite'] == 0:
            match2.append((kk, vv))
    match = match2
    all_matches.append(match)

    #-----------------Enter recursion-----------------
    all_matches = _enumMaximumMatchingIter(g, match, all_matches, None)

    return all_matches


def _enumMaximumMatchingIter(g, match, all_matches, add_e=None):
    """Recurively search maximum matchings.

    Parameters
    ----------
    g : 
        Undirected bipartite graph. Nodes are separated by their
        'bipartite' attribute.
    match : 
        List of edges forming one maximum matching of `g`.
    all_matches : 
	    List, each is a list of edges forming a maximum matching of `g`.
	    Newly found matchings will be appended into this list.
    add_e : tuple, optional
        Edge used to form subproblems. If not `None`, will be added to each
        newly found matchings.

    Returns
    -------
    list
        Updated list of all maximum matchings.

    Author
    ------
    guangzhi XU (xugzhi1987@gmail.com; guangzhi.xu@outlook.com)
    Update time: 2017-05-21 20:09:06.

    """
    import networkx as nx

    #---------------Form directed graph D---------------
    d = _formDirected(g, match)

    #-----------------Find cycles in D-----------------
    cycles = list(nx.simple_cycles(d))

    if len(cycles) == 0:

        #---------If no cycle, find a feasible path---------
        all_uncovered = set(g.node).difference(set([ii[0] for ii in match]))
        all_uncovered = all_uncovered.difference(set([ii[1] for ii in match]))
        all_uncovered = list(all_uncovered)

        #--------------If no path, terminiate--------------
        if len(all_uncovered) == 0:
            return all_matches

        #----------Find a length 2 feasible path----------
        idx = 0
        uncovered = all_uncovered[idx]
        while True:

            if uncovered not in nx.isolates(g):
                paths = nx.single_source_shortest_path(d, uncovered, cutoff=2)
                len2paths = [vv for kk, vv in paths.items() if len(vv) == 3]

                if len(len2paths) > 0:
                    reversed = False
                    break

                #----------------Try reversed path----------------
                paths_rev = nx.single_source_shortest_path(d.reverse(), uncovered, cutoff=2)
                len2paths = [vv for kk, vv in paths_rev.items() if len(vv) == 3]

                if len(len2paths) > 0:
                    reversed = True
                    break

            idx += 1
            if idx > len(all_uncovered) - 1:
                return all_matches

            uncovered = all_uncovered[idx]

        #-------------Create a new matching M'-------------
        len2path = len2paths[0]
        if reversed:
            len2path = len2path[::-1]
        len2path = list(zip(len2path[:-1], len2path[1:]))

        new_match = []
        for ee in d.edges():
            if ee in len2path:
                if g.node[ee[1]]['bipartite'] == 0:
                    new_match.append((ee[1], ee[0]))
            else:
                if g.node[ee[0]]['bipartite'] == 0:
                    new_match.append(ee)

        if add_e is not None:
            for ii in add_e:
                new_match.append(ii)

        all_matches.append(new_match)

        #---------------------Select e---------------------
        e = set(len2path).difference(set(match))
        e = list(e)[0]

        #-----------------Form subproblems-----------------
        g_plus = g.copy()
        g_minus = g.copy()
        g_plus.remove_node(e[0])
        g_plus.remove_node(e[1])

        g_minus.remove_edge(e[0], e[1])

        add_e_new = [
            e,
        ]
        if add_e is not None:
            add_e_new.extend(add_e)

        all_matches = _enumMaximumMatchingIter(g_minus, match, all_matches, add_e)
        all_matches = _enumMaximumMatchingIter(g_plus, new_match, all_matches, add_e_new)

    else:
        #----------------Find a cycle in D----------------
        cycle = cycles[0]
        cycle.append(cycle[0])
        cycle = list(zip(cycle[:-1], cycle[1:]))

        #-------------Create a new matching M'-------------
        new_match = []
        for ee in d.edges():
            if ee in cycle:
                if g.node[ee[1]]['bipartite'] == 0:
                    new_match.append((ee[1], ee[0]))
            else:
                if g.node[ee[0]]['bipartite'] == 0:
                    new_match.append(ee)

        if add_e is not None:
            for ii in add_e:
                new_match.append(ii)

        all_matches.append(new_match)

        #-----------------Choose an edge E-----------------
        e = set(match).intersection(set(cycle))
        e = list(e)[0]

        #-----------------Form subproblems-----------------
        g_plus = g.copy()
        g_minus = g.copy()
        g_plus.remove_node(e[0])
        g_plus.remove_node(e[1])
        g_minus.remove_edge(e[0], e[1])

        add_e_new = [
            e,
        ]
        if add_e is not None:
            add_e_new.extend(add_e)

        all_matches = _enumMaximumMatchingIter(g_minus, new_match, all_matches, add_e)
        all_matches = _enumMaximumMatchingIter(g_plus, match, all_matches, add_e_new)

    return all_matches


def _enumMaximumMatching2(g):
    """Find all maximum matchings in an undirected bipartite graph `g`.
    Similar to _enumMaximumMatching but implemented using adjacency matrix
    of graph for slight speed boost.

    Parameters
    ----------
    g: 
        Undirected bipartite graph. Nodes are separated by their
        'bipartite' attribute.

    Returns
    -------
    list
        Each is a list of edges forming a maximum matching of `g`. 

    Author
    ------
    guangzhi XU (xugzhi1987@gmail.com; guangzhi.xu@outlook.com)
    Update time: 2017-05-21 20:04:51.

    """
    import networkx as nx
    from scipy import sparse

    s1 = set(n for n, d in g.nodes(data=True) if d['bipartite'] == 0)
    s2 = set(g) - s1
    n1 = len(s1)
    nodes = list(s1) + list(s2)

    adj = nx.adjacency_matrix(g, nodes).tolil()
    all_matches = []

    #----------------Find one matching----------------
    match = nx.bipartite.hopcroft_karp_matching(g)

    matchadj = np.zeros(adj.shape).astype('int')
    for kk, vv in match.items():
        matchadj[nodes.index(kk), nodes.index(vv)] = 1
    matchadj = sparse.lil_matrix(matchadj)

    all_matches.append(matchadj)

    #-----------------Enter recursion-----------------
    all_matches = _enumMaximumMatchingIter2(adj, matchadj, all_matches, n1, None, True)

    #---------------Re-orient match arcs---------------
    all_matches2 = []
    for ii in all_matches:
        match_list = sparse.find(ii[:n1] == 1)
        m1 = [nodes[jj] for jj in match_list[0]]
        m2 = [nodes[jj] for jj in match_list[1]]
        match_list = zip(m1, m2)

        all_matches2.append(match_list)

    print('got all')
    return all_matches2


def _enumMaximumMatchingIter2(adj, matchadj, all_matches, n1, add_e=None, check_cycle=True):
    """Recurively search maximum matchings.
    Similar to _enumMaximumMatching but implemented using adjacency matrix
    of graph for a slight speed boost.

    Parameters
    ----------
#    g : 
#        Undirected bipartite graph. Nodes are separated by their
#        'bipartite' attribute.
#    match : 
#        List of edges forming one maximum matching of `g`.
#    all_matches : 
#	    List, each is a list of edges forming a maximum matching of `g`.
#	    Newly found matchings will be appended into this list.
    add_e : tuple, optional
        Edge used to form subproblems. If not `None`, will be added to each
        newly found matchings.

    Returns
    -------
    list
        Updated list of all maximum matchings.

    Author
    ------
    guangzhi XU (xugzhi1987@gmail.com; guangzhi.xu@outlook.com)
    Update time: 2017-05-21 20:09:06.

    """
    import networkx as nx
    from scipy import sparse

    #-------------------Find cycles-------------------
    if check_cycle:
        d = matchadj.multiply(adj)
        d[n1:, :] = adj[n1:, :] - matchadj[n1:, :].multiply(adj[n1:, :])

        dg = nx.from_numpy_matrix(d.toarray(), create_using=nx.DiGraph())
        cycles = list(nx.simple_cycles(dg))
        if len(cycles) == 0:
            check_cycle = False
        else:
            check_cycle = True

    if check_cycle:
        cycle = cycles[0]
        cycle.append(cycle[0])
        cycle = zip(cycle[:-1], cycle[1:])

        #--------------Create a new matching--------------
        new_match = matchadj.copy()
        for ee in cycle:
            if matchadj[ee[0], ee[1]] == 1:
                new_match[ee[0], ee[1]] = 0
                new_match[ee[1], ee[0]] = 0
                e = ee
            else:
                new_match[ee[0], ee[1]] = 1
                new_match[ee[1], ee[0]] = 1

        if add_e is not None:
            for ii in add_e:
                new_match[ii[0], ii[1]] = 1

        all_matches.append(new_match)

        #-----------------Form subproblems-----------------
        g_plus = adj.copy()
        g_minus = adj.copy()
        g_plus[e[0], :] = 0
        g_plus[:, e[1]] = 0
        g_plus[:, e[0]] = 0
        g_plus[e[1], :] = 0
        g_minus[e[0], e[1]] = 0
        g_minus[e[1], e[0]] = 0

        add_e_new = [
            e,
        ]
        if add_e is not None:
            add_e_new.extend(add_e)

        all_matches = _enumMaximumMatchingIter2(g_minus, new_match, all_matches, n1, add_e, check_cycle)
        all_matches = _enumMaximumMatchingIter2(g_plus, matchadj, all_matches, n1, add_e_new, check_cycle)

    else:
        #---------------Find uncovered nodes---------------
        uncovered = np.where(np.sum(matchadj, axis=1) == 0)[0]

        if len(uncovered) == 0:
            return all_matches

        #---------------Find feasible paths---------------
        paths = []
        for ii in uncovered:
            aa = adj[ii, :].dot(matchadj)
            if aa.sum() == 0:
                continue
            paths.append((ii, int(sparse.find(aa == 1)[1][0])))
            if len(paths) > 0:
                break

        if len(paths) == 0:
            return all_matches

        #----------------------Find e----------------------
        feas1, feas2 = paths[0]
        e = (feas1, int(sparse.find(matchadj[:, feas2] == 1)[0]))

        #----------------Create a new match----------------
        new_match = matchadj.copy()
        new_match[feas2, :] = 0
        new_match[:, feas2] = 0
        new_match[feas1, e[1]] = 1
        new_match[e[1], feas1] = 1

        if add_e is not None:
            for ii in add_e:
                new_match[ii[0], ii[1]] = 1

        all_matches.append(new_match)

        #-----------------Form subproblems-----------------
        g_plus = adj.copy()
        g_minus = adj.copy()
        g_plus[e[0], :] = 0
        g_plus[:, e[1]] = 0
        g_plus[:, e[0]] = 0
        g_plus[e[1], :] = 0
        g_minus[e[0], e[1]] = 0
        g_minus[e[1], e[0]] = 0

        add_e_new = [
            e,
        ]
        if add_e is not None:
            add_e_new.extend(add_e)

        all_matches = _enumMaximumMatchingIter2(g_minus, matchadj, all_matches, n1, add_e, check_cycle)
        all_matches = _enumMaximumMatchingIter2(g_plus, new_match, all_matches, n1, add_e_new, check_cycle)

    #if len(all_matches) % 1000 == 0:
    #    print('len', len(all_matches))

    #print('another')
    return all_matches


# commented as unused [Apr 2019]
#def _findCycle(adj, n1):
#    from scipy import sparse
#
#    path = []
#    visited = set()
#
#    def visit(v):
#        if v in visited:
#            return False
#        visited.add(v)
#        path.append(v)
#        neighbours = sparse.find(adj[v, :] == 1)[1]
#        for nn in neighbours:
#            if nn in path or visit(nn):
#                return True
#        path.remove(v)
#        return False
#
#    nodes = range(n1)
#    result = any(visit(v) for v in nodes)
#    return result, path


def uno(edges, match=None, verbose=1):
    """Perform Uno's algorithm to enumerate all equivalent matchings among
    the bipartite graph defined by `edges`. Optionally given a single
    known `match`.

    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.107.8179&rep=rep1&type=pdf

    "Algorithms for Enumerating All Perfect, Maximum and Maximal Matchings
    in Bipartite Graphs" by Takeaki UNO

    """
    import networkx as nx

    if match is None:
        p_match = None
    else:
        p_match = {(1, m[0]): (0, m[1]) for m in match}
        p_m_inv = {(0, m[1]): (1, m[0]) for m in match}
        p_match.update(p_m_inv)

    p_edges = [[(1, e[0]), (0, e[1])] for e in edges]
    if verbose >= 2:
        print('Edges:')
        for e in p_edges:
            print('\t', e)

    g = nx.Graph()
    for e in p_edges:
        g.add_node(e[0], bipartite=0)
        g.add_node(e[1], bipartite=1)
        if verbose >= 2:
            print('  Node:', e[0], e[1])
    g.add_edges_from(p_edges)

    all_matches = _enumMaximumMatching(g, starter_match=p_match)
    p_all_matches = [sorted([(pt[0][1], pt[1][1]) for pt in am]) for am in all_matches]

    return p_all_matches
QCElemental-0.5.0/qcelemental/util/importing.py000066400000000000000000000052321351361252000214770ustar00rootroot00000000000000import os
import shutil
import sys
from typing import Union


def which_import(module: str, *, return_bool: bool = False, raise_error: bool = False,
                 raise_msg: str = None) -> Union[bool, None, str]:
    """Tests to see if a Python module is available.

    Returns
    -------
    str or None
        By default, returns `__init__.py`-like path if module found or `None` if not.
    bool
        When `return_bool=True`, returns whether or not found.

    Raises
    ------
    ModuleNotFoundError
        When `raises_error=True` and module not found. Raises generic message plus any `raise_msg`.

    """
    import importlib
    module_spec = importlib.util.find_spec(module)

    if module_spec is None:
        if raise_error:
            raise ModuleNotFoundError(
                f"Python module '{module}' not found in envvar PYTHONPATH.{' ' + raise_msg if raise_msg else ''}")
        elif return_bool:
            return False
        else:
            return None
    else:
        if return_bool:
            return True
        else:
            return module_spec.origin


def which(command: str, *, return_bool: bool = False, raise_error: bool = False,
          raise_msg: str = None, env: str = None) -> Union[bool, None, str]:
    """Test to see if a command is available.

    Returns
    -------
    str or None
        By default, returns command path if command found or `None` if not.
        Environment is $PATH or `os.pathsep`-separated `env`, less any None values.
    bool
        When `return_bool=True`, returns whether or not found.

    Raises
    ------
    ModuleNotFoundError
        When `raises_error=True` and command not found. Raises generic message plus any `raise_msg`.

    """
    if env is None:
        lenv = {'PATH': os.pathsep + os.environ.get('PATH', '') + os.path.dirname(sys.executable)}
    else:
        lenv = {'PATH': os.pathsep.join([os.path.abspath(x) for x in env.split(os.pathsep) if x != ''])}
    lenv = {k: v for k, v in lenv.items() if v is not None}

    ans = shutil.which(command, mode=os.F_OK | os.X_OK, path=lenv['PATH'])

    if raise_error and ans is None:
        raise ModuleNotFoundError(
            f"Command '{command}' not found in envvar PATH.{' ' + raise_msg if raise_msg else ''}")

    if return_bool:
        return bool(ans)
    else:
        return ans


def safe_version(*args, **kwargs) -> str:
    """
    Package resources is a very slow load
    """
    import pkg_resources
    return pkg_resources.safe_version(*args, **kwargs)


def parse_version(*args, **kwargs):
    """
    Package resources is a very slow load
    """
    import pkg_resources
    return pkg_resources.parse_version(*args, **kwargs)
QCElemental-0.5.0/qcelemental/util/internal.py000066400000000000000000000007551351361252000213100ustar00rootroot00000000000000from typing import Dict

from qcelemental.extras import get_information


def provenance_stamp(routine: str) -> Dict[str, str]:
    """Return dictionary satisfying QCSchema,
    https://github.com/MolSSI/QCSchema/blob/master/qcschema/dev/definitions.py#L23-L41
    with QCElemental's credentials for creator and version. The
    generating routine's name is passed in through `routine`.

    """
    return {'creator': 'QCElemental', 'version': get_information('version'), 'routine': routine}
QCElemental-0.5.0/qcelemental/util/itertools.py000066400000000000000000000012711351361252000215120ustar00rootroot00000000000000import itertools


def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    # straight from the docs, https://docs.python.org/3/library/itertools.html#itertools-recipes
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in itertools.filterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element
QCElemental-0.5.0/qcelemental/util/misc.py000066400000000000000000000225411351361252000204240ustar00rootroot00000000000000import math
import re
from typing import Dict, List

import numpy as np

from ..physical_constants import constants


def distance_matrix(a: np.ndarray, b: np.ndarray) -> np.ndarray:
    """Euclidean distance matrix between rows of arrays `a` and `b`. Equivalent to
    `scipy.spatial.distance.cdist(a, b, 'euclidean')`. Returns a.shape[0] x b.shape[0] array.

    """
    assert a.shape[1] == b.shape[1], """Inner dimensions do not match"""
    distm = np.zeros([a.shape[0], b.shape[0]])
    for i in range(a.shape[0]):
        distm[i] = np.linalg.norm(a[i] - b, axis=1)
    return distm


def update_with_error(a: Dict, b: Dict, path=None) -> Dict:
    """Merges `b` into `a` like dict.update; however, raises KeyError if values of a
    key shared by `a` and `b` conflict.

    Adapted from: https://stackoverflow.com/a/7205107

    """
    if path is None:
        path = []
    for key in b:
        if key in a:
            if isinstance(a[key], dict) and isinstance(b[key], dict):
                update_with_error(a[key], b[key], path + [str(key)])
            elif a[key] == b[key]:
                pass  # same leaf value
            elif a[key] is None:
                a[key] = b[key]
            elif (isinstance(a[key], (list, tuple)) and
                  not isinstance(a[key], str) and
                  isinstance(b[key], (list, tuple)) and
                  not isinstance(b[key], str) and
                  len(a[key]) == len(b[key]) and
                  all((av is None or av == bv) for av, bv in zip(a[key], b[key]))):  # yapf: disable
                a[key] = b[key]
            else:
                raise KeyError('Conflict at {}: {} vs. {}'.format('.'.join(path + [str(key)]), a[key], b[key]))
        else:
            a[key] = b[key]
    return a


def standardize_efp_angles_units(units: str, geom_hints: List[List[float]]) -> List[List[float]]:
    """Applies to the pre-validated xyzabc or points hints in `geom_hints`
    the libefp default (1) units of [a0] and (2) radian angle range of
    (-pi, pi]. The latter is handy since this is how libefp returns hints

    """

    def radrge(radang):
        """Adjust `radang` by 2pi into (-pi, pi] range."""
        if radang > math.pi:
            return radang - 2 * math.pi
        elif radang <= -math.pi:
            return radang + 2 * math.pi
        else:
            return radang

    if units == 'Angstrom':
        iutau = 1. / constants.bohr2angstroms
    else:
        iutau = 1.

    hints = []
    for hint in geom_hints:
        if len(hint) == 6:
            x, y, z = [i * iutau for i in hint[:3]]
            a, b, c = [radrge(i) for i in hint[3:]]
            hints.append([x, y, z, a, b, c])
        if len(hint) == 9:
            points = [i * iutau for i in hint]
            hints.append(points)

    return hints


def filter_comments(string: str) -> str:
    """Remove from `string` any Python-style comments ('#' to end of line)."""

    return re.sub(r'(^|[^\\])#.*', '', string)


def unnp(dicary: Dict, _path=None, *, flat: bool=False) -> Dict:
    """Return `dicary` with any ndarray values replaced by lists.

    Parameters
    ----------
    dicary: dict
        Dictionary where any internal iterables are dict or list.
    flat : bool, optional
        Whether the returned lists are flat or nested.

    Returns
    -------
    dict
        Input with any ndarray values replaced by lists.

    """
    if _path is None:
        _path = []

    ndicary = {}
    for k, v in dicary.items():
        if isinstance(v, dict):
            ndicary[k] = unnp(v, _path + [str(k)], flat=flat)
        elif isinstance(v, list):
            # relying on Py3.6+ ordered dict here
            fakedict = {kk: vv for kk, vv in enumerate(v)}
            tolisted = unnp(fakedict, _path + [str(k)], flat=flat)
            ndicary[k] = list(tolisted.values())
        else:
            try:
                v.shape
            except AttributeError:
                ndicary[k] = v
            else:
                if flat:
                    ndicary[k] = v.ravel().tolist()
                else:
                    ndicary[k] = v.tolist()
    return ndicary


def _norm(points) -> float:
    """
    Return the Frobenius norm across axis=-1, NumPy's internal norm is crazy slow (~4x)
    """

    tmp = np.atleast_2d(points)
    return np.sqrt(np.einsum("ij,ij->i", tmp, tmp))


def measure_coordinates(coordinates, measurements, degrees=False):
    """
    Measures a geometry array based on 0-based indices provided, automatically detects distance, angle,
    and dihedral based on length of measurement input.
    """

    coordinates = np.atleast_2d(coordinates)
    num_coords = coordinates.shape[0]

    single = False
    if isinstance(measurements[0], int):
        measurements = [measurements]
        single = True

    ret = []
    for num, m in enumerate(measurements):
        if any(x >= num_coords for x in m):
            raise ValueError(f"An index of measurement {num} is out of bounds.")

        kwargs = {}
        if len(m) == 2:
            func = compute_distance
        elif len(m) == 3:
            func = compute_angle
            kwargs = {"degrees": degrees}
        elif len(m) == 4:
            func = compute_dihedral
            kwargs = {"degrees": degrees}
        else:
            raise KeyError(f"Unrecognized number of arguments for measurement {num}, found {len(m)}, expected 2-4.")

        val = func(*[coordinates[x] for x in m], **kwargs)
        ret.append(float(val))

    if single:
        return ret[0]
    else:
        return ret


def compute_distance(points1, points2) -> np.ndarray:
    """
    Computes the distance between the provided points on a per-row basis.

    Parameters
    ----------
    points1 : array-like
        The first list of points, can be 1D or 2D
    points2 : array-like
        The second list of points, can be 1D or 2D

    Returns
    -------
    distances : np.ndarray
        The array of distances between points1 and points2

    Notes
    -----
    Units are not considered inside these expressions, please preconvert to the same units before using.

    See Also
    --------
    distance_matrix
        Computes the distance between the provided points in all rows.
        compute_distance result is the diagonal of the distance_matrix result.

    """
    points1 = np.atleast_2d(points1)
    points2 = np.atleast_2d(points2)

    return _norm(points1 - points2)


def compute_angle(points1, points2, points3, *, degrees: bool=False) -> np.ndarray:
    """
    Computes the angle (p1, p2 [vertex], p3) between the provided points on a per-row basis.

    Parameters
    ----------
    points1 : np.ndarray
        The first list of points, can be 1D or 2D
    points2 : np.ndarray
        The second list of points, can be 1D or 2D
    points3 : np.ndarray
        The third list of points, can be 1D or 2D
    degrees : bool, options
        Returns the angle in degrees rather than radians if True

    Returns
    -------
    angles : np.ndarray
        The angle between the three points in radians

    Notes
    -----
    Units are not considered inside these expressions, please preconvert to the same units before using.
    """

    points1 = np.atleast_2d(points1)
    points2 = np.atleast_2d(points2)
    points3 = np.atleast_2d(points3)

    v12 = points1 - points2
    v23 = points2 - points3

    denom = _norm(v12) * _norm(v23)
    cosine_angle = np.einsum("ij,ij->i", v12, v23) / denom

    angle = np.pi - np.arccos(cosine_angle)

    if degrees:
        return np.degrees(angle)
    else:
        return angle


def compute_dihedral(points1, points2, points3, points4, *, degrees: bool=False) -> np.ndarray:
    """
    Computes the dihedral angle (p1, p2, p3, p4) between the provided points on a per-row basis using the Praxeolitic formula.

    Parameters
    ----------
    points1 : np.ndarray
        The first list of points, can be 1D or 2D
    points2 : np.ndarray
        The second list of points, can be 1D or 2D
    points3 : np.ndarray
        The third list of points, can be 1D or 2D
    points4 : np.ndarray
        The third list of points, can be 1D or 2D
    degrees : bool, options
        Returns the dihedral angle in degrees rather than radians if True

    Returns
    -------
    dihedrals : np.ndarray
        The dihedral angle between the four points in radians

    Notes
    -----
    Units are not considered inside these expressions, please preconvert to the same units before using.
    """

    # FROM: https://stackoverflow.com/questions/20305272/

    points1 = np.atleast_2d(points1)
    points2 = np.atleast_2d(points2)
    points3 = np.atleast_2d(points3)
    points4 = np.atleast_2d(points4)

    # Build the three vectors
    v1 = -1.0 * (points2 - points1)
    v2 = points3 - points2
    v3 = points4 - points3

    # Normalize the central vector
    v2 = v2 / _norm(v2)

    # v = projection of b0 onto plane perpendicular to b1
    #   = b0 minus component that aligns with b1
    # w = projection of b2 onto plane perpendicular to b1
    #   = b2 minus component that aligns with b1
    v = v1 - np.einsum("ij,ij->i", v1, v1) * v2
    w = v3 - np.einsum("ij,ij->i", v3, v2) * v2

    # angle between v and w in a plane is the torsion angle
    # v and w may not be normalized but that's fine since tan is y/x
    x = np.einsum("ij,ij->i", v, w)
    y = np.einsum("ij,ij->i", np.cross(v2, v), w)
    angle = np.arctan2(y, x)

    if degrees:
        return np.degrees(angle)
    else:
        return angle
QCElemental-0.5.0/qcelemental/util/np_blockwise.py000066400000000000000000000072301351361252000221460ustar00rootroot00000000000000import numpy as np


def blockwise_contract(arr):
    """Undo blockwise_expand, returning `arr` to original 2D array."""

    if len(arr.shape) != 4:
        print('Not appropriate for un_blockwise')
    gr, gc, lr, lc = arr.shape
    ans = np.reshape(arr, (gr * gc, lr, lc))

    def unblockshaped(arr, h, w):
        """
        Return an array of shape (h, w) where
        h * w = arr.size

        If arr is of shape (n, nrows, ncols), n sublocks of shape (nrows, ncols),
        then the returned array preserves the "physical" layout of the sublocks.

        From: https://stackoverflow.com/a/16873755
        """
        n, nrows, ncols = arr.shape
        return (arr.reshape(h // nrows, -1, nrows, ncols).swapaxes(1, 2).reshape(h, w))

    ans = unblockshaped(ans, gr * lr, gc * lc)
    return ans


def blockwise_expand(a, blockshape, aslist=False, require_aligned_blocks=True):
    """
    Return a 2N-D view of the given N-D array, rearranged so each ND block (tile)
    of the original array is indexed by its block address using the first N
    indexes of the output array.

    Note: This function is nearly identical to ``skimage.util.view_as_blocks()``, except:
          - "imperfect" block shapes are permitted (via require_aligned_blocks=False)
          - only contiguous arrays are accepted.  (This function will NOT silently copy your array.)
            As a result, the return value is *always* a view of the input.

    Args:
        a: The ND array
        blockshape: The tile shape

        aslist: If True, return all blocks as a list of ND blocks
                instead of a 2D array indexed by ND block coordinate.
        require_aligned_blocks: If True, check to make sure no data is "left over"
                                in each row/column/etc. of the output view.
                                That is, the blockshape must divide evenly into the full array shape.
                                If False, "leftover" items that cannot be made into complete blocks
                                will be discarded from the output view.

    Sources
    -------
    code: https://github.com/ilastik/lazyflow/blob/master/lazyflow/utility/blockwise_view.py
    so: Inspired by the 2D example shown here: http://stackoverflow.com/a/8070716/162094

    Here's a 2D example (this function also works for ND):

    >>> a = np.arange(1,21).reshape(4,5)
    >>> print a
    [[ 1  2  3  4  5]
     [ 6  7  8  9 10]
     [11 12 13 14 15]
     [16 17 18 19 20]]
    >>> view = blockwise_view(a, (2,2), False)
    >>> print view
    [[[[ 1  2]
       [ 6  7]]
    
      [[ 3  4]
       [ 8  9]]]
    
    
     [[[11 12]
       [16 17]]
    
      [[13 14]
       [18 19]]]]

    """
    assert a.flags['C_CONTIGUOUS'], "This function relies on the memory layout of the array."
    blockshape = tuple(blockshape)
    outershape = tuple(np.array(a.shape) // blockshape)
    view_shape = outershape + blockshape

    if require_aligned_blocks:
        assert (np.mod(a.shape, blockshape) == 0).all(), \
            "blockshape {} must divide evenly into array shape {}"\
            .format( blockshape, a.shape )

    # inner strides: strides within each block (same as original array)
    intra_block_strides = a.strides

    # outer strides: strides from one block to another
    inter_block_strides = tuple(a.strides * np.array(blockshape))

    # This is where the magic happens.
    # Generate a view with our new strides (outer+inner).
    view = np.lib.stride_tricks.as_strided(a, shape=view_shape, strides=(inter_block_strides + intra_block_strides))

    if aslist:
        return list(map(view.__getitem__, np.ndindex(outershape)))
    return view
QCElemental-0.5.0/qcelemental/util/np_rand3drot.py000066400000000000000000000045261351361252000220710ustar00rootroot00000000000000import numpy as np


def random_rotation_matrix(deflection: float=1.0, randnums=None) -> np.ndarray:
    """Generates a random 3D rotation matrix.

    Parameters
    ----------
    deflection : float, optional
        Magnitude of the rotation. For 0, no rotation; for 1, competely random
        rotation. Small deflection => small perturbation.
    randnums : array, optional
        3 random numbers in the range [0, 1]. If `None`, they will be auto-generated.

    Returns
    -------
    3 x 3 ndarray
        Rotation matrix on random distribution.

    Sources
    -------
    improved: http://demonstrations.wolfram.com/sourcecode.html?demoname=SamplingAUniformlyRandomRotation&demodisplayname=Sampling%20a%20Uniformly%20Random%20Rotation
    py code: from http://blog.lostinmyterminal.com/python/2015/05/12/random-rotation-matrix.html
    c code: from http://www.realtimerendering.com/resources/GraphicsGems/gemsiii/rand_rotation.c
    orig: James Arvo, Graphics Gems III (IBM Version) 1992, Pages 117-120, https://doi.org/10.1016/B978-0-08-050755-2.50034-8

    """
    if randnums is None:
        randnums = np.random.uniform(size=(3, ))

    theta, phi, z = randnums

    # rotation about the pole (Z)
    #   from Wolfram, improved by subtr half so rotation unbiased
    theta = (theta - 1 / 2) * deflection * 2 * np.pi
    # direction of pole deflection
    phi = phi * 2 * np.pi
    # magnitude of pole deflection
    z = z * 2 * deflection

    # Compute a vector V used for distributing points over the sphere
    # via the reflection I - V Transpose(V).  This formulation of V
    # will guarantee that if x[1] and x[2] are uniformly distributed,
    # the reflected points will be uniform on the sphere.  Note that V
    # has length sqrt(2) to eliminate the 2 in the Householder matrix.
    r = np.sqrt(z)
    V = (np.sin(phi) * r, np.cos(phi) * r, np.sqrt(2.0 - z))

    st = np.sin(theta)
    ct = np.cos(theta)

    R = np.array(((ct, st, 0), (-st, ct, 0), (0, 0, 1)))
    R_z_pi = np.diag([-1., -1., 1])

    # Construct the rotation matrix  (V Transpose(V) - I) R. * R_z(pi)
    #   which is equivalent to V.S - R.
    # From Wolfram, Arno's code is missing the multiplication by R_z(pi),
    #   which is unnoticable for random rotations but causes problems
    #   for random perturbations.
    M = (np.outer(V, V) - np.eye(3)).dot(R).dot(R_z_pi)

    return M
QCElemental-0.5.0/qcelemental/util/scipy_hungarian.py000066400000000000000000000244661351361252000226640ustar00rootroot00000000000000# [Apr 2018] stolen directly from scipy so I can get an array back
#   https://github.com/scipy/scipy/blob/master/scipy/optimize/_hungarian.py
# [Apr 2019]
#   * apply MAINT: Switch np.where(c) for np.nonzero(c) 9757612
#   * transpose reduced_cost if cost_matrix had to be transposed

# Hungarian algorithm (Kuhn-Munkres) for solving the linear sum assignment
# problem. Taken from scikit-learn. Based on original code by Brian Clapper,
# adapted to NumPy by Gael Varoquaux.
# Further improvements by Ben Root, Vlad Niculae and Lars Buitinck.
#
# Copyright (c) 2008 Brian M. Clapper , Gael Varoquaux
# Author: Brian M. Clapper, Gael Varoquaux
# License: 3-clause BSD

import numpy as np


def linear_sum_assignment(cost_matrix, return_cost=False):
    """Solve the linear sum assignment problem.

    The linear sum assignment problem is also known as minimum weight matching
    in bipartite graphs. A problem instance is described by a matrix C, where
    each C[i,j] is the cost of matching vertex i of the first partite set
    (a "worker") and vertex j of the second set (a "job"). The goal is to find
    a complete assignment of workers to jobs of minimal cost.

    Formally, let X be a boolean matrix where :math:`X[i,j] = 1` iff row i is
    assigned to column j. Then the optimal assignment has cost

    .. math::
        \\min \\sum_i \\sum_j C_{i,j} X_{i,j}

    s.t. each row is assignment to at most one column, and each column to at
    most one row.

    This function can also solve a generalization of the classic assignment
    problem where the cost matrix is rectangular. If it has more rows than
    columns, then not every row needs to be assigned to a column, and vice
    versa.

    The method used is the Hungarian algorithm, also known as the Munkres or
    Kuhn-Munkres algorithm.

    Parameters
    ----------
    cost_matrix : array
        The cost matrix of the bipartite graph.
    return_cost : bool, optional
        If True, also return a copy of the cost_matrix reduced to maximal
        zeros at the end of the Munkres algorithm.

    Returns
    -------
    row_ind, col_ind : array
        An array of row indices and one of corresponding column indices giving
        the optimal assignment. The cost of the assignment can be computed
        as ``cost_matrix[row_ind, col_ind].sum()``. The row indices will be
        sorted; in the case of a square cost matrix they will be equal to
        ``numpy.arange(cost_matrix.shape[0])``.
    (row_ind, col_ind), cost
        Only provided if `return_cost` is True.

    Notes
    -----
    .. versionadded:: 0.17.0

    Examples
    --------
    >>> cost = np.array([[4, 1, 3], [2, 0, 5], [3, 2, 2]])
    >>> from scipy.optimize import linear_sum_assignment
    >>> row_ind, col_ind = linear_sum_assignment(cost)
    >>> col_ind
    array([1, 0, 2])
    >>> cost[row_ind, col_ind].sum()
    5

    References
    ----------
    1. http://csclab.murraystate.edu/bob.pilgrim/445/munkres.html

    2. Harold W. Kuhn. The Hungarian Method for the assignment problem.
       *Naval Research Logistics Quarterly*, 2:83-97, 1955.

    3. Harold W. Kuhn. Variants of the Hungarian method for assignment
       problems. *Naval Research Logistics Quarterly*, 3: 253-258, 1956.

    4. Munkres, J. Algorithms for the Assignment and Transportation Problems.
       *J. SIAM*, 5(1):32-38, March, 1957.

    5. https://en.wikipedia.org/wiki/Hungarian_algorithm
    """
    cost_matrix = np.asarray(cost_matrix)
    if len(cost_matrix.shape) != 2:
        raise ValueError("expected a matrix (2-d array), got a %r array"
                         % (cost_matrix.shape,))

    if not (np.issubdtype(cost_matrix.dtype, np.number) or
            cost_matrix.dtype == np.dtype(np.bool)):
        raise ValueError("expected a matrix containing numerical entries, got %s"
                         % (cost_matrix.dtype,))

    if np.any(np.isinf(cost_matrix) | np.isnan(cost_matrix)):
        raise ValueError("matrix contains invalid numeric entries")

    if cost_matrix.dtype == np.dtype(np.bool):
        cost_matrix = cost_matrix.astype(np.int)

    # The algorithm expects more columns than rows in the cost matrix.
    if cost_matrix.shape[1] < cost_matrix.shape[0]:
        cost_matrix = cost_matrix.T
        transposed = True
    else:
        transposed = False

    state = _Hungary(cost_matrix)

    # No need to bother with assignments if one of the dimensions
    # of the cost matrix is zero-length.
    step = None if 0 in cost_matrix.shape else _step1

    while step is not None:
        step = step(state)

    if transposed:
        marked = state.marked.T
        reduced_cost = state.C.T
    else:
        marked = state.marked
        reduced_cost = state.C

    if return_cost:
        return np.nonzero(marked == 1), reduced_cost
    else:
        return np.nonzero(marked == 1)


class _Hungary(object):
    """State of the Hungarian algorithm.

    Parameters
    ----------
    cost_matrix : 2D matrix
        The cost matrix. Must have shape[1] >= shape[0].
    """

    def __init__(self, cost_matrix):
        self.C = cost_matrix.copy()

        n, m = self.C.shape
        self.row_uncovered = np.ones(n, dtype=bool)
        self.col_uncovered = np.ones(m, dtype=bool)
        self.Z0_r = 0
        self.Z0_c = 0
        self.path = np.zeros((n + m, 2), dtype=int)
        self.marked = np.zeros((n, m), dtype=int)

    def _clear_covers(self):
        """Clear all covered matrix cells"""
        self.row_uncovered[:] = True
        self.col_uncovered[:] = True


# Individual steps of the algorithm follow, as a state machine: they return
# the next step to be taken (function to be called), if any.

def _step1(state):
    """Steps 1 and 2 in the Wikipedia page."""

    # Step 1: For each row of the matrix, find the smallest element and
    # subtract it from every element in its row.
    state.C -= state.C.min(axis=1)[:, np.newaxis]
    # Step 2: Find a zero (Z) in the resulting matrix. If there is no
    # starred zero in its row or column, star Z. Repeat for each element
    # in the matrix.
    for i, j in zip(*np.nonzero(state.C == 0)):
        if state.col_uncovered[j] and state.row_uncovered[i]:
            state.marked[i, j] = 1
            state.col_uncovered[j] = False
            state.row_uncovered[i] = False

    state._clear_covers()
    return _step3


def _step3(state):
    """
    Cover each column containing a starred zero. If n columns are covered,
    the starred zeros describe a complete set of unique assignments.
    In this case, Go to DONE, otherwise, Go to Step 4.
    """
    marked = (state.marked == 1)
    state.col_uncovered[np.any(marked, axis=0)] = False

    if marked.sum() < state.C.shape[0]:
        return _step4


def _step4(state):
    """
    Find a noncovered zero and prime it. If there is no starred zero
    in the row containing this primed zero, Go to Step 5. Otherwise,
    cover this row and uncover the column containing the starred
    zero. Continue in this manner until there are no uncovered zeros
    left. Save the smallest uncovered value and Go to Step 6.
    """
    # We convert to int as numpy operations are faster on int
    C = (state.C == 0).astype(int)
    covered_C = C * state.row_uncovered[:, np.newaxis]
    covered_C *= np.asarray(state.col_uncovered, dtype=int)
    n = state.C.shape[0]
    m = state.C.shape[1]

    while True:
        # Find an uncovered zero
        row, col = np.unravel_index(np.argmax(covered_C), (n, m))
        if covered_C[row, col] == 0:
            return _step6
        else:
            state.marked[row, col] = 2
            # Find the first starred element in the row
            star_col = np.argmax(state.marked[row] == 1)
            if state.marked[row, star_col] != 1:
                # Could not find one
                state.Z0_r = row
                state.Z0_c = col
                return _step5
            else:
                col = star_col
                state.row_uncovered[row] = False
                state.col_uncovered[col] = True
                covered_C[:, col] = C[:, col] * (
                    np.asarray(state.row_uncovered, dtype=int))
                covered_C[row] = 0


def _step5(state):
    """
    Construct a series of alternating primed and starred zeros as follows.
    Let Z0 represent the uncovered primed zero found in Step 4.
    Let Z1 denote the starred zero in the column of Z0 (if any).
    Let Z2 denote the primed zero in the row of Z1 (there will always be one).
    Continue until the series terminates at a primed zero that has no starred
    zero in its column. Unstar each starred zero of the series, star each
    primed zero of the series, erase all primes and uncover every line in the
    matrix. Return to Step 3
    """
    count = 0
    path = state.path
    path[count, 0] = state.Z0_r
    path[count, 1] = state.Z0_c

    while True:
        # Find the first starred element in the col defined by
        # the path.
        row = np.argmax(state.marked[:, path[count, 1]] == 1)
        if state.marked[row, path[count, 1]] != 1:
            # Could not find one
            break
        else:
            count += 1
            path[count, 0] = row
            path[count, 1] = path[count - 1, 1]

        # Find the first prime element in the row defined by the
        # first path step
        col = np.argmax(state.marked[path[count, 0]] == 2)
        if state.marked[row, col] != 2:
            col = -1
        count += 1
        path[count, 0] = path[count - 1, 0]
        path[count, 1] = col

    # Convert paths
    for i in range(count + 1):
        if state.marked[path[i, 0], path[i, 1]] == 1:
            state.marked[path[i, 0], path[i, 1]] = 0
        else:
            state.marked[path[i, 0], path[i, 1]] = 1

    state._clear_covers()
    # Erase all prime markings
    state.marked[state.marked == 2] = 0
    return _step3


def _step6(state):
    """
    Add the value found in Step 4 to every element of each covered row,
    and subtract it from every element of each uncovered column.
    Return to Step 4 without altering any stars, primes, or covered lines.
    """
    # the smallest uncovered value in the matrix
    if np.any(state.row_uncovered) and np.any(state.col_uncovered):
        minval = np.min(state.C[state.row_uncovered], axis=0)
        minval = np.min(minval[state.col_uncovered])
        state.C[~state.row_uncovered] += minval
        state.C[:, state.col_uncovered] -= minval
    return _step4
QCElemental-0.5.0/qcelemental/util/test_gph_uno_bipartite.py000066400000000000000000000204161351361252000242310ustar00rootroot00000000000000# [Apr 2019]
# * split off from gph_uno_bipartite.py file for test suite. see that file for attributions.
# * AmbiguousSolution errors seem to have cropped up, though not in the alignment usage.

import pytest
from ..tests.addons import using_networkx, using_scipy

from qcelemental.util.gph_uno_bipartite import uno, _enumMaximumMatching, _enumMaximumMatching2


@using_networkx
def test_example4(alg=1):

    edges = [(0, 0),
            (0, 1),
            (1, 5),
            (1, 6),
            (2, 0),
            (2, 1),
            (3, 5),
            (3, 6),
            (4, 2),
            (4, 3),
            (5, 2),
            (5, 3),
            (6, 4),
            (6, 7),
            (7, 4),
            (7, 7)]
    match = [(0, 0), (2, 1), (4, 2), (5, 3), (6, 4), (3, 5), (1, 6), (7, 7)]

    ref = [[(0, 0), (2, 1), (4, 2), (5, 3), (6, 4), (3, 5), (1, 6), (7, 7)],  # ----
           [(0, 1), (2, 0), (4, 2), (5, 3), (6, 4), (3, 5), (1, 6), (7, 7)],  # *---

           [(0, 0), (2, 1), (4, 3), (5, 2), (6, 4), (3, 5), (1, 6), (7, 7)],  # -*--
           [(0, 1), (2, 0), (4, 3), (5, 2), (6, 4), (3, 5), (1, 6), (7, 7)],  # **--

           [(0, 0), (2, 1), (4, 2), (5, 3), (6, 7), (3, 5), (1, 6), (7, 4)],  # --*-
           [(0, 1), (2, 0), (4, 2), (5, 3), (6, 7), (3, 5), (1, 6), (7, 4)],  # *-*-

           [(0, 0), (2, 1), (4, 2), (5, 3), (6, 4), (3, 6), (1, 5), (7, 7)],  # ---*
           [(0, 1), (2, 0), (4, 2), (5, 3), (6, 4), (3, 6), (1, 5), (7, 7)],  # *--*

           [(0, 0), (2, 1), (4, 3), (5, 2), (6, 7), (3, 5), (1, 6), (7, 4)],  # -**-
           [(0, 1), (2, 0), (4, 3), (5, 2), (6, 7), (3, 5), (1, 6), (7, 4)],  # ***-

           [(0, 0), (2, 1), (4, 3), (5, 2), (6, 4), (3, 6), (1, 5), (7, 7)],  # -*-*
           [(0, 1), (2, 0), (4, 3), (5, 2), (6, 4), (3, 6), (1, 5), (7, 7)],  # **-*

           [(0, 0), (2, 1), (4, 3), (5, 2), (6, 7), (3, 6), (1, 5), (7, 4)],  # -***
           [(0, 1), (2, 0), (4, 3), (5, 2), (6, 7), (3, 6), (1, 5), (7, 4)],  # ****

           [(0, 0), (2, 1), (4, 2), (5, 3), (6, 7), (3, 6), (1, 5), (7, 4)],  # --**
           [(0, 1), (2, 0), (4, 2), (5, 3), (6, 7), (3, 6), (1, 5), (7, 4)],  # *-**
        ]
    ref = [sorted(r) for r in ref]

#cost:
# [[ 0.000  0.000  83.505  83.505  53.406  3.378  3.378  53.406]
# [ 3.398  3.398  53.169  53.169  29.828  0.000  0.000  29.828]
# [ 0.000  0.000  83.293  83.293  53.237  3.336  3.336  53.237]
# [ 3.359  3.359  53.323  53.323  29.944  0.000  0.000  29.944]
# [ 83.559  83.559  0.000  0.000  3.372  53.380  53.380  3.372]
# [ 83.297  83.297  0.000  0.000  3.320  53.171  53.171  3.320]
# [ 53.240  53.240  3.379  3.379  0.000  29.830  29.830  0.000]
# [ 53.468  53.468  3.322  3.322  0.000  30.001  30.001  0.000]]
#ptsCR [(0, 0), (2, 1), (4, 2), (5, 3), (6, 4), (3, 5), (1, 6), (7, 7)]

#    ans = uno(edges, verbose=2)
#    _check('Example 4a (internal match)', ans, ref, verbose=2)

    ans = uno(edges, verbose=2, match=match)
    _check('Example 4b (provided match)', ans, ref, verbose=2)


@using_networkx
def test_example3(alg=1):

    match = [(1, 2), (3, 4), (5, 6), (7, 8)]
    edges = [(1, 2),
             (1, 4),
             (1, 6),
             (3, 4),
             (3, 6),
             (3, 8), 
             (5, 6),
             (5, 8),
             (5, 2),
             (7, 8),
             (7, 2),
             (7, 4)]

    ref = [ [(1, 2), (3, 6), (5, 8), (7, 4)],
            [(1, 2), (3, 4), (5, 6), (7, 8)],
            [(1, 2), (3, 8), (5, 6), (7, 4)],
            [(1, 4), (3, 6), (5, 2), (7, 8)],
            [(1, 4), (3, 6), (5, 8), (7, 2)],
            [(1, 4), (3, 8), (5, 6), (7, 2)],
            [(1, 6), (3, 4), (5, 2), (7, 8)],
            [(1, 6), (3, 4), (5, 8), (7, 2)],
            [(1, 6), (3, 8), (5, 2), (7, 4)]]

    ans = uno(edges, verbose=2)
    _check('Example 3a (internal match)', ans, ref)

    ans = uno(edges, verbose=2, match=match)
    _check('Example 3b (provided match)', ans, ref, verbose=2)


def _check(msg, ans, ref, verbose=1):

    tans = [tuple(qw) for qw in ans]
    tref = [tuple(qw) for qw in ref]
    extra_answers = set(tans).difference(set(tref))
    missd_answers = set(tref).difference(set(tans))
    if verbose >= 2:
        for a in tans:
            print('Computed:', a)
        for a in tref:
            print('Supplied:', a)

    assert (extra_answers == set())
    assert (missd_answers == set())
    #    print(msg, 'failed:')
    #    if extra_answers != set():
    #        for a in extra_answers:
    #            print('Incomplete Ref:', a)
    #    if missd_answers != set():
    #        for a in missd_answers:
    #            print('Incomplete Soln:', a)


@using_networkx
@pytest.mark.parametrize("alg", [
    pytest.param(1),
    pytest.param(2, marks=using_scipy),
])
def test_example2(alg):
    """https://mathematica.stackexchange.com/questions/77410/find-all-perfect-matchings-of-a-graph/82893#82893"""
    import networkx as nx

    g = nx.Graph()
    edges = [[(1, 1), (0, 2)],
             [(1, 1), (0, 4)],
             [(1, 1), (0, 6)],
             [(1, 3), (0, 4)],
             [(1, 3), (0, 6)],
             [(1, 3), (0, 8)], 
             [(1, 5), (0, 6)],
             [(1, 5), (0, 8)],
             [(1, 5), (0, 2)],
             [(1, 7), (0, 8)],
             [(1, 7), (0, 2)],
             [(1, 7), (0, 4)]]

#1 <-> 2, 3 <-> 6, 4 <-> 7, 5 <-> 8
#1 <-> 2, 3 <-> 4, 5 <-> 6, 7 <-> 8
#1 <-> 2, 3 <-> 8, 4 <-> 7, 5 <-> 6
#1 <-> 4, 2 <-> 5, 3 <-> 6, 7 <-> 8
#1 <-> 4, 2 <-> 7, 3 <-> 6, 5 <-> 8
#1 <-> 4, 2 <-> 7, 3 <-> 8, 5 <-> 6
#1 <-> 6, 2 <-> 5, 3 <-> 4, 7 <-> 8
#1 <-> 6, 2 <-> 7, 3 <-> 4, 5 <-> 8
#1 <-> 6, 2 <-> 5, 3 <-> 8, 4 <-> 7

#Match2: [(1, 2), (3, 6), (5, 8), (7, 4)]
#Match2: [(1, 2), (3, 4), (5, 6), (7, 8)]
#Match2: [(1, 2), (3, 8), (5, 6), (7, 4)]
#Match2: [(1, 4), (3, 6), (5, 2), (7, 8)]
#Match2: [(1, 4), (3, 6), (5, 8), (7, 2)]
#Match2: [(1, 4), (3, 8), (5, 6), (7, 2)]
#Match2: [(1, 6), (3, 4), (5, 2), (7, 8)]
#Match2: [(1, 6), (3, 4), (5, 8), (7, 2)]
#Match2: [(1, 6), (3, 8), (5, 2), (7, 4)]

    for ii in edges:
        g.add_node(ii[0], bipartite=0)
        g.add_node(ii[1], bipartite=1)

    g.add_edges_from(edges)
    #plotGraph(g)

    if alg == 1:
        all_matches = _enumMaximumMatching(g)
    elif alg == 2:
        all_matches = _enumMaximumMatching2(g)

    ref = [ [(1, 2), (3, 6), (5, 8), (7, 4)],
            [(1, 2), (3, 4), (5, 6), (7, 8)],
            [(1, 2), (3, 8), (5, 6), (7, 4)],
            [(1, 4), (3, 6), (5, 2), (7, 8)],
            [(1, 4), (3, 6), (5, 8), (7, 2)],
            [(1, 4), (3, 8), (5, 6), (7, 2)],
            [(1, 6), (3, 4), (5, 2), (7, 8)],
            [(1, 6), (3, 4), (5, 8), (7, 2)],
            [(1, 6), (3, 8), (5, 2), (7, 4)]]

    for mm in all_matches:
        ans = sorted([(ii[0][1], ii[1][1]) for ii in mm])
        if ans in ref:
            ref.remove(ans)
        print('Match2:', ans)
        g_match = nx.Graph()
        for ii in mm:
            g_match.add_edge(ii[0], ii[1])
        #plotGraph(g_match)

    assert (ref == [])
    print('Example 2 passed')


# Apparently, an AmbiguousSolution
#def test_example1(alg=1):
#    g=nx.Graph()
#    edges=[
#            [(1,0), (0,0)],
#            [(1,0), (0,1)],
#            [(1,0), (0,2)],
#            [(1,1), (0,0)],
#            [(1,2), (0,2)],
#            #[(1,2), (0,5)],
#            [(1,3), (0,2)],
#            #[(1,3), (0,3)],
#            [(1,4), (0,3)],
#            [(1,4), (0,5)],
#            [(1,5), (0,2)],
#            [(1,5), (0,4)],
#            #[(1,5), (0,6)],
#            [(1,6), (0,1)],
#            [(1,6), (0,4)],
#            [(1,6), (0,6)]
#            ]
#
#    for ii in edges:
#        g.add_node(ii[0], bipartite=0)
#        g.add_node(ii[1], bipartite=1)
#        print('  Node:', ii[0], ii[1])
#
#    g.add_edges_from(edges)
#    #plotGraph(g)
#
#    if alg == 1:
#        all_matches = _enumMaximumMatching(g)
#    elif alg == 2:
#        all_matches = _enumMaximumMatching2(g)
#
#    for mm in sorted(all_matches):
#        ans = [(ii[0][1], ii[1][1]) for ii in mm]
#        #print('Match:', mm)
#        print('Match2:', sorted(ans))
#        g_match = nx.Graph()
#        for ii in mm:
#            g_match.add_edge(ii[0], ii[1])
#        #plotGraph(g_match)


# Single-commented actually work
## test_example1(alg=1)
#test_example2(alg=1)
## test_example1(alg=2)
#test_example2(alg=2)
#test_example3(alg=1)
#test_example4(alg=1)
## test_example1(alg=2)
QCElemental-0.5.0/qcelemental/util/test_scipy_hungarian.py000066400000000000000000000056731351361252000237220ustar00rootroot00000000000000# [Apr 2019] stolen directly from scipy so I can test getting an array back
#   https://github.com/scipy/scipy/blob/master/scipy/optimize/tests/test_hungarian.py
#   * change imports to local
#   * skip importing and testing `matrix`
#   * add testing of reduced cost for non-T (reduced matrix for T is different)

# Author: Brian M. Clapper, G. Varoquaux, Lars Buitinck
# License: BSD

from numpy.testing import assert_array_equal
from pytest import raises as assert_raises

import numpy as np

from qcelemental.util.scipy_hungarian import linear_sum_assignment


def test_linear_sum_assignment():
    for cost_matrix, expected_cost, expected_reduced_cost_matrix in [
        # Square
        ([[400, 150, 400],
          [400, 450, 600],
          [300, 225, 300]],
         [150, 400, 300],
         [[250,   0, 175],
          [  0,  50, 125],
          [ 75,   0,   0]]
         ),

        # Rectangular variant
        ([[400, 150, 400, 1],
          [400, 450, 600, 2],
          [300, 225, 300, 3]],
         [150, 2, 300],
         [[102,   0, 102,   0],
          [101, 299, 301,   0],
          [  0,  73,   0,   0]]
         ),

        # Square
        ([[10, 10, 8],
          [9, 8, 1],
          [9, 7, 4]],
         [10, 1, 7],
         [[0, 0, 1],
          [5, 4, 0],
          [2, 0, 0]]
         ),

        # Rectangular variant
        ([[10, 10, 8, 11],
          [9, 8, 1, 1],
          [9, 7, 4, 10]],
         [10, 1, 4],
         [[0, 0, 0, 3],
          [6, 5, 0, 0],
          [3, 1, 0, 6]]
         ),

        # n == 2, m == 0 matrix
        ([[], []],
         [],
         [[], []]),
    ]:
        cost_matrix = np.array(cost_matrix)
        (row_ind, col_ind), reduced_cost_matrix = linear_sum_assignment(cost_matrix, return_cost=True)
        assert_array_equal(row_ind, np.sort(row_ind))
        assert_array_equal(expected_cost, cost_matrix[row_ind, col_ind])
        assert_array_equal(expected_reduced_cost_matrix, reduced_cost_matrix)

        cost_matrix = cost_matrix.T
        row_ind, col_ind = linear_sum_assignment(cost_matrix)
        assert_array_equal(row_ind, np.sort(row_ind))
        assert_array_equal(np.sort(expected_cost),
                           np.sort(cost_matrix[row_ind, col_ind]))


def test_linear_sum_assignment_input_validation():
    assert_raises(ValueError, linear_sum_assignment, [1, 2, 3])

    C = [[1, 2, 3], [4, 5, 6]]
    assert_array_equal(linear_sum_assignment(C),
                       linear_sum_assignment(np.asarray(C)))
    # assert_array_equal(linear_sum_assignment(C),
    #                    linear_sum_assignment(matrix(C)))

    I = np.identity(3)
    assert_array_equal(linear_sum_assignment(I.astype(np.bool)),
                       linear_sum_assignment(I))
    assert_raises(ValueError, linear_sum_assignment, I.astype(str))

    I[0][0] = np.nan
    assert_raises(ValueError, linear_sum_assignment, I)

    I = np.identity(3)
    I[1][1] = np.inf
    assert_raises(ValueError, linear_sum_assignment, I)
QCElemental-0.5.0/readthedocs.yml000066400000000000000000000001311351361252000166470ustar00rootroot00000000000000conda:
    file: docs/requirements.yml
python:
    version: 3
    setup_py_install: true
QCElemental-0.5.0/setup.cfg000066400000000000000000000015621351361252000154710ustar00rootroot00000000000000# Helper file to handle all configs

[coverage:run]
# .coveragerc to control coverage.py and pytest-cov
# Omit the test directory from test coverage
omit =
    */tests/*
    qcelemental/_version.py

[isort]
line_length=120

[yapf]
# YAPF, in .style.yapf files this shows up as "[style]" header
COLUMN_LIMIT = 119
INDENT_WIDTH = 4
USE_TABS = False

[flake8]
# Flake8, PyFlakes, etc
max-line-length = 119

[versioneer]
# Automatic version numbering scheme
VCS = git
style = pep440
versionfile_source = qcelemental/_version.py
versionfile_build = qcelemental/_version.py
tag_prefix = ''

[aliases]
test=pytest

[mypy]

[mypy-numpy]
ignore_missing_imports = True

[mypy-pytest]
ignore_missing_imports = True

[mypy-networkx]
ignore_missing_imports = True

[mypy-pint]
ignore_missing_imports = True

[mypy-mpmath]
ignore_missing_imports = True

[mypy-scipy]
ignore_missing_imports = TrueQCElemental-0.5.0/setup.py000066400000000000000000000044221351361252000153600ustar00rootroot00000000000000import os
import sys
import setuptools
import versioneer

short_description = "QCElemental is a resource module for quantum chemistry containing physical"
"constants and periodic table data from NIST and molecule handlers."

# from https://github.com/pytest-dev/pytest-runner#conditional-requirement
needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
pytest_runner = ['pytest-runner'] if needs_pytest else []

try:
    with open("README.md", "r") as handle:
        long_description = handle.read()
except FileNotFoundError:
    long_description = short_description

if __name__ == "__main__":
    setuptools.setup(
        name='qcelemental',
        description='Essentials for Quantum Chemistry.',
        author='The QCArchive Development Team',
        author_email='qcarchive@molssi.org',
        url="https://github.com/MolSSI/QCElemental",
        license='BSD-3C',
        version=versioneer.get_version(),
        cmdclass=versioneer.get_cmdclass(),
        packages=setuptools.find_packages(exclude=['*checkup*']),
        include_package_data=True,
        package_data={'': [os.path.join('qcelemental', 'data', '*.json')]},
        setup_requires=[] + pytest_runner,
        python_requires='>=3.6',
        install_requires=['numpy', 'pint', 'pydantic >= 0.30.1'],
        extras_require={
            'docs': [
                'numpydoc',
                'sphinx',  # autodoc was broken in 1.3.1
                'sphinxcontrib-napoleon',
                'sphinx_rtd_theme',
            ],
            'tests': [
                'pytest >= 4.0.0',
                'pytest-cov',
            ],
            'align': [
                'networkx',
            ],
            'viz': [
                'py3dmol',
            ],
        },
        tests_require=[
            'pytest >= 3.9.1',
            'pytest-cov',
        ],
        classifiers=[
            'Development Status :: 4 - Beta',
            'Intended Audience :: Science/Research',
            'Programming Language :: Python :: 3 :: Only',
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3.6',
            'Programming Language :: Python :: 3.7',
        ],
        zip_safe=False,
        long_description=long_description,
        long_description_content_type="text/markdown")
QCElemental-0.5.0/versioneer.py000066400000000000000000002060031351361252000164000ustar00rootroot00000000000000
# Version: 0.18

"""The Versioneer - like a rocketeer, but for versions.

The Versioneer
==============

* like a rocketeer, but for versions!
* https://github.com/warner/python-versioneer
* Brian Warner
* License: Public Domain
* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy
* [![Latest Version]
(https://pypip.in/version/versioneer/badge.svg?style=flat)
](https://pypi.python.org/pypi/versioneer/)
* [![Build Status]
(https://travis-ci.org/warner/python-versioneer.png?branch=master)
](https://travis-ci.org/warner/python-versioneer)

This is a tool for managing a recorded version number in distutils-based
python projects. The goal is to remove the tedious and error-prone "update
the embedded version string" step from your release process. Making a new
release should be as easy as recording a new tag in your version-control
system, and maybe making new tarballs.


## Quick Install

* `pip install versioneer` to somewhere to your $PATH
* add a `[versioneer]` section to your setup.cfg (see below)
* run `versioneer install` in your source tree, commit the results

## Version Identifiers

Source trees come from a variety of places:

* a version-control system checkout (mostly used by developers)
* a nightly tarball, produced by build automation
* a snapshot tarball, produced by a web-based VCS browser, like github's
  "tarball from tag" feature
* a release tarball, produced by "setup.py sdist", distributed through PyPI

Within each source tree, the version identifier (either a string or a number,
this tool is format-agnostic) can come from a variety of places:

* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows
  about recent "tags" and an absolute revision-id
* the name of the directory into which the tarball was unpacked
* an expanded VCS keyword ($Id$, etc)
* a `_version.py` created by some earlier build step

For released software, the version identifier is closely related to a VCS
tag. Some projects use tag names that include more than just the version
string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool
needs to strip the tag prefix to extract the version identifier. For
unreleased software (between tags), the version identifier should provide
enough information to help developers recreate the same tree, while also
giving them an idea of roughly how old the tree is (after version 1.2, before
version 1.3). Many VCS systems can report a description that captures this,
for example `git describe --tags --dirty --always` reports things like
"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the
0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has
uncommitted changes.

The version identifier is used for multiple purposes:

* to allow the module to self-identify its version: `myproject.__version__`
* to choose a name and prefix for a 'setup.py sdist' tarball

## Theory of Operation

Versioneer works by adding a special `_version.py` file into your source
tree, where your `__init__.py` can import it. This `_version.py` knows how to
dynamically ask the VCS tool for version information at import time.

`_version.py` also contains `$Revision$` markers, and the installation
process marks `_version.py` to have this marker rewritten with a tag name
during the `git archive` command. As a result, generated tarballs will
contain enough information to get the proper version.

To allow `setup.py` to compute a version too, a `versioneer.py` is added to
the top level of your source tree, next to `setup.py` and the `setup.cfg`
that configures it. This overrides several distutils/setuptools commands to
compute the version when invoked, and changes `setup.py build` and `setup.py
sdist` to replace `_version.py` with a small static file that contains just
the generated version data.

## Installation

See [INSTALL.md](./INSTALL.md) for detailed installation instructions.

## Version-String Flavors

Code which uses Versioneer can learn about its version string at runtime by
importing `_version` from your main `__init__.py` file and running the
`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can
import the top-level `versioneer.py` and run `get_versions()`.

Both functions return a dictionary with different flavors of version
information:

* `['version']`: A condensed version string, rendered using the selected
  style. This is the most commonly used value for the project's version
  string. The default "pep440" style yields strings like `0.11`,
  `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section
  below for alternative styles.

* `['full-revisionid']`: detailed revision identifier. For Git, this is the
  full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac".

* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the
  commit date in ISO 8601 format. This will be None if the date is not
  available.

* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that
  this is only accurate if run in a VCS checkout, otherwise it is likely to
  be False or None

* `['error']`: if the version string could not be computed, this will be set
  to a string describing the problem, otherwise it will be None. It may be
  useful to throw an exception in setup.py if this is set, to avoid e.g.
  creating tarballs with a version string of "unknown".

Some variants are more useful than others. Including `full-revisionid` in a
bug report should allow developers to reconstruct the exact code being tested
(or indicate the presence of local changes that should be shared with the
developers). `version` is suitable for display in an "about" box or a CLI
`--version` output: it can be easily compared against release notes and lists
of bugs fixed in various releases.

The installer adds the following text to your `__init__.py` to place a basic
version in `YOURPROJECT.__version__`:

    from ._version import get_versions
    __version__ = get_versions()['version']
    del get_versions

## Styles

The setup.cfg `style=` configuration controls how the VCS information is
rendered into a version string.

The default style, "pep440", produces a PEP440-compliant string, equal to the
un-prefixed tag name for actual releases, and containing an additional "local
version" section with more detail for in-between builds. For Git, this is
TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags
--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the
tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and
that this commit is two revisions ("+2") beyond the "0.11" tag. For released
software (exactly equal to a known tag), the identifier will only contain the
stripped tag, e.g. "0.11".

Other styles are available. See [details.md](details.md) in the Versioneer
source tree for descriptions.

## Debugging

Versioneer tries to avoid fatal errors: if something goes wrong, it will tend
to return a version of "0+unknown". To investigate the problem, run `setup.py
version`, which will run the version-lookup code in a verbose mode, and will
display the full contents of `get_versions()` (including the `error` string,
which may help identify what went wrong).

## Known Limitations

Some situations are known to cause problems for Versioneer. This details the
most significant ones. More can be found on Github
[issues page](https://github.com/warner/python-versioneer/issues).

### Subprojects

Versioneer has limited support for source trees in which `setup.py` is not in
the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are
two common reasons why `setup.py` might not be in the root:

* Source trees which contain multiple subprojects, such as
  [Buildbot](https://github.com/buildbot/buildbot), which contains both
  "master" and "slave" subprojects, each with their own `setup.py`,
  `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI
  distributions (and upload multiple independently-installable tarballs).
* Source trees whose main purpose is to contain a C library, but which also
  provide bindings to Python (and perhaps other langauges) in subdirectories.

Versioneer will look for `.git` in parent directories, and most operations
should get the right version string. However `pip` and `setuptools` have bugs
and implementation details which frequently cause `pip install .` from a
subproject directory to fail to find a correct version string (so it usually
defaults to `0+unknown`).

`pip install --editable .` should work correctly. `setup.py install` might
work too.

Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in
some later version.

[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking
this issue. The discussion in
[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the
issue from the Versioneer side in more detail.
[pip PR#3176](https://github.com/pypa/pip/pull/3176) and
[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve
pip to let Versioneer work correctly.

Versioneer-0.16 and earlier only looked for a `.git` directory next to the
`setup.cfg`, so subprojects were completely unsupported with those releases.

### Editable installs with setuptools <= 18.5

`setup.py develop` and `pip install --editable .` allow you to install a
project into a virtualenv once, then continue editing the source code (and
test) without re-installing after every change.

"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a
convenient way to specify executable scripts that should be installed along
with the python package.

These both work as expected when using modern setuptools. When using
setuptools-18.5 or earlier, however, certain operations will cause
`pkg_resources.DistributionNotFound` errors when running the entrypoint
script, which must be resolved by re-installing the package. This happens
when the install happens with one version, then the egg_info data is
regenerated while a different version is checked out. Many setup.py commands
cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into
a different virtualenv), so this can be surprising.

[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes
this one, but upgrading to a newer version of setuptools should probably
resolve it.

### Unicode version strings

While Versioneer works (and is continually tested) with both Python 2 and
Python 3, it is not entirely consistent with bytes-vs-unicode distinctions.
Newer releases probably generate unicode version strings on py2. It's not
clear that this is wrong, but it may be surprising for applications when then
write these strings to a network connection or include them in bytes-oriented
APIs like cryptographic checksums.

[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates
this question.


## Updating Versioneer

To upgrade your project to a new release of Versioneer, do the following:

* install the new Versioneer (`pip install -U versioneer` or equivalent)
* edit `setup.cfg`, if necessary, to include any new configuration settings
  indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details.
* re-run `versioneer install` in your source tree, to replace
  `SRC/_version.py`
* commit any changed files

## Future Directions

This tool is designed to make it easily extended to other version-control
systems: all VCS-specific components are in separate directories like
src/git/ . The top-level `versioneer.py` script is assembled from these
components by running make-versioneer.py . In the future, make-versioneer.py
will take a VCS name as an argument, and will construct a version of
`versioneer.py` that is specific to the given VCS. It might also take the
configuration arguments that are currently provided manually during
installation by editing setup.py . Alternatively, it might go the other
direction and include code from all supported VCS systems, reducing the
number of intermediate scripts.


## License

To make Versioneer easier to embed, all its code is dedicated to the public
domain. The `_version.py` that it creates is also in the public domain.
Specifically, both are released under the Creative Commons "Public Domain
Dedication" license (CC0-1.0), as described in
https://creativecommons.org/publicdomain/zero/1.0/ .

"""

from __future__ import print_function
try:
    import configparser
except ImportError:
    import ConfigParser as configparser
import errno
import json
import os
import re
import subprocess
import sys


class VersioneerConfig:
    """Container for Versioneer configuration parameters."""


def get_root():
    """Get the project root directory.

    We require that all commands are run from the project root, i.e. the
    directory that contains setup.py, setup.cfg, and versioneer.py .
    """
    root = os.path.realpath(os.path.abspath(os.getcwd()))
    setup_py = os.path.join(root, "setup.py")
    versioneer_py = os.path.join(root, "versioneer.py")
    if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)):
        # allow 'python path/to/setup.py COMMAND'
        root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
        setup_py = os.path.join(root, "setup.py")
        versioneer_py = os.path.join(root, "versioneer.py")
    if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)):
        err = ("Versioneer was unable to run the project root directory. "
               "Versioneer requires setup.py to be executed from "
               "its immediate directory (like 'python setup.py COMMAND'), "
               "or in a way that lets it use sys.argv[0] to find the root "
               "(like 'python path/to/setup.py COMMAND').")
        raise VersioneerBadRootError(err)
    try:
        # Certain runtime workflows (setup.py install/develop in a setuptools
        # tree) execute all dependencies in a single python process, so
        # "versioneer" may be imported multiple times, and python's shared
        # module-import table will cache the first one. So we can't use
        # os.path.dirname(__file__), as that will find whichever
        # versioneer.py was first imported, even in later projects.
        me = os.path.realpath(os.path.abspath(__file__))
        me_dir = os.path.normcase(os.path.splitext(me)[0])
        vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0])
        if me_dir != vsr_dir:
            print("Warning: build in %s is using versioneer.py from %s"
                  % (os.path.dirname(me), versioneer_py))
    except NameError:
        pass
    return root


def get_config_from_root(root):
    """Read the project setup.cfg file to determine Versioneer config."""
    # This might raise EnvironmentError (if setup.cfg is missing), or
    # configparser.NoSectionError (if it lacks a [versioneer] section), or
    # configparser.NoOptionError (if it lacks "VCS="). See the docstring at
    # the top of versioneer.py for instructions on writing your setup.cfg .
    setup_cfg = os.path.join(root, "setup.cfg")
    parser = configparser.SafeConfigParser()
    with open(setup_cfg, "r") as f:
        parser.readfp(f)
    VCS = parser.get("versioneer", "VCS")  # mandatory

    def get(parser, name):
        if parser.has_option("versioneer", name):
            return parser.get("versioneer", name)
        return None
    cfg = VersioneerConfig()
    cfg.VCS = VCS
    cfg.style = get(parser, "style") or ""
    cfg.versionfile_source = get(parser, "versionfile_source")
    cfg.versionfile_build = get(parser, "versionfile_build")
    cfg.tag_prefix = get(parser, "tag_prefix")
    if cfg.tag_prefix in ("''", '""'):
        cfg.tag_prefix = ""
    cfg.parentdir_prefix = get(parser, "parentdir_prefix")
    cfg.verbose = get(parser, "verbose")
    return cfg


class NotThisMethod(Exception):
    """Exception raised if a method is not valid for the current scenario."""


# these dictionaries contain VCS-specific tools
LONG_VERSION_PY = {}
HANDLERS = {}


def register_vcs_handler(vcs, method):  # decorator
    """Decorator to mark a method as the handler for a particular VCS."""
    def decorate(f):
        """Store f in HANDLERS[vcs][method]."""
        if vcs not in HANDLERS:
            HANDLERS[vcs] = {}
        HANDLERS[vcs][method] = f
        return f
    return decorate


def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
                env=None):
    """Call the given command(s)."""
    assert isinstance(commands, list)
    p = None
    for c in commands:
        try:
            dispcmd = str([c] + args)
            # remember shell=False, so use git.cmd on windows, not just git
            p = subprocess.Popen([c] + args, cwd=cwd, env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=(subprocess.PIPE if hide_stderr
                                         else None))
            break
        except EnvironmentError:
            e = sys.exc_info()[1]
            if e.errno == errno.ENOENT:
                continue
            if verbose:
                print("unable to run %s" % dispcmd)
                print(e)
            return None, None
    else:
        if verbose:
            print("unable to find command, tried %s" % (commands,))
        return None, None
    stdout = p.communicate()[0].strip()
    if sys.version_info[0] >= 3:
        stdout = stdout.decode()
    if p.returncode != 0:
        if verbose:
            print("unable to run %s (error)" % dispcmd)
            print("stdout was %s" % stdout)
        return None, p.returncode
    return stdout, p.returncode


LONG_VERSION_PY['git'] = '''
# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
# directories (produced by setup.py build) will contain a much shorter file
# that just contains the computed version number.

# This file is released into the public domain. Generated by
# versioneer-0.18 (https://github.com/warner/python-versioneer)

"""Git implementation of _version.py."""

import errno
import os
import re
import subprocess
import sys


def get_keywords():
    """Get the keywords needed to look up the version information."""
    # these strings will be replaced by git during git-archive.
    # setup.py/versioneer.py will grep for the variable names, so they must
    # each be defined on a line of their own. _version.py will just call
    # get_keywords().
    git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s"
    git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s"
    git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s"
    keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
    return keywords


class VersioneerConfig:
    """Container for Versioneer configuration parameters."""


def get_config():
    """Create, populate and return the VersioneerConfig() object."""
    # these strings are filled in when 'setup.py versioneer' creates
    # _version.py
    cfg = VersioneerConfig()
    cfg.VCS = "git"
    cfg.style = "%(STYLE)s"
    cfg.tag_prefix = "%(TAG_PREFIX)s"
    cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s"
    cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s"
    cfg.verbose = False
    return cfg


class NotThisMethod(Exception):
    """Exception raised if a method is not valid for the current scenario."""


LONG_VERSION_PY = {}
HANDLERS = {}


def register_vcs_handler(vcs, method):  # decorator
    """Decorator to mark a method as the handler for a particular VCS."""
    def decorate(f):
        """Store f in HANDLERS[vcs][method]."""
        if vcs not in HANDLERS:
            HANDLERS[vcs] = {}
        HANDLERS[vcs][method] = f
        return f
    return decorate


def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
                env=None):
    """Call the given command(s)."""
    assert isinstance(commands, list)
    p = None
    for c in commands:
        try:
            dispcmd = str([c] + args)
            # remember shell=False, so use git.cmd on windows, not just git
            p = subprocess.Popen([c] + args, cwd=cwd, env=env,
                                 stdout=subprocess.PIPE,
                                 stderr=(subprocess.PIPE if hide_stderr
                                         else None))
            break
        except EnvironmentError:
            e = sys.exc_info()[1]
            if e.errno == errno.ENOENT:
                continue
            if verbose:
                print("unable to run %%s" %% dispcmd)
                print(e)
            return None, None
    else:
        if verbose:
            print("unable to find command, tried %%s" %% (commands,))
        return None, None
    stdout = p.communicate()[0].strip()
    if sys.version_info[0] >= 3:
        stdout = stdout.decode()
    if p.returncode != 0:
        if verbose:
            print("unable to run %%s (error)" %% dispcmd)
            print("stdout was %%s" %% stdout)
        return None, p.returncode
    return stdout, p.returncode


def versions_from_parentdir(parentdir_prefix, root, verbose):
    """Try to determine the version from the parent directory name.

    Source tarballs conventionally unpack into a directory that includes both
    the project name and a version string. We will also support searching up
    two directory levels for an appropriately named parent directory
    """
    rootdirs = []

    for i in range(3):
        dirname = os.path.basename(root)
        if dirname.startswith(parentdir_prefix):
            return {"version": dirname[len(parentdir_prefix):],
                    "full-revisionid": None,
                    "dirty": False, "error": None, "date": None}
        else:
            rootdirs.append(root)
            root = os.path.dirname(root)  # up a level

    if verbose:
        print("Tried directories %%s but none started with prefix %%s" %%
              (str(rootdirs), parentdir_prefix))
    raise NotThisMethod("rootdir doesn't start with parentdir_prefix")


@register_vcs_handler("git", "get_keywords")
def git_get_keywords(versionfile_abs):
    """Extract version information from the given file."""
    # the code embedded in _version.py can just fetch the value of these
    # keywords. When used from setup.py, we don't want to import _version.py,
    # so we do it with a regexp instead. This function is not used from
    # _version.py.
    keywords = {}
    try:
        f = open(versionfile_abs, "r")
        for line in f.readlines():
            if line.strip().startswith("git_refnames ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["refnames"] = mo.group(1)
            if line.strip().startswith("git_full ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["full"] = mo.group(1)
            if line.strip().startswith("git_date ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["date"] = mo.group(1)
        f.close()
    except EnvironmentError:
        pass
    return keywords


@register_vcs_handler("git", "keywords")
def git_versions_from_keywords(keywords, tag_prefix, verbose):
    """Get version information from git keywords."""
    if not keywords:
        raise NotThisMethod("no keywords at all, weird")
    date = keywords.get("date")
    if date is not None:
        # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant
        # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601
        # -like" string, which we must then edit to make compliant), because
        # it's been around since git-1.5.3, and it's too difficult to
        # discover which version we're using, or to work around using an
        # older one.
        date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
    refnames = keywords["refnames"].strip()
    if refnames.startswith("$Format"):
        if verbose:
            print("keywords are unexpanded, not using")
        raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
    refs = set([r.strip() for r in refnames.strip("()").split(",")])
    # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
    # just "foo-1.0". If we see a "tag: " prefix, prefer those.
    TAG = "tag: "
    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
    if not tags:
        # Either we're using git < 1.8.3, or there really are no tags. We use
        # a heuristic: assume all version tags have a digit. The old git %%d
        # expansion behaves like git log --decorate=short and strips out the
        # refs/heads/ and refs/tags/ prefixes that would let us distinguish
        # between branches and tags. By ignoring refnames without digits, we
        # filter out many common branch names like "release" and
        # "stabilization", as well as "HEAD" and "master".
        tags = set([r for r in refs if re.search(r'\d', r)])
        if verbose:
            print("discarding '%%s', no digits" %% ",".join(refs - tags))
    if verbose:
        print("likely tags: %%s" %% ",".join(sorted(tags)))
    for ref in sorted(tags):
        # sorting will prefer e.g. "2.0" over "2.0rc1"
        if ref.startswith(tag_prefix):
            r = ref[len(tag_prefix):]
            if verbose:
                print("picking %%s" %% r)
            return {"version": r,
                    "full-revisionid": keywords["full"].strip(),
                    "dirty": False, "error": None,
                    "date": date}
    # no suitable tags, so version is "0+unknown", but full hex is still there
    if verbose:
        print("no suitable tags, using unknown + full revision id")
    return {"version": "0+unknown",
            "full-revisionid": keywords["full"].strip(),
            "dirty": False, "error": "no suitable tags", "date": None}


@register_vcs_handler("git", "pieces_from_vcs")
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
    """Get version from 'git describe' in the root of the source tree.

    This only gets called if the git-archive 'subst' keywords were *not*
    expanded, and _version.py hasn't already been rewritten with a short
    version string, meaning we're inside a checked out source tree.
    """
    GITS = ["git"]
    if sys.platform == "win32":
        GITS = ["git.cmd", "git.exe"]

    out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
                          hide_stderr=True)
    if rc != 0:
        if verbose:
            print("Directory %%s not under git control" %% root)
        raise NotThisMethod("'git rev-parse --git-dir' returned error")

    # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
    # if there isn't one, this yields HEX[-dirty] (no NUM)
    describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty",
                                          "--always", "--long",
                                          "--match", "%%s*" %% tag_prefix],
                                   cwd=root)
    # --long was added in git-1.5.5
    if describe_out is None:
        raise NotThisMethod("'git describe' failed")
    describe_out = describe_out.strip()
    full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
    if full_out is None:
        raise NotThisMethod("'git rev-parse' failed")
    full_out = full_out.strip()

    pieces = {}
    pieces["long"] = full_out
    pieces["short"] = full_out[:7]  # maybe improved later
    pieces["error"] = None

    # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
    # TAG might have hyphens.
    git_describe = describe_out

    # look for -dirty suffix
    dirty = git_describe.endswith("-dirty")
    pieces["dirty"] = dirty
    if dirty:
        git_describe = git_describe[:git_describe.rindex("-dirty")]

    # now we have TAG-NUM-gHEX or HEX

    if "-" in git_describe:
        # TAG-NUM-gHEX
        mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
        if not mo:
            # unparseable. Maybe git-describe is misbehaving?
            pieces["error"] = ("unable to parse git-describe output: '%%s'"
                               %% describe_out)
            return pieces

        # tag
        full_tag = mo.group(1)
        if not full_tag.startswith(tag_prefix):
            if verbose:
                fmt = "tag '%%s' doesn't start with prefix '%%s'"
                print(fmt %% (full_tag, tag_prefix))
            pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'"
                               %% (full_tag, tag_prefix))
            return pieces
        pieces["closest-tag"] = full_tag[len(tag_prefix):]

        # distance: number of commits since tag
        pieces["distance"] = int(mo.group(2))

        # commit: short hex revision ID
        pieces["short"] = mo.group(3)

    else:
        # HEX: no tags
        pieces["closest-tag"] = None
        count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
                                    cwd=root)
        pieces["distance"] = int(count_out)  # total number of commits

    # commit date: see ISO-8601 comment in git_versions_from_keywords()
    date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"],
                       cwd=root)[0].strip()
    pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)

    return pieces


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if "+" in pieces.get("closest-tag", ""):
        return "."
    return "+"


def render_pep440(pieces):
    """Build up version string, with post-release "local version identifier".

    Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
    get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty

    Exceptions:
    1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += plus_or_dot(pieces)
            rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"])
            if pieces["dirty"]:
                rendered += ".dirty"
    else:
        # exception #1
        rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"],
                                          pieces["short"])
        if pieces["dirty"]:
            rendered += ".dirty"
    return rendered


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"]:
            rendered += ".post.dev%%d" %% pieces["distance"]
    else:
        # exception #1
        rendered = "0.post.dev%%d" %% pieces["distance"]
    return rendered


def render_pep440_post(pieces):
    """TAG[.postDISTANCE[.dev0]+gHEX] .

    The ".dev0" means dirty. Note that .dev0 sorts backwards
    (a dirty tree will appear "older" than the corresponding clean one),
    but you shouldn't be releasing software with -dirty anyways.

    Exceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += ".post%%d" %% pieces["distance"]
            if pieces["dirty"]:
                rendered += ".dev0"
            rendered += plus_or_dot(pieces)
            rendered += "g%%s" %% pieces["short"]
    else:
        # exception #1
        rendered = "0.post%%d" %% pieces["distance"]
        if pieces["dirty"]:
            rendered += ".dev0"
        rendered += "+g%%s" %% pieces["short"]
    return rendered


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += ".post%%d" %% pieces["distance"]
            if pieces["dirty"]:
                rendered += ".dev0"
    else:
        # exception #1
        rendered = "0.post%%d" %% pieces["distance"]
        if pieces["dirty"]:
            rendered += ".dev0"
    return rendered


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"]:
            rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"])
    else:
        # exception #1
        rendered = pieces["short"]
    if pieces["dirty"]:
        rendered += "-dirty"
    return rendered


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"])
    else:
        # exception #1
        rendered = pieces["short"]
    if pieces["dirty"]:
        rendered += "-dirty"
    return rendered


def render(pieces, style):
    """Render the given version pieces into the requested style."""
    if pieces["error"]:
        return {"version": "unknown",
                "full-revisionid": pieces.get("long"),
                "dirty": None,
                "error": pieces["error"],
                "date": None}

    if not style or style == "default":
        style = "pep440"  # the default

    if style == "pep440":
        rendered = render_pep440(pieces)
    elif style == "pep440-pre":
        rendered = render_pep440_pre(pieces)
    elif style == "pep440-post":
        rendered = render_pep440_post(pieces)
    elif style == "pep440-old":
        rendered = render_pep440_old(pieces)
    elif style == "git-describe":
        rendered = render_git_describe(pieces)
    elif style == "git-describe-long":
        rendered = render_git_describe_long(pieces)
    else:
        raise ValueError("unknown style '%%s'" %% style)

    return {"version": rendered, "full-revisionid": pieces["long"],
            "dirty": pieces["dirty"], "error": None,
            "date": pieces.get("date")}


def get_versions():
    """Get version information or return default if unable to do so."""
    # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
    # __file__, we can work backwards from there to the root. Some
    # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
    # case we can only use expanded keywords.

    cfg = get_config()
    verbose = cfg.verbose

    try:
        return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
                                          verbose)
    except NotThisMethod:
        pass

    try:
        root = os.path.realpath(__file__)
        # versionfile_source is the relative path from the top of the source
        # tree (where the .git directory might live) to this file. Invert
        # this to find the root from __file__.
        for i in cfg.versionfile_source.split('/'):
            root = os.path.dirname(root)
    except NameError:
        return {"version": "0+unknown", "full-revisionid": None,
                "dirty": None,
                "error": "unable to find root of source tree",
                "date": None}

    try:
        pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
        return render(pieces, cfg.style)
    except NotThisMethod:
        pass

    try:
        if cfg.parentdir_prefix:
            return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
    except NotThisMethod:
        pass

    return {"version": "0+unknown", "full-revisionid": None,
            "dirty": None,
            "error": "unable to compute version", "date": None}
'''


@register_vcs_handler("git", "get_keywords")
def git_get_keywords(versionfile_abs):
    """Extract version information from the given file."""
    # the code embedded in _version.py can just fetch the value of these
    # keywords. When used from setup.py, we don't want to import _version.py,
    # so we do it with a regexp instead. This function is not used from
    # _version.py.
    keywords = {}
    try:
        f = open(versionfile_abs, "r")
        for line in f.readlines():
            if line.strip().startswith("git_refnames ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["refnames"] = mo.group(1)
            if line.strip().startswith("git_full ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["full"] = mo.group(1)
            if line.strip().startswith("git_date ="):
                mo = re.search(r'=\s*"(.*)"', line)
                if mo:
                    keywords["date"] = mo.group(1)
        f.close()
    except EnvironmentError:
        pass
    return keywords


@register_vcs_handler("git", "keywords")
def git_versions_from_keywords(keywords, tag_prefix, verbose):
    """Get version information from git keywords."""
    if not keywords:
        raise NotThisMethod("no keywords at all, weird")
    date = keywords.get("date")
    if date is not None:
        # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
        # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
        # -like" string, which we must then edit to make compliant), because
        # it's been around since git-1.5.3, and it's too difficult to
        # discover which version we're using, or to work around using an
        # older one.
        date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
    refnames = keywords["refnames"].strip()
    if refnames.startswith("$Format"):
        if verbose:
            print("keywords are unexpanded, not using")
        raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
    refs = set([r.strip() for r in refnames.strip("()").split(",")])
    # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
    # just "foo-1.0". If we see a "tag: " prefix, prefer those.
    TAG = "tag: "
    tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
    if not tags:
        # Either we're using git < 1.8.3, or there really are no tags. We use
        # a heuristic: assume all version tags have a digit. The old git %d
        # expansion behaves like git log --decorate=short and strips out the
        # refs/heads/ and refs/tags/ prefixes that would let us distinguish
        # between branches and tags. By ignoring refnames without digits, we
        # filter out many common branch names like "release" and
        # "stabilization", as well as "HEAD" and "master".
        tags = set([r for r in refs if re.search(r'\d', r)])
        if verbose:
            print("discarding '%s', no digits" % ",".join(refs - tags))
    if verbose:
        print("likely tags: %s" % ",".join(sorted(tags)))
    for ref in sorted(tags):
        # sorting will prefer e.g. "2.0" over "2.0rc1"
        if ref.startswith(tag_prefix):
            r = ref[len(tag_prefix):]
            if verbose:
                print("picking %s" % r)
            return {"version": r,
                    "full-revisionid": keywords["full"].strip(),
                    "dirty": False, "error": None,
                    "date": date}
    # no suitable tags, so version is "0+unknown", but full hex is still there
    if verbose:
        print("no suitable tags, using unknown + full revision id")
    return {"version": "0+unknown",
            "full-revisionid": keywords["full"].strip(),
            "dirty": False, "error": "no suitable tags", "date": None}


@register_vcs_handler("git", "pieces_from_vcs")
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
    """Get version from 'git describe' in the root of the source tree.

    This only gets called if the git-archive 'subst' keywords were *not*
    expanded, and _version.py hasn't already been rewritten with a short
    version string, meaning we're inside a checked out source tree.
    """
    GITS = ["git"]
    if sys.platform == "win32":
        GITS = ["git.cmd", "git.exe"]

    out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
                          hide_stderr=True)
    if rc != 0:
        if verbose:
            print("Directory %s not under git control" % root)
        raise NotThisMethod("'git rev-parse --git-dir' returned error")

    # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
    # if there isn't one, this yields HEX[-dirty] (no NUM)
    describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty",
                                          "--always", "--long",
                                          "--match", "%s*" % tag_prefix],
                                   cwd=root)
    # --long was added in git-1.5.5
    if describe_out is None:
        raise NotThisMethod("'git describe' failed")
    describe_out = describe_out.strip()
    full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
    if full_out is None:
        raise NotThisMethod("'git rev-parse' failed")
    full_out = full_out.strip()

    pieces = {}
    pieces["long"] = full_out
    pieces["short"] = full_out[:7]  # maybe improved later
    pieces["error"] = None

    # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
    # TAG might have hyphens.
    git_describe = describe_out

    # look for -dirty suffix
    dirty = git_describe.endswith("-dirty")
    pieces["dirty"] = dirty
    if dirty:
        git_describe = git_describe[:git_describe.rindex("-dirty")]

    # now we have TAG-NUM-gHEX or HEX

    if "-" in git_describe:
        # TAG-NUM-gHEX
        mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
        if not mo:
            # unparseable. Maybe git-describe is misbehaving?
            pieces["error"] = ("unable to parse git-describe output: '%s'"
                               % describe_out)
            return pieces

        # tag
        full_tag = mo.group(1)
        if not full_tag.startswith(tag_prefix):
            if verbose:
                fmt = "tag '%s' doesn't start with prefix '%s'"
                print(fmt % (full_tag, tag_prefix))
            pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
                               % (full_tag, tag_prefix))
            return pieces
        pieces["closest-tag"] = full_tag[len(tag_prefix):]

        # distance: number of commits since tag
        pieces["distance"] = int(mo.group(2))

        # commit: short hex revision ID
        pieces["short"] = mo.group(3)

    else:
        # HEX: no tags
        pieces["closest-tag"] = None
        count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
                                    cwd=root)
        pieces["distance"] = int(count_out)  # total number of commits

    # commit date: see ISO-8601 comment in git_versions_from_keywords()
    date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"],
                       cwd=root)[0].strip()
    pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)

    return pieces


def do_vcs_install(manifest_in, versionfile_source, ipy):
    """Git-specific installation logic for Versioneer.

    For Git, this means creating/changing .gitattributes to mark _version.py
    for export-subst keyword substitution.
    """
    GITS = ["git"]
    if sys.platform == "win32":
        GITS = ["git.cmd", "git.exe"]
    files = [manifest_in, versionfile_source]
    if ipy:
        files.append(ipy)
    try:
        me = __file__
        if me.endswith(".pyc") or me.endswith(".pyo"):
            me = os.path.splitext(me)[0] + ".py"
        versioneer_file = os.path.relpath(me)
    except NameError:
        versioneer_file = "versioneer.py"
    files.append(versioneer_file)
    present = False
    try:
        f = open(".gitattributes", "r")
        for line in f.readlines():
            if line.strip().startswith(versionfile_source):
                if "export-subst" in line.strip().split()[1:]:
                    present = True
        f.close()
    except EnvironmentError:
        pass
    if not present:
        f = open(".gitattributes", "a+")
        f.write("%s export-subst\n" % versionfile_source)
        f.close()
        files.append(".gitattributes")
    run_command(GITS, ["add", "--"] + files)


def versions_from_parentdir(parentdir_prefix, root, verbose):
    """Try to determine the version from the parent directory name.

    Source tarballs conventionally unpack into a directory that includes both
    the project name and a version string. We will also support searching up
    two directory levels for an appropriately named parent directory
    """
    rootdirs = []

    for i in range(3):
        dirname = os.path.basename(root)
        if dirname.startswith(parentdir_prefix):
            return {"version": dirname[len(parentdir_prefix):],
                    "full-revisionid": None,
                    "dirty": False, "error": None, "date": None}
        else:
            rootdirs.append(root)
            root = os.path.dirname(root)  # up a level

    if verbose:
        print("Tried directories %s but none started with prefix %s" %
              (str(rootdirs), parentdir_prefix))
    raise NotThisMethod("rootdir doesn't start with parentdir_prefix")


SHORT_VERSION_PY = """
# This file was generated by 'versioneer.py' (0.18) from
# revision-control system data, or from the parent directory name of an
# unpacked source archive. Distribution tarballs contain a pre-generated copy
# of this file.

import json

version_json = '''
%s
'''  # END VERSION_JSON


def get_versions():
    return json.loads(version_json)
"""


def versions_from_file(filename):
    """Try to determine the version from _version.py if present."""
    try:
        with open(filename) as f:
            contents = f.read()
    except EnvironmentError:
        raise NotThisMethod("unable to read _version.py")
    mo = re.search(r"version_json = '''\n(.*)'''  # END VERSION_JSON",
                   contents, re.M | re.S)
    if not mo:
        mo = re.search(r"version_json = '''\r\n(.*)'''  # END VERSION_JSON",
                       contents, re.M | re.S)
    if not mo:
        raise NotThisMethod("no version_json in _version.py")
    return json.loads(mo.group(1))


def write_to_version_file(filename, versions):
    """Write the given version number to the given _version.py file."""
    os.unlink(filename)
    contents = json.dumps(versions, sort_keys=True,
                          indent=1, separators=(",", ": "))
    with open(filename, "w") as f:
        f.write(SHORT_VERSION_PY % contents)

    print("set %s to '%s'" % (filename, versions["version"]))


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if "+" in pieces.get("closest-tag", ""):
        return "."
    return "+"


def render_pep440(pieces):
    """Build up version string, with post-release "local version identifier".

    Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
    get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty

    Exceptions:
    1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += plus_or_dot(pieces)
            rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
            if pieces["dirty"]:
                rendered += ".dirty"
    else:
        # exception #1
        rendered = "0+untagged.%d.g%s" % (pieces["distance"],
                                          pieces["short"])
        if pieces["dirty"]:
            rendered += ".dirty"
    return rendered


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"]:
            rendered += ".post.dev%d" % pieces["distance"]
    else:
        # exception #1
        rendered = "0.post.dev%d" % pieces["distance"]
    return rendered


def render_pep440_post(pieces):
    """TAG[.postDISTANCE[.dev0]+gHEX] .

    The ".dev0" means dirty. Note that .dev0 sorts backwards
    (a dirty tree will appear "older" than the corresponding clean one),
    but you shouldn't be releasing software with -dirty anyways.

    Exceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += ".post%d" % pieces["distance"]
            if pieces["dirty"]:
                rendered += ".dev0"
            rendered += plus_or_dot(pieces)
            rendered += "g%s" % pieces["short"]
    else:
        # exception #1
        rendered = "0.post%d" % pieces["distance"]
        if pieces["dirty"]:
            rendered += ".dev0"
        rendered += "+g%s" % pieces["short"]
    return rendered


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"] or pieces["dirty"]:
            rendered += ".post%d" % pieces["distance"]
            if pieces["dirty"]:
                rendered += ".dev0"
    else:
        # exception #1
        rendered = "0.post%d" % pieces["distance"]
        if pieces["dirty"]:
            rendered += ".dev0"
    return rendered


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        if pieces["distance"]:
            rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
    else:
        # exception #1
        rendered = pieces["short"]
    if pieces["dirty"]:
        rendered += "-dirty"
    return rendered


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces["closest-tag"]:
        rendered = pieces["closest-tag"]
        rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
    else:
        # exception #1
        rendered = pieces["short"]
    if pieces["dirty"]:
        rendered += "-dirty"
    return rendered


def render(pieces, style):
    """Render the given version pieces into the requested style."""
    if pieces["error"]:
        return {"version": "unknown",
                "full-revisionid": pieces.get("long"),
                "dirty": None,
                "error": pieces["error"],
                "date": None}

    if not style or style == "default":
        style = "pep440"  # the default

    if style == "pep440":
        rendered = render_pep440(pieces)
    elif style == "pep440-pre":
        rendered = render_pep440_pre(pieces)
    elif style == "pep440-post":
        rendered = render_pep440_post(pieces)
    elif style == "pep440-old":
        rendered = render_pep440_old(pieces)
    elif style == "git-describe":
        rendered = render_git_describe(pieces)
    elif style == "git-describe-long":
        rendered = render_git_describe_long(pieces)
    else:
        raise ValueError("unknown style '%s'" % style)

    return {"version": rendered, "full-revisionid": pieces["long"],
            "dirty": pieces["dirty"], "error": None,
            "date": pieces.get("date")}


class VersioneerBadRootError(Exception):
    """The project root directory is unknown or missing key files."""


def get_versions(verbose=False):
    """Get the project version from whatever source is available.

    Returns dict with two keys: 'version' and 'full'.
    """
    if "versioneer" in sys.modules:
        # see the discussion in cmdclass.py:get_cmdclass()
        del sys.modules["versioneer"]

    root = get_root()
    cfg = get_config_from_root(root)

    assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg"
    handlers = HANDLERS.get(cfg.VCS)
    assert handlers, "unrecognized VCS '%s'" % cfg.VCS
    verbose = verbose or cfg.verbose
    assert cfg.versionfile_source is not None, \
        "please set versioneer.versionfile_source"
    assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix"

    versionfile_abs = os.path.join(root, cfg.versionfile_source)

    # extract version from first of: _version.py, VCS command (e.g. 'git
    # describe'), parentdir. This is meant to work for developers using a
    # source checkout, for users of a tarball created by 'setup.py sdist',
    # and for users of a tarball/zipball created by 'git archive' or github's
    # download-from-tag feature or the equivalent in other VCSes.

    get_keywords_f = handlers.get("get_keywords")
    from_keywords_f = handlers.get("keywords")
    if get_keywords_f and from_keywords_f:
        try:
            keywords = get_keywords_f(versionfile_abs)
            ver = from_keywords_f(keywords, cfg.tag_prefix, verbose)
            if verbose:
                print("got version from expanded keyword %s" % ver)
            return ver
        except NotThisMethod:
            pass

    try:
        ver = versions_from_file(versionfile_abs)
        if verbose:
            print("got version from file %s %s" % (versionfile_abs, ver))
        return ver
    except NotThisMethod:
        pass

    from_vcs_f = handlers.get("pieces_from_vcs")
    if from_vcs_f:
        try:
            pieces = from_vcs_f(cfg.tag_prefix, root, verbose)
            ver = render(pieces, cfg.style)
            if verbose:
                print("got version from VCS %s" % ver)
            return ver
        except NotThisMethod:
            pass

    try:
        if cfg.parentdir_prefix:
            ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
            if verbose:
                print("got version from parentdir %s" % ver)
            return ver
    except NotThisMethod:
        pass

    if verbose:
        print("unable to compute version")

    return {"version": "0+unknown", "full-revisionid": None,
            "dirty": None, "error": "unable to compute version",
            "date": None}


def get_version():
    """Get the short version string for this project."""
    return get_versions()["version"]


def get_cmdclass():
    """Get the custom setuptools/distutils subclasses used by Versioneer."""
    if "versioneer" in sys.modules:
        del sys.modules["versioneer"]
        # this fixes the "python setup.py develop" case (also 'install' and
        # 'easy_install .'), in which subdependencies of the main project are
        # built (using setup.py bdist_egg) in the same python process. Assume
        # a main project A and a dependency B, which use different versions
        # of Versioneer. A's setup.py imports A's Versioneer, leaving it in
        # sys.modules by the time B's setup.py is executed, causing B to run
        # with the wrong versioneer. Setuptools wraps the sub-dep builds in a
        # sandbox that restores sys.modules to it's pre-build state, so the
        # parent is protected against the child's "import versioneer". By
        # removing ourselves from sys.modules here, before the child build
        # happens, we protect the child from the parent's versioneer too.
        # Also see https://github.com/warner/python-versioneer/issues/52

    cmds = {}

    # we add "version" to both distutils and setuptools
    from distutils.core import Command

    class cmd_version(Command):
        description = "report generated version string"
        user_options = []
        boolean_options = []

        def initialize_options(self):
            pass

        def finalize_options(self):
            pass

        def run(self):
            vers = get_versions(verbose=True)
            print("Version: %s" % vers["version"])
            print(" full-revisionid: %s" % vers.get("full-revisionid"))
            print(" dirty: %s" % vers.get("dirty"))
            print(" date: %s" % vers.get("date"))
            if vers["error"]:
                print(" error: %s" % vers["error"])
    cmds["version"] = cmd_version

    # we override "build_py" in both distutils and setuptools
    #
    # most invocation pathways end up running build_py:
    #  distutils/build -> build_py
    #  distutils/install -> distutils/build ->..
    #  setuptools/bdist_wheel -> distutils/install ->..
    #  setuptools/bdist_egg -> distutils/install_lib -> build_py
    #  setuptools/install -> bdist_egg ->..
    #  setuptools/develop -> ?
    #  pip install:
    #   copies source tree to a tempdir before running egg_info/etc
    #   if .git isn't copied too, 'git describe' will fail
    #   then does setup.py bdist_wheel, or sometimes setup.py install
    #  setup.py egg_info -> ?

    # we override different "build_py" commands for both environments
    if "setuptools" in sys.modules:
        from setuptools.command.build_py import build_py as _build_py
    else:
        from distutils.command.build_py import build_py as _build_py

    class cmd_build_py(_build_py):
        def run(self):
            root = get_root()
            cfg = get_config_from_root(root)
            versions = get_versions()
            _build_py.run(self)
            # now locate _version.py in the new build/ directory and replace
            # it with an updated value
            if cfg.versionfile_build:
                target_versionfile = os.path.join(self.build_lib,
                                                  cfg.versionfile_build)
                print("UPDATING %s" % target_versionfile)
                write_to_version_file(target_versionfile, versions)
    cmds["build_py"] = cmd_build_py

    if "cx_Freeze" in sys.modules:  # cx_freeze enabled?
        from cx_Freeze.dist import build_exe as _build_exe
        # nczeczulin reports that py2exe won't like the pep440-style string
        # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g.
        # setup(console=[{
        #   "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION
        #   "product_version": versioneer.get_version(),
        #   ...

        class cmd_build_exe(_build_exe):
            def run(self):
                root = get_root()
                cfg = get_config_from_root(root)
                versions = get_versions()
                target_versionfile = cfg.versionfile_source
                print("UPDATING %s" % target_versionfile)
                write_to_version_file(target_versionfile, versions)

                _build_exe.run(self)
                os.unlink(target_versionfile)
                with open(cfg.versionfile_source, "w") as f:
                    LONG = LONG_VERSION_PY[cfg.VCS]
                    f.write(LONG %
                            {"DOLLAR": "$",
                             "STYLE": cfg.style,
                             "TAG_PREFIX": cfg.tag_prefix,
                             "PARENTDIR_PREFIX": cfg.parentdir_prefix,
                             "VERSIONFILE_SOURCE": cfg.versionfile_source,
                             })
        cmds["build_exe"] = cmd_build_exe
        del cmds["build_py"]

    if 'py2exe' in sys.modules:  # py2exe enabled?
        try:
            from py2exe.distutils_buildexe import py2exe as _py2exe  # py3
        except ImportError:
            from py2exe.build_exe import py2exe as _py2exe  # py2

        class cmd_py2exe(_py2exe):
            def run(self):
                root = get_root()
                cfg = get_config_from_root(root)
                versions = get_versions()
                target_versionfile = cfg.versionfile_source
                print("UPDATING %s" % target_versionfile)
                write_to_version_file(target_versionfile, versions)

                _py2exe.run(self)
                os.unlink(target_versionfile)
                with open(cfg.versionfile_source, "w") as f:
                    LONG = LONG_VERSION_PY[cfg.VCS]
                    f.write(LONG %
                            {"DOLLAR": "$",
                             "STYLE": cfg.style,
                             "TAG_PREFIX": cfg.tag_prefix,
                             "PARENTDIR_PREFIX": cfg.parentdir_prefix,
                             "VERSIONFILE_SOURCE": cfg.versionfile_source,
                             })
        cmds["py2exe"] = cmd_py2exe

    # we override different "sdist" commands for both environments
    if "setuptools" in sys.modules:
        from setuptools.command.sdist import sdist as _sdist
    else:
        from distutils.command.sdist import sdist as _sdist

    class cmd_sdist(_sdist):
        def run(self):
            versions = get_versions()
            self._versioneer_generated_versions = versions
            # unless we update this, the command will keep using the old
            # version
            self.distribution.metadata.version = versions["version"]
            return _sdist.run(self)

        def make_release_tree(self, base_dir, files):
            root = get_root()
            cfg = get_config_from_root(root)
            _sdist.make_release_tree(self, base_dir, files)
            # now locate _version.py in the new base_dir directory
            # (remembering that it may be a hardlink) and replace it with an
            # updated value
            target_versionfile = os.path.join(base_dir, cfg.versionfile_source)
            print("UPDATING %s" % target_versionfile)
            write_to_version_file(target_versionfile,
                                  self._versioneer_generated_versions)
    cmds["sdist"] = cmd_sdist

    return cmds


CONFIG_ERROR = """
setup.cfg is missing the necessary Versioneer configuration. You need
a section like:

 [versioneer]
 VCS = git
 style = pep440
 versionfile_source = src/myproject/_version.py
 versionfile_build = myproject/_version.py
 tag_prefix =
 parentdir_prefix = myproject-

You will also need to edit your setup.py to use the results:

 import versioneer
 setup(version=versioneer.get_version(),
       cmdclass=versioneer.get_cmdclass(), ...)

Please read the docstring in ./versioneer.py for configuration instructions,
edit setup.cfg, and re-run the installer or 'python versioneer.py setup'.
"""

SAMPLE_CONFIG = """
# See the docstring in versioneer.py for instructions. Note that you must
# re-run 'versioneer.py setup' after changing this section, and commit the
# resulting files.

[versioneer]
#VCS = git
#style = pep440
#versionfile_source =
#versionfile_build =
#tag_prefix =
#parentdir_prefix =

"""

INIT_PY_SNIPPET = """
from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
"""


def do_setup():
    """Main VCS-independent setup function for installing Versioneer."""
    root = get_root()
    try:
        cfg = get_config_from_root(root)
    except (EnvironmentError, configparser.NoSectionError,
            configparser.NoOptionError) as e:
        if isinstance(e, (EnvironmentError, configparser.NoSectionError)):
            print("Adding sample versioneer config to setup.cfg",
                  file=sys.stderr)
            with open(os.path.join(root, "setup.cfg"), "a") as f:
                f.write(SAMPLE_CONFIG)
        print(CONFIG_ERROR, file=sys.stderr)
        return 1

    print(" creating %s" % cfg.versionfile_source)
    with open(cfg.versionfile_source, "w") as f:
        LONG = LONG_VERSION_PY[cfg.VCS]
        f.write(LONG % {"DOLLAR": "$",
                        "STYLE": cfg.style,
                        "TAG_PREFIX": cfg.tag_prefix,
                        "PARENTDIR_PREFIX": cfg.parentdir_prefix,
                        "VERSIONFILE_SOURCE": cfg.versionfile_source,
                        })

    ipy = os.path.join(os.path.dirname(cfg.versionfile_source),
                       "__init__.py")
    if os.path.exists(ipy):
        try:
            with open(ipy, "r") as f:
                old = f.read()
        except EnvironmentError:
            old = ""
        if INIT_PY_SNIPPET not in old:
            print(" appending to %s" % ipy)
            with open(ipy, "a") as f:
                f.write(INIT_PY_SNIPPET)
        else:
            print(" %s unmodified" % ipy)
    else:
        print(" %s doesn't exist, ok" % ipy)
        ipy = None

    # Make sure both the top-level "versioneer.py" and versionfile_source
    # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so
    # they'll be copied into source distributions. Pip won't be able to
    # install the package without this.
    manifest_in = os.path.join(root, "MANIFEST.in")
    simple_includes = set()
    try:
        with open(manifest_in, "r") as f:
            for line in f:
                if line.startswith("include "):
                    for include in line.split()[1:]:
                        simple_includes.add(include)
    except EnvironmentError:
        pass
    # That doesn't cover everything MANIFEST.in can do
    # (http://docs.python.org/2/distutils/sourcedist.html#commands), so
    # it might give some false negatives. Appending redundant 'include'
    # lines is safe, though.
    if "versioneer.py" not in simple_includes:
        print(" appending 'versioneer.py' to MANIFEST.in")
        with open(manifest_in, "a") as f:
            f.write("include versioneer.py\n")
    else:
        print(" 'versioneer.py' already in MANIFEST.in")
    if cfg.versionfile_source not in simple_includes:
        print(" appending versionfile_source ('%s') to MANIFEST.in" %
              cfg.versionfile_source)
        with open(manifest_in, "a") as f:
            f.write("include %s\n" % cfg.versionfile_source)
    else:
        print(" versionfile_source already in MANIFEST.in")

    # Make VCS-specific changes. For git, this means creating/changing
    # .gitattributes to mark _version.py for export-subst keyword
    # substitution.
    do_vcs_install(manifest_in, cfg.versionfile_source, ipy)
    return 0


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open("setup.py", "r") as f:
        for line in f.readlines():
            if "import versioneer" in line:
                found.add("import")
            if "versioneer.get_cmdclass()" in line:
                found.add("cmdclass")
            if "versioneer.get_version()" in line:
                found.add("get_version")
            if "versioneer.VCS" in line:
                setters = True
            if "versioneer.versionfile_source" in line:
                setters = True
    if len(found) != 3:
        print("")
        print("Your setup.py appears to be missing some important items")
        print("(but I might be wrong). Please make sure it has something")
        print("roughly like the following:")
        print("")
        print(" import versioneer")
        print(" setup( version=versioneer.get_version(),")
        print("        cmdclass=versioneer.get_cmdclass(),  ...)")
        print("")
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print("now lives in setup.cfg, and should be removed from setup.py")
        print("")
        errors += 1
    return errors


if __name__ == "__main__":
    cmd = sys.argv[1]
    if cmd == "setup":
        errors = do_setup()
        errors += scan_setup_py()
        if errors:
            sys.exit(1)