コード例 #1
0
def skip_if_missing(package_name: str, reason: Optional[str] = None):
    """
    Helper function to generate a pytest.mark.skipif decorator
    for any package. This allows tests to be skipped if some
    optional dependency is not found.

    Parameters
    ----------
    package_name : str
        The name of the package that is required for a test(s)
    reason : str, optional
        Explanation of why the skipped it to be tested

    Returns
    -------
    requires_package : _pytest.mark.structures.MarkDecorator
        A pytest decorator that will skip tests if the package is not available
    """
    import pytest

    if not reason:
        reason = f"Package {package_name} is required, but was not found."
    requires_package = pytest.mark.skipif(not has_package(package_name),
                                          reason=reason)
    return requires_package
コード例 #2
0
 def validate_type(cls, val):
     """Process an array tagged with units into one tagged with "OpenFF" style units"""
     unit_ = getattr(cls, "__unit__", Any)
     if unit_ is Any:
         if isinstance(val, (list, np.ndarray)):
             # TODO: Can this exception be raised with knowledge of the field it's in?
             raise MissingUnitError(
                 f"Value {val} needs to be tagged with a unit"
             )
         elif isinstance(val, unit.Quantity):
             # Redundant cast? Maybe this handles pint vs openff.interchange.unit?
             return unit.Quantity(val)
         elif isinstance(val, simtk_unit.Quantity):
             return _from_omm_quantity(val)
         else:
             raise UnitValidationError(
                 f"Could not validate data of type {type(val)}"
             )
     else:
         unit_ = unit(unit_)
         if isinstance(val, unit.Quantity):
             assert unit_.dimensionality == val.dimensionality
             return val.to(unit_)
         if isinstance(val, simtk_unit.Quantity):
             return _from_omm_quantity(val).to(unit_)
         if isinstance(val, (np.ndarray, list)):
             if has_package("unyt"):
                 # Must check for unyt_array, not unyt_quantity, which is a subclass
                 if isinstance(val, unyt.unyt_array):
                     return _from_unyt_quantity(val).to(unit_)
                 else:
                     return val * unit_
             else:
                 return val * unit_
         if isinstance(val, bytes):
             # Define outside loop
             dt = np.dtype(int)
             dt.newbyteorder("<")
             return np.frombuffer(val, dtype=dt) * unit_
         if isinstance(val, str):
             # could do custom deserialization here?
             raise NotImplementedError
             #  return unit.Quantity(val).to(unit_)
         raise UnitValidationError(
             f"Could not validate data of type {type(val)}"
         )
コード例 #3
0
 def validate_type(cls, val):
     """Process a value tagged with units into one tagged with "OpenFF" style units"""
     unit_ = getattr(cls, "__unit__", Any)
     if unit_ is Any:
         if isinstance(val, (float, int)):
             # TODO: Can this exception be raised with knowledge of the field it's in?
             raise MissingUnitError(f"Value {val} needs to be tagged with a unit")
         elif isinstance(val, unit.Quantity):
             return unit.Quantity(val)
         elif isinstance(val, simtk_unit.Quantity):
             return _from_omm_quantity(val)
         else:
             raise UnitValidationError(
                 f"Could not validate data of type {type(val)}"
             )
     else:
         unit_ = unit(unit_)
         if isinstance(val, unit.Quantity):
             # some custom behavior could go here
             assert unit_.dimensionality == val.dimensionality
             # return through converting to some intended default units (taken from the class)
             return val.to(unit_)
             # could return here, without converting
             # (could be inconsistent with data model - heteregenous but compatible units)
             # return val
         if isinstance(val, simtk_unit.Quantity):
             return _from_omm_quantity(val).to(unit_)
         if has_package("unyt"):
             if isinstance(val, unyt.unyt_quantity):
                 return _from_unyt_quantity(val).to(unit_)
         if isinstance(val, (float, int)) and not isinstance(val, bool):
             return val * unit_
         if isinstance(val, str):
             # could do custom deserialization here?
             return unit.Quantity(val).to(unit_)
         raise UnitValidationError(f"Could not validate data of type {type(val)}")
コード例 #4
0
from typing import TYPE_CHECKING

from openff.toolkit.topology import Molecule, Topology
from openff.utilities.utilities import has_package, requires_package
from simtk import unit

if has_package("mbuild") or TYPE_CHECKING:
    import mbuild as mb


@requires_package("mbuild")
def offmol_to_compound(off_mol: "Molecule") -> "mb.Compound":
    """Covert an OpenFF Molecule into an mBuild Compound.

    Examples
    --------

    .. code-block:: pycon

        >>> from openff.toolkit.topology import Molecule
        >>> from openff.interchange.components.mbuild import offmol_to_compound
        >>> mol = Molecule.from_smiles("CCO")
        >>> compound = offmol_to_compound(mol)
        >>> type(compound), compound.n_particles, compound.n_bonds
        (<class 'mbuild.compound.Compound'>, 9, 8)

    """
    if not off_mol.has_unique_atom_names:
        off_mol.generate_unique_atom_names()

    if off_mol.n_conformers == 0:
コード例 #5
0
import json
from typing import TYPE_CHECKING, Any, Dict

import numpy as np
from openff.units import unit
from openff.utilities.utilities import has_package, requires_package
from simtk import unit as simtk_unit

from openff.interchange.exceptions import (
    MissingUnitError,
    UnitValidationError,
    UnsupportedExportError,
)

if TYPE_CHECKING or has_package("unyt"):
    import unyt


class _FloatQuantityMeta(type):
    def __getitem__(self, t):
        return type("FloatQuantity", (FloatQuantity,), {"__unit__": t})


class FloatQuantity(float, metaclass=_FloatQuantityMeta):
    @classmethod
    def __get_validators__(cls):
        yield cls.validate_type

    @classmethod
    def validate_type(cls, val):
        """Process a value tagged with units into one tagged with "OpenFF" style units"""
コード例 #6
0
def test_has_executable():
    assert has_executable("pwd")
    assert has_executable("pytest")
    assert not has_package("pyyyyython")
コード例 #7
0
def test_has_package():
    assert has_package("os")
    assert has_package("pytest")
    assert not has_package("nummmmmmpy")
コード例 #8
0
@skip_if_missing("openeye.oechem")
@pytest.mark.skipif("OE_LICENSE" in os.environ,
                    reason="Requires an OpenEye license is NOT set up")
def test_requires_oe_module_installed_missing_license():
    """Tests that the ``requires_package`` utility behaves as expected while OpenEye toolkits are
    installed but no OpenEye license is set up."""
    def dummy_function():
        pass

    with pytest.raises(MissingOptionalDependencyError) as error_info:
        requires_oe_module("oechem")(dummy_function)()

    assert "oechem" in str(error_info.value)
    assert "conda-forge" not in str(error_info.value)


@pytest.mark.skipif(has_package("openeye.oechem"),
                    reason="Requires OpenEye toolkits are NOT installed")
def test_requires_oe_module_not_installed():
    """Tests that the ``requires_package`` utility behaves as expected while OpenEye toolkits are
    installed."""
    def dummy_function():
        pass

    with pytest.raises(MissingOptionalDependencyError) as error_info:
        requires_oe_module("oechem")(dummy_function)()

    assert "oechem" in str(error_info.value)
    assert "conda-forge" not in str(error_info.value)
コード例 #9
0
from openff.utilities.utilities import has_package

from openff.interchange.components.potentials import Potential, PotentialHandler
from openff.interchange.models import PotentialKey, TopologyKey
from openff.interchange.types import FloatQuantity

if TYPE_CHECKING:
    from foyer.forcefield import Forcefield
    from foyer.topology_graph import TopologyGraph

    from openff.interchange.components.mdtraj import OFFBioTop

# Is this the safest way to achieve PotentialKey id separation?
POTENTIAL_KEY_SEPARATOR = "-"

if has_package("foyer"):
    from foyer.topology_graph import TopologyGraph  # noqa


def _copy_params(params: Dict[str, float],
                 *drop_keys: str,
                 param_units: Dict = None) -> Dict:
    """copy parameters from a dictionary"""
    params_copy = copy(params)
    for drop_key in drop_keys:
        params_copy.pop(drop_key, None)
    if param_units:
        for unit_item, units in param_units.items():
            params_copy[unit_item] = params_copy[unit_item] * units
    return params_copy