Giter VIP home page Giter VIP logo

qcelemental's Introduction

QCElemental

Build Status codecov Documentation Status Chat on Slack python

Documentation: GitHub Pages

Core data structures for Quantum Chemistry. QCElemental also contains 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) in a renewable manner (class around NIST-published JSON file).

This project also contains a generator, validator, and translator for Molecule QCSchema.

✨ Getting Started

  • Installation. QCElemental supports Python 3.7+.

    python -m pip install qcelemental
  • To install QCElemental with molecule visualization capabilities (useful in iPython or Jupyter notebook environments):

    python -m pip install 'qcelemental[viz]`
  • To install QCElemental with various alignment capabilities using networkx

    python -m pip install 'qcelemental[align]`
  • Or install both:

    python -m pip install 'qcelemental[viz,align]`
  • See documentation

Periodic Table

A variety of periodic table quantities are available using virtually any alias:

>>> 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:

>>> 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.label
'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, arbitrary conversion factors can be obtained:

>>> 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 (details).

>>> 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).dict()
{'numeric': True, 'label': 'I', 'units': 'angstrom', 'data': Decimal('1.39'), 'comment': 'e.s.d.=3 n=451', 'doi': 'DOI: 10.1039/b801115j'}

van der Waals Radii

Van der Waals radii are accessible for most of the periodic table from Mantina, J. Phys. Chem. A (2009) doi: 10.1021/jp8111556 (details).

>>> import qcelemental as qcel
>>> qcel.vdwradii.get('I')
3.7416577284064996
>>> qcel.vdwradii.get('I', units='angstrom')
1.98
>>> qcel.vdwradii.get(116)
Traceback (most recent call last):
...
qcelemental.exceptions.DataUnavailableError: ('vanderwaals radius', 'Lv')
>>> qcel.vdwradii.get('iodine', return_tuple=True).dict()
{'numeric': True, 'label': 'I', 'units': 'angstrom', 'data': Decimal('1.98'), 'doi': 'DOI: 10.1021/jp8111556'}

qcelemental's People

Contributors

ahurta92 avatar awvwgk avatar bennybp avatar coltonbh avatar dgasmith avatar dotsdl avatar eljost avatar ffangliu avatar hannahbrucemacdonald avatar haozeke avatar jthorton avatar laurennk avatar lgtm-com[bot] avatar lnaden avatar loriab avatar mattwelborn avatar mattwthompson avatar muammar avatar philipmnel avatar psi-rking avatar robertodr avatar sgreene8 avatar sheepforce avatar simonboothroyd avatar sinamostafanejad avatar sjrl avatar tuckerburgin avatar tybalduf avatar wardlt avatar zhi-wang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qcelemental's Issues

Tests fail

==================================== ERRORS ====================================
___________________ ERROR at setup of test_from_file_string ____________________
file /build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py, line 155
  def test_from_file_string(tmp_path):
E       fixture 'tmp_path' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, cov, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py:155
____________________ ERROR at setup of test_from_file_json _____________________
file /build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py, line 166
  def test_from_file_json(tmp_path):
E       fixture 'tmp_path' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, cov, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py:166
____________________ ERROR at setup of test_from_file_numpy ____________________
file /build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py, line 175
  def test_from_file_numpy(tmp_path):
E       fixture 'tmp_path' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, cov, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/build/BUILD/QCElemental-0.3.0/qcelemental/tests/test_molecule.py:175
=================================== FAILURES ===================================
__________________________ test_to_string_error[inp0] __________________________

inp = ('subject1', {'atom_format': '{elea}{elem}{elbl}', 'dtype': 'xyz', 'prec': 8, 'units': 'kg'})

    @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):
E       AttributeError: module 'pint' has no attribute 'errors'

qcelemental/tests/test_molparse_to_string.py:111: AttributeError
___________ test_unit_conversion_nist[hartree-Hz-6.579683920711e15] ____________

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'hartree', to_unit = 'Hz', expected = Decimal('6.579683920711E+15')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
____________ test_unit_conversion_nist[amu-hartree-3.4231776902e7] _____________

self = <Quantity(1.0, 'atomic_mass_unit')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'amu', to_unit = 'hartree', expected = Decimal('34231776.902')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'atomic_mass_unit')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
_________ test_unit_conversion_nist[hartree-kilogram-4.850870129e-35] __________

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'hartree', to_unit = 'kilogram'
expected = Decimal('4.850870129E-35')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
________ test_unit_conversion_nist[hartree-wavenumber-2.194746313702e5] ________

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'hartree', to_unit = 'wavenumber'
expected = Decimal('219474.6313702')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
____________ test_unit_conversion_nist[hartree-kelvin-3.1577513e5] _____________

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'hartree', to_unit = 'kelvin', expected = Decimal('315775.13')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
_________ test_unit_conversion_nist[millihartree-Hz-6.579683920711e9] __________

self = <Quantity(1.0, 'millihartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'millihartree', to_unit = 'Hz', expected = Decimal('6579683920.711')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'millihartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
___________ test_unit_conversion_nist[mhartree-Hz-6.579683920711e9] ____________

self = <Quantity(1.0, 'millihartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'mhartree', to_unit = 'Hz', expected = Decimal('6579683920.711')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'millihartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
_________ test_unit_conversion_nist[hartree-microgram-4.850870129e-26] _________

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'hartree', to_unit = 'microgram'
expected = Decimal('4.850870129E-26')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'hartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
_____ test_unit_conversion_nist[microhartree-wavenumber-2.194746313702e-7] _____

self = <Quantity(1.0, 'microhartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'microhartree', to_unit = 'wavenumber'
expected = Decimal('2.194746313702E-7')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'microhartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
_______ test_unit_conversion_nist[uhartree-wavenumber-2.194746313702e-7] _______

self = <Quantity(1.0, 'microhartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = 'uhartree', to_unit = 'wavenumber'
expected = Decimal('2.194746313702E-7')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, 'microhartree')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
______________ test_unit_conversion_nist[1/m-hartree-4.556335e-8] ______________

self = <Quantity(1.0, '1 / meter')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
>           return getattr(self._magnitude, item)
E           AttributeError: 'float' object has no attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1000: AttributeError

During handling of the above exception, another exception occurred:

from_unit = '1/m', to_unit = 'hartree', expected = Decimal('4.556335E-8')

    @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)

qcelemental/tests/test_units.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
qcelemental/physical_constants/context.py:230: in conversion_factor
    return self.ureg.convert(factor, base_unit, conv_unit)
/usr/lib/python3.7/site-packages/pint/unit.py:1031: in convert
    src = self._active_ctx.transform(a, b, self, src)
/usr/lib/python3.7/site-packages/pint/context.py:246: in transform
    return self[(src, dst)].transform(src, dst, registry, value)
/usr/lib/python3.7/site-packages/pint/context.py:193: in transform
    return self.funcs[_key](registry, value, **self.defaults)
qcelemental/physical_constants/ureg.py:120: in transformer
    left_unit = _find_nist_unit(val)
qcelemental/physical_constants/ureg.py:94: in _find_nist_unit
    for value in unit.to_tuple()[1]:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Quantity(1.0, '1 / meter')>, item = 'to_tuple'

    def __getattr__(self, item):
        # Attributes starting with `__array_` are common attributes of NumPy ndarray.
        # They are requested by numpy functions.
        if item.startswith('__array_'):
            if isinstance(self._magnitude, ndarray):
                return getattr(self._magnitude, item)
            else:
                # If an `__array_` attributes is requested but the magnitude is not an ndarray,
                # we convert the magnitude to a numpy ndarray.
                self._magnitude = _to_magnitude(self._magnitude, force_ndarray=True)
                return getattr(self._magnitude, item)
        elif item in self.__handled:
            if not isinstance(self._magnitude, ndarray):
                self._magnitude = _to_magnitude(self._magnitude, True)
            attr = getattr(self._magnitude, item)
            if callable(attr):
                return functools.partial(self.__numpy_method_wrap, attr)
            return attr
        try:
            return getattr(self._magnitude, item)
        except AttributeError as ex:
            raise AttributeError("Neither Quantity object nor its magnitude ({0})"
>                                "has attribute '{1}'".format(self._magnitude, item))
E           AttributeError: Neither Quantity object nor its magnitude (1.0)has attribute 'to_tuple'

/usr/lib/python3.7/site-packages/pint/quantity.py:1003: AttributeError
========== 12 failed, 507 passed, 2 xpassed, 3 error in 16.57 seconds ==========

Result --> SingleResult

So we've got

  • OptimizationInput/Optimization
  • ResultInput/Result

And in another project, I've got the potential for

  • FindifResultInput/FindifResult
  • CBSResultInput/CBSResult

etc. The optimization pair doesn't particularly signal "schema" to me. And it might be convenient to distinguish between the set of *ResultInput/*Result pairs and the particular energy/gradient/hessian calc that ResultInput/Result now represents.

It is suggested that the two first items above become the below so that the * of *ResultInput/*Result is never the empty string.

  • OptimizationResultInput/OptimizationResult
  • SingleResultInput/SingleResult (AnalyticResult?)

Please weigh in on this change, even if it's just an up/down emoji response.

Tests not working

Packaging QCElemental in Fedora to update to Psi4 1.3 I get

Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.1xi4Zs
+ umask 022
+ cd /home/jzlehtol/rpmbuild/BUILD
+ cd qcelemental-0.2.5
+ /usr/bin/python3 setup.py test
/usr/lib/python3.7/site-packages/setuptools/dist.py:398: UserWarning: Normalizing 'v0.2.5' to '0.2.5'
  normalized_version,
running test
running egg_info
writing qcelemental.egg-info/PKG-INFO
writing dependency_links to qcelemental.egg-info/dependency_links.txt
writing requirements to qcelemental.egg-info/requires.txt
writing top-level names to qcelemental.egg-info/top_level.txt
reading manifest file 'qcelemental.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '*.json' under directory 'qcelemental'
warning: no previously-included files matching '*.py' found under directory 'qcelemental/checkup_data'
warning: no previously-included files matching '*.md' found under directory 'qcelemental/checkup_data'
writing manifest file 'qcelemental.egg-info/SOURCES.txt'
running build_ext
Traceback (most recent call last):
  File "setup.py", line 57, in <module>
    long_description_content_type="text/markdown"
  File "/usr/lib/python3.7/site-packages/setuptools/__init__.py", line 140, in setup
    return distutils.core.setup(**attrs)
  File "/usr/lib64/python3.7/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/lib64/python3.7/distutils/dist.py", line 966, in run_commands
    self.run_command(cmd)
  File "/usr/lib64/python3.7/distutils/dist.py", line 985, in run_command
    cmd_obj.run()
  File "/usr/lib/python3.7/site-packages/setuptools/command/test.py", line 228, in run
    self.run_tests()
  File "/usr/lib/python3.7/site-packages/setuptools/command/test.py", line 250, in run_tests
    exit=False,
  File "/usr/lib64/python3.7/unittest/main.py", line 100, in __init__
    self.parseArgs(argv)
  File "/usr/lib64/python3.7/unittest/main.py", line 124, in parseArgs
    self._do_discovery(argv[2:])
  File "/usr/lib64/python3.7/unittest/main.py", line 244, in _do_discovery
    self.createTests(from_discovery=True, Loader=Loader)
  File "/usr/lib64/python3.7/unittest/main.py", line 154, in createTests
    self.test = loader.discover(self.start, self.pattern, self.top)
  File "/usr/lib64/python3.7/unittest/loader.py", line 347, in discover
    tests = list(self._find_tests(start_dir, pattern))
  File "/usr/lib64/python3.7/unittest/loader.py", line 404, in _find_tests
    full_path, pattern, namespace)
  File "/usr/lib64/python3.7/unittest/loader.py", line 481, in _find_test_path
    tests = self.loadTestsFromModule(package, pattern=pattern)
  File "/usr/lib/python3.7/site-packages/setuptools/command/test.py", line 54, in loadTestsFromModule
    tests.append(self.loadTestsFromName(submodule))
  File "/usr/lib64/python3.7/unittest/loader.py", line 191, in loadTestsFromName
    return self.loadTestsFromModule(obj)
  File "/usr/lib/python3.7/site-packages/setuptools/command/test.py", line 54, in loadTestsFromModule
    tests.append(self.loadTestsFromName(submodule))
  File "/usr/lib64/python3.7/unittest/loader.py", line 214, in loadTestsFromName
    raise TypeError("don't know how to make test from: %s" % obj)
TypeError: don't know how to make test from: {'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'}}}
error: Bad exit status from /var/tmp/rpm-tmp.1xi4Zs (%check)

Non-contiguous Fragments

Currently reading non-schema into the internal QCElemental format may reorder the symbols. It would be good not to do a reorder unless explicitly requested.

Bootcamp: Changeset 8

diff --git a/qcelemental/models/common_models.py b/qcelemental/models/common_models.py
index 58c3d5c..e98c791 100644
--- a/qcelemental/models/common_models.py
+++ b/qcelemental/models/common_models.py
@@ -3,6 +3,7 @@ from typing import Any, Dict, Optional
 
 import numpy as np
 
+from pydantic import Schema
 from .basemodels import ProtoModel
 
 # Encoders, to be deprecated
@@ -44,9 +45,19 @@ class DriverEnum(str, Enum):
 
 class ComputeError(ProtoModel):
     """The type of error message raised"""
-    error_type: str  # Error enumeration not yet strict
-    error_message: str
-    extras: Optional[Dict[str, Any]] = None
+    error_type: str = Schema(  # Error enumeration not yet strict
+        ...,
+        description="The type of error which was thrown. Restrict this field short classifiers e.g. 'input_error'"
+    )
+    error_message: str = Schema(
+        ...,
+        description="Text associated with the thrown error, often the backtrace, but can contain additional "
+                    "information as well."
+    )
+    extras: Optional[Dict[str, Any]] = Schema(
+        None,
+        description="Additional data to ship with the ComputeError object."
+    )
 
 
 class FailedOperation(ProtoModel):

Bootcamp: Changeset 5

diff --git a/qcelemental/covalent_radii.py b/qcelemental/covalent_radii.py
index 5d7ab98..65d138a 100644
--- a/qcelemental/covalent_radii.py
+++ b/qcelemental/covalent_radii.py
@@ -21,20 +21,24 @@ class CovalentRadii:

     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.
+    doi : str
+        The DOI of the current context.
+    name : str
+        The name of the context ('ALVAREZ2008')
+    native_units : str
+        The units the original data was provided in.
     year : int
         The year the context was created.

     """

-    def __init__(self, context="ALVAREZ2008"):
+    def __init__(self, context: str="ALVAREZ2008"):
         self.cr = collections.OrderedDict()

         from .data import alvarez_2008_covalent_radii
@@ -64,7 +68,7 @@ class CovalentRadii:
             ident, units, value, comment = alias
             self.cr[ident.capitalize()] = Datum(ident, units, value, comment=comment)

-    def __str__(self):
+    def __str__(self) -> str:
         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']:

dev wishlist

(a-d) try out ghost atom round-tripping through mol.to_string() for various programs
(e) I’ve got a vdW radii for all main groups that I collected last week. it needs a front-end interface in imitation of covalent radii
(f) I’ve also got a partial vdW radii from gamess that Asim uses for RESP that needs some reference checks and can be an alternate vdW context

  • I hear scipy is getting a c-based Hungarian algorithm. the slight extension qcel has (extra return quantity and accompanying tests) can be propsed to scipy
  • could distribute tests into subfolders, though it’s tricky for some of the molecules ones
  • quick Cartesian findif
  • prepare models dir for more schema — official opt, vib, findif. later will be cbs, nbody
  • current pubchem lets us get away w/o dependencies but https://pubchempy.readthedocs.io/en/latest/ might be better or alternate

Testing complex numbers

I am using the testing functionality within Psi4 and I am running into this warning when using compare_arrays:

 /home/roberto/Workspace/robertodr/psi4/build_xtensor/stage/lib/qcelemental/testing.py:106: ComplexWarning: Casting complex values to real discards the imaginary part
  xptd, cptd = np.array(expected, dtype=np.float), np.array(computed, dtype=np.float)

for complex numbers this is unwanted, as I'd like to test that both real and imaginary parts are as expected.

I changed that line to:

xptd, cptd = np.array(expected, dtype=expected.dtype), np.array(computed, dtype=computed.dtype)

though it doesn't seem exactly correct to do this. Probably a check that the types match between expected and computed should be done before checking that the actual values match.

@loriab suggested getting rid of this line https://github.com/MolSSI/QCElemental/blob/master/qcelemental/datum.py#L47 but the warning still pops up.

Bootcamp: Changeset 7

diff --git a/qcelemental/models/common_models.py b/qcelemental/models/common_models.py
index 58c3d5c..d8d1bd5 100644
--- a/qcelemental/models/common_models.py
+++ b/qcelemental/models/common_models.py
@@ -3,6 +3,7 @@ from typing import Any, Dict, Optional
 
 import numpy as np
 
+from pydantic import Schema
 from .basemodels import ProtoModel
 
 # Encoders, to be deprecated
@@ -19,8 +20,18 @@ class Provenance(ProtoModel):
 
 
 class Model(ProtoModel):
-    method: str
-    basis: Optional[str] = None
+    """
+    The quantum chemistry model specification for a given operation to compute against
+    """
+    method: str = Schema(
+        ...,
+        description="The quantum chemistry method to evaluate (e.g., B3LYP, PBE, ...)."
+    )
+    basis: Optional[str] = Schema(
+        None,
+        description="The quantum chemistry basis set to evaluate (e.g., 6-31g, cc-pVDZ, ...). Can be ``None`` for "
+                    "methods without basis sets."
+    )
 
     # basis_spec: BasisSpec = None  # This should be exclusive with basis, but for now will be omitted
 

Allow to skip test cases that download data

Some build environments (like Ubuntu autobuilders) have internet firewalled off to ensure that the build process is self-contained. In cases like this, quite a few test cases seem to fail because they try to download stuff.

So it would be convenient if there was an option or switch to skip those tests.

Molecule Hashable

Add a Molecule "hashable" field to prevent hash generation and rounding.

Test errors on Fedora rawhide

QCElemental has been finally approved as a Fedora package, so that I can update Psi4 to the 1.3 series.

Unfortunately, there are some test errors in the build, all of them arising from the same line

==================================== ERRORS ====================================
_____________ ERROR collecting qcelemental/molutil/test_molutil.py _____________
qcelemental/molutil/test_molutil.py:73: in <module>
    chiral = qcel.models.Molecule.from_data(
qcelemental/models/molecule.py:759: in from_data
    input_dict = to_schema(mol_dict["qm"], dtype=2)
qcelemental/molparse/to_schema.py:48: in to_schema
    geom = geom * constants.conversion_factor(molrec["units"], units)
qcelemental/physical_constants/context.py:258: in conversion_factor
    base_unit = self.ureg.parse_expression(base_unit)
qcelemental/physical_constants/context.py:157: in ureg
    self._ureg = build_units_registry(self)
qcelemental/physical_constants/ureg.py:162: in build_units_registry
    ureg.enable_contexts(c1, c2, c3, c4, c5)
/usr/lib/python3.8/site-packages/pint/registry.py:1108: in enable_contexts
    for (src, dst), func in ctx.funcs.items():
E   RuntimeError: dictionary keys changed during iteration

rejigger errors

The psi4-originated parts of qcel raised ValidationErrors in general. But that's pydantic's pet error, too, so the former got backed away to ValueErrors. But maybe not enough, hence #42 (comment) . Go through and unify error handling (w/o forgetting the docstrings) so that we're not catching generic Exceptions.

orientation and ordering in get_fragment

The get_fragment() fn has been working nicely for fractal fragment filtering for a while. It has two issues:

  • (a) the returned mol always has real frags first, followed by ghosted frags. so if enough things match, get_fragment(1, 0) and be the same mol (down to atom ordering) as get_fragment(0, 1). this will surprise users of psi4.Molecule.extract_subsets() who expect fragment ordering to be preserved. The latter behavior is being implemented in #74.

  • (b) the current fn comes with an orient=False default. But that's not getting passed through to anywhere, so probably default False is imposed. Easy to pass this flag along but probably should be careful of downstream.

Should molecular formulas be Hill-ordered?

Describe the bug
Molecular formulas (Molecule.get_molecular_formula) are currently alphabetically ordered. Should they be Hill ordered?

Additional context
This would require a data migration in Fractal.

Hill order: the number of carbon atoms in a molecule is indicated first, the number of hydrogen atoms next, and then the number of all other chemical elements subsequently, in alphabetical order of the chemical symbols. When the formula contains no carbon, all the elements, including hydrogen, are listed alphabetically.

Native Molecule Hashing

Is your feature request related to a problem? Please describe.
mol1 == mol2 should use get_hash() not whatever comparison is native to Pydantic.

Describe the solution you'd like
Override __hash__ in Molecule to call get_hash() and maybe deprecate that function so that hash(Molecule) works just as well.

@mattwelborn

Bootcamp: Changeset 6

diff --git a/qcelemental/covalent_radii.py b/qcelemental/covalent_radii.py
index 5d7ab98..7b6014b 100644
--- a/qcelemental/covalent_radii.py
+++ b/qcelemental/covalent_radii.py
@@ -64,10 +64,11 @@ class CovalentRadii:
             ident, units, value, comment = alias
             self.cr[ident.capitalize()] = Datum(ident, units, value, comment=comment)

-    def __str__(self):
+    def __str__(self) -> str:
         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']:
+    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
@@ -123,12 +124,12 @@ class CovalentRadii:
         else:
             return qca.to_units(units)

-    def string_representation(self):
+    def string_representation(self) -> str:
         """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):
+    def write_c_header(self, filename: str = 'covrad.h', missing: float = 2.0) -> None:
         """Write C header file defining covalent radii array.

         Parameters

Molecule.to_file() should support file-like objects

Is your feature request related to a problem? Please describe.
Currently, writing many molecules to a file requires (1) conversion to JSON as a string, then (2) writing the string to a file.

Describe the solution you'd like
Molecule supports the from_file() method, but its argument currently only accepts filename strings. Adding support for file-like objects would make it much more flexible in being able to flush its serialized contents to a file that is already open, or gzipped, etc.

Describe alternatives you've considered
This would purely be a convenience feature.

Bootcamp: Changesset 3

diff --git a/qcelemental/physical_constants/context.py b/qcelemental/physical_constants/context.py
index 22a1911..f19403a 100644
--- a/qcelemental/physical_constants/context.py
+++ b/qcelemental/physical_constants/context.py
@@ -21,6 +21,8 @@ class PhysicalConstantsContext:

     Attributes
     ----------
+    doi : str
+        The DOI of the current context.
     name : str
         The name of the context ('CODATA2014')
     pc : dict of Datum
@@ -29,9 +31,10 @@ class PhysicalConstantsContext:
         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.
+    raw_codata : Dict[str, Any]
+        A dictionary representation of the raw context data.
     year : int
         The year the context was created.
-
     """

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

ProtoModel.parse_raw should try everything if encoding==None

Currently, when encoding==None, the encoding is determined to be JSON if the datatype is str and MsgPack if the datatype is bytes. This issue proposes to just try all of the parsers for datatypes supported by QCElemental, e.g.:

data = None
for parser in [yaml_parser, msgpack_parser, json_parser]:
    try:
        data = parser(blob)
        break
    except ParserError:
        pass
else:
    raise TypeError("Cannot parse blob")

Additionally, if parse_file cannot determine datatype, it should call parse_raw with encoding=None rather than raising.

This issue blocks MolSSI/QCEngine#136.

Bootcamp: Changesset 2

diff --git a/qcelemental/periodic_table.py b/qcelemental/periodic_table.py
index ccf4d5a..18a2db6 100644
--- a/qcelemental/periodic_table.py
+++ b/qcelemental/periodic_table.py
@@ -421,8 +421,14 @@ class PeriodicTable:
                 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."""
+    def write_c_header(self, filename: str = 'masses.h') -> None:
+        """Write C header file defining arrays of mass and element information.
+
+        Parameters
+        ----------
+        filename : str, optional
+            The filename to write to.
+        """

         text = [
             '#ifndef _qcelemental_masses_h_', '#define _qcelemental_masses_h_', '',

Flaky tests

Describe the bug
Pubchem tests occasionally fail on CI.

Expected behavior
Pubchem tests should always pass to ensure CI is stable.

Additional context

We could consider a pytest wrapper like the following:

@pytest.mark.flaky(reruns=5)
def test_example():
    import random
    assert random.choice([True, False])

From this pytest module. Not an overwhelming fan of adding a new test depends, but could help. Also we could make with an xfail, but I feel this is dangerous.

hbar in constants

@dgasmith Also, how would you feel about adding all of the atomic units with generic names (e.g. au_distance, au_charge, au_energy) just to make it easy on people so they don't have to remember Bohr, e, Hartree etc.?

That's strange, I commented on this this afternoon, but it's disappeared. I'll try to remember what I wrote:

  • The aliases that are there grandfathered from psi4. I don't object to more (and hbar is a good candidate) but I'd like to gather opinions about whether we should be free or sparing with them.
  • Associated is that I aliased the codata 2014 constant names into 2018. how far to we wwant to continue this? 2014 to 2022 or just 2018 to 2022
  • Note that codata 2018 changed some units from s to Hz
  • Note that the constants haven't been systematically fed into pint. there's some it may not recognize: GeV, T (period)

Conversion from bohr to angstrom does not work with CODATA2018

Describe the bug

Using CODATA2018 conversion from bohr to Angstrom seems to be broken.

To Reproduce

>>> import qcelemental as qcel; print(qcel.__file__, qcel.__version__)
/home/kjellgren/miniconda3/lib/python3.7/site-packages/qcelemental/__init__.py v0.13.1

A minimal not-working example is:

>>> import qcelemental
>>> constants2018 = qcelemental.PhysicalConstantsContext('CODATA2018')
>>> print(constants2018.conversion_factor('bohr', 'angstrom'))
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-1-a84be772d51b> in <module>
      3 print(constants.conversion_factor('bohr', 'angstrom'))
      4 constants2018 = qcelemental.PhysicalConstantsContext('CODATA2018')
----> 5 print(constants2018.conversion_factor('bohr', 'angstrom'))

~/miniconda3/lib/python3.7/site-packages/qcelemental/physical_constants/context.py in conversion_factor(self, base_unit, conv_unit)
    316         # First make sure we either have Units or Quantities
    317         if isinstance(base_unit, str):
--> 318             base_unit = self.ureg.parse_expression(base_unit)
    319 
    320         if isinstance(conv_unit, str):

~/miniconda3/lib/python3.7/site-packages/qcelemental/physical_constants/context.py in ureg(self)
    215         """
    216         if self._ureg is None:
--> 217             self._ureg = build_units_registry(self)
    218 
    219         return self._ureg

~/miniconda3/lib/python3.7/site-packages/qcelemental/physical_constants/ureg.py in build_units_registry(context)
     77     }
     78     for k, v in phys_const_map.items():
---> 79         ureg.define(f"{k} = {phys_const[v]['value']} * {phys_const[v]['unit']}")
     80 
     81     ureg.define(f"au_pressure = au_energy / au_length**3")  # not in CODATA

KeyError: 'atomic unit of mom.um'

Expected behavior

It is expected that the above code should print a number around 0.52917721067, i.e. work as:

>>> from qcelemental import constants
>>> print(constants.conversion_factor('bohr', 'angstrom'))
0.52917721067

But using CODATA2018 instead of CODATA2014 (as the above code).

Bootcamp: Changeset 4

diff --git a/qcelemental/physical_constants/context.py b/qcelemental/physical_constants/context.py
index 22a1911..71b58e4 100644
--- a/qcelemental/physical_constants/context.py
+++ b/qcelemental/physical_constants/context.py
@@ -106,7 +106,7 @@ class PhysicalConstantsContext:
             callname = qca.label.translate(self._transtable)
             setattr(self, callname, float(qca.data))

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

     @property
@@ -238,7 +238,7 @@ class PhysicalConstantsContext:

         return print_variables(self.pc)

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

         try:
@@ -270,8 +270,19 @@ class PhysicalConstantsContext:
                     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)."""
+    def _get_pi(self, from_scratch: bool = False) -> 'Decimal':
+        """Get pi to 36 digits (or more with mpmath).
+
+        Parameters
+        ----------
+        from_scratch : bool, optional
+            If True, recomputes Pi from mpmath.
+
+        Returns
+        -------
+        Decimal
+            A representation of Pi
+        """

         if from_scratch:  # pragma: no cover
             from mpmath import mp

Nglview renders molecule incorrectly

Describe the bug
A benzene molecule is rendered incorrectly in Jupyter.
image

To Reproduce
nglview-sdf string:

"""
QCElemental

 12 12  0  0  0  0  0  0  0  0  0
   -36.7161    41.9528   -36.0171 C   0  0     0  0  0  0  0  0
   -36.0692    41.9257   -34.7771 C   0  0     0  0  0  0  0  0
   -36.8074    41.7153   -33.6075 C   0  0     0  0  0  0  0  0
   -38.1924    41.5319   -33.6781 C   0  0     0  0  0  0  0  0
   -38.8393    41.5589   -34.9181 C   0  0     0  0  0  0  0  0
   -38.1012    41.7694   -36.0877 C   0  0     0  0  0  0  0  0
   -36.1398    42.1171   -36.9301 H   0  0     0  0  0  0  0  0
   -34.9879    42.0689   -34.7220 H   0  0     0  0  0  0  0  0
   -36.3024    41.6941   -32.6394 H   0  0     0  0  0  0  0  0
   -38.7687    41.3675   -32.7651 H   0  0     0  0  0  0  0  0
   -39.9206    41.4158   -34.9732 H   0  0     0  0  0  0  0  0
   -38.6062    41.7906   -37.0558 H   0  0     0  0  0  0  0  0
  1  2  1  0  0  0  0
  1  6  1  0  0  0  0
  1  7  1  0  0  0  0
  2  3  1  0  0  0  0
  2  8  1  0  0  0  0
  3  4  1  0  0  0  0
  3  9  1  0  0  0  0
  4  5  1  0  0  0  0
  4 10  1  0  0  0  0
  5  6  1  0  0  0  0
  5 11  1  0  0  0  0
  6 12  1  0  0  0  0
"""

Additional context

  • qcelemental version 0.11.1
  • nglview version 2.7.1

Sparse Molecules

Is your feature request related to a problem? Please describe.
Molecules are typically 3x as heavy as they need to be as many items like mass/real/isotope are generally needed. This causes issues on both object creation speed and serialized size at a number of layers.

Describe alternatives you've considered
Several options are possible:

  • Molecule.mass = None all values are defaulted to None instead of created values. We could have a create/strip functions that would fill/remove these fields on the fly. .dict() would remove all created fields in the serialization.
  • Molecule.mass is a lazy evaluated field unless provided. This may not be possible due to metaclass issues, but worth a try.
  • We have a SimpleMolecule class which contains a subset of Molecule fields. Not my favorite solution, but a quick one.

This is becomes a fairly serious issue for the Database and handling large numbers of Molecules.

@loriab @mattwelborn

Some elements missing in /util

Tried to import QCElemental/models/molecule.py but I got a complaint since it's not being able to find measure_coordinates, provenance_stamp and which_import which are not located in the util folder.

symmetry in qca

Is your feature request related to a problem? Please describe.

Opening for long-term consideration. Issue is more appropriate for QCEngine but sol'n would probably be in QCElemental.

There are procedures that need a bit of symmetry help, and their numbers are growing. Presently, they tend to be tied to Psi4's libmints by a line or two.

Describe the solution you'd like

As far as at-hand solutions, I do have the point group analysis from psi4 (from psi3, from NIH) in python, from whence it could be detached from the qcdb.Molecule class where it resides. The SALCs, iirc from last check, need an extra file or two translated from libmints. These could be cleaned up for qcel. Symmetry identification is all PG. SALCs are Abelian only.

Non-QCA alternative is that I do the SALC libmints to py translation sometime and these procedures still derive from qcng.ProcedureHarness but have a qcdb dependence.

Describe alternatives you've considered

Additional context

fyi, @psi-rking @AlexHeide

Testing utilities

I was adding some features to Engine and it occurred to me that some testing features are quite useful in the ecosystem such as this CLI testing tool. What do we think about adding several testing utilities here that do not depend on libraries outside of standard Python.

I worry a bit that QCElemental will become a general dumping ground if we keep adding things here arbitrarily however. Too many modules is problematic, too few that do too many things is also an issue. Where do we draw the line?

If possible I would like to keep the depends of the library as the following:

  • NumPy
  • Pint
  • pydantic

to keep the footprint pretty small.

Clarify NIST license

I was under the impression that the NIST CODATA is in the public domain, but I could not find any good pointers to that on https://www.nist.gov/srd. The only thing I could find is https://www.nist.gov/srd/public-law which is troublesome and not open data / open source, so if the data used by QCElemental is under that license, it is unclear whether QCElemental could be shipped by Linux distributions like Debian or Red Hat that require Open Source.

The top-level LICENSE file does not seem to cover that so it would be good if that could be clarified.

Bootcamp: Changeset 9

diff --git a/qcelemental/models/common_models.py b/qcelemental/models/common_models.py
index 58c3d5c..ebb23d6 100644
--- a/qcelemental/models/common_models.py
+++ b/qcelemental/models/common_models.py
@@ -3,6 +3,7 @@ from typing import Any, Dict, Optional
 
 import numpy as np
 
+from pydantic import Schema
 from .basemodels import ProtoModel
 
 # Encoders, to be deprecated
@@ -50,11 +51,37 @@ class ComputeError(ProtoModel):
 
 
 class FailedOperation(ProtoModel):
-    id: str = None
-    input_data: Any = None
-    success: bool = False
-    error: ComputeError
-    extras: Optional[Dict[str, Any]] = None
+    """
+    A record indicating that a given operation (compute, procedure, etc.) has failed and contains the reason and
+    input data which generated the failure.
+
+    """
+    id: str = Schema(
+        None,
+        description="A unique identifier which links this FailedOperation, often of the same Id of the operation "
+                    "should it have been successful. This will often be set programmatically by a database such as "
+                    "Fractal."
+    )
+    input_data: Any = Schema(
+        None,
+        description="The input data which was passed in that generated this failure. This should be the complete "
+                    "input which when attempted to be run, caused the operation to fail."
+    )
+    success: bool = Schema(
+        False,
+        description="A boolean indicator that the operation failed consistent with the model of successful operations. "
+                    "Should always be False. Allows programmatic assessment of all operations a"
+    )
+    error: ComputeError = Schema(
+        ...,
+        description="A container which has details of the error that failed this operation. See the "
+                    ":class:`ComputeError` for more details."
+    )
+    extras: Optional[Dict[str, Any]] = Schema(
+        None,
+        description="Additional information to bundle with this Failed Operation. Details which pertain specifically "
+                    "to a thrown error should be contained in the `error` field. See :class:`ComputeError` for details."
+    )
 
 
 qcschema_input_default = "qcschema_input"

Codecov report combining

At the moment, Codecov reports are not correctly merging resulting in a lower coverage status than is truly available. Unsure why this is as all reports are uploaded correctly, it looks like only the first report is correctly merged.

A small hunch is that the git SHA is not correctly being uploaded from all reports.

dummy

poking to test slack integration

optimize PT storage

Right now, Z, E, A, EA, EE lists and dicts are being stored on self of PeriodicTable. Figure out what's optimal to store vs zip-and-lookup at runtime.

add center_of_mass function

We needed this yesterday on models.Molecule. Posting it in case anyone wants a starter project. Should test on example that does and doesn't have fix_com set. (True should give origin.)

INFO: no py38

No, we can't use Python 3.8 for a bit until a tweak goes into pint, hgrecco/pint#842. Symptom: RuntimeError: dictionary keys changed during iteration.

Bootcamp: Changesset 1

diff --git a/qcelemental/periodic_table.py b/qcelemental/periodic_table.py
index ccf4d5a..c81db3a 100644
--- a/qcelemental/periodic_table.py
+++ b/qcelemental/periodic_table.py
@@ -178,19 +178,13 @@ class PeriodicTable:

         Parameters
         ----------
-        atom : int or str
+        atom : Union[int, 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]

Adding Common Thermochemistry Functions

Is your feature request related to a problem? Please describe.
I am taking the results of QCEngine calculations and using them to compute thermodynamic properties. Would QCElemental be a good home for them?

Describe the solution you'd like
Ability to take a QCEngine AtomicResult and compute thermodynamic properties.

Describe alternatives you've considered
I have implemented some in another project

Additional context
Has someone else already done this?

Clarify qcelemental/checkup_data/{physconst,periodictable}.py license

Those two files have a Psi4 license header, is that intended? I guess it makes sense as they might have been copied over from Psi4, but maybe it would be better to check with the Psi4 project whether they/you are fine with relinquishing that copyright and just have it be the top-level LICENSE.md?

Molecule masses from symbol issue

Describe the bug
Nucleon symbols and values are in the periodictable information, but do not propagate their values into a Molecules mass. For example symbol D or He3 do not correctly review masses of 2 or 3, respectively.

To Reproduce

>>> qcel.models.Molecule(symbols=["He3"], geometry=[0,0,0]).masses
array([4.00260325413])

Expected behavior
The mass of the Helium3 to be 3 and change.

Additional context
The issues comes from reconcile_nucleus where everything is validated off of atomic number rather than the input symbol. This looks like a non trivial fix to that logic.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.