Skip to content

Commit

Permalink
Csse layout reorg rb2025 (#468)
Browse files Browse the repository at this point in the history
* first tidying

* fix pkg_resources error?

* misc

* Mol v3

* trajectory workings

* fix var

* post-Christmas opt/td

* use qcel next2025
  • Loading branch information
loriab authored Jan 21, 2025
1 parent 7fccecd commit 5577d35
Show file tree
Hide file tree
Showing 24 changed files with 235 additions and 99 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ jobs:
# note: any activate/deactivate use the conda cmd. other cmds use mamba cmd.

- name: Special Config - NWChem
if: "(matrix.cfg.label == 'NWChem70')"
if: matrix.cfg.label == 'NWChem70'
run: |
sudo apt-get -y install nwchem
- name: Special Config - QCore
if: "(matrix.cfg.label == 'QCore')"
if: matrix.cfg.label == 'QCore'
run: |
qcore --accept-license
Expand All @@ -180,18 +180,18 @@ jobs:
#if: false
run: |
conda remove qcelemental --force
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536d' --no-deps
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536f_rb2025_take2' --no-deps
# note: conda remove --force, not mamba remove --force b/c https://github.com/mamba-org/mamba/issues/412
# alt. is micromamba but not yet ready for setup-miniconda https://github.com/conda-incubator/setup-miniconda/issues/75
- name: Special Config - QCEngine Dep
if: "(startsWith(matrix.cfg.label, 'Psi4')) || (matrix.cfg.label == 'ADCC') || (matrix.cfg.label == 'optimization-dispersion')"
if: (startsWith(matrix.cfg.label, 'Psi4')) || (matrix.cfg.label == 'ADCC') || (matrix.cfg.label == 'optimization-dispersion')
run: |
conda remove qcengine --force
# QCEngine CI and Psi4 are circularly dependent, so a hack is in order
- name: Special Config - Faux Pydantic Upgrade
if: "((matrix.cfg.label == 'Psi4-1.6') || (matrix.cfg.label == 'optimization-dispersion')) && (runner.os != 'Windows')"
if: ((matrix.cfg.label == 'Psi4-1.6') || (matrix.cfg.label == 'optimization-dispersion')) && (runner.os != 'Windows')
run: |
sed -i s/from\ pydantic\ /from\ pydantic.v1\ /g ${CONDA_PREFIX}/lib/python${{ matrix.cfg.python-version }}/site-packages/psi4/driver/*py
Expand All @@ -203,7 +203,7 @@ jobs:
python -m pip install 'git+https://github.com/MolSSI/QCElemental.git@next2025' --no-deps
- name: Special Config - Forced Interface Upgrade
if: "(matrix.cfg.label == 'Psi4-1.6')"
if: matrix.cfg.label == 'Psi4-1.6'
run: |
grep -r "local_options" ${CONDA_PREFIX}/lib/python${{ matrix.cfg.python-version }}/site-packages/psi4/driver/
sed -i "s/local_options/task_config/g" ${CONDA_PREFIX}/lib/python${{ matrix.cfg.python-version }}/site-packages/psi4/driver/procrouting/*py
Expand All @@ -221,7 +221,7 @@ jobs:
git describe
- name: QCEngineRecords
if: "(matrix.cfg.label != 'Psi4-1.6')"
if: matrix.cfg.label != 'Psi4-1.6'
run: |
qcengine info
export QCER_VER=`python -c "import qcengine.testing; print(qcengine.testing.QCENGINE_RECORDS_COMMIT)"`
Expand Down Expand Up @@ -269,7 +269,7 @@ jobs:
#if: false
run: |
conda remove qcelemental --force
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536d' --no-deps
python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536f_rb2025_take2' --no-deps
- name: Environment Information
run: |
Expand Down
14 changes: 10 additions & 4 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,16 @@ Misc.

MUST (Unmerged)
+++++++++++++++
torsiondrive rewritten in v2.
berny harness rewritten in v2. optking and geometric natively speak v1, so adapted as well as can be.
allow nwchemdriver w/o driver=energy. provenance now nwchemdriver not nwchemrelax
Optking now fills in ``v2.OptimizationResult.stdout``. Through v2, once can alter gradient protocols in an optimization.
- (:pr:`462`)
- (:pr:`462`) adapt harnesses for TD.initial_molecules -> TD.initial_molecule and TD.optimization_history -> TD.scan_results
- (:pr:`462`) rdkit, store ``AtomicResult.properties.return_gradient`` and ``calcinfo_natom``. mrchem, store ``AtomicResult.properties.return_gradient``.
- (:pr:`462`) lightly Adapt harnesses for Mol v3
- (:pr:`462`) Use packaging instead of setuptools to provide version parsing
- (:pr:`462`) torsiondrive now accepts protocols. use ``protocols={"scan_results": "all"}`` if going to be converted to v1.
- (:pr:`461`) torsiondrive rewritten in v2.
- (:pr:`461`) berny harness rewritten in v2. optking and geometric natively speak v1, so adapted as well as can be.
- (:pr:`461`) allow nwchemdriver w/o driver=energy. provenance now nwchemdriver not nwchemrelax
- (:pr:`461`) Optking now fills in ``v2.OptimizationResult.stdout``. Through v2, once can alter gradient protocols in an optimization.
- (:pr:`460`) integrate ``AtomicInput.specification`` into harnesses and show what new inputs look like in tests
- (:pr:`459`) gcp, mp2d several got properties.return_energy, retunr_gradient
- (:pr:`460`) If you're missing something from AtomicResult.extras, check AtomicResult.input_data.extras in case it was passed in on input
Expand Down
7 changes: 5 additions & 2 deletions qcengine/procedures/berny.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Any, ClassVar, Dict, Union

import numpy as np
from qcelemental.models.v2 import FailedOperation, OptimizationInput, OptimizationResult
from qcelemental.models.v2 import FailedOperation, Molecule, OptimizationInput, OptimizationResult
from qcelemental.util import which_import

import qcengine
Expand Down Expand Up @@ -85,11 +85,14 @@ def compute(
except Exception:
error = {"error_type": "unknown", "error_message": f"Berny error:\n{traceback.format_exc()}"}
else:
final_molecule = trajectory[-1]["molecule"]
output = {
"input_data": input_model,
"final_molecule": trajectory[-1]["molecule"],
"final_molecule": final_molecule,
"properties": {
"nuclear_repulsion_energy": Molecule(**final_molecule).nuclear_repulsion_energy(),
"return_energy": trajectory[-1]["properties"]["return_energy"],
"return_gradient": trajectory[-1]["properties"]["return_gradient"],
"optimization_iterations": len(trajectory),
},
"trajectory_results": trajectory,
Expand Down
5 changes: 4 additions & 1 deletion qcengine/procedures/optking.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import logging
import sys
from io import StringIO
from typing import Any, ClassVar, Dict, Union
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Union

from qcelemental.models.v1 import OptimizationResult
from qcelemental.models.v2 import OptimizationInput
from qcelemental.util import safe_version, which_import

from .model import ProcedureHarness

if TYPE_CHECKING:
from ..config import TaskConfig


class OptKingProcedure(ProcedureHarness):

Expand Down
8 changes: 4 additions & 4 deletions qcengine/procedures/torsiondrive.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def _compute(self, input_model: "TorsionDriveInput", config: "TaskConfig"):
state = torsiondrive.td_api.create_initial_state(
dihedrals=dihedrals,
grid_spacing=grid_spacing,
elements=input_model.initial_molecules[0].symbols,
init_coords=[molecule.geometry.flatten().tolist() for molecule in input_model.initial_molecules],
elements=input_model.initial_molecule[0].symbols,
init_coords=[molecule.geometry.flatten().tolist() for molecule in input_model.initial_molecule],
dihedral_ranges=dihedral_ranges,
energy_upper_limit=energy_upper_limit,
energy_decrease_thresh=energy_decrease_thresh,
Expand Down Expand Up @@ -128,7 +128,7 @@ def _compute(self, input_model: "TorsionDriveInput", config: "TaskConfig"):
output_data["final_energies"][grid_point] = final_energy
output_data["final_molecules"][grid_point] = final_molecule

output_data["optimization_history"] = optimization_results
output_data["scan_results"] = optimization_results

if error is not None:
output_data["error"] = error
Expand Down Expand Up @@ -185,7 +185,7 @@ def _spawn_optimization(

from qcengine import compute

input_molecule = input_model.initial_molecules[0].copy(deep=True).dict()
input_molecule = input_model.initial_molecule[0].copy(deep=True).dict()
input_molecule["geometry"] = np.array(job).reshape(len(input_molecule["symbols"]), 3)
input_molecule = Molecule.from_data(input_molecule)

Expand Down
8 changes: 4 additions & 4 deletions qcengine/programs/cfour/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ def harvest_outfile_pass(outtext):
psivar_coord = Molecule(
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=2
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=3
),
)

Expand All @@ -1015,7 +1015,7 @@ def harvest_outfile_pass(outtext):
psivar_coord = Molecule(
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=2
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=3
),
)

Expand All @@ -1034,7 +1034,7 @@ def harvest_outfile_pass(outtext):
psivar_coord = Molecule(
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=2
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=3
),
)

Expand Down Expand Up @@ -1374,7 +1374,7 @@ def harvest_GRD(grd):
mol = Molecule(
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=2
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=3
),
)

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/gamess/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def harvest_outfile_pass(outtext):
qcvar_coord = Molecule(
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=2
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"], dtype=3
),
)

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/mace.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def compute(self, input_data: "AtomicInput", config: "TaskConfig") -> Union["Ato
ret_data["input_data"] = input_data
ret_data["molecule"] = input_data.molecule
ret_data["provenance"] = Provenance(creator="mace", version=mace.__version__, routine="mace")
ret_data["schema_name"] = "qcschema_atomic_output"
ret_data["schema_name"] = "qcschema_atomic_result"
ret_data["success"] = True

# Form up a dict first, then sent to BaseModel to avoid repeat kwargs which don't override each other
Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/molpro.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ def parse_output(self, outfiles: Dict[str, str], input_model: "AtomicInput") ->
# Final output_data assignments needed for the AtomicResult object
output_data["properties"] = properties
output_data["extras"] = extras
output_data["schema_name"] = "qcschema_atomic_output"
output_data["schema_name"] = "qcschema_atomic_result"
output_data["stdout"] = outfiles["dispatch.out"]
output_data["success"] = True
output_data["provenance"] = input_model.provenance # TODO better stamp?
Expand Down
8 changes: 4 additions & 4 deletions qcengine/programs/mrchem.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def compute(self, input_model: "AtomicInput", config: "TaskConfig") -> "AtomicRe
input_data = copy.deepcopy(job_input["mrchem_json"])

output_data = {
"schema_name": "qcschema_atomic_output",
"schema_name": "qcschema_atomic_result",
"schema_version": 2,
"input_data": input_model,
"molecule": input_model.molecule,
Expand Down Expand Up @@ -170,9 +170,9 @@ def compute(self, input_model: "AtomicInput", config: "TaskConfig") -> "AtomicRe
if input_model.specification.driver == "energy":
output_data["return_result"] = mrchem_output["properties"]["scf_energy"]["E_tot"]
elif input_model.specification.driver == "gradient":
output_data["return_result"] = mrchem_output["properties"]["geometric_derivative"]["geom-1"][
"total"
]
grad = mrchem_output["properties"]["geometric_derivative"]["geom-1"]["total"]
output_data["return_result"] = grad
output_data["properties"]["return_gradient"] = grad
elif input_model.specification.driver == "properties":
output_data["return_result"] = {
f"{ks[1]}": {f"{ks[2]}": _nested_get(mrchem_output, ks)} for ks in computed_rsp_props
Expand Down
10 changes: 7 additions & 3 deletions qcengine/programs/nwchem/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
import logging
import re
from decimal import Decimal
from typing import Optional, Tuple
from typing import TYPE_CHECKING, Optional, Tuple

import numpy as np
import qcelemental as qcel
from qcelemental.molparse import regex

from ..util import PreservingDict

if TYPE_CHECKING:
from qcelemental.models.v2 import Molecule

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -845,7 +848,7 @@ def harvest_outfile_pass(outtext):
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"],
dtype=2,
dtype=3,
),
)

Expand All @@ -867,7 +870,7 @@ def harvest_outfile_pass(outtext):
validate=False,
**qcel.molparse.to_schema(
qcel.molparse.from_string(molxyz, dtype="xyz+", fix_com=True, fix_orientation=True)["qm"],
dtype=2,
dtype=3,
),
)

Expand Down Expand Up @@ -921,6 +924,7 @@ def harvest_outfile_pass(outtext):
logger.debug("matched total dipole")

# UNIT = DEBYE(S)
d2au = Decimal(qcel.constants.conversion_factor("debye", "e * bohr"))
psivar[f"CURRENT DIPOLE"] = d2au * np.array([mobj.group(7), mobj.group(8), mobj.group(9)])
# total?

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/psi4.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def compute(self, input_model: "AtomicInput", config: "TaskConfig") -> "AtomicRe
error_type = "execution_error"

# Reset the schema if required
output_data["schema_name"] = "qcschema_atomic_output"
output_data["schema_name"] = "qcschema_atomic_result"
output_data.pop("memory", None)
output_data.pop("nthreads", None)
output_data["stdout"] = output_data.pop("raw_output", None)
Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/qcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def parse_output(self, output: Dict[str, Any], input_model: "AtomicInput") -> "A

output_data["properties"] = properties

output_data["schema_name"] = "qcschema_atomic_output"
output_data["schema_name"] = "qcschema_atomic_result"
output_data["success"] = True

return AtomicResult(**output_data)
Expand Down
10 changes: 5 additions & 5 deletions qcengine/programs/qcvar_identities_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Any, Dict, List

import numpy as np
from qcelemental.models.v2 import AtomicResultProperties
from qcelemental.models.v2 import AtomicProperties

from .util import PreservingDict

Expand Down Expand Up @@ -427,7 +427,7 @@ def build_out(rawvars: Dict[str, Any], verbose: int = 1) -> None:
}


def build_atomicproperties(qcvars: "PreservingDict") -> AtomicResultProperties:
def build_atomicproperties(qcvars: "PreservingDict") -> AtomicProperties:
"""For results extracted from QC output in QCDB terminology, translate to QCSchema terminology.
Parameters
Expand All @@ -437,13 +437,13 @@ def build_atomicproperties(qcvars: "PreservingDict") -> AtomicResultProperties:
Returns
-------
atprop : AtomicResultProperties
Object of calculation information in QCSchema AtomicResultProperties terminology.
atprop : AtomicProperties
Object of calculation information in QCSchema AtomicProperties terminology.
"""
atprop = {}
for pv, dpv in qcvars.items():
if pv in qcvars_to_atomicproperties:
atprop[qcvars_to_atomicproperties[pv]] = dpv

return AtomicResultProperties(**atprop)
return AtomicProperties(**atprop)
11 changes: 8 additions & 3 deletions qcengine/programs/rdkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,18 @@ def compute(self, input_data: "AtomicInput", config: "TaskConfig") -> "AtomicRes

ff.Initialize()

ret_data["properties"] = {"return_energy": ff.CalcEnergy() * ureg.conversion_factor("kJ / mol", "hartree")}
ret_data["properties"] = {
"return_energy": ff.CalcEnergy() * ureg.conversion_factor("kJ / mol", "hartree"),
"calcinfo_natom": len(jmol.symbols),
}
if input_data.specification.driver == "gradient":
coef = ureg.conversion_factor("kJ / mol", "hartree") * ureg.conversion_factor("angstrom", "bohr")
ret_data["properties"]["return_gradient"] = [x * coef for x in ff.CalcGrad()]

if input_data.specification.driver == "energy":
ret_data["return_result"] = ret_data["properties"]["return_energy"]
elif input_data.specification.driver == "gradient":
coef = ureg.conversion_factor("kJ / mol", "hartree") * ureg.conversion_factor("angstrom", "bohr")
ret_data["return_result"] = [x * coef for x in ff.CalcGrad()]
ret_data["return_result"] = ret_data["properties"]["return_gradient"]
else:
raise InputError(f"Driver {input_data.specification.driver} not implemented for RDKit.")

Expand Down
2 changes: 1 addition & 1 deletion qcengine/programs/terachem.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def parse_output(self, outfiles: Dict[str, str], input_model: "AtomicInput") ->

output_data["properties"] = properties

output_data["schema_name"] = "qcschema_atomic_output"
output_data["schema_name"] = "qcschema_atomic_result"
output_data["stdout"] = outfiles["tc.out"]
# TODO Should only return True if TeraChem calculation terminated properly
output_data["success"] = True
Expand Down
Loading

0 comments on commit 5577d35

Please sign in to comment.