Skip to content

Commit

Permalink
noncontig passthrough
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Nov 11, 2022
1 parent 292350f commit 0cc6ee9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
10 changes: 9 additions & 1 deletion qcelemental/models/molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,22 @@ def __init__(self, orient: bool = False, validate: Optional[bool] = None, **kwar
# original_keys = set(kwargs.keys()) # revive when ready to revisit sparsity

nonphysical = kwargs.pop("nonphysical", False)
throw_reorder = not (kwargs.pop("allow_noncontiguous_but_reorder", False)) # experimental
schema = to_schema(
from_schema(kwargs, nonphysical=nonphysical), dtype=kwargs["schema_version"], copy=False, np_out=True
from_schema(kwargs, nonphysical=nonphysical, throw_reorder=throw_reorder),
dtype=kwargs["schema_version"],
copy=False,
np_out=True,
)
schema = _filter_defaults(schema)

kwargs["validated"] = True
kwargs = {**kwargs, **schema} # Allow any extra fields
validate = True
else:
# these kwargs only relevant for validation
kwargs.pop("nonphysical", None)
kwargs.pop("allow_noncontiguous_but_reorder", None)

super().__init__(**kwargs)

Expand Down
8 changes: 6 additions & 2 deletions qcelemental/molparse/from_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .from_arrays import from_arrays


def from_schema(molschema: Dict, *, nonphysical: bool = False, verbose: int = 1) -> Dict:
def from_schema(molschema: Dict, *, nonphysical: bool = False, throw_reorder: bool = True, verbose: int = 1) -> Dict:
r"""Construct molecule dictionary representation from non-Psi4 schema.
Parameters
Expand All @@ -16,6 +16,10 @@ def from_schema(molschema: Dict, *, nonphysical: bool = False, verbose: int = 1)
Dictionary form of Molecule following known schema.
nonphysical
Do allow masses outside an element's natural range to pass validation?
throw_reorder
Do, when non-contiguous fragments detected, raise
ValidationError (``True``) or to proceed to reorder atoms to
contiguize fragments (``False``).
verbose
Amount of printing.
Expand Down Expand Up @@ -54,7 +58,7 @@ def from_schema(molschema: Dict, *, nonphysical: bool = False, verbose: int = 1)
mass=ms.get("masses", None),
real=ms.get("real", None),
elbl=ms.get("atom_labels", None),
throw_reorder=True,
throw_reorder=throw_reorder,
)

molrec = from_arrays(
Expand Down
32 changes: 32 additions & 0 deletions qcelemental/tests/test_molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,38 @@ def test_charged_fragment():
# })


@pytest.mark.parametrize(
"validate, allow_noncontiguous_but_reorder", [(True, True), (True, False), (False, True), (False, False)]
)
def test_noncontig(validate, allow_noncontiguous_but_reorder):
mol = {
"fragments": [[2, 0], [1]],
"geometry": np.array([[0.0, 0.0, 1.0], [0.0, 0.0, 2.0], [0.0, 0.0, 0.0]]),
"symbols": np.array(["Li", "H", "He"]),
"fragment_multiplicities": [4, 2],
}

if validate:
if allow_noncontiguous_but_reorder:
mol = Molecule(**mol, validate=validate, allow_noncontiguous_but_reorder=allow_noncontiguous_but_reorder)
assert compare(["He", "Li", "H"], mol.symbols)
assert compare([2, 3, 1], mol.atomic_numbers)
assert compare_values([[0, 0, 0], [0, 0, 1], [0, 0, 2]], mol.geometry)
assert compare([4, 2], mol.fragment_multiplicities)

else:
with pytest.raises(qcel.ValidationError) as e:
Molecule(**mol, validate=validate, allow_noncontiguous_but_reorder=allow_noncontiguous_but_reorder)
assert "QCElemental would need to reorder atoms to accommodate non-contiguous fragments" in str(e.value)

else:
mol = Molecule(**mol, validate=validate, allow_noncontiguous_but_reorder=allow_noncontiguous_but_reorder)
assert compare(["Li", "H", "He"], mol.symbols)
assert compare([3, 1, 2], mol.atomic_numbers)
assert compare_values([[0, 0, 1], [0, 0, 2], [0, 0, 0]], mol.geometry)
assert compare([4, 2], mol.fragment_multiplicities)


@pytest.mark.parametrize("group_fragments, orient", [(True, True), (False, False)]) # original # Psi4-like
def test_get_fragment(group_fragments, orient):
mol = Molecule(
Expand Down

0 comments on commit 0cc6ee9

Please sign in to comment.