From 53ee67fd08356e2f590ea1ac9c3f10ffb4e7530c Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 4 Feb 2025 01:21:43 -0500 Subject: [PATCH 1/2] TD properties and scan_properties --- qcengine/procedures/torsiondrive.py | 19 ++++++++++++++----- qcengine/tests/test_procedures.py | 28 +++++++++++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/qcengine/procedures/torsiondrive.py b/qcengine/procedures/torsiondrive.py index bb50b225..52c9518f 100644 --- a/qcengine/procedures/torsiondrive.py +++ b/qcengine/procedures/torsiondrive.py @@ -8,6 +8,7 @@ FailedOperation, Molecule, OptimizationInput, + OptimizationProperties, OptimizationResult, TorsionDriveInput, TorsionDriveResult, @@ -119,16 +120,20 @@ def _compute(self, input_model: "TorsionDriveInput", config: "TaskConfig"): } # even if we hit an error during the torsiondrive, we output what we can - output_data["final_energies"], output_data["final_molecules"] = {}, {} + output_data["scan_properties"], output_data["final_molecules"] = {}, {} for grid_point, results in optimization_results.items(): - final_energy, final_molecule = self._find_final_results(results) + final_energy, final_properties, final_molecule = self._find_final_results(results) - output_data["final_energies"][grid_point] = final_energy + # v1: output_data["final_energies"][grid_point] = final_energy + output_data["scan_properties"][grid_point] = final_properties output_data["final_molecules"][grid_point] = final_molecule output_data["scan_results"] = optimization_results + output_data["properties"] = { + "calcinfo_ngrid": len(optimization_results), + } if error is not None: output_data["error"] = error @@ -211,14 +216,18 @@ def _spawn_optimization( @staticmethod def _find_final_results( optimization_results: List[OptimizationResult], - ) -> Tuple[float, Molecule]: + ) -> Tuple[float, OptimizationProperties, Molecule]: """Returns the energy and final molecule of the lowest energy optimization in a set.""" final_energies = np.array([result.properties.return_energy for result in optimization_results]) lowest_energy_idx = final_energies.argmin() - return float(final_energies[lowest_energy_idx]), optimization_results[lowest_energy_idx].final_molecule + return ( + float(final_energies[lowest_energy_idx]), + optimization_results[lowest_energy_idx].properties, + optimization_results[lowest_energy_idx].final_molecule, + ) def _spawn_optimizations( self, next_jobs: Dict[str, List[float]], input_model: "TorsionDriveInput", config: "TaskConfig" diff --git a/qcengine/tests/test_procedures.py b/qcengine/tests/test_procedures.py index a7714b12..920992bb 100644 --- a/qcengine/tests/test_procedures.py +++ b/qcengine/tests/test_procedures.py @@ -687,7 +687,10 @@ def test_torsiondrive_generic(schema_versions, request, scan_ptcl): if not (from_v2(request.node.name) and scan_ptcl == "none"): assert {*opthist_tgt} == expected_grid_ids - assert {*ret.final_energies} == expected_grid_ids + if "v2" in request.node.name: + assert {*ret.scan_properties} == expected_grid_ids + else: + assert {*ret.final_energies} == expected_grid_ids assert {*ret.final_molecules} == expected_grid_ids assert ( @@ -741,9 +744,9 @@ def test_torsiondrive_extra_constraints(schema_versions, request): if from_v2(request.node.name): input_data = models.TorsionDriveInput( - initial_molecules=[models.Molecule(**qcng.get_molecule("propane", return_dict=True))], + initial_molecule=[models.Molecule(**qcng.get_molecule("propane", return_dict=True))], specification=models.TorsionDriveSpecification( - keywords=models.TDKeywords(dihedrals=[(3, 0, 1, 2)], grid_spacing=[180]), + keywords=models.TorsionDriveKeywords(dihedrals=[(3, 0, 1, 2)], grid_spacing=[180]), specification=models.OptimizationSpecification( program="geomeTRIC", keywords=keywords, @@ -753,7 +756,9 @@ def test_torsiondrive_extra_constraints(schema_versions, request): driver=models.DriverEnum.gradient, model=models.Model(method="small", basis=None), ), + protocols=models.OptimizationProtocols(trajectory_results="all"), ), + protocols=models.TorsionDriveProtocols(scan_results="all"), ), ) else: @@ -782,11 +787,16 @@ def test_torsiondrive_extra_constraints(schema_versions, request): assert ret.success expected_grid_ids = {"180", "0"} + opthist_tgt = ret.scan_results if "v2" in request.node.name else ret.optimization_history - assert {*ret.optimization_history} == expected_grid_ids - - assert {*ret.final_energies} == expected_grid_ids + assert {*opthist_tgt} == expected_grid_ids + if "v2" in request.node.name: + assert {*ret.scan_properties} == expected_grid_ids + else: + assert {*ret.final_energies} == expected_grid_ids assert {*ret.final_molecules} == expected_grid_ids + if "v2" in request.node.name: + assert ret.properties.calcinfo_ngrid == 2 assert ( pytest.approx(ret.final_molecules["180"].measure([3, 0, 1, 2]), abs=1.0e-2) == 180.0 @@ -796,11 +806,11 @@ def test_torsiondrive_extra_constraints(schema_versions, request): assert pytest.approx(ret.final_molecules["0"].measure([3, 0, 1, 2]), abs=1.0e-2) == 0.0 assert ret.provenance.creator.lower() == "torsiondrive" - assert ret.optimization_history["180"][0].provenance.creator.lower() == "geometric" + assert opthist_tgt["180"][0].provenance.creator.lower() == "geometric" if "v2" in request.node.name: - assert ret.optimization_history["180"][0].trajectory_results[0].provenance.creator.lower() == "mace" + assert opthist_tgt["180"][0].trajectory_results[0].provenance.creator.lower() == "mace" else: - assert ret.optimization_history["180"][0].trajectory[0].provenance.creator.lower() == "mace" + assert opthist_tgt["180"][0].trajectory[0].provenance.creator.lower() == "mace" assert "Using MACE-OFF23 MODEL for MACECalculator" in ret.stdout assert "All optimizations converged at lowest energy. Job Finished!\n" in ret.stdout From 56946065d70a6490334b7ccdbfe198a88059b33b Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 4 Feb 2025 01:35:12 -0500 Subject: [PATCH 2/2] new base --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 817e736e..bdd04e09 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -180,7 +180,7 @@ jobs: #if: false run: | conda remove qcelemental --force - python -m pip install 'git+https://github.com/MolSSI/QCElemental.git@next2025' --no-deps + python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536g' --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 @@ -200,7 +200,7 @@ jobs: run: | conda install pydantic=2 -c conda-forge conda remove qcelemental --force - python -m pip install 'git+https://github.com/MolSSI/QCElemental.git@next2025' --no-deps + python -m pip install 'git+https://github.com/loriab/QCElemental.git@csse_layout_536g' --no-deps - name: Special Config - Forced Interface Upgrade if: matrix.cfg.label == 'Psi4-1.6'