Exemple #1
0
    def filter_function(data_row):

        n_components = data_row["N Components"]

        for index in range(n_components):

            smiles = data_row[f"Component {index + 1}"]
            molecule = Molecule.from_smiles(smiles, allow_undefined_stereo=True)

            if not all([x.element.symbol in allowed_elements for x in molecule.atoms]):

                return False

        return True
Exemple #2
0
def smiles_to_svg(smiles: str, torsion_indices: (int, int), image_width: int = 200, image_height: int = 200) -> str:
    """Renders a 2D representation of a molecule based on its SMILES representation as
    an SVG string.

    Parameters
    ----------
    smiles
        The SMILES pattern.
    torsion_indices
        The torsion indices for the molecule.
    image_width
        The width to make the final SVG.
    image_height
        The height to make the final SVG.

    Returns
    -------
        The 2D SVG representation.
    """
    
    # Parse the SMILES into an RDKit molecule
    smiles_parser = Chem.rdmolfiles.SmilesParserParams()
    smiles_parser.removeHs = False
    
    oe_conformed = False
    try:
        oe_molecule, status = smiles2oemol(smiles)
        openff_molecule = Molecule.from_openeye(oe_molecule)
        rdkit_molecule = openff_molecule.to_rdkit()
        oe_conformed = True
    except:
        rdkit_molecule = Chem.MolFromSmiles(smiles, smiles_parser)
   
    # Generate a set of 2D coordinates.
    Chem.rdDepictor.Compute2DCoords(rdkit_molecule)

    drawer = rdMolDraw2D.MolDraw2DSVG(image_width, image_height)

    torsion_bonds = []
    if oe_conformed:
        for i in range(len(torsion_indices) - 1):
            if rdkit_molecule.GetBondBetweenAtoms(torsion_indices[i], torsion_indices[i+1]):
                torsion_bonds.append(rdkit_molecule.GetBondBetweenAtoms(torsion_indices[i], torsion_indices[i+1]).GetIdx())
    
    rdMolDraw2D.PrepareAndDrawMolecule(drawer, rdkit_molecule, highlightBonds = torsion_bonds)
        
    drawer.FinishDrawing()

    svg_content = drawer.GetDrawingText()
    return svg_content
    def setUp(self):
        # TODO: Harmonize with test_system_generator.py infrastructure

        # Read test molecules
        from openforcefield.topology import Molecule
        filename = get_data_filename("minidrugbank/MiniDrugBank-without-unspecified-stereochemistry.sdf")
        molecules = Molecule.from_file(filename, allow_undefined_stereo=True)
        # Filter molecules as appropriate
        self.molecules = self.filter_molecules(molecules)

        # Suppress DEBUG logging from various packages
        import logging
        for name in ['parmed', 'matplotlib']:
            logging.getLogger(name).setLevel(logging.WARNING)
def test_ff_mol2(test_ff, mol2_fnm):
    """
    Test creating system with mol2 file
    """
    from openforcefield.topology import Molecule as Off_Molecule
    from openforcefield.topology import Topology as Off_Topology
    try:
        off_molecule = Off_Molecule.from_file(mol2_fnm)
        off_topology = Off_Topology.from_molecules(off_molecule)
        test_ff.create_openmm_system(off_topology)
        molecule_labels = test_ff.label_molecules(off_topology)[0]
    except Exception as e:
        return False, str(e), None
    return True, '', molecule_labels
    def test_load_one_mol_sdf_without_charge(self, toolkit):
        """Test loading one molecule from a .sdf file WITHOUT charges"""
        registry = make_registry(toolkit)
        ethanol = get_data_file_path("molecules/ethanol.sdf")
        assert Molecule.from_file(ethanol).partial_charges is None

        mols_out = generate_conformers(
            molecule=ethanol,
            forcefield="openff-1.0.0.offxml",
            registry=registry,
        )

        assert len(mols_out) > 1
        assert mols_out[0].partial_charges is not None
Exemple #6
0
def checkTorsion(molList, ff_name):
    """
    Take mollist and check if the molecules in a list match a specific torsion id

        Parameters
        ----------
        molList : List of objects
            List of oemols with datatags generated in genData function

        Returns
        -------
        molList : list of objects
            List of oemol objects that have a datatag "IDMatch" that contain the torsion id
            involved in the QCA torsion drive
    """

    matches = []
    count = 0
    mols = []
    for mol in molList:
        molecule = Molecule.from_mapped_smiles(mol.GetData("cmiles"))
        topology = Topology.from_molecules(molecule)
        # Let's label using the Parsley force field
        forcefield = ForceField(ff_name)
        # Run the molecule labeling
        molecule_force_list = forcefield.label_molecules(topology)
        params = []
        # Print out a formatted description of the torsion parameters applied to this molecule
        for mol_idx, mol_forces in enumerate(molecule_force_list):
            # print(f'Forces for molecule {mol_idx}')
            for force_tag, force_dict in mol_forces.items():
                if force_tag == "ProperTorsions":
                    for (atom_indices, parameter) in force_dict.items():
                        params.append(parameter.id)
                        if atom_indices == mol.GetData("TDindices") or tuple(
                            reversed(atom_indices)
                        ) == mol.GetData("TDindices"):
                            count += 1
                            mol.SetData("IDMatch", parameter.id)
                            mols.append(mol)
    print(
        "Out of "
        + str(len(molList))
        + " molecules, "
        + str(count)
        + " were processed with checkTorsion()"
    )

    return mols
Exemple #7
0
    def get_energies(self, resolution=30, get_thetas=False):
        """
        It returns the energies of this energetic profile calculator.

        Parameters
        ----------
        resolution : float
            The resolution, in degrees, that is applied when rotating
            the dihedral rotatable bond. Default is 30 degrees
        get_thetas : bool
            Whether to return thetas (dihedral angles) or not. Default
            is False

        Returns
        -------
        dihedral_energies : a simtk.unit.Quantity object
            The array of energies represented with a simtk's Quantity
            object
        thetas : list[float]
            The array of thetas, only if requested in the corresponding
            function parameter
        """
        mol_with_conformers = \
            self.dihedral_benchmark.generate_dihedral_conformers(
                resolution)

        from openforcefield.topology import Molecule

        mol = Molecule.from_rdkit(mol_with_conformers)

        dihedral_energies = list()

        for i, conformer in enumerate(mol.conformers):
            energy = self._calc_energy(conformer)
            dihedral_energies.append(energy)

        if get_thetas:
            from rdkit.Chem import rdMolTransforms

            thetas = list()

            for conf in mol_with_conformers.GetConformers():
                thetas.append(
                    rdMolTransforms.GetDihedralDeg(
                        conf, *self.dihedral_benchmark.atom_indexes))

            return dihedral_energies, thetas

        return dihedral_energies
    def _build_molecule_arrays(self):
        """Converts the input substance into a list of molecules and a list
        of counts for how many of each there should be as determined by the
        `max_molecules` input and the substances respective mole fractions.

        Returns
        -------
        list of openforcefield.topology.Molecule
            The list of molecules.
        list of int
            The number of each molecule which should be added to the system.
        """
        from openforcefield.topology import Molecule

        molecules = []

        for component in self.substance.components:

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

        # Determine how many molecules of each type will be present in the system.
        molecules_per_component = self.substance.get_molecules_per_component(
            self.max_molecules, count_exact_amount=self.count_exact_amount)
        number_of_molecules = [0] * self.substance.number_of_components

        for index, component in enumerate(self.substance.components):
            number_of_molecules[index] = molecules_per_component[
                component.identifier]

        total_n_molecules = sum(number_of_molecules)

        if not self.count_exact_amount:

            n_exact_molecule = sum(
                amount.value for component in self.substance.components
                for amount in self.substance.amounts[component.identifier]
                if isinstance(amount, ExactAmount))

            total_n_molecules -= n_exact_molecule

        if total_n_molecules > self.max_molecules:

            raise ValueError(
                f"The number of molecules to create ({total_n_molecules}) is "
                f"greater than the maximum number requested ({self.max_molecules})."
            )

        return molecules, number_of_molecules, None
Exemple #9
0
def test_OEMol_to_omm_ff(molecule=smiles_to_oemol('CC')):
    """
    Generating openmm objects for simulation from an OEMol object

    Parameters
    ----------
    molecule : openeye.oechem.OEMol

    Returns
    -------
    system : openmm.System
        openmm system object
    positions : unit.quantity
        positions of the system
    topology : app.topology.Topology
        openmm compatible topology object
    """
    import simtk.openmm.app as app
    import simtk.unit as unit
    from perses.utils.openeye import OEMol_to_omm_ff
    from simtk import openmm
    from openmmforcefields.generators import SystemGenerator
    from openforcefield.topology import Molecule

    #default arguments for SystemGenerators
    barostat = None
    forcefield_files = ['amber14/protein.ff14SB.xml', 'amber14/tip3p.xml']
    forcefield_kwargs = {
        'removeCMMotion': False,
        'ewaldErrorTolerance': 1e-4,
        'nonbondedMethod': app.NoCutoff,
        'constraints': app.HBonds,
        'hydrogenMass': 4 * unit.amus
    }
    small_molecule_forcefield = 'gaff-2.11'
    system_generator = SystemGenerator(
        forcefields=forcefield_files,
        barostat=barostat,
        forcefield_kwargs=forcefield_kwargs,
        small_molecule_forcefield=small_molecule_forcefield,
        molecules=[Molecule.from_openeye(molecule)],
        cache=None)

    system, positions, topology = OEMol_to_omm_ff(molecule, system_generator)

    assert (type(system) == type(openmm.System())
            ), "An openmm.System has not been generated from OEMol_to_omm_ff()"

    return system, positions, topology
def test_fragmentation_apply():
    """
    Make sure that fragmentation is working.
    """
    fragmenter = workflow_components.WBOFragmenter()
    assert fragmenter.is_available()
    # check that a molecule with no rotatable bonds fails if we dont want the parent back
    benzene = Molecule.from_file(get_data("benzene.sdf"), "sdf")
    result = fragmenter.apply([benzene, ], processors=1)
    assert result.n_molecules == 0

    # now try ethanol
    ethanol = Molecule.from_file(get_data("methanol.sdf"), "sdf")
    fragmenter.include_parent = True
    result = fragmenter.apply([ethanol, ], processors=1)
    assert result.n_molecules == 1

    # now try a molecule which should give fragments
    diphenhydramine = Molecule.from_smiles("O(CCN(C)C)C(c1ccccc1)c2ccccc2")
    fragmenter.include_parent = False
    result = fragmenter.apply([diphenhydramine, ], processors=1)
    assert result.n_molecules == 4
    for molecule in result.molecules:
        assert "dihedrals" in molecule.properties
Exemple #11
0
    def generate_fitting_task(
        self,
        molecule: off.Molecule,
        fragment: bool,
        attributes: MoleculeAttributes,
        fragment_parent_mapping: Optional[Dict[int, int]] = None,
        dihedrals: Optional[List[Tuple[int, int, int, int]]] = None,
    ) -> Union[TorsionTask, OptimizationTask, HessianTask]:
        """
        For the given collection workflow generate a task schema for the input molecule.
        """
        if molecule.n_conformers < self.target_conformers:
            molecule.generate_conformers(n_conformers=self.target_conformers,
                                         clear_existing=False)

        # build a dict of the data
        data = dict(
            name=self.collection_workflow,
            attributes=attributes,
            provenance=self.provenance(),
            fragment=fragment,
            fragment_parent_mapping=fragment_parent_mapping,
            molecule=molecule,
            dihedrals=dihedrals,
        )
        if self.collection_workflow == "torsion1d":
            task = TorsionTask(**data)
        elif self.collection_workflow == "optimization":
            task = OptimizationTask(**data)
        elif self.collection_workflow == "hessian":
            task = HessianTask(**data)
        else:
            raise NotImplementedError(
                f"The collection workflow {self.collection_workflow} is not supported."
            )
        return task
Exemple #12
0
def biphenyl_workflow(target) -> OptimizationSchema:
    """
    Create a workflow schema which targets the rotatable bond in ethane.
    """
    mol = Molecule.from_file(get_data("biphenyl.sdf"), "sdf")
    workflow = WorkflowFactory()
    # turn off bespoke terms we want fast fitting
    workflow.generate_bespoke_terms = False
    workflow.expand_torsion_terms = False
    fb = ForceBalanceOptimizer()
    target = target()
    fb.set_optimization_target(target=target)
    workflow.set_optimizer(optimizer=fb)
    schema = workflow.fitting_schema_from_molecules(molecules=mol)
    return schema.tasks[0]
def get_smirnoff_params(mol: oechem.OEMol) -> {"id": ["atom_indices"]}:
    """For the given molecule, finds the SMIRNOFF params and their atom indices"""
    off_mol = Molecule.from_openeye(mol, allow_undefined_stereo=True)
    try:
        topology = Topology.from_molecules(off_mol)
    except Exception as e:
        return {}
    molecule_force_list = utilize_params_util.SMIRNOFF.label_molecules(topology)

    params = defaultdict(list)
    for force_tag, force_dict in molecule_force_list[0].items():
        for (atom_index, parameter) in force_dict.items():
            params[parameter.id].append(atom_index)

    return params
    def label_molecule(self, molecule: off.Molecule) -> Dict[str, str]:
        """
        Type the molecule with the forcefield and return a molecule parameter dictionary.

        Parameters
        ----------
        molecule: off.Molecule
            The openforcefield.topology.Molecule that should be labeled by the forcefield.

        Returns
        -------
        Dict[str, str]
            A dictionary of each parameter assigned to molecule organised by parameter handler type.
        """
        return self.forcefield.label_molecules(molecule.to_topology())[0]
Exemple #15
0
    def test_to_file_fileformat_invalid(self):
        """
        Checks for invalid file format
        """
        from openforcefield.tests.test_forcefield import create_ethanol
        from openforcefield.topology import Molecule, Topology

        topology = Topology()
        mol = Molecule.from_pdb_and_smiles(
            get_data_file_path("systems/test_systems/1_ethanol.pdb"), "CCO")
        topology.add_molecule(mol)
        positions = mol.conformers[0]
        fname = "ethanol_file.pdb"
        with pytest.raises(NotImplementedError):
            topology.to_file(fname, positions, file_format="AbC")
Exemple #16
0
    def filter_function(data_row):

        n_components = data_row["N Components"]

        for index in range(n_components):

            smiles = data_row[f"Component {index + 1}"]
            molecule = Molecule.from_smiles(smiles, allow_undefined_stereo=True)

            if np.isclose(sum([atom.formal_charge for atom in molecule.atoms]), 0.0):
                continue

            return False

        return True
Exemple #17
0
 def test_from_openmm_duplicate_unique_mol(self):
     """Check that a DuplicateUniqueMoleculeError is raised if we try to pass in two indistinguishably unique mols"""
     from simtk.openmm import app
     pdbfile = app.PDBFile(
         get_data_file_path(
             'systems/packmol_boxes/cyclohexane_ethanol_0.4_0.6.pdb'))
     molecules = [
         Molecule.from_file(get_data_file_path(name))
         for name in ('molecules/ethanol.mol2',
                      'molecules/ethanol_reordered.mol2',
                      'molecules/cyclohexane.mol2')
     ]
     with self.assertRaises(DuplicateUniqueMoleculeError) as context:
         topology = Topology.from_openmm(pdbfile.topology,
                                         unique_molecules=molecules)
Exemple #18
0
    def _get_rdkit_mcs_mapping(fragment: Molecule, parent: Molecule) -> Dict[int, int]:
        """
        Use rdkit MCS function to find the maximum mapping between the fragment and parent molecule.
        """

        from rdkit import Chem
        from rdkit.Chem import rdFMCS

        parent_rdkit = parent.to_rdkit()
        fragment_rdkit = fragment.to_rdkit()
        mcs = rdFMCS.FindMCS(
            [parent_rdkit, fragment_rdkit],
            atomCompare=rdFMCS.AtomCompare.CompareElements,
            bondCompare=rdFMCS.BondCompare.CompareAny,
            ringMatchesRingOnly=True,
            completeRingsOnly=True,
        )
        # make a new molecule from the mcs
        match_mol = Chem.MolFromSmarts(mcs.smartsString)
        # get the mcs parent/fragment mapping
        matches_parent = parent_rdkit.GetSubstructMatch(match_mol)
        matches_fragment = fragment_rdkit.GetSubstructMatch(match_mol)
        mapping = dict(zip(matches_fragment, matches_parent))
        return mapping
def gen_tid_molecules_list(molecule_attributes, molecules_list_dict,
                           forcefield):
    # gen dictionary with keys, including all tids in the input forcefield
    ff_torsion_param_list = forcefield.get_parameter_handler(
        'ProperTorsions').parameters

    tid_molecules_list = {}
    for torsion_param in ff_torsion_param_list:
        tid_molecules_list[torsion_param.id] = []

    for idx, (mol_index, mol_attr) in enumerate(molecule_attributes.items()):
        mapped_smiles = mol_attr[
            'canonical_isomeric_explicit_hydrogen_mapped_smiles']
        qcjson_mol = molecules_list_dict[mol_index][0]
        oemol = cmiles.utils.load_molecule(qcjson_mol)
        off_mol = Off_Molecule.from_openeye(oemol, allow_undefined_stereo=True)

        torsions_coverage, center_tids = smirnoff_analysis_torsions(
            forcefield, off_mol)
        filtered_torsions_coverage = filter_torsions_coverage(
            torsions_coverage, oemol)

        for tid, indices_list in filtered_torsions_coverage.items():

            for indices in indices_list:
                covered_tids = []
                i, j, k, l = indices
                tids = center_tids[tuple(sorted([j, k]))]
                for i in tids:
                    if i not in covered_tids:
                        covered_tids.append(i)
                tid_molecules_list[tid].append({
                    'mol_index': mol_index,
                    'indices': indices,
                    'covered_tids': covered_tids
                })
    print("\n## Torsion parameter: matched molecules ##\n" + '-' * 90)
    print(
        f"{'idx':<7} {'ID':7s} {'SMIRKS Pattern':70s} {'Number of molecules matched'}"
    )
    for idx, (tid, molecules_list) in enumerate(tid_molecules_list.items()):
        torsion_param = get_torsion_definition(ff_torsion_param_list, tid)
        print(
            f'{idx:<7} {torsion_param.id:7s} {torsion_param.smirks:70s} {len(molecules_list)}'
        )
    print('-' * 90)

    return tid_molecules_list
Exemple #20
0
def select_torsions(molecules_list_dict,
                    molecule_attributes,
                    forcefield,
                    target_coverage=3):
    torsions_dict = {}
    smirks_torsions_counter = Counter()
    i_mol = 0
    for mol_index, mol_attr in molecule_attributes.items():
        print(f'{i_mol:<7d}: {mol_index}')
        i_mol += 1
        mapped_smiles = mol_attr[
            'canonical_isomeric_explicit_hydrogen_mapped_smiles']
        # round trip from QCFractal molecule to OpenEye molecule then to Off Molecule
        # this is needed for now to ensure atom indeices are consistent
        qcjson_mol = molecules_list_dict[mol_index][0]
        oemol = cmiles.utils.load_molecule(qcjson_mol)
        off_mol = Off_Molecule.from_openeye(oemol, allow_undefined_stereo=True)
        torsions_coverage = smirnoff_analyze_torsions(forcefield, off_mol)
        for smirks, torsion_idx_list in torsions_coverage.items():
            for atom_indices in torsion_idx_list:
                if smirks_torsions_counter[smirks] < target_coverage:
                    smirks_torsions_counter[smirks] += 1
                    canonical_torsion_index = cmiles.utils.to_canonical_label(
                        mapped_smiles, atom_indices)
                    torsions_dict[canonical_torsion_index] = {
                        'initial_molecules': molecules_list_dict[mol_index],
                        'atom_indices': [atom_indices],
                        'attributes': mol_attr,
                    }
                    print(
                        f"  - torsion {atom_indices} added for smirks {smirks}"
                    )
                else:
                    print(
                        f"  - torsion {atom_indices} skipped because {smirks} have {smirks_torsions_counter[smirks]} already"
                    )
    print("\n## Selected Torsion Coverage ##\n" + '-' * 90)
    ff_torsion_param_list = forcefield.get_parameter_handler(
        'ProperTorsions').parameters
    n_covered = 0
    for param in ff_torsion_param_list:
        count = smirks_torsions_counter[param.smirks]
        print(f"{param.smirks:80s} : {count:7d}")
        if count > 0:
            n_covered += 1
    print('-' * 90)
    print(f'{n_covered} / {len(ff_torsion_param_list)} torsion SMIRKs covered')
    return torsions_dict
Exemple #21
0
def smirnoff_analyze_parameter_coverage(forcefield, tgt_opts):
    printcool("SMIRNOFF Parameter Coverage Analysis")
    assert hasattr(forcefield, 'offxml'), "Only SMIRNOFF Force Field is supported"
    parameter_assignment_data = defaultdict(list)
    parameter_counter = Counter()
    # The openforcefield.typing.engines.smirnoff.ForceField object should now be contained in forcebalance.forcefield.FF
    ff = forcefield.openff_forcefield
    # analyze each target
    for tgt_option in tgt_opts:
        target_path = os.path.join('targets', tgt_option['name'])
        # aggregate mol2 file paths from all targets
        mol2_paths = []
        if tgt_option['type'] == 'OPTGEOTARGET_SMIRNOFF':
            # parse optgeo_options_txt and get the names of the mol2 files
            optgeo_options_txt = os.path.join(target_path, tgt_option['optgeo_options_txt'])
            sys_opts = forcebalance.opt_geo_target.OptGeoTarget.parse_optgeo_options(optgeo_options_txt)
            mol2_paths = [os.path.join(target_path,fnm) for sysopt in sys_opts.values() for fnm in sysopt['mol2']]
        elif tgt_option['type'].endswith('_SMIRNOFF'):
            mol2_paths = [os.path.join(target_path,fnm) for fnm in tgt_option['mol2']]
        # analyze SMIRKs terms
        for mol_fnm in mol2_paths:
            # we work with one file at a time to avoid the topology sliently combine "same" molecules
            openff_mol = OffMolecule.from_file(mol_fnm)
            off_topology = OffTopology.from_molecules([openff_mol])
            molecule_force_list = ff.label_molecules(off_topology)
            for mol_idx, mol_forces in enumerate(molecule_force_list):
                for force_tag, force_dict in mol_forces.items():
                    # e.g. force_tag = 'Bonds'
                    for atom_indices, parameter in force_dict.items():
                        param_dict = {'id': parameter.id, 'smirks': parameter.smirks, 'type':force_tag, 'atoms': list(atom_indices),}
                        parameter_assignment_data[mol_fnm].append(param_dict)
                        parameter_counter[parameter.smirks] += 1
    # write out parameter assignment data
    out_json_path = os.path.join(forcefield.root, 'smirnoff_parameter_assignments.json')
    with open(out_json_path, 'w') as jsonfile:
        json.dump(parameter_assignment_data, jsonfile, indent=2)
        logger.info("Force field assignment data written to %s\n" % out_json_path)
    # print parameter coverages
    logger.info("%4s %-100s   %10s\n" % ("idx", "Parameter", "Count"))
    logger.info("-"*118 + '\n')
    n_covered = 0
    for i,p in enumerate(forcefield.plist):
        smirks = p.split('/')[-1]
        logger.info('%4i %-100s : %10d\n' % (i, p, parameter_counter[smirks]))
        if parameter_counter[smirks] > 0:
            n_covered += 1
    logger.info("SNIRNOFF Parameter Coverage Analysis result: %d/%d parameters are covered.\n" % (n_covered, len(forcefield.plist)))
    logger.info("-"*118 + '\n')
Exemple #22
0
def test_torsiondrive_index():
    """
    Test generating an index using torsiondrive, this should tag the atoms in the torsion.
    """

    mol = Molecule.from_file(get_data("methanol.sdf"))

    mol.properties["atom_map"] = {4: 0, 0: 1, 1: 2, 5: 3}

    factory = TorsiondriveDatasetFactory()

    index = factory.create_index(mol)

    tags = ["[C:2]", "[H:1]", "[O:3]", "[H:4]"]
    for tag in tags:
        assert tag in index
Exemple #23
0
        def filter_function(physical_property):

            substance = physical_property.substance

            for component in substance.components:

                molecule = Molecule.from_smiles(component.smiles,
                                                allow_undefined_stereo=True)

                if not all([
                        x.element.symbol in allowed_elements
                        for x in molecule.atoms
                ]):
                    return False

            return True
Exemple #24
0
    def from_directory(
        cls: Type[T], directory: str, name: str, options: Dict[str, Any]
    ) -> T:
        from openforcefield.topology import Molecule

        input_molecule_path = os.path.join(directory, options["mol2"])

        input_molecule = Molecule.from_file(
            input_molecule_path, allow_undefined_stereo=True
        )

        return cls(
            name=name,
            molecule=input_molecule.to_smiles(explicit_hydrogens=False),
            options=options,
        )
def test_rmsd_filter():
    """
    Test the RMSD conformer filter method.
    """
    import copy

    from simtk import unit

    rmsd_filter = workflow_components.RMSDCutoffConformerFilter(cutoff=1)
    mol = Molecule.from_smiles("CCCC")
    # make a lot of conformers for the molecule
    mol.generate_conformers(n_conformers=1000, rms_cutoff=0.5 * unit.angstrom, toolkit_registry=RDKitToolkitWrapper())
    ref_mol = copy.deepcopy(mol)
    result = rmsd_filter.apply([mol, ], processors=1)
    # now make sure the number of conformers is different
    assert result.molecules[0].n_conformers != ref_mol.n_conformers
def test_bespoke_target_torsion_smirks():
    """
    Generate bespoke torsion smirks only for the target torsions and make sure the intended atoms are covered.
    """
    gen = SmirksGenerator()
    mol = Molecule.from_file(get_data("OCCO.sdf"))

    torsion_smirks = gen._get_bespoke_torsion_smirks(molecule=mol,
                                                     central_bonds=[(1, 2)])
    # there should be 3 unique smirks for this molecule
    # H-C-C-H, H-C-C-O, O-C-C-O
    assert len(torsion_smirks) == 3
    for smirk in torsion_smirks:
        atoms = condense_matches(mol.chemical_environment_matches(
            smirk.smirks))
        assert compare_matches(atoms, smirk.atoms) is True
def test_packmol_paracetamol():

    from openforcefield.topology import Molecule

    # Test something a bit more tricky than water
    molecules = [Molecule.from_smiles("CC(=O)NC1=CC=C(C=C1)O")]

    trajectory, _ = packmol.pack_box(molecules, [1],
                                     box_size=([20] * 3) * unit.angstrom)

    assert trajectory is not None

    assert trajectory.n_chains == 1
    assert trajectory.n_residues == 1
    assert trajectory.n_atoms == 20
    assert trajectory.topology.n_bonds == 20
def mol2_to_smiles(file_path):
    """Loads a receptor from a mol2 file.

    Parameters
    ----------
    file_path: str
        The file path to the mol2 file.

    Returns
    -------
    str
        The smiles descriptor of the loaded receptor molecule
    """

    receptor_molecule = Molecule.from_file(file_path, 'MOL2')
    return receptor_molecule.to_smiles()
def test_generate_smirks(bespoke_smirks):
    """
    Test the main worker method to gather bespoke and non bespoke terms.
    """
    gen = SmirksGenerator()
    gen.target_smirks = [
        SmirksType.Vdw,
    ]
    gen.generate_bespoke_terms = bespoke_smirks

    mol = Molecule.from_smiles("CC")
    smirks_list = gen.generate_smirks(molecule=mol)

    # we only request one parameter type
    types = set([smirk.type for smirk in smirks_list])
    assert len(types) == 1
Exemple #30
0
def min_ffxml(mol, ofs, ffxml):
    """
    Minimize the mol with force field input from FFXML file.

    Parameters
    ----------
    mol : OpenEye single-conformer molecule
    ofs : OpenEye output filestream
    ffxml : string
        name of FFXML file

    """

    # make copy of the input mol
    oe_mol = oechem.OEGraphMol(mol)

    try:
        # create openforcefield molecule ==> prone to triggering Exception
        off_mol = Molecule.from_openeye(oe_mol)

        # load in force field
        ff = ForceField(ffxml)

        # create components for OpenMM system
        topology = Topology.from_molecules(molecules=[off_mol])

        # create openmm system ==> prone to triggering Exception
        #system = ff.create_openmm_system(topology, charge_from_molecules=[off_mol])
        system = ff.create_openmm_system(topology)

    except Exception as e:
        smilabel = oechem.OEGetSDData(oe_mol, "SMILES QCArchive")
        print( ' >>> openforcefield failed to create OpenMM system: '
               f'{oe_mol.GetTitle()} {smilabel}: {e}')
        return

    positions = structure.extractPositionsFromOEMol(oe_mol)

    # minimize structure with ffxml
    newpos, energy = run_openmm(topology, system, positions)

    # save geometry, save energy as tag, write mol to file
    oe_mol.SetCoords(oechem.OEFloatArray(newpos))
    oechem.OESetSDData(oe_mol, "Energy FFXML", str(energy))
    oechem.OEWriteConstMolecule(ofs, oe_mol)

    return