def to_force_field(self):
        """Returns the SMIRNOFF force field created from this source.

        Returns
        -------
        openforcefield.typing.engines.smirnoff.ForceField
            The created force field.
        """
        from openforcefield.typing.engines import smirnoff
        return smirnoff.ForceField(self._inner_xml)
    def __init__(self,
                 source_tree,
                 name,
                 filename=None,
                 ff_kwargs=None,
                 verbose=False):
        super().__init__(source_tree, name, verbose=verbose)

        # This tree operates on entries
        self._select = "Entry"

        self._exception_on_unassigned = True

        self._transformer = offsb.api.tk.ValenceDict

        if ff_kwargs is None:
            ff_kwargs = {}

        if filename is not None:

            logger = logging.getLogger("openforcefield")
            level = logger.getEffectiveLevel()
            logger.setLevel(level=logging.ERROR)
            ext = ".offxml"
            if not filename.endswith(ext):
                filename += ext
            self.filename = filename

            found = False
            for entry_point in ["."] + list(
                    iter_entry_points(
                        group="openforcefield.smirnoff_forcefield_directory")):
                if type(entry_point) == str:
                    pth = entry_point
                else:
                    pth = entry_point.load()()[0]
                abspth = os.path.join(pth, filename)
                if verbose:
                    self.logger.info("Searching {}".format(abspth))
                if os.path.exists(abspth):
                    self.abs_path = abspth
                    if verbose:
                        self.logger.info("Found {}".format(abspth))
                    found = True
                    break
            if not found:
                raise Exception("Forcefield could not be found")
            if verbose:
                self.logger.info("loading {}".format(self.abs_path))
            self.forcefield = OFF.ForceField(self.abs_path,
                                             disable_version_check=True,
                                             **ff_kwargs)
            logger.setLevel(level=level)
def test_force_field_serialization():

    from openforcefield.typing.engines import smirnoff

    force_field = smirnoff.ForceField(get_data_filename('forcefield/smirnoff99Frosst.offxml'))

    serialized_force_field = serialize_force_field(force_field)
    deserialized_force_field = deserialize_force_field(serialized_force_field)

    original_generators = force_field.getGenerators()
    deserialized_generators = deserialized_force_field.getGenerators()

    assert len(original_generators) == len(deserialized_generators)
Example #4
0
    def _get_off_forcefield(self, hashstring, offxml):

        from openforcefield.typing.engines import smirnoff

        key = hashlib.sha256(hashstring.encode()).hexdigest()

        # get forcefield from cache, build new one if not present
        off_forcefield = self._get_cache(key) if key in self._CACHE else smirnoff.ForceField(offxml)

        # cache forcefield, no matter what
        # handles updating time touched, dropping items if cache too large
        self._cache_it(key, off_forcefield)

        return off_forcefield
def compute_estimate_async():
    """Submit calculations to a running server instance"""
    from openforcefield.typing.engines import smirnoff

    setup_timestamp_logging()

    # Load in the data set of interest.
    data_set = ThermoMLDataSet.from_file(get_data_filename('properties/single_dielectric.xml'))
    # Load in the force field to use.
    force_field = smirnoff.ForceField(get_data_filename('forcefield/smirnoff99Frosst.offxml'))

    # new_property_0 = copy.deepcopy(data_set.properties['COCCO{1.0}'][0])
    # new_property_0.thermodynamic_state.temperature -= 2.0 * unit.kelvin
    # new_property_0.id = str(uuid4())
    #
    # data_set.properties['COCCO{1.0}'].append(new_property_0)
    #
    # new_property_1 = copy.deepcopy(data_set.properties['COCCO{1.0}'][0])
    # new_property_1.thermodynamic_state.temperature += 2.0 * unit.kelvin
    # new_property_1.id = str(uuid4())
    #
    # data_set.properties['COCCO{1.0}'].append(new_property_1)

    # Modify the submission options
    submission_options = PropertyEstimatorOptions()

    workflow_options = PropertyWorkflowOptions(PropertyWorkflowOptions.ConvergenceMode.RelativeUncertainty,
                                               relative_uncertainty_fraction=100000)

    submission_options.workflow_options = {
        'Density': workflow_options,
        'Dielectric': workflow_options,
        'EnthalpyOfMixing': workflow_options
    }
    # submission_options.allowed_calculation_layers = ['SimulationLayer']
    submission_options.allowed_calculation_layers = ['ReweightingLayer']

    # Create the client object.
    property_estimator = client.PropertyEstimatorClient()
    # Submit the request to a running server.
    request = property_estimator.request_estimate(data_set, force_field, submission_options)

    logging.info('Request info: {}'.format(str(request)))

    # Wait for the results.
    result = request.results(synchronous=True)

    logging.info('The server has returned a response: {}'.format(result.json()))
def compute_estimate_sync():
    """Submit calculations to a running server instance"""
    from openforcefield.typing.engines import smirnoff

    setup_timestamp_logging()

    # Load in the data set of interest.
    data_set = ThermoMLDataSet.from_file(get_data_filename('properties/single_density.xml'))
    # Load in the force field to use.
    force_field = smirnoff.ForceField(get_data_filename('forcefield/smirnoff99Frosst.offxml'))

    # Create the client object.
    property_estimator = client.PropertyEstimatorClient()
    # Submit the request to a running server, and wait for the results.
    result = property_estimator.request_estimate(data_set, force_field)

    logging.info('The server has returned a response: {}'.format(result))
Example #7
0
def test_local_force_field_storage():
    """A simple test to that force fields can be stored and
    retrieved using the local storage backend."""

    from openforcefield.typing.engines import smirnoff
    force_field = smirnoff.ForceField(
        get_data_filename('forcefield/smirnoff99Frosst.offxml'))

    with tempfile.TemporaryDirectory() as temporary_directory:

        local_storage = LocalFileStorage(temporary_directory)
        local_storage.store_force_field('tmp_id', force_field)

        retrieved_force_field = local_storage.retrieve_force_field('tmp_id')

        serialized_force_field = serialize_force_field(force_field)
        serialized_retrieved_force_field = serialize_force_field(
            retrieved_force_field)

        assert json.dumps(serialized_force_field) == json.dumps(
            serialized_retrieved_force_field)

        local_storage_new = LocalFileStorage(temporary_directory)
        assert local_storage_new.has_force_field(force_field)
def test_estimate_request():
    """Test sending an estimator request to a server."""

    from openforcefield.typing.engines import smirnoff

    with tempfile.TemporaryDirectory() as temporary_directory:

        storage_directory = path.join(temporary_directory, 'storage')
        working_directory = path.join(temporary_directory, 'working')

        dummy_property = create_dummy_property(Density)

        dummy_data_set = PhysicalPropertyDataSet()
        dummy_data_set.properties[dummy_property.substance.identifier] = [
            dummy_property
        ]

        force_field = smirnoff.ForceField(
            get_data_filename('forcefield/smirnoff99Frosst.offxml'))

        calculation_backend = DaskLocalClusterBackend(1, ComputeResources())
        storage_backend = LocalFileStorage(storage_directory)

        PropertyEstimatorServer(calculation_backend,
                                storage_backend,
                                working_directory=working_directory)

        property_estimator = PropertyEstimatorClient()
        options = PropertyEstimatorOptions(
            allowed_calculation_layers=[TestCalculationLayer])

        request = property_estimator.request_estimate(dummy_data_set,
                                                      force_field, options)
        result = request.results(synchronous=True, polling_interval=0)

        assert not isinstance(result, PropertyEstimatorException)
def find_smirks_parameters(smiles_list, molecule_paths):
    """Finds the force field parameters which would
    be assigned to a list of molecules defined by the provided
    SMILES patterns.

    Parameters
    ----------
    smiles_list: list of str
        The SMILES patterns of the target molecules
    molecule_paths: list of Path
        The list of molecules that correspond to the SMILES strings (to make it easier to see which molecules
        utilize which parameters)

    Returns
    -------
    dict of str and list of str
        A dictionary with keys of SMIRKS patterns, and
        values of lists of SMILES patterns which would utilize
        those patterns, and the parameter ID in the force field.
    """

    force_field = smirnoff.ForceField('smirnoff99Frosst-1.0.9.offxml')

    smiles_by_smirks = {}
    smiles_by_smirks["Bonds"] = {}
    smiles_by_smirks["Angles"] = {}
    smiles_by_smirks["ProperTorsions"] = {}
    smiles_by_smirks["vdW"] = {}
    smiles_by_smirks["ImproperTorsions"] = {}
    smiles_by_smirks["Electrostatics"] = {}

    # Populate the dictionary using the open force field toolkit.
    for index, smiles in enumerate(smiles_list):

        ifs = oechem.oemolistream()

        if not ifs.open(str(molecule_paths[index])):
            logging.error(
                f'Unable to open {molecule_paths[index]} for reading...')

        ifs.open(str(molecule_paths[index]))
        oe_mols = []
        for mol in ifs.GetOEMols():
            oe_mols.append(oechem.OEMol(mol))
        oechem.OE3DToAtomStereo(oe_mols[0])
        molecule = Molecule.from_openeye(oe_mols[0])

        # molecule = Molecule.from_smiles(smiles, allow_undefined_stereo=True)
        topology = Topology.from_molecules([molecule])

        molecule_force_list = force_field.label_molecules(topology)

        for molecule_index, molecule_forces in enumerate(molecule_force_list):
            print(f'Forces for molecule {molecule_index}')
            for force_name, force_dict in molecule_forces.items():
                print(f"\n{force_name}:")
                for (atom_indices, parameter) in force_dict.items():
                    atomstr = ''
                    for idx in atom_indices:
                        atomstr += '%5s' % idx
                    print("atoms: %s  parameter_id: %s  smirks %s" % ([
                        oe_mols[0].GetAtom(oechem.OEHasAtomIdx(i)).GetName()
                        for i in atom_indices
                    ], parameter.id, parameter.smirks))

                    # This is not catching _all_ the atoms that hit a certain parameter.
                    # I think these need to be initialized in the outer loop.
                    # Each parameter is getting a list of length 1.

                    if parameter.id not in smiles_by_smirks[force_name]:
                        smiles_by_smirks[force_name][parameter.id] = {}
                    if "atom_indices" not in smiles_by_smirks[force_name]:
                        smiles_by_smirks[force_name][
                            parameter.id]["atom_indices"] = []
                    if "atom_names" not in smiles_by_smirks[force_name]:
                        smiles_by_smirks[force_name][
                            parameter.id]["atom_names"] = []

                    smiles_by_smirks[force_name][
                        parameter.id]["atom_indices"].append(atom_indices)
                    smiles_by_smirks[force_name][
                        parameter.id]["atom_names"].append([
                            oe_mols[0].GetAtom(
                                oechem.OEHasAtomIdx(i)).GetName()
                            for i in atom_indices
                        ])
                    smiles_by_smirks[force_name][
                        parameter.id]["smirks"] = parameter.smirks

    return smiles_by_smirks
Example #10
0
def create_xml_system_files(molecule_mol2_filepath, tip3p_mol2_filepath,
                            vacuum_pdb_filepath, solvated_pdb_filepath,
                            vacuum_xml_filepath, solvated_xml_filepath):
    """Create vacuum and solvated OpenMM systems and save in XML format.

    Parameters
    ----------
    molecule_mol2_filepath : str
        Path to the mol2 file describing the molecule.
    tip3p_mol2_filepath : str
        Path to the mol2 file describing the water molecule with TIP3P charges.
    vacuum_pdb_filepath : str
        Path to the PDB file for the molecule in vacuum.
    solvated_pdb_filepath : str
        Path to the PDB file for the solvated molecule.
    vacuum_xml_filepath : str
        Output path of the vacuum system.
    solvated_xml_filepath : str
        Output path of the solvated system.

    """
    # Load TIP3P water into OpenEye molecule.
    water_oe_mol = load_oe_graph_mol(tip3p_mol2_filepath)

    # Load solvated molecule into OpeneEye molecule.
    molecule_oe_mol = load_oe_graph_mol(molecule_mol2_filepath)

    # Load forcefield.
    # TODO add HBonds constraint through createSystem when openforcefield#32 is implemented.
    ff = smirnoff.ForceField('forcefield/smirnoff99Frosst.ffxml',
                             'hbonds.ffxml', 'forcefield/tip3p.ffxml')

    # Load vacuum and solvated PDBFiles.
    pdb_file_vacuum = openmm.app.PDBFile(vacuum_pdb_filepath)
    pdb_file_solvated = openmm.app.PDBFile(solvated_pdb_filepath)

    # Create vacuum and solvated system.
    system_vacuum = ff.createSystem(pdb_file_vacuum.topology,
                                    molecules=[molecule_oe_mol],
                                    nonbondedMethod=smirnoff.NoCutoff)
    # TODO add HBonds constraints here when openforcefield#32 is implemented.
    system_solvated = ff.createSystem(
        pdb_file_solvated.topology,
        molecules=[molecule_oe_mol, water_oe_mol],
        nonbondedMethod=smirnoff.PME,
        nonbondedCutoff=1.1 * unit.nanometer,
        ewaldErrorTolerance=1e-4)  #, constraints=smirnoff.HBonds)

    # Fix switching function.
    # TODO remove this when openforcefield#31 is fixed
    for force in system_solvated.getForces():
        if isinstance(force, openmm.NonbondedForce):
            force.setUseSwitchingFunction(True)
            force.setSwitchingDistance(1.0 * unit.nanometer)

    # Save XML files.
    for system, xml_filepath in zip(
        [system_vacuum, system_solvated],
        [vacuum_xml_filepath, solvated_xml_filepath]):
        system_serialized = openmm.XmlSerializer.serialize(system)
        with open(xml_filepath, 'w') as f:
            f.write(system_serialized)
Example #11
0
    def _initialize(self):
        """Initializes the target.
        """

        # Load in the ESP data store.
        esp_store = MoleculeESPStore(
            os.path.join(self.tgtdir, self.recharge_esp_store))

        # Define the molecules to include in the training set.
        smiles = [smiles_pattern for smiles_pattern in esp_store.list()]

        # Determine which BCC parameters are being optimized.
        force_field = smirnoff.ForceField(os.path.join(self.FF.ffdir,
                                                       self.FF.offxml),
                                          allow_cosmetic_attributes=True)

        bcc_handler = force_field.get_parameter_handler("ChargeIncrementModel")

        if bcc_handler.partial_charge_method.lower() != "am1elf10":
            raise NotImplementedError()

        # TODO: it is assumed that the MDL aromaticity model should be used
        #       rather than the once specified in the FF as the model is not
        #       currently exposed. See OpenFF toolkit issue #663.
        bcc_collection = from_smirnoff(bcc_handler)
        bcc_smirks = [bcc.smirks for bcc in bcc_collection.parameters]

        # Determine the indices of the BCC parameters being refit.
        bcc_to_parameter_index = {}

        for parameter_index, field_list in enumerate(self.FF.pfields):

            split_key = field_list[0].split("/")

            parameter_tag = split_key[0].strip()
            parameter_smirks = split_key[3].strip()

            if (parameter_tag != "ChargeIncrementModel"
                    or field_list[3] != "charge_increment1"):
                continue

            bcc_index = bcc_smirks.index(parameter_smirks)
            bcc_to_parameter_index[bcc_index] = parameter_index

        fixed_parameters = [
            i for i in range(len(bcc_smirks))
            if i not in bcc_to_parameter_index
        ]

        self._parameter_to_bcc_map = np.array([
            bcc_to_parameter_index[i]
            for i in range(len(bcc_collection.parameters))
            if i not in fixed_parameters
        ])

        charge_settings = ChargeSettings(theory="am1",
                                         symmetrize=True,
                                         optimize=True)

        # Pre-calculate the expensive operations which are needed to evaluate the
        # objective function, but do not depend on the current parameters.
        objective_terms = ESPOptimization.compute_objective_terms(
            smiles, esp_store, bcc_collection, fixed_parameters,
            charge_settings)

        self._design_matrix = np.vstack([
            objective_term.design_matrix for objective_term in objective_terms
        ])
        self._target_residuals = np.vstack([
            objective_term.target_residuals
            for objective_term in objective_terms
        ])

        # Track which residuals map to which molecule.
        residual_counter = 0

        for smiles_pattern in smiles:
            esp_records = esp_store.retrieve(smiles_pattern)

            n_residuals = sum(
                len(esp_record.grid_coordinates) for esp_record in esp_records)

            self._molecule_residual_ranges[smiles_pattern] = np.array(
                [i + residual_counter for i in range(n_residuals)])

            residual_counter += len(
                self._molecule_residual_ranges[smiles_pattern])
"""

#
# Load and parameterize the small molecule
#

# Load the small molecule
from openforcefield.utils import get_data_file_path

ligand_filename = get_data_file_path('molecules/toluene.mol2')
molecule = Molecule.from_file(ligand_filename)

# Load the smirnoff99Frosst force field
from openforcefield.typing.engines import smirnoff

forcefield = smirnoff.ForceField('test_forcefields/smirnoff99Frosst.offxml')

# Create a ParmEd structure for the molecule
molecule_structure = forcefield.create_parmed_structure(
    topology=molecule.to_topology(), positions=molecule.positions)
print('Molecule:', molecule_structure)

#
# Load and parameterize the protein
#

# Load the protein topology
protein_pdb_filename = get_data_file_path('proteins/T4-protein.pdb')
protein_pdbfile = app.PDBFile(protein_pdb_filename)

# Load the AMBER protein force field, along with a solvent force field
Example #13
0
"""

#
# Load and parameterize the small molecule
#

# Load the small molecule
from openforcefield.utils import get_data_file_path

ligand_filename = get_data_file_path('molecules/toluene.mol2')
molecule = Molecule.from_file(ligand_filename)

# Load the smirnoff99Frosst force field
from openforcefield.typing.engines import smirnoff

forcefield = smirnoff.ForceField('smirnoff99Frosst.offxml')

# Create a ParmEd structure for the molecule
molecule_structure = forcefield.create_parmed_structure(
    topology=molecule.to_topology(), positions=molecule.positions)
print('Molecule:', molecule_structure)

#
# Load and parameterize the protein
#

# Load the protein topology
protein_pdb_filename = get_data_file_path('proteins/T4-protein.pdb')
protein_pdbfile = app.PDBFile(protein_pdb_filename)

# Load the AMBER protein force field, along with a solvent force field
Example #14
0
    def submit_jobs(self, mvals, AGrad=True, AHess=True):
        """
        Submit jobs for evaluating the objective function

        Parameters
        ----------
        mvals: np.ndarray
            mvals array containing the math values of the parameters
        AGrad: bool
            Flag for computing gradients of not
        AHess: bool
            Flag for computing hessian or not

        Notes
        -----
        1. This function is called before wq_complete() and get().
        2. This function should not block.
        """

        # Make the force field based on the current values of the parameters.
        self.FF.make(mvals)

        force_field = smirnoff.ForceField(self.FF.offxml,
                                          allow_cosmetic_attributes=True)

        # strip out cosmetic attributes
        with tempfile.NamedTemporaryFile(mode="w", suffix=".offxml") as file:
            force_field.to_file(file.name, discard_cosmetic_attributes=True)
            force_field = smirnoff.ForceField(file.name)

        # Determine which gradients (if any) we should be estimating.
        parameter_gradient_keys = []

        self._gradient_key_mappings = {}
        self._parameter_units = {}

        if AGrad is True:

            index_counter = 0

            for field_list in self.FF.pfields:

                string_key = field_list[0]
                key_split = string_key.split("/")

                parameter_tag = key_split[0].strip()
                parameter_smirks = key_split[3].strip()
                parameter_attribute = key_split[2].strip()

                # Use the full attribute name (e.g. k1) for the gradient key.
                parameter_gradient_key = ParameterGradientKey(
                    tag=parameter_tag,
                    smirks=parameter_smirks,
                    attribute=parameter_attribute,
                )

                # Find the unit of the gradient parameter.
                parameter_value, is_cosmetic = self._parameter_value_from_gradient_key(
                    parameter_gradient_key)

                if parameter_value is None or is_cosmetic:
                    # We don't wan't gradients w.r.t. cosmetic parameters.
                    continue

                parameter_unit = parameter_value.units
                parameter_gradient_keys.append(parameter_gradient_key)

                self._gradient_key_mappings[
                    parameter_gradient_key] = index_counter
                self._parameter_units[parameter_gradient_key] = parameter_unit

                index_counter += 1

        # Submit the estimation request.
        self._pending_estimate_request, _ = self._client.request_estimate(
            property_set=self._reference_data_set,
            force_field_source=force_field,
            options=self._options.estimation_options,
            parameter_gradient_keys=parameter_gradient_keys,
        )

        logger.info("Requesting the estimation of {} properties, and their "
                    "gradients with respect to {} parameters.\n".format(
                        len(self._reference_data_set),
                        len(parameter_gradient_keys)))

        if (self._pending_estimate_request.results(
                True, polling_interval=self._options.polling_interval)[0] is
                None):

            raise RuntimeError(
                "No `EvaluatorServer` could be found to submit the calculations to. "
                "Please double check that a server is running, and that the connection "
                "settings specified in the input script are correct.")
from openforcefield.typing.engines import smirnoff
from simtk import unit

force_field = smirnoff.ForceField('smirnoff99Frosst_experimental.offxml')

# t9
# [#1:1]-[#6X4:2]-[#6X4:3]-[#8X2:4]
# H1-C1-C2-O2
# GAFF v2.1
#   k = 0.16    per = 3
# SMIRNOFF99Frosst
#   k = 0.25    per = 1
#   k = 0.00    per = 3

#
# < Proper
# smirks = "[#1:1]-[#6X4:2]-[#6X4:3]-[#8X2:4]"
# id = "t9"
# idivf1 = "1"
# k1 = "0.000"
# periodicity1 = "3"
# phase1 = "0.0"
# phase2 = "0.0"
# k2 = "0.250"
# periodicity2 = "1"
# idivf2 = "1" / >

parameter = force_field.get_parameter_handler(
    'ProperTorsions').parameters["[#1:1]-[#6X4:2]-[#6X4:3]-[#8X2:4]"]
assert (parameter.k[0] == 0.0 * unit.kilocalorie_per_mole)
assert (parameter.k[1] == 0.250 * unit.kilocalorie_per_mole)
 def associate(self, source):
     super().associate(source)
     if self.forcefield is None:
         self.forcefield = OFF.ForceField(self.abs_path,
                                          disable_version_check=True)