예제 #1
0
    def test_from_mdtraj(self):
        """Test construction of an OpenFF Topology from an MDTraj Topology object"""
        import mdtraj as md

        pdb_path = get_data_file_path(
            "systems/test_systems/1_cyclohexane_1_ethanol.pdb")
        trj = md.load(pdb_path)

        with pytest.raises(MissingUniqueMoleculesError,
                           match="requires a list of Molecule objects"):
            Topology.from_mdtraj(trj.top)

        unique_molecules = [
            Molecule.from_smiles(mol_name) for mol_name in ["C1CCCCC1", "CCO"]
        ]
        top = Topology.from_mdtraj(trj.top, unique_molecules=unique_molecules)

        assert top.n_topology_molecules == 2
        assert top.n_topology_bonds == 26
예제 #2
0
def _atom_indices_by_role(
    substance: Substance, coordinate_path: str
) -> Dict[Component.Role, List[int]]:
    """Retrieve the indices of the atoms which belong to components with a
    specific role.
    """
    import mdtraj
    from openff.toolkit.topology import Molecule, Topology

    # Split the substance into the components assigned each role.
    components_by_role = _components_by_role(substance)

    # Create OFF representations of the components
    off_molecules = {
        component: Molecule.from_smiles(component.smiles)
        for components in components_by_role.values()
        for component in components
    }

    # Load in the complex structure.
    mdtraj_trajectory: mdtraj.Trajectory = mdtraj.load_pdb(coordinate_path)

    off_topology: Topology = Topology.from_mdtraj(
        mdtraj_trajectory.topology, off_molecules.values()
    )

    atom_indices = defaultdict(list)

    for component_role in components_by_role:

        for component in components_by_role[component_role]:

            # Find the indices of all instances of this component.
            off_molecule = off_molecules[component]

            for topology_molecule in off_topology.topology_molecules:

                if (
                    topology_molecule.reference_molecule.to_smiles()
                    != off_molecule.to_smiles()
                ):
                    continue

                atom_indices[component_role].extend(
                    [
                        i + topology_molecule.atom_start_topology_index
                        for i in range(topology_molecule.n_atoms)
                    ]
                )

    return atom_indices
예제 #3
0
def test_compute_gradients(tmpdir, smirks, all_zeros):

    # Load a short trajectory.
    coordinate_path = get_data_filename("test/trajectories/water.pdb")
    trajectory_path = get_data_filename("test/trajectories/water.dcd")

    trajectory = mdtraj.load_dcd(trajectory_path, coordinate_path)

    observables = ObservableFrame({
        "PotentialEnergy":
        ObservableArray(
            np.zeros(len(trajectory)) * unit.kilojoule / unit.mole)
    })

    _compute_gradients(
        [ParameterGradientKey("vdW", smirks, "epsilon")],
        observables,
        ForceField("openff-1.2.0.offxml"),
        ThermodynamicState(298.15 * unit.kelvin, 1.0 * unit.atmosphere),
        Topology.from_mdtraj(trajectory.topology, [Molecule.from_smiles("O")]),
        trajectory,
        ComputeResources(),
        True,
    )

    assert len(
        observables["PotentialEnergy"].gradients[0].value) == len(trajectory)

    if all_zeros:
        assert np.allclose(
            observables["PotentialEnergy"].gradients[0].value,
            0.0 * unit.kilojoule / unit.kilocalorie,
        )
    else:
        assert not np.allclose(
            observables["PotentialEnergy"].gradients[0].value,
            0.0 * unit.kilojoule / unit.kilocalorie,
        )