Skip to content

Commit

Permalink
mbresprop as primary, not qcvars
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Jun 3, 2024
1 parent 01f9313 commit ee29d20
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 149 deletions.
65 changes: 1 addition & 64 deletions qcmanybody/computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,6 @@ def get_results(
component_properties = external_results.pop("component_properties")
stdout = external_results.pop("stdout")

# load QCVariables
qcvars = {
"NUCLEAR REPULSION ENERGY": self.molecule.nuclear_repulsion_energy(),
"NBODY NUMBER": nbody_number,
}

properties = {
"calcinfo_nmc": len(self.nbodies_per_mc_level),
"calcinfo_nfr": self.nfragments, # or len(self.molecule.fragments)
Expand All @@ -520,27 +514,12 @@ def get_results(
"return_energy": ret_energy,
}

for k, val in external_results.items():
if k == "results":
k = "nbody"
qcvars[k] = val

qcvars["CURRENT ENERGY"] = ret_energy
if self.driver == "gradient":
qcvars["CURRENT GRADIENT"] = ret_ptype
properties["return_gradient"] = ret_ptype
elif self.driver == "hessian":
qcvars["CURRENT GRADIENT"] = ret_gradient
qcvars["CURRENT HESSIAN"] = ret_ptype
properties["return_gradient"] = ret_gradient
properties["return_hessian"] = ret_ptype

# build_out(qcvars)
atprop = build_manybodyproperties(qcvars["nbody"])
# print("ATPROP")
# v2: pp.pprint(atprop.model_dump())
# pp.pprint(atprop.dict())

# output_data = {
# "schema_version": 1,
# "molecule": gamessmol, # overwrites with outfile Cartesians in case fix_*=F
Expand All @@ -559,30 +538,20 @@ def get_results(
# print("QCVARS PRESCREEN")
# pp.pprint(qcvars)

for qcv, val in qcvars.items():
if not isinstance(val, dict):
qcvars[qcv] = val

# v2: component_results = self.model_dump()['task_list'] # TODO when/where include the indiv outputs
# ?component_results = self.dict()['task_list'] # TODO when/where include the indiv outputs
# for k, val in component_results.items():
# val['molecule'] = val['molecule'].to_schema(dtype=2)

# print("QCVARS")
# pp.pprint(qcvars)

nbody_model = ManyBodyResult(
**{
"input_data": self.input_data,
#'molecule': self.molecule,
# v2: 'properties': {**atprop.model_dump(), **properties},
"properties": {**atprop.dict(), **properties},
"properties": {**external_results["results"], **properties},
"component_properties": component_properties,
"component_results": component_results,
"provenance": provenance_stamp(__name__),
"extras": {
"qcvars": qcvars,
},
"return_result": ret_ptype,
"stdout": stdout,
"success": True,
Expand All @@ -592,35 +561,3 @@ def get_results(
# logger.debug('\nNBODY QCSchema:\n' + pp.pformat(nbody_model.model_dump()))

return nbody_model


qcvars_to_manybodyproperties = {}
# v2: for skprop in ManyBodyResultProperties.model_fields.keys():
for skprop in ManyBodyResultProperties.__fields__.keys():
qcvar = skprop.replace("_body", "-body").replace("_corr", "-corr").replace("_", " ").upper()
qcvars_to_manybodyproperties[qcvar] = skprop
qcvars_to_manybodyproperties["CURRENT ENERGY"] = "return_energy"
qcvars_to_manybodyproperties["CURRENT GRADIENT"] = "return_gradient"
qcvars_to_manybodyproperties["CURRENT HESSIAN"] = "return_hessian"


def build_manybodyproperties(qcvars: Mapping) -> ManyBodyResultProperties:
"""For results extracted from QC output in QCDB terminology, translate to QCSchema terminology.
Parameters
----------
qcvars : PreservingDict
Dictionary of calculation information in QCDB QCVariable terminology.
Returns
-------
atprop : ManyBodyResultProperties
Object of calculation information in QCSchema ManyBodyResultProperties terminology.
"""
atprop = {}
for pv, dpv in qcvars.items():
if pv in qcvars_to_manybodyproperties:
atprop[qcvars_to_manybodyproperties[pv]] = dpv

return ManyBodyResultProperties(**atprop)
4 changes: 2 additions & 2 deletions qcmanybody/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,8 @@ def analyze(
for bt in self.bsse_type:
nbody_dict.update(
collect_vars(
bt.upper(),
property_label.upper(),
bt,
property_label,
all_results[f"{property_label}_body_dict"][bt],
self.max_nbody,
is_embedded,
Expand Down
31 changes: 31 additions & 0 deletions qcmanybody/models/manybody_output_pydv1.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,37 @@ class Config(ProtoModel.Config):
)


def _qcvars_translator(cls, reverse: bool = False) -> Dict[str, str]:
"""Form translation map between many-body results QCSchema and Psi4/QCDB terminologies.
Parameters
----------
reverse
Keys are QCVariable names (`reverse=True`) rather than QCSchema names (default; `reverse=False`).
Returns
-------
dict
Map from ManyBodyResultProperties field names to QCVariable names, or reverse.
"""
qcvars_to_mbprop = {}
# v2: for skprop in ManyBodyResultProperties.model_fields.keys():
for skprop in cls.__fields__.keys():
qcvar = skprop.replace("_body", "-body").replace("_corr", "-corr").replace("_", " ").upper()
qcvars_to_mbprop[qcvar] = skprop
for ret in ["energy", "gradient", "hessian"]:
qcvars_to_mbprop[f"CURRENT {ret.upper()}"] = f"return_{ret}"

if reverse:
return qcvars_to_mbprop
else:
return {v: k for k, v in qcvars_to_mbprop.items()}


ManyBodyResultProperties.to_qcvariables = classmethod(_qcvars_translator)


# ==== Results ================================================================


Expand Down
54 changes: 31 additions & 23 deletions qcmanybody/tests/test_mbe_he4_multilevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@
# v2: from qcelemental.models.procedures_manybody import AtomicSpecification, ManyBodyKeywords, ManyBodyInput
from qcelemental.testing import compare_recursive, compare_values

from qcmanybody.computer import ManyBodyComputer, qcvars_to_manybodyproperties
from qcmanybody.models import AtomicSpecification, ManyBodyInput, ManyBodyKeywords
from qcmanybody.computer import ManyBodyComputer
from qcmanybody.models import AtomicSpecification, ManyBodyInput, ManyBodyKeywords, ManyBodyResultProperties
from qcmanybody.utils import translate_qcvariables

from .addons import using, uusing
from .test_mbe_he4_singlelevel import sumdict as sumdict_single


def skprop(qcvar):
# qcng: return qcng.procedures.manybody.qcvars_to_manybodyproperties[qcvar]
return qcvars_to_manybodyproperties[qcvar]


@pytest.fixture(scope="function")
def mbe_data_multilevel_631g():
# note that spherical/cartesian irrelevant for He & 6-31G, and fc/ae irrelevant for He
Expand Down Expand Up @@ -731,6 +727,12 @@ def test_nbody_he4_multi(levels, mbe_keywords, anskey, bodykeys, outstrs, calcin
print(f"MMMMMMM {request.node.name}")
pprint.pprint(ret.dict(), width=200)

# don't want QCVariables stashed in extras, but prepare the qcvars translation, and check it
assert ret.extras == {}, f"[w] extras wrongly present: {ret.extras.keys()}"
qcvars = translate_qcvariables(ret.properties.dict())

skprop = ManyBodyResultProperties.to_qcvariables(reverse=True)

refs = he4_refs_conv_multilevel_631g[pattern]
ans = refs[anskey]
ref_nmbe = calcinfo_nmbe[pattern]
Expand All @@ -739,29 +741,29 @@ def test_nbody_he4_multi(levels, mbe_keywords, anskey, bodykeys, outstrs, calcin
atol = 2.5e-8

for qcv, ref in refs.items():
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in ref_bodykeys:
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[b] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[z] {qcv=} wrongly present"
assert qcv not in qcvars, f"[z] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

for qcv in sumdict["4b_all"]:
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in ref_sumdict:
ref = refs[ref_sumdict[qcv]]
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[d] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[y] {qcv=} wrongly present"
assert qcv not in qcvars, f"[y] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

for qcv, ref in {
"CURRENT ENERGY": ans,
}.items():
skp = skprop(qcv)
assert compare_values(ref, ret.extras["qcvars"][qcv], atol=atol, label=f"[e] qcvars {qcv}")
skp = skprop[qcv]
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[e] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[f] skprop {skp}")
assert compare_values(ans, ret.return_result, atol=atol, label=f"[g] ret")

Expand Down Expand Up @@ -825,6 +827,12 @@ def test_nbody_he4_supersys(levels, mbe_keywords, anskey, bodykeys, outstrs, cal
print(f"MMMMMMM {request.node.name}")
pprint.pprint(ret.dict(), width=200)

# don't want QCVariables stashed in extras, but prepare the qcvars translation, and check it
assert ret.extras == {}, f"[w] extras wrongly present: {ret.extras.keys()}"
qcvars = translate_qcvariables(ret.properties.dict())

skprop = ManyBodyResultProperties.to_qcvariables(reverse=True)

refs = he4_refs_conv_multilevel_631g[pattern]
ans = refs[anskey]
ref_nmbe = calcinfo_nmbe[pattern]
Expand All @@ -833,29 +841,29 @@ def test_nbody_he4_supersys(levels, mbe_keywords, anskey, bodykeys, outstrs, cal
atol = 2.5e-8

for qcv, ref in refs.items():
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in ref_bodykeys:
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[b] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[z] {qcv=} wrongly present"
assert qcv not in qcvars, f"[z] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

for qcv in sumdict["4b_all"]:
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in ref_sumdict:
ref = refs[ref_sumdict[qcv]]
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[d] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[y] {qcv=} wrongly present"
assert qcv not in qcvars, f"[y] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

for qcv, ref in {
"CURRENT ENERGY": ans,
}.items():
skp = skprop(qcv)
assert compare_values(ref, ret.extras["qcvars"][qcv], atol=atol, label=f"[e] qcvars {qcv}")
skp = skprop[qcv]
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[e] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[f] skprop {skp}")
assert compare_values(ans, ret.return_result, atol=atol, label=f"[g] ret")

Expand Down
36 changes: 18 additions & 18 deletions qcmanybody/tests/test_mbe_he4_singlelevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@
from qcelemental.testing import compare_recursive, compare_values

from qcmanybody import ManyBodyComputer
from qcmanybody.computer import qcvars_to_manybodyproperties
from qcmanybody.models import AtomicSpecification, ManyBodyInput, ManyBodyKeywords
from qcmanybody.models import AtomicSpecification, ManyBodyInput, ManyBodyKeywords, ManyBodyResultProperties
from qcmanybody.utils import translate_qcvariables

from .addons import using, uusing


def skprop(qcvar):
# qcng: return qcng.procedures.manybody.qcvars_to_manybodyproperties[qcvar]
return qcvars_to_manybodyproperties[qcvar]


he4_refs_species = {
"NO": ('[\"(auto)\", [1, 2, 4], [1, 2, 4]]', -8.644153798224503),
"CP": ('[\"(auto)\", [1, 2, 4], [1, 2, 3, 4]]', -8.64425850181438),
Expand Down Expand Up @@ -236,7 +230,7 @@ def skprop(qcvar):
}




sumdict = {
"4b_all": {
Expand Down Expand Up @@ -586,7 +580,7 @@ def he_tetramer():
{"bsse_type": "nocp", "return_total_data": False, "max_nbody": 1},
"NOCP-CORRECTED INTERACTION ENERGY THROUGH 1-BODY",
[k for k in he4_refs_conv if (k.startswith("NOCP-") and ("1-BODY" in k))],
None,
None,
4, # maybe TODO this could be 0 but rtd hasn't be used to winnow nocp
id="1b_nocp"),
pytest.param(
Expand Down Expand Up @@ -632,6 +626,12 @@ def test_nbody_he4_single(program, basis, keywords, mbe_keywords, anskey, bodyke
# v2: pprint.pprint(ret.model_dump(), width=200)
pprint.pprint(ret.dict(), width=200)

# don't want QCVariables stashed in extras, but prepare the qcvars translation, and check it
assert ret.extras == {}, f"[w] extras wrongly present: {ret.extras.keys()}"
qcvars = translate_qcvariables(ret.properties.dict())

skprop = ManyBodyResultProperties.to_qcvariables(reverse=True)

_inner = request.node.name.split("[")[1].split("]")[0]
kwdsln, progln = _inner.split("-")
refs = he4_refs_df if progln == "psi4_df" else he4_refs_conv
Expand All @@ -640,22 +640,22 @@ def test_nbody_he4_single(program, basis, keywords, mbe_keywords, anskey, bodyke
atol = 1.0e-8

for qcv, ref in refs.items():
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in bodykeys:
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[a] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[b] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[z] {qcv=} wrongly present"
assert qcv not in qcvars, f"[z] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

for qcv in sumdict["4b_all"]:
skp = skprop(qcv)
skp = skprop[qcv]
if qcv in sumdict[kwdsln]:
ref = refs[sumdict[kwdsln][qcv]]
assert compare_values(ref, ret.extras["qcvars"]["nbody"][qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[c] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[d] skprop {skp}")
else:
assert qcv not in ret.extras["qcvars"]["nbody"], f"[y] {qcv=} wrongly present"
assert qcv not in qcvars, f"[y] {qcv=} wrongly present"
assert getattr(ret.properties, skp) is None

if "3b" in kwdsln and not progln.endswith("df"):
Expand All @@ -665,8 +665,8 @@ def test_nbody_he4_single(program, basis, keywords, mbe_keywords, anskey, bodyke
for qcv, ref in {
"CURRENT ENERGY": ans,
}.items():
skp = skprop(qcv)
assert compare_values(ref, ret.extras["qcvars"][qcv], atol=atol, label=f"[e] qcvars {qcv}")
skp = skprop[qcv]
assert compare_values(ref, qcvars[qcv], atol=atol, label=f"[e] qcvars {qcv}")
assert compare_values(ref, getattr(ret.properties, skp), atol=atol, label=f"[f] skprop {skp}")
assert compare_values(ans, ret.return_result, atol=atol, label=f"[g] ret")

Expand Down
Loading

0 comments on commit ee29d20

Please sign in to comment.