def double_point_crossover(m1, m2, bf):
    '''double point crossover for rings'''
    crossed_mols = []
    n1 = random.randint(1, 4)
    n2 = random.randint(n1 - 1, 4)
    print n1
    print n2
    if n2 == 0:
        n2 = 1
    cp1 = return_cut_points(m1)
    cp2 = return_cut_points(m2)
    actual_cp1 = get_actual_cut_pts(m1, n1, cp1)
    #print actual_cp1
    actual_cp2 = get_actual_cut_pts(m2, n2, cp2)
    #print actual_cp2
    frags1 = frag_mol(m1, actual_cp1, bf)
    frags2 = frag_mol(m2, actual_cp2, bf)
    print frags1
    print frags2
    fm = [Chem.MolToSmiles(x, True) for x in frags1]
    fm2 = [Chem.MolToSmiles(x, True) for x in frags2]
    print fm
    print fm2
    temp_mol1 = Chem.CombineMols(frags1[0], frags2[1])
    temp_mol2 = Chem.CombineMols(frags2[0], frags1[1])
    crossed_mol1 = join_mols(temp_mol1)
    crossed_mol2 = join_mols(temp_mol2)
    fixed_mol1 = ring_fixer(crossed_mol1, m1)
    fixed_mol2 = ring_fixer(crossed_mol2, m2)
    crossed_mols.append(fixed_mol1)
    crossed_mols.append(fixed_mol2)
    return crossed_mols
Example #2
0
def clean_charges(molec):
    """
    this is a temporary hack. The real solution is to
    generate several BO matrices in ac2bo and pick the one
    with the lowest number of atomic charges
    """
    rxn_smarts = [
        '[N+:1]=[*:2]-[O-:3]>>[N+0:1]-[*:2]=[O-0:3]',
        '[N+:1]=[*:2]-[*:3]=[*:4]-[O-:5]>>'
        '[N+0:1]-[*:2]=[*:3]-[*:4]=[O-0:5]'
    ]

    fragments = Chem.GetMolFrags(molec, asMols=True)

    for i, fragment in enumerate(fragments):
        for smarts in rxn_smarts:
            patt = Chem.MolFromSmarts(smarts.split(">>")[0])
            while fragment.HasSubstructMatch(patt):
                rxn = AllChem.ReactionFromSmarts(smarts)
                ps = rxn.RunReactants((fragment, ))
                fragment = ps[0][0]
        if i == 0:
            molec = fragment
        else:
            molec = Chem.CombineMols(molec, fragment)

    return molec
Example #3
0
def _compute_fragment_join(
    mol,
    fragment,
    mol_atom_count,
    bond_between_rings=True,
    asMols=True,
):
    """List all posibilities of where a fragment can be attached to a mol"""
    fragment = copy.copy(
        fragment
    )  # need to copy the fragment copy is faster than all the other methods
    with dm.without_rdkit_log():
        combined = Chem.CombineMols(mol, fragment)
        for i1 in range(mol.GetNumAtoms()):
            a1 = combined.GetAtomWithIdx(i1)
            if a1.GetImplicitValence() == 0:
                continue
            for i2 in range(fragment.GetNumAtoms()):
                i2 += mol_atom_count
                a2 = combined.GetAtomWithIdx(i2)
                if a2.GetImplicitValence() == 0:
                    continue
                # no bond between atoms already in rings
                if not bond_between_rings and a1.IsInRing() and a2.IsInRing():
                    continue
                # no bond to form large rings
                else:
                    possibilities = _all_atom_join(combined, a1, a2)
                    for x in possibilities:
                        x = dm.sanitize_mol(x)
                        if x is not None:
                            if not asMols:
                                x = dm.to_smiles(x)
                            yield x
Example #4
0
    def normalize(self, mol):
        """Apply a series of Normalization transforms to correct functional groups and recombine charges.

        A series of transforms are applied to the molecule. For each Normalization, the transform is applied repeatedly
        until no further changes occur. If any changes occurred, we go back and start from the first Normalization
        again, in case the changes mean an earlier transform is now applicable. The molecule is returned once the entire
        series of Normalizations cause no further changes or if max_restarts (default 200) is reached.

        :param mol: The molecule to normalize.
        :type mol: :rdkit:`Mol <Chem.rdchem.Mol-class.html>`
        :return: The normalized fragment.
        :rtype: :rdkit:`Mol <Chem.rdchem.Mol-class.html>`
        """

        log.debug('Running Normalizer')
        # Normalize each fragment separately to get around quirky RunReactants behaviour
        fragments = []
        for fragment in Chem.GetMolFrags(mol, asMols=True):
            fragments.append(self._normalize_fragment(fragment))
        
        # Join normalized fragments into a single molecule again
        outmol = fragments.pop()
        for fragment in fragments:
            outmol = Chem.CombineMols(outmol, fragment)
        return outmol
Example #5
0
def apply_reaction_smarts(plams_mol, reaction_smarts):
    """
    Applies reaction smirks and returns product
    """
    def react(reactant, reaction):
        """ Apply reaction to reactant and return products """
        ps = reaction.RunReactants([reactant])
        # keep reactant if no reaction applied
        if len(ps) == 0:
            return [reactant]
        products = []
        for p in ps:
            Chem.SanitizeMol(p[0])
            q = Chem.AddHs(p[0])
            Chem.SanitizeMol(q)
            gen_coords(q)
            products.append(q)
        return products

    rdmol = plams2rdkit(plams_mol)
    reaction = AllChem.ReactionFromSmarts(reaction_smarts)
    # RDKit removes fragments that are disconnected from the reaction center
    # In order to keep these, the molecule is first split in separate fragments
    # and the results, including non-reacting parts, are re-combined afterwards
    frags = (Chem.GetMolFrags(rdmol, asMols=True))
    product = Chem.Mol()
    for frag in frags:
        for p in react(frag, reaction):
            product = Chem.CombineMols(product, p)
    return rdkit2plams(product)
Example #6
0
    def judge_n_move_on(self, combined, combined_map, other, possible_map,
                        others, disregarded):
        """
        The mutables need to be within their own scope

        :param combined:
        :param combined_map:
        :param other:
        :param possible_map:
        :param others:
        :param disregarded:
        :return:
        """
        if len(possible_map) == 0:
            # reject
            combined = Chem.Mol(combined)
            disregarded = [*disregarded, other]  # new obj
        else:
            # accept
            combined_map = {**combined_map, **possible_map}  # new obj
            combined = Chem.CombineMols(combined, other)  # new obj
            name = '-'.join([
                m.GetProp('_Name') for m in (combined, other)
                if m.HasProp('_Name')
            ])
            combined.SetProp('_Name', name)
            disregarded = disregarded.copy()  # new obj
        # do inners
        accounted_for = set(combined_map.keys())
        template_sorter = self.template_sorter_factory(accounted_for)
        sorted_others = sorted(others[1:], key=template_sorter)
        self.unmerge_inner(combined, combined_map, sorted_others, disregarded)
Example #7
0
def AddArRing(mol, bond):
    # if double bond
    if all( atom.GetImplicitValence() for atom in (bond.GetBeginAtom(), bond.GetEndAtom())):
        pass
    elif bond.GetBondType() == bondorder[3]:
        bond.SetBondType(bondorder[2])
    else:
        print "wrong kind of atom given"
        raise MutateFail

    #print "in AddArRing!", Chem.MolToSmiles(mol)

    def AwithLabel(label):
        return filter(lambda atom: atom.HasProp(label),
                      mol.GetAtoms())[0].GetIdx()

    butadiene = Chem.MolFromSmiles('C=CC=C')
    butadiene.GetAtomWithIdx(0).SetBoolProp('buta1', True)
    butadiene.GetAtomWithIdx(3).SetBoolProp('buta2', True)
    bond.GetBeginAtom().SetBoolProp('ah1', True)
    bond.GetEndAtom().SetBoolProp('ah2', True)
    mol = Chem.RWMol(Chem.CombineMols(mol, butadiene))
    try:
        mol.AddBond(AwithLabel('buta1'), AwithLabel('ah1'), bondorder[1])
        mol.AddBond(AwithLabel('buta2'), AwithLabel('ah2'), bondorder[1])
    except RuntimeError:
        raise MutateFail
    #print "Finished AddArRing!", Chem.MolToSmiles(mol)
    return mol
 def _emergency_joining(self, mol):
     """
     The last check to see if the mol is connected, before being rectified (valence fixes).
     """
     frags = Chem.GetMolFrags(mol, asMols=True, sanitizeFrags=False)
     n = len(frags)
     while n > 1:
         log.warning(f'Molecule disconnected in {n} parts. Please inspect final product!')
         name = mol.GetProp('_Name')
         for i, frag in enumerate(frags):
             frag.SetProp('_Name', f'name.{i}')
         closeness = np.ones([n, n])
         closeness.fill(float('nan'))
         for a, b in itertools.combinations(list(range(n)), 2):
             closeness[a, b] = self._find_closest(frags[a], frags[b])[3]
         p = np.where(closeness == np.nanmin(closeness))
         frags = list(frags)
         first = frags[p[0][0]]
         second = frags[p[1][0]]
         mol = self.join_neighboring_mols(first, second)
         frags.remove(first)
         frags.remove(second)
         for part in frags:
             mol = Chem.CombineMols(mol, part)
             mol.SetProp('_Name', name)
         frags = Chem.GetMolFrags(mol, asMols=True, sanitizeFrags=False)
         n = len(frags)
     return mol
Example #9
0
def clean_charges(mol):
    Chem.SanitizeMol(mol)
    #rxn_smarts = ['[N+:1]=[*:2]-[C-:3]>>[N+0:1]-[*:2]=[C-0:3]',
    #              '[N+:1]=[*:2]-[O-:3]>>[N+0:1]-[*:2]=[O-0:3]',
    #              '[N+:1]=[*:2]-[*:3]=[*:4]-[O-:5]>>[N+0:1]-[*:2]=[*:3]-[*:4]=[O-0:5]',
    #              '[#8:1]=[#6:2]([!-:6])[*:3]=[*:4][#6-:5]>>[*-:1][*:2]([*:6])=[*:3][*:4]=[*+0:5]',
    #              '[O:1]=[c:2][c-:3]>>[*-:1][*:2][*+0:3]',
    #              '[O:1]=[C:2][C-:3]>>[*-:1][*:2]=[*+0:3]']

    rxn_smarts = [
        '[#6,#7:1]1=[#6,#7:2][#6,#7:3]=[#6,#7:4][CX3-,NX3-:5][#6,#7:6]1=[#6,#7:7]>>\
                   [#6,#7:1]1=[#6,#7:2][#6,#7:3]=[#6,#7:4][-0,-0:5]=[#6,#7:6]1[#6-,#7-:7]',
        '[#6,#7:1]1=[#6,#7:2][#6,#7:3](=[#6,#7:4])[#6,#7:5]=[#6,#7:6][CX3-,NX3-:7]1>>\
                   [#6,#7:1]1=[#6,#7:2][#6,#7:3]([#6-,#7-:4])=[#6,#7:5][#6,#7:6]=[-0,-0:7]1'
    ]

    fragments = Chem.GetMolFrags(mol, asMols=True, sanitizeFrags=False)

    for i, fragment in enumerate(fragments):
        for smarts in rxn_smarts:
            patt = Chem.MolFromSmarts(smarts.split(">>")[0])
            while fragment.HasSubstructMatch(patt):
                rxn = AllChem.ReactionFromSmarts(smarts)
                ps = rxn.RunReactants((fragment, ))
                fragment = ps[0][0]
                Chem.SanitizeMol(fragment)
                #print(Chem.MolToSmiles(fragment))
        if i == 0:
            mol = fragment
        else:
            mol = Chem.CombineMols(mol, fragment)

    return mol
Example #10
0
def clean_charges(mol):
    # this is a temporary hack. The real solution is to generate several BO matrices in AC2BO and pick the one
    # with the lowest number of atomic charges
    #
    #print 'clean_charges',Chem.MolToSmiles(mol)
    rxn_smarts = [
        '[N+:1]=[*:2]-[O-:3]>>[N+0:1]-[*:2]=[O-0:3]',
        '[N+:1]=[*:2]-[*:3]=[*:4]-[O-:5]>>[N+0:1]-[*:2]=[*:3]-[*:4]=[O-0:5]',
        '[#8:1]=[#6:2]([!-:6])[*:3]=[*:4][#6-:5]>>[*-:1][*:2]([*:6])=[*:3][*:4]=[*+0:5]',
        '[O:1]=[c:2][c-:3]>>[*-:1][*:2][*+0:3]',
        '[O:1]=[C:2][C-:3]>>[*-:1][*:2]=[*+0:3]'
    ]

    fragments = Chem.GetMolFrags(mol, asMols=True)

    for i, fragment in enumerate(fragments):
        for smarts in rxn_smarts:
            patt = Chem.MolFromSmarts(smarts.split(">>")[0])
            while fragment.HasSubstructMatch(patt):
                rxn = AllChem.ReactionFromSmarts(smarts)
                ps = rxn.RunReactants((fragment, ))
                fragment = ps[0][0]
        if i == 0:
            mol = fragment
        else:
            mol = Chem.CombineMols(mol, fragment)

    #print Chem.MolToSmiles(mol)

    return mol
Example #11
0
    def clean_charges(mol):
        # this hack should not be needed any more but is kept just in case
        #

        rxn_smarts = [
            '[N+:1]=[*:2]-[C-:3]>>[N+0:1]-[*:2]=[C-0:3]',
            '[N+:1]=[*:2]-[O-:3]>>[N+0:1]-[*:2]=[O-0:3]',
            '[N+:1]=[*:2]-[*:3]=[*:4]-[O-:5]>>[N+0:1]-[*:2]=[*:3]-[*:4]=[O-0:5]',
            '[#8:1]=[#6:2]([!-:6])[*:3]=[*:4][#6-:5]>>[*-:1][*:2]([*:6])=[*:3][*:4]=[*+0:5]',
            '[O:1]=[c:2][c-:3]>>[*-:1][*:2][*+0:3]',
            '[O:1]=[C:2][C-:3]>>[*-:1][*:2]=[*+0:3]'
        ]

        fragments = Chem.GetMolFrags(mol, asMols=True, sanitizeFrags=False)

        for i, fragment in enumerate(fragments):
            for smarts in rxn_smarts:
                patt = Chem.MolFromSmarts(smarts.split(">>")[0])
                while fragment.HasSubstructMatch(patt):
                    rxn = AllChem.ReactionFromSmarts(smarts)
                    ps = rxn.RunReactants((fragment, ))
                    fragment = ps[0][0]
            if i == 0:
                mol = fragment
            else:
                mol = Chem.CombineMols(mol, fragment)

        return mol
    def ModifyMolInPlace(self, reactants):
        # This applies transformation for all the matching pattern found in mol
        if len(self.reactantquery) != 1:
            raise ReactionQueryError('ModifyMolInPlace: Only usable for',
                                     'monomolecular transformation')
        if isinstance(reactants, Chem.Mol):
            reactants = [reactants]
        elif isinstance(reactants, tuple):
            reactants = list(reactants)
        # Error test
        if len(reactants) != len(self.reactantquery):
            raise ReactionQueryError('Number of reactant mis-match')
        for i in range(0, len(reactants)):
            if not isinstance(reactants[i], Chem.Mol):
                raise ReactionQueryError("Unrecognized instance'" +
                                         type(reactants[i]) + "'")
            reactants[i] = Chem.AddHs(reactants[i])
        # make matrix of matching index
        self.match_indexes = list()
        i = 0
        for reactant_name in self.reactantquery:
            if isinstance(self.reactantquery[reactant_name], Chem.Mol):
                match = reactants[i].GetSubstructMatches(
                    self.reactantquery[reactant_name])
                if not match:
                    return tuple()
                else:
                    self.match_indexes.append(match)
            elif isinstance(self.reactantquery[reactant_name], MolQuery):
                match = self.reactantquery[reactant_name].\
                    GetQueryMatches(reactants[i])
                if not match:
                    return tuple()
                else:
                    self.match_indexes.append(match)
            i += 1
        # make a index for combined reactants mol object
        self.combined_mol_match_index = list()
        for match in itpd(*self.match_indexes):
            row = list()
            modifier = 0
            for i in range(0, len(match)):
                if i != 0:
                    modifier = reactants[i - 1].GetNumAtoms()
                row += list(
                    map(add, list(match[i]), [modifier] * len(match[i])))
            self.combined_mol_match_index.append(row)
        # Combine reactants
        self.combined_mol = reactants[0]
        for i in range(1, len(reactants)):
            self.combined_mol = Chem.CombineMols(self.combined_mol,
                                                 reactants[i])

        self.combined_mol = Chem.RWMol(self.combined_mol)
        # Transform!!        product_list = list()
        for matches in self.combined_mol_match_index:
            for transform in self.transformations:
                transform(self.combined_mol, matches)
        return self.combined_mol
def single_point_crossover(m1, m2, bf):
    '''single point crossover for rings'''
    crossed_mols = []
    n1 = random.randint(1, 4)
    cp1 = return_cut_points(m1)
    cp2 = return_cut_points(m2)
    actual_cp1 = get_actual_cut_pts(m1, n1, cp1)
    actual_cp2 = get_actual_cut_pts(m2, n1, cp2)
    frags1 = frag_mol(m1, actual_cp1, bf)
    frags2 = frag_mol(m2, actual_cp2, bf)
    temp_mol1 = Chem.CombineMols(frags1[0], frags2[1])
    temp_mol2 = Chem.CombineMols(frags2[0], frags1[1])
    crossed_mol1 = join_mols(temp_mol1)
    crossed_mol2 = join_mols(temp_mol2)
    crossed_mols.append(crossed_mol1)
    crossed_mols.append(crossed_mol2)
    return crossed_mols
def make_complex(mol):
	"""
	PRE: Takes in a molecule aligned with the macrocycle
	POST: combines it with the macrocycle and returns a complex molecule
	"""
	macrocycle=Chem.MolFromMolBlock(get_CB_BLOCK(), removeHs=False)
	complex_CB_guest = Chem.CombineMols(mol, macrocycle)
	return complex_CB_guest
Example #15
0
def NormalCrossover(m1, m2):
    #Fragment molecules
    m1fs = GetFragment(m1)
    m2fs = GetFragment(m2)

    #pick fragments for crossover checking:
    # 1. Molecular weight
    Choices = []
    #maxWeight = mprms.maxWeight
    if maxWeight > 0:
        w1 = [Descriptors.MolWt(f) for f in m1fs]
        w2 = [Descriptors.MolWt(f) for f in m2fs]
        for i, j in ((i, j) for i in xrange(2) for j in xrange(2)):
            if w1[i] + w2[j] < maxWeight + 50.0: Choices.append((i, j))
    # 2. Number of Atoms
    #MxAtm=mprms.MxAtm
    if MxAtm > 0:
        a1 = [f.GetNumAtoms() for f in m1fs]
        a2 = [f.GetNumAtoms() for f in m2fs]
        for i, j in ((i, j) for i in xrange(2) for j in xrange(2)):
            if a1[i] + a2[j] < MxAtm + 4: Choices.append((i, j))

    if len(Choices) == 0:
        raise MutateFail()
    else:
        choice = random.choice(Choices)
        mol1 = m1fs[choice[0]]
        mol2 = m2fs[choice[1]]

    # now mol2 has to be connected to mol1
    # but what happens here?
    mol1.SetProp('parent1', m1.GetProp('isosmi'))
    mol2.SetProp('parent2', m2.GetProp('isosmi'))

    #Append molecule 2 to molecule 1.
    newmol = Chem.CombineMols(mol1, mol2)
    newids = Chem.GetMolFrags(newmol)

    # Now, bond the two fragments to create the child molecule.
    # We choose a random pair of possible atoms to do the attachment;
    possibleA1 = [
        atom for atom in GetIAtoms(newids[0], newmol) if EmptyValence(atom) > 0
    ]
    possibleA2 = [
        atom for atom in GetIAtoms(newids[1], newmol) if EmptyValence(atom) > 0
    ]

    if len(possibleA1) == 0 or len(possibleA2) == 0:
        #print "no possible atoms!"
        raise MutateFail()
    newmolRW = Chem.RWMol(newmol)
    atom1 = random.choice(possibleA1)
    atom2 = random.choice(possibleA2)
    newmolRW.AddBond(atom1.GetIdx(), atom2.GetIdx(), Chem.BondType.SINGLE)

    #print "new mol!", Chem.MolToSmiles(newmolRW)
    mol = newmolRW.GetMol()
    return mol
def join(scaffold_smi, decoration_smi, keep_label_on_atoms=False):
    """
    Joins a SMILES scaffold with a decoration. They must be labelled.
    :param scaffold_smi: SMILES of the scaffold.
    :param decoration_smi: SMILES of the decoration.
    :param keep_label_on_atoms: Add the labels to the atoms after attaching the molecule.
    This is useful when debugging, but it can give problems.
    :return: A Mol object of the joined scaffold.
    """
    scaffold = uc.to_mol(scaffold_smi)
    decoration = uc.to_mol(decoration_smi)

    if scaffold and decoration:
        # obtain id in the decoration
        try:
            attachment_points = [atom.GetProp("molAtomMapNumber") for atom in decoration.GetAtoms()
                                 if atom.GetSymbol() == ATTACHMENT_POINT_TOKEN]
            if len(attachment_points) != 1:
                return None  # more than one attachment point...
            attachment_point = attachment_points[0]
        except KeyError:
            return None

        combined_scaffold = rkc.RWMol(rkc.CombineMols(decoration, scaffold))
        attachments = [atom for atom in combined_scaffold.GetAtoms()
                       if atom.GetSymbol() == ATTACHMENT_POINT_TOKEN and
                       atom.HasProp("molAtomMapNumber") and atom.GetProp("molAtomMapNumber") == attachment_point]
        if len(attachments) != 2:
            return None  # something weird

        neighbors = []
        for atom in attachments:
            if atom.GetDegree() != 1:
                return None  # the attachment is wrongly generated
            neighbors.append(atom.GetNeighbors()[0])

        bonds = [atom.GetBonds()[0] for atom in attachments]
        bond_type = rkc.BondType.SINGLE
        if any(bond for bond in bonds if bond.GetBondType() == rkc.BondType.DOUBLE):
            bond_type = rkc.BondType.DOUBLE

        combined_scaffold.AddBond(neighbors[0].GetIdx(), neighbors[1].GetIdx(), bond_type)
        combined_scaffold.RemoveAtom(attachments[0].GetIdx())
        combined_scaffold.RemoveAtom(attachments[1].GetIdx())

        if keep_label_on_atoms:
            for neigh in neighbors:
                _add_attachment_point_num(neigh, attachment_point)

        scaffold = combined_scaffold.GetMol()
        try:
            rkc.SanitizeMol(scaffold)
        except ValueError:  # sanitization error
            return None
    else:
        return None

    return scaffold
Example #17
0
def test_dual_topology_standard_decoupling():

    # this class is used in double decoupling stages of the RABFE protocol. It modifies the
    # DualTopology class in one ways:
    # 1) the nonbonded terms are interpolated at lambda=0 such that the epsilons and charges are at half strength.

    ff = Forcefield.load_from_file("smirnoff_1_1_0_sc.py")
    mol_a = Chem.AddHs(Chem.MolFromSmiles("c1ccccc1O"))
    mol_b = Chem.AddHs(Chem.MolFromSmiles("c1ccccc1F"))
    mol_c = Chem.CombineMols(mol_a, mol_b)
    mol_top = topology.DualTopologyStandardDecoupling(mol_a, mol_b, ff)

    decouple_torsion_params, torsion_potential = mol_top.parameterize_proper_torsion(
        ff.pt_handle.params)

    combined_decouple_torsion_params, combined_torsion_potential = mol_top.parameterize_periodic_torsion(
        ff.pt_handle.params, ff.it_handle.params)

    assert len(combined_torsion_potential.get_lambda_mult()) == len(
        combined_torsion_potential.get_idxs())
    assert len(combined_torsion_potential.get_lambda_mult()) == len(
        combined_torsion_potential.get_lambda_offset())

    # impropers should always be turned on.
    # num_proper_torsions = len(torsion_potential.get_idxs())

    assert np.all(combined_torsion_potential.get_lambda_mult() == 0)
    assert np.all(combined_torsion_potential.get_lambda_offset() == 1)

    qlj_params, nonbonded_potential = mol_top.parameterize_nonbonded(
        ff.q_handle.params, ff.lj_handle.params)

    assert isinstance(nonbonded_potential, potentials.NonbondedInterpolated)

    expected_qlj = topology.standard_qlj_typer(mol_c)
    expected_qlj[:, 0] = expected_qlj[:, 0] / 2  # charges should be halved
    expected_qlj[:, 2] = expected_qlj[:, 2] / 2  # eps should be halved

    src_qlj_params = qlj_params[:len(qlj_params) // 2]
    dst_qlj_params = qlj_params[len(qlj_params) // 2:]

    np.testing.assert_array_equal(src_qlj_params, expected_qlj)

    expected_qlj = topology.standard_qlj_typer(mol_c)

    np.testing.assert_array_equal(dst_qlj_params, expected_qlj)

    combined_lambda_plane_idxs = nonbonded_potential.get_lambda_plane_idxs()
    combined_lambda_offset_idxs = nonbonded_potential.get_lambda_offset_idxs()

    A = mol_a.GetNumAtoms()
    B = mol_b.GetNumAtoms()
    C = mol_c.GetNumAtoms()

    np.testing.assert_array_equal(combined_lambda_plane_idxs, np.zeros(C))
    np.testing.assert_array_equal(combined_lambda_offset_idxs[:A], np.zeros(A))
    np.testing.assert_array_equal(combined_lambda_offset_idxs[A:], np.ones(B))
Example #18
0
def make_peptide_bond(mol, res=None, start="N", end="C", delete="OXT"):
    """Performs one condesation rxn between a molecule and residue/itself
    default creates peptide bond

    Parameters
    ----------
        mol : rdkmol
            Main molecule on which reaction is performed
        res : rdkmol
            None or a single residue, when it is None, self-condensation is performed on @mol
        start : str
            atom name of one of the two atoms to which connection is established
        end : str
            atom name of the other atom to which connection is established
        delete : str
            default to hydroxy oxygen thats eliminated during condensation

    Returns
    -------
    mol : rdkmol
        modified molecule
    """
    startIdx, endIdx, deleteIdx = -1, -1, -1
    for idx, atm in enumerate(mol.GetAtoms(
    )):  # get the last occurence of end and delete atomname
        if atm.GetPDBResidueInfo().GetName().strip() == end:
            endIdx = idx
        elif atm.GetPDBResidueInfo().GetName().strip() == delete:
            deleteIdx = idx

    if res is not None:  #residue addition
        lastResNum = -1
        for idx, atm in enumerate(mol.GetAtoms()):
            lastResNum = atm.GetPDBResidueInfo().GetResidueNumber()
        lastResNum += 1
        for idx, atm in enumerate(
                res.GetAtoms()):  #get the last occurence of start atomname
            atm.GetPDBResidueInfo().SetResidueNumber(lastResNum)
            if atm.GetPDBResidueInfo().GetName().strip() == start:
                startIdx = idx
        startIdx += mol.GetNumAtoms()
        mol = Chem.CombineMols(mol, res)
    else:  #cyclisation
        for idx, atm in enumerate(
                mol.GetAtoms()):  #get the first occurence of start atomname
            if atm.GetPDBResidueInfo().GetName().strip() == start:
                startIdx = idx
                break

    mol = Chem.RWMol(mol)
    mol.AddBond(startIdx, endIdx, Chem.BondType.SINGLE)
    mol.RemoveAtom(deleteIdx)
    mol.UpdatePropertyCache()
    Chem.GetSSSR(mol)
    return mol.GetMol()
    def RunReactants(self, reactants):
        if isinstance(reactants,Chem.Mol):
            reactants = [reactants]
        elif isinstance(reactants,tuple):
            reactants = list(reactants)
        # Error test
        if len(reactants) != len(self.reactantquery):
            raise ReactionQueryError('Number of reactant mis-match')
        for i in xrange(0,len(reactants)):
            if not isinstance(reactants[i],Chem.Mol):
                raise ReactionQueryError("Unrecognized instance'"+type(reactants[i])+"'")
            reactants[i] = Chem.AddHs(reactants[i])
        # make matrix of matching index
        self.match_indexes = list()
        i = 0
        for reactant_name in self.reactantquery:
            if isinstance(self.reactantquery[reactant_name],Chem.Mol):
                match = reactants[i].GetSubstructMatches(self.reactantquery[reactant_name])
                if not match:
                    return tuple()
                else:
                    self.match_indexes.append(match)
            elif isinstance(self.reactantquery[reactant_name],MolQuery):
                match = self.reactantquery[reactant_name].GetQueryMatches(reactants[i])
                if not match:
                    return tuple()
                else:
                    self.match_indexes.append(match)
            i += 1
        # make a index for combined reactants mol object
        self.combined_mol_match_index = list()
        for match in itpd(*self.match_indexes):
            row = list()
            modifier = 0
            for i in xrange(0,len(match)):
                if i != 0:
                    modifier = reactants[i-1].GetNumAtoms()
                row += map(add,list(match[i]),[modifier]*len(match[i]))
            self.combined_mol_match_index.append(row)
        # Combine reactants
        self.combined_mol = reactants[0]
        for i in xrange(1,len(reactants)):
            self.combined_mol = Chem.CombineMols(self.combined_mol,reactants[i])

        self.combined_mol = Chem.RWMol(self.combined_mol)
        # Transform!!
        product_list = list()
        for matches in self.combined_mol_match_index:
            products = self.combined_mol.__copy__()
            for transform in self.transformations:
                transform(products, matches)
            products = Chem.GetMolFrags(products,asMols=True,sanitizeFrags=False)
            product_list.append(products)
        return tuple(product_list)
Example #20
0
def make_conformer(mol, conf_a, conf_b):
    mol.RemoveAllConformers()
    mol = Chem.CombineMols(mol, mol)
    cc = Chem.Conformer(mol.GetNumAtoms())
    conf = np.concatenate([conf_a, conf_b])
    conf *= 10
    for idx, pos in enumerate(onp.asarray(conf)):
        cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2])))
    mol.AddConformer(cc)

    return mol
Example #21
0
def sub_att(mainmol, fun_mol, pair):
    ls_submol = []

    mainmol = Chem.MolFromSmiles(mainmol)
    for i in pair:
        combo = Chem.CombineMols(mainmol, fun_mol)
        edcombo = Chem.EditableMol(combo)
        edcombo.AddBond(i[0], i[1], order=Chem.rdchem.BondType.SINGLE)
        back = edcombo.GetMol()
        back = Chem.MolToSmiles(back, isomericSmiles=True, canonical=True)
        ls_submol.append(back)
    return ls_submol
Example #22
0
def __gen_replacements(mol1, mol2, db_name, radius, dist=None, min_size=0, max_size=8, min_rel_size=0, max_rel_size=1,
                       min_inc=-2, max_inc=2, max_replacements=None, replace_cycles=False,
                       protected_ids_1=None, protected_ids_2=None, min_freq=10):

    def func():
        for env, core, *ids in f:  # if link = True ids is two tuples, if link = False ids is a single tuple

            num_heavy_atoms = Chem.MolFromSmiles(core).GetNumHeavyAtoms()
            hac_ratio = num_heavy_atoms / mol_hac

            if (min_size <= num_heavy_atoms <= max_size and min_rel_size <= hac_ratio <= max_rel_size) \
                    or (replace_cycles and cycle_pattern.search(core)):

                frag_sma = combine_core_env_to_rxn_smarts(core, env)

                min_atoms = num_heavy_atoms + min_inc
                max_atoms = num_heavy_atoms + max_inc

                rep = __get_replacements(cur, env, dist, min_atoms, max_atoms, radius, min_freq)
                for core_smi, core_sma, freq in rep:
                    if core_smi != core:
                        if link:
                            yield frag_sma, core_sma, freq, ids[0], ids[1]
                        else:
                            yield frag_sma, core_sma, freq, ids[0]

    link = False
    if not isinstance(mol1, Chem.Mol):
        raise StopIteration("The first molecule in __gen_replacement always must be specified")
    if isinstance(mol1, Chem.Mol) and isinstance(mol2, Chem.Mol):
        link = True

    if link:
        f = __fragment_mol_link(mol1=mol1, mol2=mol2, radius=radius, protected_ids_1=protected_ids_1,
                                protected_ids_2=protected_ids_2)
        mol = Chem.CombineMols(mol1, mol2)
    else:
        mol = mol1
        f = __fragment_mol(mol, radius, protected_ids=protected_ids_1)

    mol_hac = mol.GetNumHeavyAtoms()

    con = sqlite3.connect(db_name)
    cur = con.cursor()

    if max_replacements is not None:
        res = list(func())
        random.shuffle(res)
        for items in res[:max_replacements]:
            yield items
    else:
        for items in func():
            yield items
Example #23
0
    def __init__(self, amine, carboxy):
        # Construct a editable Mol from modified Amine and Carboxylic acid
        edMol = Chem.EditableMol(
            Chem.CombineMols(amine.Modify(), carboxy.Modify()))

        atomIdxDict = {}
        # Match atom list indice to atom mapping numbers
        for i, atm in enumerate(edMol.GetMol().GetAtoms()):
            atomIdxDict[atm.GetAtomMapNum()] = i

        # Find attaching atoms by mapping number on each constituent mol and make a single bond
        edMol.AddBond(atomIdxDict[amine.reactAtom],
                      atomIdxDict[carboxy.reactAtom],
                      order=Chem.rdchem.BondType.SINGLE)
        #replace all single bond in the product as an arbitrary single bond (allow aromaticity)
        self.sma = Chem.MolToSmarts(edMol.GetMol()).replace(
            "-,:", '')  #.replace("-", '')
        # Construct the final product
        super().__init__(Chem.MolFromSmarts(self.sma))
        hA = "{" + amine.hybridization + "}"
        if amine.modifArg:
            aReac = "{" + {
                1: 'A',
                2: '\\alpha',
                3: '\\beta'
            }[amine.reactAtom] + amine.modifArg + "}"
        else:
            aReac = "{" + {
                1: 'A',
                2: '\\alpha',
                3: '\\beta'
            }[amine.reactAtom] + "}"

        hB = "{" + carboxy.hybridization + "}"

        if carboxy.modifArg:
            bReac = "{" + {
                5: 'B[O]',
                6: 'B[C]',
                7: '\\alpha',
                8: '\\beta'
            }[carboxy.reactAtom] + carboxy.modifArg + "}"
        else:
            bReac = "{" + {
                5: 'B[O]',
                6: 'B[C]',
                7: '\\alpha',
                8: '\\beta'
            }[carboxy.reactAtom] + "}"

        latexModStr = '$^{}{}^{}/^{}{}^{}$'.format(hA, '{NH_2}', aReac, hB,
                                                   '{COOH}', bReac)
        self.SetProp('Modification', latexModStr)
Example #24
0
def merge_CB_guest(mol):
    """Merges the CB7 structure taken from a saved file with the structure of the guest as computed
    The argments are a mol object for the guest structure and two flags gen_ETKDG and gen_no_chiral that indicate how and if the guest structure was converged"""
    # CB_HOST = Chem.SDMolSupplier('../CB_candidate.sdf', removeHs=False)[0]
    CB_HOST = Chem.MolFromMolBlock(get_CB_BLOCK(), removeHs=False)
    complex_cb_guest = Chem.CombineMols(CB_HOST, mol)
    Chem.GetSSSR(complex_cb_guest)  # Dirty fix to avoid an error
    # ff = AllChem.MMFFGetMoleculeForceField(complex_cb_guest, pyMMFFMolProperties=AllChem.MMFFGetMoleculeProperties(complex_cb_guest), ignoreInterfragInteractions=False, nonBondedThresh=100.0)
    # converged = ff.Minimize(n_steps, tol, tol)
    # E_complex = ff.CalcEnergy()
    # converged = converge(complex_cb_guest)
    return complex_cb_guest
def join_total(frags):
    '''joins list of multiple fragments together, returns new mol'''
    print len(frags)
    join_pts = [0, 1, 2, 3]
    for x in join_pts:
        #print x
        if x == 0:
            temp_mol = Chem.CombineMols(frags[x], frags[x + 1])
            atch_mol = join_mols(temp_mol)
            #r = atch_mol.GetRingInfo()
            #print r.NumRings()
            continue
        if x == 4:
            break
        else:
            temp_mol = Chem.CombineMols(atch_mol, frags[x + 1])
            new_atch_mol = join_mols(temp_mol)
            #r = new_atch_mol.GetRingInfo()
            #print r.NumRings()
            atch_mol = new_atch_mol
    return atch_mol
Example #26
0
def combine(skeleton, arm):
    '''
    combine a skeleton and an arm to form a complete molecule graph
    TODO: the smiles representations are different after combining,
          might because the node index is different
    TODO: unstandardized molecules fail to get features
    '''
    mol = Chem.CombineMols(skeleton.mol, arm.mol)
    mol = Chem.RWMol(mol)
    u = skeleton.u
    v = skeleton.mol.GetNumAtoms() + arm.v
    mol.AddBond(u, v, arm.bond_type)
    return mol.GetMol()
Example #27
0
def make_conformer(mol, conf_a, conf_b):
    """Remove all of mol's conformers, make a new mol containing two copies of mol,
    assign positions to each copy using conf_a and conf_b, respectively, assumed in nanometers"""
    mol.RemoveAllConformers()
    mol = Chem.CombineMols(mol, mol)
    cc = Chem.Conformer(mol.GetNumAtoms())
    conf = np.concatenate([conf_a, conf_b])
    conf *= 10  # TODO: label this unit conversion?
    for idx, pos in enumerate(np.asarray(conf)):
        cc.SetAtomPosition(idx, (float(pos[0]), float(pos[1]), float(pos[2])))
    mol.AddConformer(cc)

    return mol
Example #28
0
def combine_core_env_to_rxn_smarts(core, env, keep_h=True):

    if isinstance(env, str):
        m_env = Chem.MolFromSmiles(env, sanitize=False)
    if isinstance(core, str):
        m_frag = Chem.MolFromSmiles(core, sanitize=False)

    backup_atom_map = "backupAtomMap"

    # put all atom maps to atom property and remove them
    for a in m_env.GetAtoms():
        atom_map = a.GetAtomMapNum()
        if atom_map:
            a.SetIntProp(backup_atom_map, atom_map)
            a.SetAtomMapNum(0)

    for a in m_frag.GetAtoms():
        atom_map = a.GetAtomMapNum()
        if atom_map:
            a.SetIntProp(backup_atom_map, atom_map)
            a.SetAtomMapNum(0)

    # set canonical ranks for atoms in env without maps
    m_env.UpdatePropertyCache()
    for atom_id, rank in zip([a.GetIdx() for a in m_env.GetAtoms()],
                             list(Chem.CanonicalRankAtoms(m_env))):
        a = m_env.GetAtomWithIdx(atom_id)
        if not a.HasProp(backup_atom_map):
            a.SetAtomMapNum(rank + 1)  # because ranks start from 0

    m = Chem.RWMol(Chem.CombineMols(m_frag, m_env))

    links = defaultdict(list)  # pairs of atom ids to create bonds
    att_to_remove = []  # ids of att points to remove
    for a in m.GetAtoms():
        if a.HasProp(backup_atom_map):
            i = a.GetIntProp(backup_atom_map)
            links[i].append(a.GetNeighbors()[0].GetIdx())
            att_to_remove.append(a.GetIdx())

    for i, j in links.values():
        m.AddBond(i, j, Chem.BondType.SINGLE)

    for i in sorted(att_to_remove, reverse=True):
        m.RemoveAtom(i)

    comb_sma = mol_to_smarts(m, keep_h)
    if not keep_h:  # remove H only in mapped env part
        comb_sma = patt_remove_h.sub('', comb_sma)
    return comb_sma
Example #29
0
 def add_custom_fragment(childGenes, GeneSet, oldGene):
     geneSet = GeneSet.CustomFrags
     newGene = Chromosome(geneSet.GetEntryDescription(\
         random.sample(range(geneSet.GetNumEntries()), 1)[0]),0)
     oldGene = oldGene + newGene.Mol.GetNumAtoms()
     combined = Chem.EditableMol(
         Chem.CombineMols(newGene.Mol, childGenes.Mol))
     combined.AddBond(0, oldGene, order=Chem.rdchem.BondType.SINGLE)
     childGenes = combined.GetMol()
     try:
         childGenes = Chromosome(Chem.MolToSmiles(childGenes), 0)
         return childGenes
     except:
         return 0
Example #30
0
    def validate_dataset(self):
        x_complex = []
        for pdb_code, ligand, pocket in zip(self.pdb_code, self.x_ligand,
                                            self.x_pocket):
            Chem.RemoveHs(ligand)
            Chem.RemoveHs(pocket)
            complx = Chem.CombineMols(ligand, pocket)
            complx.SetProp('_Name', '{}_complex'.format(pdb_code))
            x_complex.append(complx)

        # Validate
        self.exclude = []
        for mol in x_complex:
            print("Validating {}".format(mol.GetProp('_Name')))
            dist = []
            coordinates = np.array([
                list(mol.GetConformer().GetAtomPosition(j))
                for j in range(mol.GetNumAtoms())
            ])
            for i in range(mol.GetNumAtoms()):
                for j in range(i, mol.GetNumAtoms()):
                    if i == j: continue
                    dist.append(np.linalg.norm(coordinates[i] -
                                               coordinates[j]))

            dist = np.array(dist)
            if len(dist[dist < 1]) > 0:
                self.exclude.append(mol.GetProp('_Name').split('_')[0])

        # Collect results
        code_new, ligands_new, pockets_new = [], [], []
        for pdb_code, ligand, pocket in zip(self.pdb_code, self.x_ligand,
                                            self.x_pocket):
            if pdb_code in self.exclude:
                continue
            else:
                code_new.append(pdb_code)
                ligands_new.append(ligand)
                pockets_new.append(pocket)
        self.pdb_code, self.x_ligand, self.x_pocket = code_new, ligands_new, pockets_new

        # Save
        w = Chem.SDWriter('../data/ligand_filtered.sdf')
        for mol in self.x_ligand:
            w.write(mol)
        w = Chem.SDWriter('../data/pocket_filtered.sdf')
        for mol in self.x_pocket:
            w.write(mol)
        print("Molecules Validated")