Example #1
0
def test_rb_energy_round_trip(tmpdir):
    """
    Make sure that no parameters are lost when reading in  RBterms.
    """
    with tmpdir.as_cwd():
        # load the molecule and parameterise
        mol = Ligand.from_file(file_name=get_data("cyclohexane.sdf"))
        XML().run(molecule=mol, input_files=[get_data("cyclohexane.xml")])
        # load the serialised system we extract the parameters from as our reference
        ref_system = XmlSerializer.deserializeSystem(
            open("serialised.xml").read())
        parm_top = load_topology(mol.to_openmm_topology(),
                                 system=ref_system,
                                 xyz=mol.openmm_coordinates())
        ref_energy = energy_decomposition_system(parm_top,
                                                 ref_system,
                                                 platform="Reference")
        # now we need to build the system from our stored parameters
        mol.write_parameters(file_name="test.xml")
        ff = app.ForceField("test.xml")
        qube_system = ff.createSystem(mol.to_openmm_topology())
        with open("qube.xml", "w") as xml_out:
            xml_out.write(XmlSerializer.serialize(qube_system))
        qube_struc = load_topology(mol.to_openmm_topology(),
                                   system=qube_system,
                                   xyz=mol.openmm_coordinates())
        qube_energy = energy_decomposition_system(qube_struc,
                                                  qube_system,
                                                  platform="Reference")
        # compare the decomposed energies of the groups
        for force_group, energy in ref_energy:
            for qube_force, qube_e in qube_energy:
                if force_group == qube_force:
                    assert energy == pytest.approx(qube_e, abs=2e-3)
Example #2
0
def test_offxml_round_trip(tmpdir, openff, molecule):
    """
    Test round tripping offxml parameters through qubekit
    """

    with tmpdir.as_cwd():
        mol = Ligand.from_file(get_data(molecule))
        offmol = Molecule.from_file(get_data(molecule))
        openff.run(mol)
        mol.to_offxml("test.offxml")
        # build another openmm system and serialise to compare with deepdiff
        offxml = ForceField("test.offxml")
        assert offxml.author == f"QUBEKit_version_{qubekit.__version__}"
        qubekit_system = offxml.create_openmm_system(
            topology=offmol.to_topology())
        qubekit_xml = xmltodict.parse(
            openmm.XmlSerializer.serialize(qubekit_system))
        with open("qubekit_xml", "w") as output:
            output.write(openmm.XmlSerializer.serialize(qubekit_system))
        openff_system = xmltodict.parse(open("serialised.xml").read())

        offxml_diff = DeepDiff(
            qubekit_xml,
            openff_system,
            ignore_order=True,
            significant_digits=6,
        )
        # the only difference should be in torsions with a 0 barrier height which are excluded from an offxml
        for item in offxml_diff["iterable_item_removed"].values():
            assert item["@k"] == "0"

        # load both systems and compute the energy
        qubekit_top = load_topology(
            mol.to_openmm_topology(),
            system=qubekit_system,
            xyz=mol.openmm_coordinates(),
        )
        qubekit_energy = energy_decomposition_system(qubekit_top,
                                                     qubekit_system,
                                                     platform="Reference")

        ref_system = XmlSerializer.deserializeSystem(
            open("serialised.xml").read())
        parm_top = load_topology(mol.to_openmm_topology(),
                                 system=ref_system,
                                 xyz=mol.openmm_coordinates())
        ref_energy = energy_decomposition_system(parm_top,
                                                 ref_system,
                                                 platform="Reference")
        # compare the decomposed energies of the groups
        for force_group, energy in ref_energy:
            for qube_force, qube_e in qubekit_energy:
                if force_group == qube_force:
                    assert energy == pytest.approx(qube_e, abs=2e-3)
Example #3
0
def test_round_trip_energy(tmpdir, molecule, method, openff, antechamber):
    """
    Make sure that no terms are missing when storing parameters from source by comparing energies.

    Note we relax the comparison to abs=2e-3 due to differences in nonbonded cutoffs, phase rounding and the ordering
    improper torsions are applied.
    """
    if method == "openff":
        engine = openff
    else:
        engine = antechamber

    with tmpdir.as_cwd():
        mol = Ligand.from_file(get_data(molecule))
        # parametrise the system
        engine.run(mol)
        # this will make a serialised system in the folder so get the reference energy
        ref_system = XmlSerializer.deserializeSystem(
            open("serialised.xml").read())
        parm_top = load_topology(mol.to_openmm_topology(),
                                 system=ref_system,
                                 xyz=mol.openmm_coordinates())
        ref_energy = energy_decomposition_system(parm_top,
                                                 ref_system,
                                                 platform="Reference")
        # now we need to build the system from our stored parameters
        mol.write_parameters(file_name="test.xml")
        ff = app.ForceField("test.xml")
        qube_system = ff.createSystem(mol.to_openmm_topology())
        with open("qube.xml", "w") as xml_out:
            xml_out.write(XmlSerializer.serialize(qube_system))
        qube_struc = load_topology(mol.to_openmm_topology(),
                                   system=qube_system,
                                   xyz=mol.openmm_coordinates())
        qube_energy = energy_decomposition_system(qube_struc,
                                                  qube_system,
                                                  platform="Reference")
        # compare the decomposed energies of the groups
        for force_group, energy in ref_energy:
            for qube_force, qube_e in qube_energy:
                if force_group == qube_force:
                    assert energy == pytest.approx(qube_e, abs=2e-3)
Example #4
0
    def init_openmm(self, integrator_params=None, create_system_params=None):
        """
        Method that initiates OpenMM by creating

        Parameters
        ----------
        integrator_params : dict
            Keyword arguments passed to the simtk.openmm.openmm.LangevinIntegrator
        create_system_params : dict
            Keyword arguments passed to simtk.openmm.app.amberprmtopfile.createSystem

        Returns
        -------
        system : simtk.openmm.openmm.System
            OpenMM system created.
        """
        from simtk.openmm import XmlSerializer

        assert self.topology_format is not None, "No topology format was provided."
        assert self.crd_format is not None, "No coordinate format was provided."

        if self.topology_format.upper() in ["AMBER", "GROMACS", "CHARMM"]:
            assert self.top_file is not None, "Topology format is {} but no topology file was provided.".format(
                self.topology_format)
        else:
            raise NotImplementedError(
                "Topology format {} is not known.".format(
                    self.topology_format))

        assert self.crd_file is not None, "create_system flag is True but no crd_file was provided."
        if self.platform_name is None:
            logging.info("No platform set. Will use reference.")
            self.platform_name = "Reference"
        else:
            assert self.platform_name in [
                "Reference", "CPU", "OpenCL", "CUDA"
            ], """create_system flag is True but no
               correct platform was provided."""

        # Read topology
        if self.topology_format.upper() == "AMBER":
            if self.topology is None:
                top = app.AmberPrmtopFile(self.top_file)
                self.topology = top.topology
        elif self.topology_format.upper() == "GROMACS":
            if self.topology is None:
                top = app.GromacsTopFile(self.top_file)
                self.topology = top.topology
        elif self.topology_format.upper() == "CHARMM":
            if self.topology is None:
                top = app.CharmmPsfFile(self.top_file)
                self.topology = top.topology
                charmm_params = app.CharmmParameterSet('charmm.rtf',
                                                       self.charmm_param_file)
        else:
            raise NotImplementedError(
                "Topology format {} is not currently supported.".format(
                    self.topology_format))

        # Read coordinate file
        if self.crd_format.upper() == "AMBER":
            crd = app.AmberInpcrdFile(self.crd_file)
        elif self.crd_format.upper() == "GROMACS":
            crd = app.GromacsGroFile(self.crd_file)
        elif self.crd_format.upper() == "CHARMM":
            crd = app.CharmmCrdFile(self.crd_file)
        elif self.crd_format.upper() == "PDB":
            crd = app.PDBFile(self.crd_file)
        else:
            raise NotImplementedError(
                "Coordinate format {} is not currently supported.".format(
                    self.crd_format))

        if self.system is None:
            if self.xml_file is None:
                assert create_system_params is not None, "No settings to create the system were provided."

                logging.info("Creating OpenMM System from {} file.".format(
                    self.topology_format))
                if self.topology_format.upper() == "CHARMM":
                    self.system = top.createSystem(charmm_params,
                                                   **create_system_params)
                else:
                    self.system = top.createSystem(**create_system_params)
            else:
                logging.info("Creating OpenMM System from XML file.")
                xml_file = open(self.xml_file)
                self.system = XmlSerializer.deserializeSystem(xml_file.read())
                xml_file.close()

        if self.integrator is None:
            assert integrator_params is not None, "No settings to create the integrator were provided."

            self.integrator = openmm.LangevinIntegrator(
                integrator_params['temperature'],
                integrator_params["frictionCoeff"],
                integrator_params["stepSize"])
            logging.info("Creating OpenMM integrator.")
        if self.platform is None:
            self.platform = openmm.Platform.getPlatformByName(
                self.platform_name)
            logging.info("Creating OpenMM platform.")
        if self.context is None:
            self.context = openmm.Context(self.system, self.integrator,
                                          self.platform)
            logging.info("Creating OpenMM Context.")

        # Set positions in context
        self.context.setPositions(crd.positions)

        return self.system