Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Csse layout reorg rb2025 #468

Merged
merged 8 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading