Skip to content

Commit

Permalink
QC-program keywords (#239)
Browse files Browse the repository at this point in the history
* helper function to get program specific keywords

* lint

* Add test for XTB verbosity (#244)

---------

Co-authored-by: Josh A. Mitchell <[email protected]>
  • Loading branch information
jthorton and Yoshanuikabundi authored Mar 23, 2023
1 parent ac5dd88 commit 6b57aa6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
20 changes: 20 additions & 0 deletions openff/bespokefit/executor/services/qcgenerator/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ def _select_atom(atoms: List[Atom]) -> int:
return candidate.molecule_atom_index


def _get_program_keywords(program: str) -> Dict[str, str]:
"""
Generate a set of pre-defined keywords for the calculation based on the program.
These are based on experience.
Args:
program: The name of the program which will run the calculation
Returns:
A dictionary of program specific keywords
"""
keywords = {}
if program.lower() == "xtb":
# <https://github.com/openforcefield/openff-bespokefit/issues/238>
keywords["verbosity"] = "muted"
return keywords


@celery_app.task(acks_late=True)
def compute_torsion_drive(task_json: str) -> TorsionDriveResult:
"""Runs a torsion drive using QCEngine."""
Expand Down Expand Up @@ -118,6 +136,7 @@ def compute_torsion_drive(task_json: str) -> TorsionDriveResult:
input_specification=QCInputSpecification(
model=task.model,
driver=DriverEnum.gradient,
keywords=_get_program_keywords(task.program),
),
optimization_spec=OptimizationSpecification(
procedure=task.optimization_spec.program,
Expand Down Expand Up @@ -171,6 +190,7 @@ def compute_optimization(
input_specification=QCInputSpecification(
model=task.model,
driver=DriverEnum.gradient,
keywords=_get_program_keywords(task.program),
),
initial_molecule=molecule.to_qcschema(conformer=i),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,40 @@ def test_compute_torsion_drive():
assert all([atom.atomic_number != 1 for atom in atoms])


def test_compute_torsion_drive_xtb():
task = Torsion1DTask(
smiles="[F][CH2:1][CH2:2][F]",
central_bond=(1, 2),
grid_spacing=180,
scan_range=(-180, 180),
program="xtb",
model=Model(method="gfn2xtb", basis=None),
)

result_json = worker.compute_torsion_drive(task.json())
assert isinstance(result_json, str)

result_dict = json.loads(result_json)
assert isinstance(result_dict, dict)

result = TorsionDriveResult.parse_obj(result_dict)
assert result.success

cmiles = result.final_molecules["180"].extras[
"canonical_isomeric_explicit_hydrogen_mapped_smiles"
]

# Make sure a molecule can be created from CMILES
final_molecule = Molecule.from_mapped_smiles(cmiles)
assert Molecule.are_isomorphic(final_molecule, Molecule.from_smiles("FCCF"))[0]
dihedral = result.keywords.dihedrals[0]
# make sure heavy atoms are targeted
atoms = [final_molecule.atoms[i] for i in dihedral]
assert all([atom.atomic_number != 1 for atom in atoms])
# Make sure the "muted" verbosity was used
assert result_dict["input_specification"]["keywords"]["verbosity"] == "muted"


def test_compute_optimization():
task = OptimizationTask(
smiles="CCCCC",
Expand Down

0 comments on commit 6b57aa6

Please sign in to comment.