Skip to content

Commit

Permalink
Merge pull request #556 from mattwelborn/molecular_formula_bug
Browse files Browse the repository at this point in the history
Storage: canonicalize molecular formula before query
  • Loading branch information
dgasmith committed Feb 9, 2020
2 parents 591cced + cdd416c commit b35acfb
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 15 deletions.
2 changes: 1 addition & 1 deletion devtools/conda-envs/adapters.yaml
Expand Up @@ -48,7 +48,7 @@ dependencies:

# QCArchive includes
- qcengine >=0.11.0
- qcelemental >=0.9.0
- qcelemental >=0.13.1

# Pip includes
- pip:
Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/base.yaml
Expand Up @@ -39,4 +39,4 @@ dependencies:

# QCArchive includes
- qcengine >=0.11.0
- qcelemental >=0.11.0
- qcelemental >=0.13.1
2 changes: 1 addition & 1 deletion devtools/conda-envs/generate_envs.py
Expand Up @@ -48,7 +48,7 @@
- pytest-cov
- requests-mock
"""
qca_ecosystem_template = ["qcengine >=0.11.0", "qcelemental >=0.9.0"]
qca_ecosystem_template = ["qcengine >=0.11.0", "qcelemental >=0.13.1"]

pip_depends_template = []

Expand Down
2 changes: 1 addition & 1 deletion devtools/conda-envs/openff.yaml
Expand Up @@ -47,4 +47,4 @@ dependencies:

# QCArchive includes
- qcengine >=0.11.0
- qcelemental >=0.9.0
- qcelemental >=0.13.1
3 changes: 2 additions & 1 deletion qcfractal/interface/client.py
Expand Up @@ -386,7 +386,8 @@ def query_molecules(
molecule_hash : QueryStr, optional
Queries the Molecule ``molecule_hash`` field.
molecular_formula : QueryStr, optional
Queries the Molecule ``molecular_formula`` field.
Queries the Molecule ``molecular_formula`` field. Molecular formulas are case-sensitive.
Molecular formulas are not order-sensitive (e.g. "H2O == OH2 != Oh2").
limit : Optional[int], optional
The maximum number of Molecules to query
skip : int, optional
Expand Down
8 changes: 8 additions & 0 deletions qcfractal/storage_sockets/sqlalchemy_socket.py
Expand Up @@ -723,6 +723,14 @@ def add_molecules(self, molecules: List[Molecule]):
return ret

def get_molecules(self, id=None, molecule_hash=None, molecular_formula=None, limit: int = None, skip: int = 0):
try:
if isinstance(molecular_formula, str):
molecular_formula = qcelemental.molutil.order_molecular_formula(molecular_formula)
elif isinstance(molecular_formula, list):
molecular_formula = [qcelemental.molutil.order_molecular_formula(form) for form in molecular_formula]
except ValueError:
# Probably, the user provided an invalid chemical formula
pass

meta = get_metadata_template()

Expand Down
56 changes: 47 additions & 9 deletions qcfractal/tests/test_storage.py
Expand Up @@ -1193,18 +1193,56 @@ def test_mol_pagination(storage_socket):

inserted = storage_socket.add_molecules(molecules)

assert inserted["meta"]["n_inserted"] == total
try:
assert inserted["meta"]["n_inserted"] == total

ret = storage_socket.get_molecules(skip=1)
assert len(ret["data"]) == total - 1
assert ret["meta"]["n_found"] == total
ret = storage_socket.get_molecules(skip=1)
assert len(ret["data"]) == total - 1
assert ret["meta"]["n_found"] == total

ret = storage_socket.get_molecules(skip=total + 1)
assert len(ret["data"]) == 0
assert ret["meta"]["n_found"] == total
ret = storage_socket.get_molecules(skip=total + 1)
assert len(ret["data"]) == 0
assert ret["meta"]["n_found"] == total

# cleanup
storage_socket.del_molecules(inserted["data"])
finally:
# cleanup
storage_socket.del_molecules(inserted["data"])


def test_mol_formula(storage_socket):
"""
Test Molecule pagination
"""

assert len(storage_socket.get_molecules()["data"]) == 0
mol_names = [
"water_dimer_minima.psimol",
]
total = len(mol_names)
molecules = []
for mol_name in mol_names:
mol = ptl.data.get_molecule(mol_name)
molecules.append(mol)

inserted = storage_socket.add_molecules(molecules)
try:
assert inserted["meta"]["n_inserted"] == total

ret = storage_socket.get_molecules(molecular_formula="H4O2")
assert len(ret["data"]) == 1
assert ret["meta"]["n_found"] == 1

ret = storage_socket.get_molecules(molecular_formula="O2H4")
assert len(ret["data"]) == 1
assert ret["meta"]["n_found"] == 1

ret = storage_socket.get_molecules(molecular_formula="H4o2")
assert len(ret["data"]) == 0
assert ret["meta"]["n_found"] == 0

finally:
# cleanup
storage_socket.del_molecules(inserted["data"])


def test_reset_task_blocks(storage_socket):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -46,7 +46,7 @@
# 'double-conversion >=3.0.0',
# QCArchive depends
"qcengine>=0.11.0",
"qcelemental>=0.11.0",
"qcelemental>=0.13.1",
],
entry_points={
"console_scripts": [
Expand Down

0 comments on commit b35acfb

Please sign in to comment.