@@ -0,0 +1,213 @@
Loading
1 +
"""
2 +
Functions for generate GAFF files and parameters.
3 +
"""
4 +
5 +
import logging
6 +
import os
7 +
import subprocess
8 +
from typing import Optional
9 +
10 +
import numpy as np
11 +
import parmed as pmd
12 +
13 +
logger = logging.getLogger(__name__)
14 +
_PI_ = np.pi
15 +
16 +
17 +
def generate_gaff(
18 +
    mol2_file: str,
19 +
    residue_name: str,
20 +
    output_name: Optional[str] = None,
21 +
    need_gaff_atom_types: Optional[bool] = True,
22 +
    generate_frcmod: Optional[bool] = True,
23 +
    directory_path: Optional[str] = "benchmarks",
24 +
    gaff_version: Optional[str] = "gaff2",
25 +
):
26 +
    """
27 +
    Module to generate GAFF files given a mol2 file.
28 +
29 +
    Parameters
30 +
    ----------
31 +
    mol2_file
32 +
        The name of the mol2 structure file.
33 +
    residue_name
34 +
        The residue name of the molecule.
35 +
    output_name
36 +
        The name for the output file.
37 +
    need_gaff_atom_types
38 +
        Whether to generate GAFF atoms or not. Currently, this is the only choice.
39 +
    gaff_version
40 +
        The GAFF version to use ("gaff1", "gaff2")
41 +
    generate_frcmod
42 +
        Option to generate a GAFF frcmod file.
43 +
    directory_path
44 +
        The working directory where the files will be stored.
45 +
    """
46 +
47 +
    if output_name is None:
48 +
        output_name = mol2_file.stem
49 +
50 +
    if need_gaff_atom_types:
51 +
        _generate_gaff_atom_types(
52 +
            mol2_file=mol2_file,
53 +
            residue_name=residue_name,
54 +
            output_name=output_name,
55 +
            gaff_version=gaff_version,
56 +
            directory_path=directory_path,
57 +
        )
58 +
        logging.debug(
59 +
            "Checking to see if we have a multi-residue MOL2 file that should be converted "
60 +
            "to single-residue..."
61 +
        )
62 +
        structure = pmd.load_file(
63 +
            os.path.join(directory_path, f"{output_name}.{gaff_version}.mol2"),
64 +
            structure=True,
65 +
        )
66 +
        if len(structure.residues) > 1:
67 +
            structure[":1"].save("tmp.mol2")
68 +
            if os.path.exists("tmp.mol2"):
69 +
                os.rename(
70 +
                    "tmp.mol2",
71 +
                    os.path.join(directory_path, f"{output_name}.{gaff_version}.mol2"),
72 +
                )
73 +
                logging.debug("Saved single-residue MOL2 file for `tleap`.")
74 +
            else:
75 +
                raise RuntimeError(
76 +
                    "Unable to convert multi-residue MOL2 file to single-residue for `tleap`."
77 +
                )
78 +
79 +
        if generate_frcmod:
80 +
            _generate_frcmod(
81 +
                mol2_file=f"{output_name}.{gaff_version}.mol2",
82 +
                gaff_version=gaff_version,
83 +
                output_name=output_name,
84 +
                directory_path=directory_path,
85 +
            )
86 +
        else:
87 +
            raise NotImplementedError()
88 +
89 +
    else:
90 +
        raise NotImplementedError()
91 +
92 +
93 +
def _generate_gaff_atom_types(
94 +
    mol2_file: str,
95 +
    residue_name: str,
96 +
    output_name: str,
97 +
    gaff_version: Optional[str] = "gaff2",
98 +
    directory_path: Optional[str] = "benchmarks",
99 +
):
100 +
    """Generate a mol2 file with GAFF atom types."""
101 +
102 +
    if gaff_version.lower() not in ["gaff", "gaff2"]:
103 +
        raise KeyError(
104 +
            f"Parameter set {gaff_version} not supported. Only [gaff, gaff2] are allowed."
105 +
        )
106 +
107 +
    p = subprocess.Popen(
108 +
        [
109 +
            "antechamber",
110 +
            "-i",
111 +
            mol2_file,
112 +
            "-fi",
113 +
            "mol2",
114 +
            "-o",
115 +
            f"{output_name}.{gaff_version}.mol2",
116 +
            "-fo",
117 +
            "mol2",
118 +
            "-rn",
119 +
            f"{residue_name.upper()}",
120 +
            "-at",
121 +
            f"{gaff_version}",
122 +
            "-an",
123 +
            "no",
124 +
            "-dr",
125 +
            "no",
126 +
            "-pf",
127 +
            "yes",
128 +
        ],
129 +
        cwd=directory_path,
130 +
    )
131 +
    p.communicate()
132 +
    print(p)
133 +
134 +
    remove_files = [
135 +
        "ANTECHAMBER_AC.AC",
136 +
        "ANTECHAMBER_AC.AC0",
137 +
        "ANTECHAMBER_BOND_TYPE.AC",
138 +
        "ANTECHAMBER_BOND_TYPE.AC0",
139 +
        "ATOMTYPE.INF",
140 +
    ]
141 +
    files = [os.path.join(directory_path, file) for file in remove_files]
142 +
    for file in files:
143 +
        if os.path.isfile(file):
144 +
            logger.debug(f"Removing temporary file: {file}")
145 +
            file.unlink()
146 +
147 +
    if not os.path.exists(f"{output_name}.{gaff_version}.mol2"):
148 +
        # Try with the newer (AmberTools 19) version of `antechamber` which doesn't have the `-dr` flag
149 +
        p = subprocess.Popen(
150 +
            [
151 +
                "antechamber",
152 +
                "-i",
153 +
                mol2_file,
154 +
                "-fi",
155 +
                "mol2",
156 +
                "-o",
157 +
                f"{output_name}.{gaff_version}.mol2",
158 +
                "-fo",
159 +
                "mol2",
160 +
                "-rn",
161 +
                f"{residue_name.upper()}",
162 +
                "-at",
163 +
                f"{gaff_version}",
164 +
                "-an",
165 +
                "no",
166 +
                "-pf",
167 +
                "yes",
168 +
            ],
169 +
            cwd=directory_path,
170 +
        )
171 +
        p.communicate()
172 +
173 +
        remove_files = [
174 +
            "ANTECHAMBER_AC.AC",
175 +
            "ANTECHAMBER_AC.AC0",
176 +
            "ANTECHAMBER_BOND_TYPE.AC",
177 +
            "ANTECHAMBER_BOND_TYPE.AC0",
178 +
            "ATOMTYPE.INF",
179 +
        ]
180 +
        files = [os.path.join(directory_path, file) for file in remove_files]
181 +
        for file in files:
182 +
            if os.path.isfile(file):
183 +
                logger.debug(f"Removing temporary file: {file}")
184 +
                file.unlink()
185 +
186 +
187 +
def _generate_frcmod(
188 +
    mol2_file: str,
189 +
    gaff_version: str,
190 +
    output_name: str,
191 +
    directory_path: Optional[str] = "benchmarks",
192 +
):
193 +
    """Generate an AMBER .frcmod file given a mol2 file."""
194 +
195 +
    if gaff_version.lower() not in ["gaff", "gaff2"]:
196 +
        raise KeyError(
197 +
            f"Parameter set {gaff_version} not supported. Only [gaff, gaff2] are allowed."
198 +
        )
199 +
200 +
    subprocess.Popen(
201 +
        [
202 +
            "parmchk2",
203 +
            "-i",
204 +
            str(mol2_file),
205 +
            "-f",
206 +
            "mol2",
207 +
            "-o",
208 +
            f"{output_name}.{gaff_version}.frcmod",
209 +
            "-s",
210 +
            f"{gaff_version}",
211 +
        ],
212 +
        cwd=directory_path,
213 +
    )
0 214
imilarity index 98%
1 215
ename from paprika/analyze.py
2 216
ename to paprika/evaluator/analyze.py

@@ -0,0 +1,254 @@
Loading
1 +
"""
2 +
Tests evaluator modules.
3 +
"""
4 +
import logging
5 +
import os
6 +
import shutil
7 +
8 +
import numpy as np
9 +
import parmed as pmd
10 +
import pytest
11 +
import pytraj as pt
12 +
13 +
from paprika.evaluator import Analyze, Setup
14 +
from paprika.evaluator.amber import generate_gaff
15 +
from paprika.restraints import DAT_restraint
16 +
17 +
logger = logging.getLogger(__name__)
18 +
19 +
20 +
@pytest.fixture
21 +
def clean_files(directory=os.path.join(os.path.dirname(__file__), "tmp")):
22 +
    # This happens before the test function call
23 +
    if os.path.isdir(directory):
24 +
        shutil.rmtree(directory)
25 +
    os.makedirs(directory, exist_ok=True)
26 +
    yield
27 +
    # This happens after the test function call
28 +
    shutil.rmtree(directory)
29 +
30 +
31 +
def test_evaluator_setup_structure(clean_files):
32 +
    temporary_directory = os.path.join(os.path.dirname(__file__), "tmp")
33 +
34 +
    G1 = ":BUT@C"
35 +
    G2 = ":BUT@C3"
36 +
37 +
    # Test prepare_complex_structure
38 +
    host_guest_pdb = os.path.join(os.path.dirname(__file__), "../data/cb6-but/vac.pdb")
39 +
    guest_atom_indices = []
40 +
    structure = pmd.load_file(host_guest_pdb, structure=True)
41 +
    for atom in structure.topology.atoms():
42 +
        if atom.residue.name == "BUT":
43 +
            guest_atom_indices.append(atom.index)
44 +
45 +
    host_guest_structure_initial = Setup.prepare_complex_structure(
46 +
        host_guest_pdb,
47 +
        guest_atom_indices,
48 +
        f"{G1} {G2}",
49 +
        24.0,
50 +
        0,
51 +
        46,
52 +
    )
53 +
54 +
    assert all(host_guest_structure_initial[G1].coordinates[0] == [0.0, 0.0, 0.0])
55 +
56 +
    host_guest_structure_final = Setup.prepare_complex_structure(
57 +
        host_guest_pdb,
58 +
        guest_atom_indices,
59 +
        f"{G1} {G2}",
60 +
        24.0,
61 +
        45,
62 +
        46,
63 +
    )
64 +
    assert all(host_guest_structure_final[G1].coordinates[0] == [0.0, 0.0, 24.0])
65 +
66 +
    cG1 = host_guest_structure_final[G1].coordinates[0]
67 +
    cG2 = host_guest_structure_final[G2].coordinates[0]
68 +
    vec = cG2 - cG1
69 +
    axis = np.array([0, 0, 1])
70 +
    theta = np.arccos(np.dot(vec, axis) / (np.linalg.norm(vec) * np.linalg.norm(axis)))
71 +
    assert theta == 0.0
72 +
73 +
    # Test prepare_host_structure
74 +
    structure = pmd.load_file(host_guest_pdb, structure=True)
75 +
    structure[":CB6"].save(os.path.join(temporary_directory, "cb6.pdb"))
76 +
    host_pdb = os.path.join(temporary_directory, "cb6.pdb")
77 +
    host_atom_indices = []
78 +
    for atom in structure.topology.atoms():
79 +
        if atom.residue.name == "CB6":
80 +
            host_atom_indices.append(atom.index)
81 +
82 +
    host_structure = Setup.prepare_host_structure(
83 +
        host_pdb,
84 +
        host_atom_indices,
85 +
    )
86 +
    center_of_mass = pmd.geometry.center_of_mass(
87 +
        host_structure.coordinates, masses=np.ones(len(host_structure.coordinates))
88 +
    )
89 +
    assert pytest.approx(center_of_mass[0], abs=1e-3) == 0.0
90 +
    assert pytest.approx(center_of_mass[1], abs=1e-3) == 0.0
91 +
    assert pytest.approx(center_of_mass[2], abs=1e-3) == 0.0
92 +
93 +
    inertia_tensor = np.dot(
94 +
        host_structure.coordinates.transpose(), host_structure.coordinates
95 +
    )
96 +
    eig_val, eig_vec = np.linalg.eig(inertia_tensor)
97 +
    assert pytest.approx(eig_vec[0, -1], abs=1e-3) == 0.0
98 +
    assert pytest.approx(eig_vec[1, -1], abs=1e-3) == 0.0
99 +
    assert pytest.approx(eig_vec[2, -1], abs=1e-3) == 1.0
100 +
101 +
    # Test add dummy
102 +
    Setup.add_dummy_atoms_to_structure(
103 +
        host_structure,
104 +
        [
105 +
            np.array([0, 0, 0]),
106 +
            np.array([0, 0, -3.0]),
107 +
            np.array([0, 2.2, -5.2]),
108 +
        ],
109 +
        np.zeros(3),
110 +
    )
111 +
    dummy_atoms = []
112 +
    for atom in host_structure.topology.atoms():
113 +
        if atom.name == "DUM":
114 +
            dummy_atoms.append(atom)
115 +
116 +
    assert len(dummy_atoms) == 3
117 +
    assert pytest.approx(host_structure[":DM1"].coordinates[0][2], abs=1e-3) == 0.0
118 +
    assert pytest.approx(host_structure[":DM2"].coordinates[0][2], abs=1e-3) == -3.0
119 +
    assert pytest.approx(host_structure[":DM3"].coordinates[0][1], abs=1e-3) == 2.2
120 +
    assert pytest.approx(host_structure[":DM3"].coordinates[0][2], abs=1e-3) == -5.2
121 +
122 +
123 +
def test_evaluator_analyze(clean_files):
124 +
    input_pdb = os.path.join(os.path.dirname(__file__), "../data/cb6-but/vac.pdb")
125 +
    structure = pmd.load_file(input_pdb, structure=True)
126 +
127 +
    guest_atom_indices = []
128 +
    for atom in structure.topology.atoms():
129 +
        if atom.residue.name == "BUT":
130 +
            guest_atom_indices.append(atom.index)
131 +
132 +
    host_guest_structure = Setup.prepare_complex_structure(
133 +
        input_pdb,
134 +
        guest_atom_indices,
135 +
        ":BUT@C :BUT@C3",
136 +
        24.0,
137 +
        0,
138 +
        46,
139 +
    )
140 +
    Setup.add_dummy_atoms_to_structure(
141 +
        host_guest_structure,
142 +
        [
143 +
            np.array([0, 0, 0]),
144 +
            np.array([0, 0, -3.0]),
145 +
            np.array([0, 2.2, -5.2]),
146 +
        ],
147 +
        np.zeros(3),
148 +
    )
149 +
150 +
    # Distance restraint
151 +
    rest1 = DAT_restraint()
152 +
    rest1.continuous_apr = True
153 +
    rest1.amber_index = True
154 +
    rest1.topology = host_guest_structure
155 +
    rest1.mask1 = ":DM1"
156 +
    rest1.mask2 = ":BUT@C"
157 +
    rest1.attach["target"] = 6.0
158 +
    rest1.attach["fraction_list"] = [0.00, 0.04, 0.181, 0.496, 1.000]
159 +
    rest1.attach["fc_final"] = 5.0
160 +
    rest1.pull["fc"] = rest1.attach["fc_final"]
161 +
    rest1.pull["target_initial"] = rest1.attach["target"]
162 +
    rest1.pull["target_final"] = 24.0
163 +
    rest1.pull["num_windows"] = 19
164 +
    rest1.initialize()
165 +
166 +
    # Angle 1 restraint
167 +
    rest2 = DAT_restraint()
168 +
    rest2.continuous_apr = True
169 +
    rest2.amber_index = True
170 +
    rest2.topology = input_pdb
171 +
    rest2.mask1 = ":DM2"
172 +
    rest2.mask2 = ":DM1"
173 +
    rest2.mask3 = ":BUT@C"
174 +
    rest2.attach["target"] = 180.0
175 +
    rest2.attach["fraction_list"] = [0.00, 0.04, 0.181, 0.496, 1.000]
176 +
    rest2.attach["fc_final"] = 100.0
177 +
    rest2.pull["fc"] = rest2.attach["fc_final"]
178 +
    rest2.pull["target_initial"] = rest2.attach["target"]
179 +
    rest2.pull["target_final"] = rest2.attach["target"]
180 +
    rest2.pull["num_windows"] = 19
181 +
    rest2.initialize()
182 +
183 +
    # Angle 2
184 +
    rest3 = DAT_restraint()
185 +
    rest3.continuous_apr = True
186 +
    rest3.amber_index = True
187 +
    rest3.topology = input_pdb
188 +
    rest3.mask1 = ":DM1"
189 +
    rest3.mask2 = ":BUT@C"
190 +
    rest3.mask3 = ":BUT@C3"
191 +
    rest3.attach["target"] = 180.0
192 +
    rest3.attach["fraction_list"] = [0.00, 0.04, 0.181, 0.496, 1.000]
193 +
    rest3.attach["fc_final"] = 100.0
194 +
    rest3.pull["fc"] = rest2.attach["fc_final"]
195 +
    rest3.pull["target_initial"] = rest2.attach["target"]
196 +
    rest3.pull["target_final"] = rest2.attach["target"]
197 +
    rest3.pull["num_windows"] = 19
198 +
    rest3.initialize()
199 +
200 +
    temperature = 298.15
201 +
    guest_restraints = [rest1, rest2, rest3]
202 +
    ref_state_work = Analyze.compute_ref_state_work(temperature, guest_restraints)
203 +
    assert pytest.approx(ref_state_work, abs=1e-3) == -7.14151
204 +
205 +
    fe_sym = Analyze.symmetry_correction(n_microstates=1, temperature=298.15)
206 +
    assert fe_sym == 0.0
207 +
    fe_sym = Analyze.symmetry_correction(n_microstates=2, temperature=298.15)
208 +
    assert pytest.approx(fe_sym, abs=1e-3) == -0.410679
209 +
210 +
211 +
def test_evaluator_gaff(clean_files):
212 +
    temporary_directory = os.path.join(os.path.dirname(__file__), "tmp")
213 +
214 +
    butane = os.path.join(os.path.dirname(__file__), "../data/cb6-but/but.mol2")
215 +
    resname = "BUT"
216 +
217 +
    gaff_version = "gaff"
218 +
    generate_gaff(
219 +
        butane,
220 +
        resname,
221 +
        output_name="but",
222 +
        gaff_version=gaff_version,
223 +
        directory_path=temporary_directory,
224 +
    )
225 +
226 +
    structure = pt.iterload(
227 +
        os.path.join(temporary_directory, f"but.{gaff_version}.mol2")
228 +
    )
229 +
230 +
    butane_atom_type = [
231 +
        "c3",
232 +
        "hc",
233 +
        "hc",
234 +
        "hc",
235 +
        "c3",
236 +
        "hc",
237 +
        "c3",
238 +
        "hc",
239 +
        "hc",
240 +
        "hc",
241 +
        "c3",
242 +
        "hc",
243 +
        "hc",
244 +
        "hc",
245 +
    ]
246 +
    residue_names = []
247 +
    for i, atom in enumerate(structure.topology.atoms):
248 +
        if atom.resname not in residue_names:
249 +
            residue_names.append(atom.resname)
250 +
251 +
        assert atom.type == butane_atom_type[i]
252 +
253 +
    assert len(residue_names) == 1
254 +
    assert residue_names[0] == resname

@@ -15,7 +15,7 @@
Loading
15 15
16 16
class Analyze:
17 17
    """
18 -
    The Analyze class provides a wrapper function around the analysis of simulations.
18 +
    The ``Analyze`` class provides a wrapper function around the analysis of simulations.
19 19
    """
20 20
21 21
    @classmethod
22 22
imilarity index 83%
23 23
ename from paprika/setup.py
24 24
ename to paprika/evaluator/setup.py

@@ -3,13 +3,10 @@
Loading
3 3
"""
4 4
5 5
import logging
6 -
import os
7 -
import subprocess
8 6
from typing import Any, Dict, List, Optional
9 7
10 8
import numpy as np
11 9
import parmed as pmd
12 -
import pkg_resources
13 10
14 11
from paprika import align
15 12
from paprika.restraints import DAT_restraint, static_DAT_restraint
@@ -20,7 +17,7 @@
Loading
20 17
21 18
class Setup:
22 19
    """
23 -
    The Setup class provides a wrapper function around the preparation of the host-guest
20 +
    The ``Setup`` class provides a wrapper function around the preparation of the host-guest
24 21
    system and the application of restraints.
25 22
    """
26 23
@@ -607,167 +604,3 @@
Loading
607 604
            restraints.append(guest_restraint)
608 605
609 606
        return restraints
610 -
611 -
612 -
def get_benchmarks():
613 -
    """
614 -
    Determine the installed `taproom` benchmarks.
615 -
    """
616 -
    installed_benchmarks = {}
617 -
618 -
    for entry_point in pkg_resources.iter_entry_points(group="taproom.benchmarks"):
619 -
        installed_benchmarks[entry_point.name] = entry_point.load()
620 -
621 -
    return installed_benchmarks
622 -
623 -
624 -
def generate_gaff(
625 -
    mol2_file,
626 -
    residue_name,
627 -
    output_name=None,
628 -
    need_gaff_atom_types=True,
629 -
    generate_frcmod=True,
630 -
    directory_path="benchmarks",
631 -
    gaff="gaff2",
632 -
):
633 -
634 -
    if output_name is None:
635 -
        output_name = mol2_file.stem
636 -
637 -
    if need_gaff_atom_types:
638 -
        _generate_gaff_atom_types(
639 -
            mol2_file=mol2_file,
640 -
            residue_name=residue_name,
641 -
            output_name=output_name,
642 -
            gaff=gaff,
643 -
            directory_path=directory_path,
644 -
        )
645 -
        logging.debug(
646 -
            "Checking to see if we have a multi-residue MOL2 file that should be converted "
647 -
            "to single-residue..."
648 -
        )
649 -
        structure = pmd.load_file(
650 -
            os.path.join(directory_path, f"{output_name}.{gaff}.mol2"), structure=True
651 -
        )
652 -
        if len(structure.residues) > 1:
653 -
            structure[":1"].save("tmp.mol2")
654 -
            if os.path.exists("tmp.mol2"):
655 -
                os.rename(
656 -
                    "tmp.mol2",
657 -
                    os.path.join(directory_path, f"{output_name}.{gaff}.mol2"),
658 -
                )
659 -
                logging.debug("Saved single-residue MOL2 file for `tleap`.")
660 -
            else:
661 -
                raise RuntimeError(
662 -
                    "Unable to convert multi-residue MOL2 file to single-residue for `tleap`."
663 -
                )
664 -
665 -
        if generate_frcmod:
666 -
            _generate_frcmod(
667 -
                mol2_file=f"{output_name}.{gaff}.mol2",
668 -
                gaff=gaff,
669 -
                output_name=output_name,
670 -
                directory_path=directory_path,
671 -
            )
672 -
        else:
673 -
            raise NotImplementedError()
674 -
675 -
676 -
def _generate_gaff_atom_types(
677 -
    mol2_file, residue_name, output_name, gaff="gaff2", directory_path="benchmarks"
678 -
):
679 -
680 -
    p = subprocess.Popen(
681 -
        [
682 -
            "antechamber",
683 -
            "-i",
684 -
            str(mol2_file),
685 -
            "-fi",
686 -
            "mol2",
687 -
            "-o",
688 -
            f"{output_name}.{gaff}.mol2",
689 -
            "-fo",
690 -
            "mol2",
691 -
            "-rn",
692 -
            f"{residue_name.upper()}",
693 -
            "-at",
694 -
            f"{gaff}",
695 -
            "-an",
696 -
            "no",
697 -
            "-dr",
698 -
            "no",
699 -
            "-pf",
700 -
            "yes",
701 -
        ],
702 -
        cwd=directory_path,
703 -
    )
704 -
    p.communicate()
705 -
706 -
    files = [
707 -
        "ANTECHAMBER_AC.AC",
708 -
        "ANTECHAMBER_AC.AC0",
709 -
        "ANTECHAMBER_BOND_TYPE.AC",
710 -
        "ANTECHAMBER_BOND_TYPE.AC0",
711 -
        "ATOMTYPE.INF",
712 -
    ]
713 -
    files = [directory_path.joinpath(i) for i in files]
714 -
    for file in files:
715 -
        if file.exists():
716 -
            logger.debug(f"Removing temporary file: {file}")
717 -
            file.unlink()
718 -
719 -
    if not os.path.exists(f"{output_name}.{gaff}.mol2"):
720 -
        # Try with the newer (AmberTools 19) version of `antechamber` which doesn't have the `-dr` flag
721 -
        p = subprocess.Popen(
722 -
            [
723 -
                "antechamber",
724 -
                "-i",
725 -
                str(mol2_file),
726 -
                "-fi",
727 -
                "mol2",
728 -
                "-o",
729 -
                f"{output_name}.{gaff}.mol2",
730 -
                "-fo",
731 -
                "mol2",
732 -
                "-rn",
733 -
                f"{residue_name.upper()}",
734 -
                "-at",
735 -
                f"{gaff}",
736 -
                "-an",
737 -
                "no",
738 -
                "-pf",
739 -
                "yes",
740 -
            ],
741 -
            cwd=directory_path,
742 -
        )
743 -
        p.communicate()
744 -
745 -
        files = [
746 -
            "ANTECHAMBER_AC.AC",
747 -
            "ANTECHAMBER_AC.AC0",
748 -
            "ANTECHAMBER_BOND_TYPE.AC",
749 -
            "ANTECHAMBER_BOND_TYPE.AC0",
750 -
            "ATOMTYPE.INF",
751 -
        ]
752 -
        files = [directory_path.joinpath(i) for i in files]
753 -
        for file in files:
754 -
            if file.exists():
755 -
                logger.debug(f"Removing temporary file: {file}")
756 -
                file.unlink()
757 -
758 -
759 -
def _generate_frcmod(mol2_file, gaff, output_name, directory_path="benchmarks"):
760 -
    subprocess.Popen(
761 -
        [
762 -
            "parmchk2",
763 -
            "-i",
764 -
            str(mol2_file),
765 -
            "-f",
766 -
            "mol2",
767 -
            "-o",
768 -
            f"{output_name}.{gaff}.frcmod",
769 -
            "-s",
770 -
            f"{gaff}",
771 -
        ],
772 -
        cwd=directory_path,
773 -
    )

@@ -0,0 +1,13 @@
Loading
1 +
import pkg_resources
2 +
3 +
4 +
def get_benchmarks():
5 +
    """
6 +
    Determine the installed ``taproom`` benchmarks.
7 +
    """
8 +
    installed_benchmarks = {}
9 +
10 +
    for entry_point in pkg_resources.iter_entry_points(group="taproom.benchmarks"):
11 +
        installed_benchmarks[entry_point.name] = entry_point.load()
12 +
13 +
    return installed_benchmarks

@@ -0,0 +1,7 @@
Loading
1 +
from .analyze import Analyze
2 +
from .setup import Setup
3 +
4 +
__all__ = [
5 +
    Analyze,
6 +
    Setup,
7 +
]
Files Coverage
paprika 74.79%
Project Totals (36 files) 74.79%
1
# Codecov configuration to make it a bit less noisy
2
coverage:
3
  status:
4
    patch: false
5
    project:
6
      default:
7
        threshold: 50%
8
comment:
9
  layout: "header"
10
  require_changes: false
11
  branches: null
12
  behavior: default
13
  flags: null
14
  paths: null
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading