Example #1
0
    def _apply(self, molecules: List[Molecule]) -> ComponentResult:
        """
        Fragment the molecules using the WBOFragmenter.

        Parameters:
            molecules: The list of molecules which should be processed by this component.

        Note:
            * If the input molecule fails fragmentation it will be fail this component and be removed even when
            `include_parent` is set to true.
            * When a molecule can not be fragmented to meet the wbo threshold the parent is likely to be included in the
            dataset.
            *
        """
        from fragmenter import fragment

        result = self._create_result()

        for molecule in molecules:
            # not having a conformer can cause issues
            if molecule.n_conformers == 0:
                molecule.generate_conformers(n_conformers=1)

            if self.include_parent:
                result.add_molecule(molecule)

            fragment_factory = fragment.WBOFragmenter(
                molecule=molecule.to_openeye(),
                functional_groups=self.functional_groups,
                verbose=False,
            )

            try:
                fragment_factory.fragment(
                    threshold=self.threshold,
                    keep_non_rotor_ring_substituents=self.
                    keep_non_rotor_ring_substituents,
                )

                # we need to store the central bond which was fragmented around
                # to make sure this is the bond we torsiondrive around
                fragmets_dict = fragment_factory.to_torsiondrive_json()

                # check we have fragments
                if fragmets_dict:

                    for fragment_data in fragmets_dict.values():
                        frag_mol = Molecule.from_mapped_smiles(
                            mapped_smiles=fragment_data["identifiers"]
                            ["canonical_isomeric_explicit_hydrogen_mapped_smiles"]
                        )
                        torsion_index = tuple(fragment_data["dihedral"][0])
                        # this is stored back into the molecule and will be used when generating the cmiles tags latter
                        torsion_tag = TorsionIndexer()
                        torsion_tag.add_torsion(torsion=torsion_index)
                        frag_mol.properties["dihedrals"] = torsion_tag
                        result.add_molecule(frag_mol)

                # if we have no fragments and we dont want the parent then we failed to fragment
                elif not fragmets_dict and not self.include_parent:
                    result.filter_molecule(molecule)

            except (RuntimeError, ValueError):
                # this will catch cmiles errors for molecules with undefined stero
                result.filter_molecule(molecule)

        return result
Example #2
0
    def fragment(self, molecule: Molecule) -> List[FragmentData]:
        """
        Fragment the molecule using the WBOFragmenter.

        Parameters:
            molecule: The openff molecule to be fragmented using the provided class settings

        Returns:
            A list of FragmentData schema which details how a parent molecule is related to a fragment and which bond
            we fragmented around.

        Raises:
            FragmenterError: If the molecule can not be fragmented.
        """
        from fragmenter import fragment

        # make sure the molecule has at least one conformer as this can cause issues
        if molecule.n_conformers == 0:
            molecule.generate_conformers(n_conformers=1)

        # set up the fragmenter
        fragment_factory = fragment.WBOFragmenter(
            molecule=molecule.to_openeye(), verbose=False)

        fragments: List[FragmentData] = []
        try:
            # fragment the molecule
            fragment_factory.fragment(
                threshold=self.wbo_threshold,
                keep_non_rotor_ring_substituents=self.
                keep_non_rotor_ring_substituents,
            )
            # now we work out the relation between the fragment and the parent
            fragments_data = fragment_factory.to_torsiondrive_json()
            # now store the data
            for data in fragments_data.values():
                off_frag = Molecule.from_mapped_smiles(
                    data["identifiers"]
                    ["canonical_isomeric_explicit_hydrogen_mapped_smiles"])
                # get the fragment parent mapping
                frag_dihedral = data["dihedral"][0][1:3]

                # in some cases we get one fragment back which is the parent molecule
                # we should not work out a mapping
                if not molecule.is_isomorphic_with(off_frag):
                    mapping = self._get_fragment_parent_mapping(
                        fragment=off_frag, parent=molecule)
                    # get the parent torsion
                    parent_dihedral = tuple(
                        [mapping[i] for i in frag_dihedral])
                    parent_molecule = molecule
                else:
                    # reuse the current fragment data as dummy parent data
                    mapping = dict((i, i) for i in range(molecule.n_atoms))
                    parent_dihedral = frag_dihedral
                    parent_molecule = off_frag
                # this is the data we need so make the fragmnetdata
                frag_data = FragmentData(
                    parent_molecule=parent_molecule,
                    parent_torsion=parent_dihedral,
                    fragment_molecule=off_frag,
                    fragment_torsion=frag_dihedral,
                    fragment_attributes=data["identifiers"],
                    fragment_parent_mapping=mapping,
                )
                fragments.append(frag_data)

            return fragments

        except RuntimeError:
            raise FragmenterError(
                f"The molecule {molecule} could not be fragmented so no fitting target was made."
            )
Example #3
0
for ki in key_list:
    print(ki)
    try:
        os.mkdir(ki)
    except FileExistsError:
        print('{} directory already exists. Files will be overwritten'.format(
            ki))
    mapped_smiles = kinase_inhibitors[ki][
        'canonical_isomeric_explicit_hydrogen_mapped_smiles']
    chemi.mol_to_image_atoms_label(mapped_smiles,
                                   map_idx=True,
                                   fname='{}/{}_mapped.png'.format(ki, ki))
    mol = oechem.OEMol()
    oechem.OESmilesToMol(mol, mapped_smiles)
    fragmenter = fragment.WBOFragmenter(mol)
    fragmenter.fragment(threshold=1.0,
                        strict_stereo=False,
                        strict_types=False,
                        keep_non_rotor_ring_substituents=False
                        )  # Try without keeping nonrotors on ring
    atoms_bonds = get_atoms_bonds_from_fragment(fragmenter.fragments)
    fragments_to_drive = {}
    with PdfPages('{}/{}_fragment_growth_2.pdf'.format(ki, ki)) as pdf:
        for target_bond in fragmenter.fragments:
            key = workflow_api.serialize_key(target_bond)
            fragments_to_drive[key] = {'path_length': [], 'wbo': []}
            atoms = copy.deepcopy(atoms_bonds[target_bond][0])
            bonds = copy.deepcopy(atoms_bonds[target_bond][1])
            pl_wbos, pl_fragments = get_wbo_growth(
                fragmenter, fragmenter.fragments[target_bond], atoms, bonds,
Example #4
0
from fragmenter import fragment, chemi
import json
"""
This is an example script to generate fragments from a molecule
Note: The current fragmentation scheme is not optimal yet so it can be slow
for larger molecules.
"""

# Create an oemol from a SMILES
oemol = chemi.smiles_to_oemol(
    'OC1(CN(C1)C(=O)C1=C(NC2=C(F)C=C(I)C=C2)C(F)=C(F)C=C1)[C@@H]1CCCCN1',
    name='Cobimetinib')

# Instantiate a fragmenter engine
frag_engine = fragment.WBOFragmenter(oemol)
# Use default options to fragment molecule.
frag_engine.fragment()
# Generate PDF with fragments
frag_engine.depict_fragments(fname='example_fragments.pdf')

# Generate input for torsiondrive jobs. These jobs will drive the central rotatable bond in the fragment
td_inputs = frag_engine.to_torsiondrive_json(max_confs=10)
with open('example_td_inputs.json', 'w') as f:
    json.dump(td_inputs, f, indent=2, sort_keys=True)

# If you want to only generate starting conformations for other calculations, use `to_qcschema_mols`
qcschema_mols = frag_engine.to_qcschema_mols(max_confs=10)
with open('example_qcschema_mols.json', 'w') as f:
    json.dump(qcschema_mols, f, indent=2, sort_keys=True)