1
- import openff .toolkit as tk
2
1
import pytest
2
+ from emmet .core .openmm import OpenMMInterchange
3
3
from jobflow import run_locally
4
- from openff .interchange import Interchange
5
- from openff .interchange .components ._packmol import pack_box
6
- from openff .toolkit import ForceField
7
- from openff .units import unit
8
-
9
- from atomate2 .openff .utils import create_mol_spec , merge_specs_by_name_and_smiles
10
4
11
5
12
6
@pytest .fixture
@@ -18,37 +12,62 @@ def run_job(job):
18
12
return run_job
19
13
20
14
21
- @pytest .fixture
15
+ @pytest .fixture ( scope = "package" )
22
16
def openmm_data (test_dir ):
23
17
return test_dir / "openmm"
24
18
25
19
26
20
@pytest .fixture (scope = "package" )
27
- def interchange ():
28
- o = create_mol_spec ("O" , 300 , charge_method = "mmff94" )
29
- cco = create_mol_spec ("CCO" , 10 , charge_method = "mmff94" )
30
- cco2 = create_mol_spec ("CCO" , 20 , name = "cco2" , charge_method = "mmff94" )
31
- mol_specs = [o , cco , cco2 ]
32
- mol_specs .sort (
33
- key = lambda x : tk .Molecule .from_json (x .openff_mol ).to_smiles () + x .name
34
- )
35
-
36
- topology = pack_box (
37
- molecules = [tk .Molecule .from_json (spec .openff_mol ) for spec in mol_specs ],
38
- number_of_copies = [spec .count for spec in mol_specs ],
39
- mass_density = 0.8 * unit .grams / unit .milliliter ,
40
- )
41
-
42
- mol_specs = merge_specs_by_name_and_smiles (mol_specs )
43
-
44
- return Interchange .from_smirnoff (
45
- force_field = ForceField ("openff_unconstrained-2.1.1.offxml" ),
46
- topology = topology ,
47
- charge_from_molecules = [
48
- tk .Molecule .from_json (spec .openff_mol ) for spec in mol_specs
49
- ],
50
- allow_nonintegral_charges = True ,
51
- )
21
+ def interchange (openmm_data ):
22
+ # we use openff to generate the interchange object that we test on
23
+ # but we don't want to create a logical dependency on openff, in
24
+ # case the user has another way of generating the interchange object
25
+ regenerate_test_data = False
26
+ if regenerate_test_data :
27
+ import openff .toolkit as tk
28
+ from openff .interchange import Interchange
29
+ from openff .interchange .components ._packmol import pack_box
30
+ from openff .toolkit import ForceField
31
+ from openff .units import unit
32
+
33
+ from atomate2 .openff .utils import (
34
+ create_mol_spec ,
35
+ merge_specs_by_name_and_smiles ,
36
+ )
37
+ from atomate2 .openmm .utils import openff_to_openmm_interchange
38
+
39
+ o = create_mol_spec ("O" , 300 , charge_method = "mmff94" )
40
+ cco = create_mol_spec ("CCO" , 10 , charge_method = "mmff94" )
41
+ cco2 = create_mol_spec ("CCO" , 20 , name = "cco2" , charge_method = "mmff94" )
42
+ mol_specs = [o , cco , cco2 ]
43
+ mol_specs .sort (
44
+ key = lambda x : tk .Molecule .from_json (x .openff_mol ).to_smiles () + x .name
45
+ )
46
+
47
+ topology = pack_box (
48
+ molecules = [tk .Molecule .from_json (spec .openff_mol ) for spec in mol_specs ],
49
+ number_of_copies = [spec .count for spec in mol_specs ],
50
+ mass_density = 0.8 * unit .grams / unit .milliliter ,
51
+ )
52
+
53
+ mol_specs = merge_specs_by_name_and_smiles (mol_specs )
54
+
55
+ openff_interchange = Interchange .from_smirnoff (
56
+ force_field = ForceField ("openff_unconstrained-2.1.1.offxml" ),
57
+ topology = topology ,
58
+ charge_from_molecules = [
59
+ tk .Molecule .from_json (spec .openff_mol ) for spec in mol_specs
60
+ ],
61
+ allow_nonintegral_charges = True ,
62
+ )
63
+
64
+ openmm_interchange = openff_to_openmm_interchange (openff_interchange )
65
+
66
+ with open (openmm_data / "interchange.json" , "w" ) as file :
67
+ file .write (openmm_interchange .model_dump_json ())
68
+
69
+ with open (openmm_data / "interchange.json" ) as file :
70
+ return OpenMMInterchange .model_validate_json (file .read ())
52
71
53
72
54
73
@pytest .fixture
0 commit comments