Example #1
0
    def _execute(self, directory, available_resources):

        from openforcefield.topology import Molecule, Topology

        pdb_file = app.PDBFile(self.coordinate_file_path)

        force_field_source = ForceFieldSource.from_json(self.force_field_path)

        if not isinstance(force_field_source, SmirnoffForceFieldSource):
            raise ValueError(
                "Only SMIRNOFF force fields are supported by this protocol.")

        force_field = force_field_source.to_force_field()

        unique_molecules = []
        charged_molecules = []

        if self.apply_known_charges:
            charged_molecules = self._generate_known_charged_molecules()

        # Load in any additional, user specified charged molecules.
        for charged_molecule_path in self.charged_molecule_paths:

            charged_molecule = Molecule.from_file(charged_molecule_path,
                                                  "MOL2")
            charged_molecules.append(charged_molecule)

        for component in self.substance.components:

            molecule = Molecule.from_smiles(smiles=component.smiles)

            if molecule is None:
                raise ValueError(
                    f"{component} could not be converted to a Molecule")

            unique_molecules.append(molecule)

        topology = Topology.from_openmm(pdb_file.topology,
                                        unique_molecules=unique_molecules)

        if len(charged_molecules) > 0:
            system = force_field.create_openmm_system(
                topology, charge_from_molecules=charged_molecules)
        else:
            system = force_field.create_openmm_system(topology)

        if system is None:

            raise RuntimeError(
                "Failed to create a system from the specified topology and molecules."
            )

        system_xml = openmm.XmlSerializer.serialize(system)
        self.system_path = os.path.join(directory, "system.xml")

        with open(self.system_path, "w") as file:
            file.write(system_xml)
Example #2
0
    def _execute(self, directory, available_resources):

        force_field_source = ForceFieldSource.from_json(self.force_field_path)

        if not isinstance(force_field_source, TLeapForceFieldSource):

            raise ValueError(
                "Only TLeap force field sources are supported by this protocol."
            )

        super(BuildTLeapSystem, self)._execute(directory, available_resources)
Example #3
0
    def _execute(self, directory, available_resources):

        with open(self.force_field_path) as file:
            force_field_source = ForceFieldSource.parse_json(file.read())

        if not isinstance(force_field_source, LigParGenForceFieldSource):

            raise ValueError(
                "Only LigParGen force field sources are supported by this protocol."
            )

        super(BuildLigParGenSystem, self)._execute(directory,
                                                   available_resources)

        with open(self.system_path) as file:
            system = openmm.XmlSerializer.deserialize(file.read())

        # Apply the OPLS mixing rules.
        self._apply_opls_mixing_rules(system)

        with open(self.system_path, "w") as file:
            file.write(openmm.XmlSerializer.serialize(system))
Example #4
0
    def _execute(self, directory, available_resources):

        from openforcefield.topology import Molecule, Topology

        force_field_source = ForceFieldSource.from_json(self.force_field_path)
        cutoff = pint_quantity_to_openmm(force_field_source.cutoff)

        # Load in the systems topology
        openmm_pdb_file = app.PDBFile(self.coordinate_file_path)

        # Create an OFF topology for better insight into the layout of the system
        # topology.
        unique_molecules = {}

        for component in self.substance:
            unique_molecule = Molecule.from_smiles(component.smiles)
            unique_molecules[unique_molecule.to_smiles()] = unique_molecule

        # Parameterize each component in the system.
        system_templates = {}

        for index, (smiles,
                    unique_molecule) in enumerate(unique_molecules.items()):

            if smiles in ["O", "[H]O[H]", "[H][O][H]"]:

                component_system = self._build_tip3p_system(
                    cutoff,
                    openmm_pdb_file.topology.getUnitCellDimensions(),
                )

            else:

                component_directory = os.path.join(directory, str(index))
                os.makedirs(component_directory, exist_ok=True)

                with temporarily_change_directory(component_directory):

                    component_system = self._parameterize_molecule(
                        unique_molecule, force_field_source, cutoff)

            system_templates[smiles] = component_system

        # Apply the parameters to the topology.
        topology = Topology.from_openmm(openmm_pdb_file.topology,
                                        unique_molecules.values())

        # Create the full system object from the component templates.
        system = self._create_empty_system(cutoff)

        for topology_molecule in topology.topology_molecules:

            smiles = topology_molecule.reference_molecule.to_smiles()
            system_template = system_templates[smiles]

            index_map = {}

            for index, topology_atom in enumerate(topology_molecule.atoms):
                index_map[topology_atom.atom.molecule_particle_index] = index

            # Append the component template to the full system.
            self._append_system(system, system_template, index_map)

        if openmm_pdb_file.topology.getPeriodicBoxVectors() is not None:

            system.setDefaultPeriodicBoxVectors(
                *openmm_pdb_file.topology.getPeriodicBoxVectors())

        # Serialize the system object.
        self.system_path = os.path.join(directory, "system.xml")

        with open(self.system_path, "w") as file:
            file.write(openmm.XmlSerializer.serialize(system))
Example #5
0
    def _execute(self, directory, available_resources):

        import mdtraj
        from openforcefield.topology import Molecule, Topology

        with open(self.force_field_path) as file:
            force_field_source = ForceFieldSource.parse_json(file.read())

        if not isinstance(force_field_source, SmirnoffForceFieldSource):

            raise ValueError(
                "Only SMIRNOFF force fields are supported by this protocol.", )

        # Load in the inputs
        force_field = force_field_source.to_force_field()

        trajectory = mdtraj.load_dcd(self.trajectory_file_path,
                                     self.coordinate_file_path)

        unique_molecules = []

        for component in self.substance.components:

            molecule = Molecule.from_smiles(smiles=component.smiles)
            unique_molecules.append(molecule)

        pdb_file = app.PDBFile(self.coordinate_file_path)
        topology = Topology.from_openmm(pdb_file.topology,
                                        unique_molecules=unique_molecules)

        # Compute the difference between the energies using the reduced force field,
        # and the full force field.
        energy_corrections = None

        if self.use_subset_of_force_field:

            target_system, _ = self._build_reduced_system(
                force_field, topology)

            subset_potentials_path = os.path.join(directory, f"subset.csv")
            subset_potentials = self._evaluate_reduced_potential(
                target_system, trajectory, subset_potentials_path,
                available_resources)

            full_statistics = StatisticsArray.from_pandas_csv(
                self.statistics_path)

            energy_corrections = (
                full_statistics[ObservableType.PotentialEnergy] -
                subset_potentials[ObservableType.PotentialEnergy])

        # Build the slightly perturbed system.
        reverse_system, reverse_parameter_value = self._build_reduced_system(
            force_field, topology, -self.perturbation_scale)

        forward_system, forward_parameter_value = self._build_reduced_system(
            force_field, topology, self.perturbation_scale)

        self.reverse_parameter_value = openmm_quantity_to_pint(
            reverse_parameter_value)
        self.forward_parameter_value = openmm_quantity_to_pint(
            forward_parameter_value)

        # Calculate the reduced potentials.
        self.reverse_potentials_path = os.path.join(directory, "reverse.csv")
        self.forward_potentials_path = os.path.join(directory, "forward.csv")

        self._evaluate_reduced_potential(
            reverse_system,
            trajectory,
            self.reverse_potentials_path,
            available_resources,
            energy_corrections,
        )
        self._evaluate_reduced_potential(
            forward_system,
            trajectory,
            self.forward_potentials_path,
            available_resources,
            energy_corrections,
        )
    def _find_relevant_gradient_keys(substance, force_field_path,
                                     parameter_gradient_keys):
        """Extract only those keys which may be applied to the
        given substance.

        Parameters
        ----------
        substance: Substance
            The substance to compare against.
        force_field_path: str
            The path to the force field which contains the parameters.
        parameter_gradient_keys: list of ParameterGradientKey
            The original list of parameter gradient keys.

        Returns
        -------
        list of ParameterGradientKey
            The filtered list of parameter gradient keys.
        """
        from openforcefield.topology import Molecule, Topology

        # noinspection PyTypeChecker
        if parameter_gradient_keys == UNDEFINED or len(
                parameter_gradient_keys) == 0:
            return []

        with open(force_field_path) as file:
            force_field_source = ForceFieldSource.parse_json(file.read())

        if not isinstance(force_field_source, SmirnoffForceFieldSource):
            return []

        force_field = force_field_source.to_force_field()

        all_molecules = []

        for component in substance.components:
            all_molecules.append(Molecule.from_smiles(component.smiles))

        topology = Topology.from_molecules(all_molecules)
        labelled_molecules = force_field.label_molecules(topology)

        reduced_parameter_keys = []

        for labelled_molecule in labelled_molecules:

            for parameter_key in parameter_gradient_keys:

                if (parameter_key.tag not in labelled_molecule
                        or parameter_key in reduced_parameter_keys):
                    continue

                contains_parameter = False

                for parameter in labelled_molecule[
                        parameter_key.tag].store.values():

                    if parameter.smirks != parameter_key.smirks:
                        continue

                    contains_parameter = True
                    break

                if not contains_parameter:
                    continue

                reduced_parameter_keys.append(parameter_key)

        return reduced_parameter_keys