示例#1
0
def select_dummy_atoms(all_dummies, helix_dummies, center, positive_pose=True):
  select = openbabel.OBMol()
  search_for = ""
  
  ## 1.1 start the search for the correct atoms
  log.info('Searching for dummies with center position ' + str(center) + "...")
  
  ## 1.2 find corresponding helix dummy
  search_for =  str(float(center)-1)
  log.debug("Starting search for: "+search_for)
  for res in openbabel.OBResidueIter(helix_dummies):
    log.debug(res.GetNumString())
    if float(res.GetNumString()) == float(search_for):
      log.info('... found dummy number 1 at helix.')
      select.AddResidue(res)
      for atom in openbabel.OBResidueAtomIter(res): 
	select.AddAtom(atom)
      break
  
  ## 1.2.1. find next helix dummy
  search_for =  str(float(center))
  for res in openbabel.OBResidueIter(helix_dummies):
    log.debug(res.GetNumString())
    if float(res.GetNumString()) == float(search_for):
      log.info('... found dummy number 2 at helix.')
      select.AddResidue(res)
      for atom in openbabel.OBResidueAtomIter(res): 
	select.AddAtom(atom)
      break
  
  ## 1.3 find next-to-center dna dummy
  search_for =  str(float(center)-1)
  for res in openbabel.OBResidueIter(all_dummies):
    log.debug(res.GetNumString())
    if float(res.GetNumString()) == float(search_for):
      log.info('... found dummy before center.')
      select.AddResidue(res)
      for atom in openbabel.OBResidueAtomIter(res): 
	select.AddAtom(atom)
      break
      
  ## 1.4 find center dna atom
  search_for =  str(float(center)+2)
  for res in openbabel.OBResidueIter(all_dummies):
    log.debug(res.GetNumString())
    if float(res.GetNumString()) == float(search_for):
      log.info('... found dummy after center.')
      select.AddResidue(res)
      for atom in openbabel.OBResidueAtomIter(res): 
	select.AddAtom(atom)
      break

  ## 1.3 check for success
  if select.NumAtoms() != 4:
    log.critical("Could not select DNA dummy atoms to align the ligand to. I have selected "+str(select.NumAtoms())+" atoms. Alignment will fail!")

  return select
示例#2
0
def saveMol(prot, outPref, outFmt):
    # apply eventual patches due to amber top to openbabel format differences and output docking format file
    currDir = os.getcwd()

    # adjust H
    for atom in prot:
        if atom.atomicnum == 1:
            atom.OBAtom.SetType('H')

    for res in ob.OBResidueIter(prot.OBMol):
        resname = res.GetName()
        if resname == 'HEM':
            #nhem=res.GetNum()
            for atm in ob.OBResidueAtomIter(res):
                if atm.GetType() == 'FE':
                    atm.SetType('Fe')
                if atm.GetType() == 'Du':
                    atName = res.GetAtomID(atm).lstrip()
                    atm.SetType(atName[0])

    print "save mol2 for docking"
    templfn = os.path.join(currDir, "%s.%s" % (outPref, outFmt))
    out = pb.Outputfile(outFmt, templfn, overwrite=True)
    out.write(prot)
    out.close()

    return templfn
示例#3
0
    def nameAtoms(self):
        """Attempts to name atoms """
        has_residues = False
        residue_has_atoms = False
        atoms_no_name = list(range(0, self.mol.NumAtoms()))

        # first try to name atoms according to biological
        # function, i.e. from a PDB file.

        # OpenBabel has problems with some elements so we need to work around
        # those here.
        for residue in openbabel.OBResidueIter(self.mol):
            has_residues = True
            if residue.GetNumAtoms() > 0:
                residue_has_atoms = True
                for atom in openbabel.OBResidueAtomIter( residue ):
                    atoms_no_name.remove(atom.GetId())
                    self._atom_names.append( residue.GetAtomID( atom ) )
            else:
                pass

        # if there are items left in "atoms_no_name" try to name them
        #print atoms_no_name
        if len(atoms_no_name) > 0:
            if self.getVerbose():
                print("Info: FragIt [FRAGMENTATION] will now try to name remaining {0:3d} atoms".format(len(atoms_no_name)))

            for i, id in enumerate(atoms_no_name):
                atom = self.mol.GetAtom(id+1)
                self._atom_names.append(atom.GetType())
                if self.getVerbose():
                    print("   atom {0:4d} is forced to have name '{1:s}'".format(id, atom.GetType()))
示例#4
0
def CypCenter(protMol):
    # Find Fe coordinates
    # Find Virtual O (cpdI) coordinates
    # Find equations of the hem plane
    listheme = [
        'C2B', 'CHB', 'C3A', 'C2A', 'CHA', 'C3D', 'C2D', 'CHD', 'C3C', 'C2C',
        'CHC', 'C3B'
    ]
    Fe_coord = None
    S_coord = None
    hemeplane_coor = dict()
    for res in ob.OBResidueIter(protMol.OBMol):
        resname = res.GetName()
        if resname == 'HEM':
            for atm in ob.OBResidueAtomIter(res):
                atmname = res.GetAtomID(atm).strip()
                if atmname in listheme:
                    hemeplane_coor[atmname] = [
                        atm.GetX(), atm.GetY(),
                        atm.GetZ()
                    ]
                elif atm.GetType() == 'FE' or atm.GetType(
                ) == 'Fe' or atmname == 'FE' or atmname == 'FE':
                    Fe_coord = [atm.GetX(), atm.GetY(), atm.GetZ()]

    #get normal of the plane of the heme ring
    hemnorm = normhem(hemeplane_coor)
    catcenter = findOcpd1(hemnorm, Fe_coord, dist=6.0)

    return catcenter
示例#5
0
def MassCenter(residue):
    wsum = 0
    v = [0, 0, 0]
    for atom in ob.OBResidueAtomIter(residue):
        w = atom.GetAtomicMass()
        wsum += w
        v[0] += w * atom.x()
        v[1] += w * atom.y()
        v[2] += w * atom.z()
    v[0] /= wsum
    v[1] /= wsum
    v[2] /= wsum
    return v
示例#6
0
def extract_ligand(obmol, res_name='INH'):
    """
    This function is used to extract the ligands which are always named 'INH'
    from CSAR structures.
    """
    ligand = ob.OBMol()

    for residue in ob.OBResidueIter(obmol):
        if residue.GetName() == res_name:

            mapping = {}

            # insert the ligand atoms into the new molecule
            for i, atom in enumerate(ob.OBResidueAtomIter(residue), 1):
                ligand.InsertAtom(atom)
                mapping[atom.GetIdx()] = i

            # re-create the bonds
            for atom in ob.OBResidueAtomIter(residue):
                for bond in ob.OBAtomBondIter(atom):
                    bgn_idx = mapping[bond.GetBeginAtomIdx()]
                    end_idx = mapping[bond.GetEndAtomIdx()]

                    ligand.AddBond(bgn_idx, end_idx, bond.GetBondOrder(),
                                   bond.GetFlags())

            # remove the ligand from the original structure
            for atom_idx in sorted(mapping.keys(), reverse=True):
                atom = obmol.GetAtom(atom_idx)
                obmol.DeleteAtom(atom)

            obmol.DeleteResidue(residue)

            break

    return pybel.Molecule(ligand)
示例#7
0
def getSurrResids(pybelMol, centerDock, radiusRes, listExclude=[]):
    listRes = []
    print 'GETSURRRESIDUE'
    print centerDock, radiusRes
    for res in ob.OBResidueIter(pybelMol.OBMol):
        if not res.GetName() in listExclude:
            inner = False
            for atm in ob.OBResidueAtomIter(res):
                coords = [atm.GetX(), atm.GetY(), atm.GetZ()]
                if dist(coords, centerDock) < radiusRes:
                    inner = True
                    break
            if inner:
                listRes.append(res.GetNum())
    return listRes
示例#8
0
def get_fingerprint(file_type,file_path):
    '''file type: file format that is accepted by Openbabel
        file_path: path to file
        returns fingerprint based on MACCS'''
    mol=next(pybel.readfile(file_type,file_path))
    fingerprint=[]
    residues=[x for x in openbabel.OBResidueIter(mol.OBMol)]
    for i in range(len(residues)-3):
        mers=residues[i:i+3]
        mol1=openbabel.OBMol()
        for r in mers:
            for atoms in openbabel.OBResidueAtomIter(r):
                mol1.AddAtom(atoms)
        mol1.ConnectTheDots()
        mol2=pybel.Molecule(mol1)
        fp=[1 if i in list(mol2.calcfp('MACCS').bits) else 0 for i in range(167)]
        fingerprint.append(fp)
    return np.asarray(fingerprint)
示例#9
0
文件: Molecule.py 项目: xis19/LocVib
    def residue_groups(self):
        groupnames = []
        groups = []

        # force residue perception
        self.obmol.GetAtom(1).GetResidue()

        for r in openbabel.OBResidueIter(self.obmol):
            resgroup = []
            for at in openbabel.OBResidueAtomIter(r):
                resgroup.append(at.GetIdx() - 1)
            groupnames.append(str(r.GetNum()))
            groups.append(resgroup)

        z = zip(groupnames, groups)
        z.sort(lambda x, y: cmp(int(x[0]), int(y[0])))
        groupnames = [x[0] for x in z]
        groups = [x[1] for x in z]

        return groups, groupnames
示例#10
0
    def tryNameFragment(self, atoms):
        matched_atoms     = 0
        frag_name     = False
        residues = self.identifyResidues()
        charge_lbls = ["", "+", "-"]

        if len(atoms) == 0:
            raise ValueError("Error: FragIt [FRAGMENTATION] Cannot name empty fragments. Aborting.")

        if len(atoms) == 1:
            atom = self.mol.GetAtom(atoms[0])
            charge_lbl = charge_lbls[atom.GetFormalCharge()]
            element = Z2LABEL[atom.GetAtomicNum()]
            return "{0:s}{1:s}".format(element, charge_lbl)
        else:
            for residue in openbabel.OBResidueIter( self.mol ):
                for atom in openbabel.OBResidueAtomIter( residue ):
                    if atom.GetIdx() in atoms:
                        return residue.GetName()
        return "None"
示例#11
0
 def atoms(self):
     """List of Atoms in the Residue"""
     return [Atom(atom) for atom in ob.OBResidueAtomIter(self.OBResidue)]
示例#12
0
def MolecularWeight(residue):
    Mw = 0
    for atom in ob.OBResidueAtomIter(residue):
        Mw += atom.GetAtomicMass()
    return Mw
示例#13
0
def PiPi(pdb_file, lig_name, centroid_distance, dih_parallel, dih_tshape):
    # Get ligand residue and print its name.
    ligAtomList = []
    ligAtomIdList = []
    mol = pybel.readfile('pdb', pdb_file).next()
    print "A total of %s residues" % mol.OBMol.NumResidues()
    lig = None
    for res in ob.OBResidueIter(mol.OBMol):
        # print res.GetName()
        if res.GetName() == lig_name:
            lig = res
            print "Ligand residue name is: ", lig.GetName()
            break
    if not lig:
        print "No ligand residue %s found, please confirm." % lig_name
        return 0
    else:
        for atom in ob.OBResidueAtomIter(lig):
            # print atom.GetIdx()
            ligAtomList.append(atom)
            ligAtomIdList.append(atom.GetIdx())

    # Set ring_id
    i = 0
    for ring in mol.sssr:
        ring.ring_id = i
        i += 1
        # print ring.ring_id

    # Determine which rings are from ligand.
    ligRingList = []
    ligAroRingList = []
    ligRingIdList = []
    recRingList = []
    recAroRingList = []
    for ring in mol.sssr:
        for atom in ligAtomList:
            if ring.IsMember(atom):
                if ring not in ligRingList:
                    ligRingList.append(ring)
                    ligRingIdList.append(ring.ring_id)
                    print "ligand ring_ID: ", ring.ring_id,
                    if ring.IsAromatic():
                        print "Aromatic"
                        ligAroRingList.append(ring)
                    else:
                        print "Saturated"
    for ring in mol.sssr:
        if ring.ring_id not in ligRingIdList:
            recRingList.append(ring)
            if ring.IsAromatic():
                recAroRingList.append(ring)
    print "\nReceptor has ", len(recRingList), " rings,",
    print " has ", len(recAroRingList), " aromatic rings."

    # Find and show the rings
    ligRingCenter = ob.vector3()
    recRingCenter = ob.vector3()
    ligNorm1 = ob.vector3()
    ligNorm2 = ob.vector3()
    recNorm1 = ob.vector3()
    recNorm2 = ob.vector3()
    coord1 = []
    coord2 = []
    pair = []  # Store the names of the objects
    pairList = []
    psObjectList = []
    i = 0
    for ligRing in ligAroRingList:
        ligRing.findCenterAndNormal(ligRingCenter, ligNorm1, ligNorm2)
        coord1 = [
            ligRingCenter.GetX(),
            ligRingCenter.GetY(),
            ligRingCenter.GetZ()
        ]
        # Create a pseudoatom for the centroid of each ring in the ligand
        objectName1 = 'psCenter%.2d' % i
        i += 1
        cmd.pseudoatom(object=objectName1, pos=coord1)
        psObjectList.append(objectName1)
        for recRing in recAroRingList:
            recRing.findCenterAndNormal(recRingCenter, recNorm1, recNorm2)
            dist = ligRingCenter.distSq(recRingCenter)
            angle = vecAngle(ligNorm1, recNorm1)
            if (dist**0.5 < centroid_distance and
                (angle < dih_parallel or angle > dih_tshape)):  # the criteria
                coord2 = [
                    recRingCenter.GetX(),
                    recRingCenter.GetY(),
                    recRingCenter.GetZ()
                ]
                # Create pseudoatom for each lig ring center
                objectName2 = 'psCenter%.2d' % i
                i += 1
                cmd.pseudoatom(object=objectName2, pos=coord2)
                psObjectList.append(objectName2)
                # pair=[coord1,coord2]
                pair = [objectName1, objectName2]
                # print "%.4f,%.4f,%.4f" % (pair[1][0],pair[1][1],pair[1][2])
                pairList.append(pair)
                cmd.distance('dist-' + objectName1 + '-' + objectName2,
                             pair[0], pair[1])
                print objectName1, objectName2, " angle is : %.2f" % angle
示例#14
0
def make_structure(request):
    def makeResidue(mol, idx, aaatoms):
        res = mol.NewResidue()
        res.SetNum(idx)
        for atom in ob.OBMolAtomIter(mol):
            if atom.GetIdx() not in aaatoms:
                res.AddAtom(atom)

    aminoacids = request.GET.getlist("as")
    color = request.GET.get("rescol", "#3EC1CD")

    mol = ob.OBMol()
    conv = ob.OBConversion()
    pattern = ob.OBSmartsPattern()
    pattern.Init("[NX3][$([CX4H1]([*])),$([CX4H2])][CX3](=[OX1])[OX2]")
    builder = ob.OBBuilder()
    conv.SetInAndOutFormats("sdf", "svg")
    conv.AddOption("d", ob.OBConversion.OUTOPTIONS)
    conv.AddOption("b", ob.OBConversion.OUTOPTIONS, "none")
    conv.ReadString(mol, str(Substrate.objects.get(pk=int(aminoacids[0])).structure))
    pattern.Match(mol)
    mollist = pattern.GetUMapList()[0]
    oatom = mol.GetAtom(mollist[4])
    catom = mol.GetAtom(mollist[2])
    firstnatom = mol.GetAtom(mollist[0])
    makeResidue(mol, 0, mollist)

    i = 1
    for aa in aminoacids[1:]:
        mol2 = ob.OBMol()
        conv.ReadString(mol2, str(Substrate.objects.get(pk=int(aa)).structure))
        pattern.Match(mol2)
        mollist = pattern.GetUMapList()[0]
        makeResidue(mol2, i, mollist)

        molnatoms = mol.NumAtoms()
        mol += mol2

        natom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[0]).GetIdx())

        builder.Connect(mol, catom.GetIdx(), natom.GetIdx())

        foatom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[4]).GetIdx())
        catom = mol.GetAtom(molnatoms + mol2.GetAtom(mollist[2]).GetIdx())
        mol.DeleteHydrogens(oatom)
        mol.DeleteAtom(oatom)

        natom.SetImplicitValence(3)
        mol.DeleteHydrogens(natom)
        mol.AddHydrogens(natom)
        oatom = foatom

        i += 1

    nidx = firstnatom.GetIdx()
    oidx =  oatom.GetIdx()
    builder.Build(mol)
    natom = mol.GetAtom(nidx)
    oatom = mol.GetAtom(oidx)
    for res in ob.OBResidueIter(mol):
        for atom in ob.OBResidueAtomIter(res):
            for bond in ob.OBAtomBondIter(atom):
                data = ob.OBPairData()
                data.SetAttribute("color")
                data.SetValue(color)
                bond.CloneData(data)
    mol.DeleteHydrogens()
    gen2d = ob.OBOp.FindType("gen2d")
    gen2d.Do(mol)

    opp = oatom.GetY() - natom.GetY()
    adj = oatom.GetX() - natom.GetX()
    angle = abs(math.atan(opp / adj))
    if opp > 0 and adj > 0:
        pass
    elif opp > 0 and adj < 0:
        angle = math.pi - angle
    elif opp < 0 and adj < 0:
        angle = math.pi + angle
    elif opp < 0 and adj > 0:
        angle = 2 * math.pi - angle
    angle = -angle
    mol.Rotate(ob.double_array([math.cos(angle), -math.sin(angle), 0,
                                math.sin(angle), math.cos(angle),  0,
                                0,               0,                1]))
    svg = conv.WriteString(mol)
    # need to get rid of square aspect ratio
    delstart = svg.find("width")
    delend = svg.find("svg", delstart)
    delend = svg.find("viewBox", delend)
    svgend = svg.rfind("</g>")
    svg = svg[0:delstart] + svg[delend:svgend]
    return HttpResponse(svg, mimetype="image/svg+xml")
示例#15
0
def generate_fragfile(filename, outtype, ffparams=None, eqgeom=False):
    # check outtype
    if outtype not in ["flex", "header", "min"]:
        sys.exit(
            'Invalid argument indicating verbosity of .dfr (%s). Use "flex", "header" or "min".'
            % outtype)

    # get basename and file extension
    base, ext = os.path.splitext(filename)

    # set openbabel file format
    obConversion = openbabel.OBConversion()
    obConversion.SetInAndOutFormats(ext[1:], "xyz")

    # read molecule to OBMol object
    mol = openbabel.OBMol()
    obConversion.ReadFile(mol, filename)

    if ffparams:
        # get atomic labels from pdb
        idToAtomicLabel = {}
        for res in openbabel.OBResidueIter(mol):
            for atom in openbabel.OBResidueAtomIter(res):
                idToAtomicLabel[atom.GetId()] = res.GetAtomID(atom).strip()

        # read force field parameters and store into dictionaries
        labelToSLabel = {}
        charges = {}
        epsilons = {}
        sigmas = {}
        bonds = {}
        angles = {}
        dihedrals = {}
        impropers = {}
        with open(ffparams, 'r') as f:
            line = f.readline()
            # read nb params
            while "$bond" not in line:
                if line.strip().startswith("#") or not line.strip():
                    line = f.readline()
                    continue

                lbl = line.split()[0]
                charges[lbl] = line.split()[1]
                epsilons[lbl] = line.split()[2]
                sigmas[lbl] = line.split()[3]
                labelToSLabel[lbl] = line.split()[4]

                line = f.readline()

            # read bond params
            line = f.readline()
            while "$angle" not in line:
                if line.strip().startswith(
                        "#") or "$end" in line or not line.strip():
                    line = f.readline()
                    continue

                line = line.replace("–", "-")

                # store the constants for the order of the input and the inverse order
                consts = "\t".join(line.split()[1:])
                bonds[line.split()[0]] = consts
                bonds["-".join(line.split()[0].split("-")[::-1])] = consts

                line = f.readline()

            # read angle params
            line = f.readline()
            while "$dihedral" not in line:
                if line.strip().startswith(
                        "#") or "$end" in line or not line.strip():
                    line = f.readline()
                    continue

                line = line.replace("–", "-")

                # store the constants for the order of the input and the inverse order
                consts = "\t".join(line.split()[1:])
                angles[line.split()[0]] = consts
                angles["-".join(line.split()[0].split("-")[::-1])] = consts

                line = f.readline()

            # read dihedrals
            line = f.readline()
            while "$improper" not in line:
                if line.strip().startswith(
                        "#") or "$end" in line or not line.strip():
                    line = f.readline()
                    continue

                line = line.replace("–", "-")

                # store the constants for the order of the input and the inverse order
                consts = "\t".join(line.split()[1:])
                dihedrals[line.split()[0]] = consts
                dihedrals["-".join(line.split()[0].split("-")[::-1])] = consts

                line = f.readline()

            # read impropers
            line = f.readline()
            while line:
                if line.strip().startswith(
                        "#") or "$end" in line or not line.strip():
                    line = f.readline()
                    continue

                line = line.replace("–", "-")

                # store the constants for the order of the input and the inverse order
                consts = "\t".join(line.split()[1:])
                impropers[line.split()[0]] = consts
                impropers["-".join(line.split()[0].split("-")[::-1])] = consts

                line = f.readline()

        # check if there are unused labels
        for lbl in charges.keys():
            fnd = False
            for i in idToAtomicLabel:
                if lbl == idToAtomicLabel[i]:
                    fnd = True
                    break
            if not fnd:
                print(
                    "!!! WARNING: There are unused atoms in your parameter file (%s) !!!"
                    % lbl)

    # split the molecule
    fragments, fragConnection, dummyToAtom = split_mol_fragments_daylight(mol)

    # dummy atoms ids
    dummyAtoms = dummyToAtom.keys()

    # write molecule to .txt file (passed as ljname to DICE)
    with open(base + ".txt", "w") as f:
        f.write("*\n1\n")
        atomToPrint = []
        for frag in fragments:
            fragAtomIterator = openbabel.OBMolAtomIter(frag)
            for atom in fragAtomIterator:
                if atom.GetId() not in dummyAtoms:
                    atomToPrint.append(atom)
        # print number of atoms
        f.write(
            str(len(atomToPrint)) +
            " \t %s (generated with fragGen)\n" % os.path.basename(base))
        # dictionary associating Atomic number with rdf label
        rdfs = {}
        rdf_label = 1
        if ffparams:
            # sort atoms by index and print (this prints the atoms, e.g., in the same order of the xyz input)
            for atom in sorted(atomToPrint, key=lambda atom: atom.GetId()):
                if atom.GetAtomicNum() not in rdfs.keys():
                    rdfs[atom.GetAtomicNum()] = str(rdf_label)
                    rdf_label += 1
                f.write(rdfs[atom.GetAtomicNum()] + " " +
                        str(atom.GetAtomicNum()) + "  \t" + str(atom.GetX()) +
                        "      \t" + str(atom.GetY()) + "      \t" +
                        str(atom.GetZ()) + "      \t" +
                        charges[idToAtomicLabel[atom.GetId()]] + "\t" +
                        epsilons[idToAtomicLabel[atom.GetId()]] + "\t" +
                        sigmas[idToAtomicLabel[atom.GetId()]] + "\n")
            f.write("$end\n")
        else:
            # sort atoms by index and print (this prints the atoms, e.g., in the same order of the xyz input)
            for atom in sorted(atomToPrint, key=lambda atom: atom.GetId()):
                if atom.GetAtomicNum() not in rdfs.keys():
                    rdfs[atom.GetAtomicNum()] = str(rdf_label)
                    rdf_label += 1
                f.write(rdfs[atom.GetAtomicNum()] + " " +
                        str(atom.GetAtomicNum()) + "  \t" + str(atom.GetX()) +
                        "      \t" + str(atom.GetY()) + "      \t" +
                        str(atom.GetZ()) + "      \t" + "q" + "\t" +
                        "epsilon" + "\t" + "sigma\n")
            f.write("$end\n")

    # write info to dfr file
    with open(base + ".dfr", "w") as f:
        # fragments and fragments connections are printed to every outtype
        f.write("$atoms fragments\n")
        fragslst = []
        for frag in fragments:
            f.write(frag.GetTitle() + "\t[ ")
            fragAtomIterator = openbabel.OBMolAtomIter(frag)
            atomlst = [
                str(dummyToAtom[x.GetId()] +
                    1) if x.GetId() in dummyAtoms else str(x.GetId() + 1)
                for x in fragAtomIterator
            ]
            fragslst.append(atomlst)
            for atom in atomlst:
                f.write(atom + "\t")
            if outtype == "min" or outtype == "header":
                f.write("] R\n")
            else:
                f.write("] F\n")
        f.write("$end atoms fragments\n")

        f.write("\n$fragment connection\n")
        for frag1, frag2 in fragConnection:
            f.write(frag1 + "\t" + frag2 + "\n")
        f.write("$end fragment connection\n")

        # bonds are printed to every outtype that is not header, since we need a connection matrix
        if outtype != "header":
            f.write("\n$bond\n")
            bondIterator = openbabel.OBMolBondIter(mol)
            if ffparams:
                for bond in bondIterator:
                    try:
                        if eqgeom:
                            f.write(
                                str(bond.GetBeginAtom().GetId() + 1) + " " +
                                str(bond.GetEndAtom().GetId() + 1) + "  \t" +
                                bonds[labelToSLabel[idToAtomicLabel[
                                    bond.GetBeginAtom().GetId()]] + "-" +
                                      labelToSLabel[idToAtomicLabel[
                                          bond.GetEndAtom().GetId()]]].split()
                                [0] + "\t" + str("%.6f" % bond.GetLength()) +
                                "\n")
                        else:
                            f.write(
                                str(bond.GetBeginAtom().GetId() + 1) + " " +
                                str(bond.GetEndAtom().GetId() + 1) + "  \t" +
                                bonds[labelToSLabel[idToAtomicLabel[
                                    bond.GetBeginAtom().GetId()]] + "-" +
                                      labelToSLabel[idToAtomicLabel[
                                          bond.GetEndAtom().GetId()]]] + "\n")
                    except KeyError as e:
                        print(
                            "The parameters for atoms %d %d (%s) was not found in the bonds list\n"
                            % (bond.GetBeginAtom().GetId() + 1,
                               bond.GetEndAtom().GetId() + 1, e))
                        raise
            else:
                for bond in bondIterator:
                    f.write(
                        str(bond.GetBeginAtom().GetId() + 1) + " " +
                        str(bond.GetEndAtom().GetId() + 1) + "  \t0.0\t" +
                        str("%.6f" % bond.GetLength()) + "\n")
            f.write("$end bond\n")

        # angles are only printed for outtype flex
        if outtype == "flex":
            f.write("\n$angle\n")
            angleIterator = openbabel.OBMolAngleIter(mol)
            if ffparams:
                for angle in angleIterator:
                    try:
                        if eqgeom:
                            atom2 = mol.GetAtomById(angle[0])
                            atom1 = mol.GetAtomById(angle[1])
                            atom3 = mol.GetAtomById(angle[2])
                            aparams = angles[
                                labelToSLabel[idToAtomicLabel[angle[1]]] +
                                "-" +
                                labelToSLabel[idToAtomicLabel[angle[0]]] +
                                "-" + labelToSLabel[idToAtomicLabel[
                                    angle[2]]]].split()
                            f.write(
                                str(angle[1] + 1) + " " + str(angle[0] + 1) +
                                " " + str(angle[2] + 1) + "   \t" +
                                aparams[0] + "\t" + aparams[1] + "\t" +
                                str("%.6f" %
                                    mol.GetAngle(atom1, atom2, atom3)) + "\n")
                        else:
                            f.write(
                                str(angle[1] + 1) + " " + str(angle[0] + 1) +
                                " " + str(angle[2] + 1) + "   \t" + angles[
                                    labelToSLabel[idToAtomicLabel[angle[1]]] +
                                    "-" +
                                    labelToSLabel[idToAtomicLabel[angle[0]]] +
                                    "-" +
                                    labelToSLabel[idToAtomicLabel[angle[2]]]] +
                                "\n")
                    except KeyError as e:
                        print(
                            "The parameters for atoms %d %d %d (%s) was not found in the angles list\n"
                            % (angle[1] + 1, angle[0] + 1, angle[2] + 1, e))
                        raise
            else:
                for angle in angleIterator:
                    # carefully select the atoms to find the angle
                    atom2 = mol.GetAtomById(angle[0])
                    atom1 = mol.GetAtomById(angle[1])
                    atom3 = mol.GetAtomById(angle[2])
                    f.write(
                        str(angle[1] + 1) + " " + str(angle[0] + 1) + " " +
                        str(angle[2] + 1) + "   \tharmonic\tK\t" +
                        str("%.6f" % mol.GetAngle(atom1, atom2, atom3)) + "\n")
            f.write("$end angle\n")

        # all the dihedrals are printed to outtype flex, but only connection between fragments are printed if outtype is min
        if outtype == "flex":
            f.write("\n$dihedral\n")
            torsionIterator = openbabel.OBMolTorsionIter(mol)
            if ffparams:
                for torsional in torsionIterator:
                    # Need to sum 1: http://forums.openbabel.org/Rotable-bonds-tp957795p957798.html
                    torsidx = [str(x + 1) for x in torsional]
                    try:
                        f.write(torsidx[0] + " " + torsidx[1] + " " +
                                torsidx[2] + " " + torsidx[3] + "   \t" +
                                dihedrals["-".join([
                                    labelToSLabel[idToAtomicLabel[x]]
                                    for x in torsional
                                ])] + "\n")
                    except KeyError as e:
                        print(
                            "The parameters for atoms %s %s %s %s (%s) was not found in the dihedrals list\n"
                            % (torsidx[0], torsidx[1], torsidx[2], torsidx[3],
                               e))
                        raise
            else:
                for torsional in torsionIterator:
                    # Need to sum 1: http://forums.openbabel.org/Rotable-bonds-tp957795p957798.html
                    torsional = [str(x + 1) for x in torsional]
                    f.write(torsional[0] + " " + torsional[1] + " " +
                            torsional[2] + " " + torsional[3] +
                            "   \tTYPE\tV1\tV2\tV3\tf1\tf2\tf3\n")
            f.write("$end dihedral\n")

            # improper dihedral = carbon with only 3 atoms connected to it (SP2 hybridization)
            # angle found following this definition --> http://cbio.bmt.tue.nl/pumma/index.php/Theory/Potentials
            f.write("\n$improper dihedral\n")
            atomIterator = openbabel.OBMolAtomIter(mol)
            for atom in atomIterator:
                # print(atom.GetHyb(), atom.GetAtomicNum(), atom.GetValence())
                # if atom.GetAtomicNum() == 6 and atom.GetValence() == 3:
                if atom.GetHyb() == 2 and atom.GetValence() == 3:
                    bondIterator = atom.BeginBonds()
                    nbrAtom = atom.BeginNbrAtom(bondIterator)
                    connectedAtoms = []
                    connectedAtoms.append(nbrAtom)
                    for i in range(2):
                        nbrAtom = atom.NextNbrAtom(bondIterator)
                        connectedAtoms.append(nbrAtom)
                    if ffparams:
                        torsional = [
                            atom.GetId(), connectedAtoms[0].GetId(),
                            connectedAtoms[1].GetId(),
                            connectedAtoms[2].GetId()
                        ]
                        # create all the permutations to check if one is found
                        perms = list(itertools.permutations(torsional[1:]))
                        nfound = 0
                        for perm in perms:
                            try:
                                joined = "-".join([
                                    labelToSLabel[idToAtomicLabel[
                                        torsional[0]]]
                                ] + [
                                    labelToSLabel[idToAtomicLabel[x]]
                                    for x in perm
                                ])
                                f.write(
                                    str(torsional[0] + 1) + " " +
                                    str(torsional[1] + 1) + " " +
                                    str(torsional[2] + 1) + " " +
                                    str(torsional[3] + 1) + "    \t" +
                                    impropers[joined] + "\n")
                            except:
                                nfound += 1

                        if nfound == len(perms):
                            joined = "-".join(
                                [labelToSLabel[idToAtomicLabel[torsional[0]]]
                                 ] + [
                                     labelToSLabel[idToAtomicLabel[x]]
                                     for x in perms[0]
                                 ])
                            raise KeyError(
                                "The key %s (or its permutations) were not found in the improper dihedrals list\n"
                                % (joined))
                    else:
                        torsional = [
                            atom.GetId() + 1, connectedAtoms[0].GetId() + 1,
                            connectedAtoms[1].GetId() + 1,
                            connectedAtoms[2].GetId() + 1
                        ]
                        torsionAngle = mol.GetTorsion(torsional[0],
                                                      torsional[1],
                                                      torsional[2],
                                                      torsional[3])
                        f.write(
                            str(torsional[0]) + " " + str(torsional[1]) + " " +
                            str(torsional[2]) + " " + str(torsional[3]) +
                            "    \tV2\t" + str("%.6f" % torsionAngle) + "\n")
            f.write("$end improper dihedral\n")

        elif outtype == "min":
            torsionIterator = openbabel.OBMolTorsionIter(mol)
            # tjf = torsionals that join fragments
            tjf = []
            # find the tjfs by checking if all the atoms of a torsional belong to the same fragment
            for tors in torsionIterator:
                tors = [str(x + 1) for x in tors]
                istjf = True
                for atomlst in fragslst:
                    if (tors[0] in atomlst) and (tors[1] in atomlst) and (
                            tors[2] in atomlst) and (tors[3] in atomlst):
                        istjf = False
                        break
                if istjf:
                    tjf.append(tors)

            f.write("\n$dihedral\n")
            if ffparams:
                for torsidx in tjf:
                    torsional = [int(x) - 1 for x in torsidx]
                    try:
                        f.write(torsidx[0] + " " + torsidx[1] + " " +
                                torsidx[2] + " " + torsidx[3] + "   \t" +
                                dihedrals["-".join([
                                    labelToSLabel[idToAtomicLabel[x]]
                                    for x in torsional
                                ])] + "\n")
                    except KeyError as e:
                        print(
                            "The parameters for atoms %s %s %s %s (%s) was not found in the dihedrals list\n"
                            % (torsidx[0], torsidx[1], torsidx[2], torsidx[3],
                               e))
                        raise
            else:
                for torsional in tjf:
                    f.write(torsional[0] + " " + torsional[1] + " " +
                            torsional[2] + " " + torsional[3] +
                            "   \tTYPE\tV1\tV2\tV3\tf1\tf2\tf3\n")
            f.write("$end dihedral\n")

    # create directory to store the fragments
    if not os.path.exists(base + "_fragments"):
        os.makedirs(base + "_fragments")

    # write framents to the cml files
    for frag in fragments:
        obConversion.WriteFile(
            frag,
            os.path.join(
                base + "_fragments",
                os.path.basename(filename).split(".")[0] + "_fragment" +
                frag.GetTitle() + ".xyz"))
示例#16
0
 def atoms(self):
     return [Atom(atom) for atom in ob.OBResidueAtomIter(self.OBResidue)]
示例#17
0
def find_PiPi(pdb_file,
              lig_name,
              centroid_distance=5.0,
              dih_parallel=25,
              dih_tshape=80,
              verbose=1):
    """
    Find Pi-Pi interactions around the specified ligand residue from the pdb file.
    :param pdb_file: path of the target file in PDB format.
    :param lig_name: ligand residue name.
    :param centroid_distance: Max ring centroid distance
    :param dih_parallel: Max dihedral (parallel)
    :param dih_tshape: Min dihedral (T-shaped)
    :return: number of Pi-Pi interactions found
    """
    # Get ligand residue and print its name.
    ligAtomList = []
    ligAtomIdList = []
    mol = next(pybel.readfile('pdb', pdb_file))
    if verbose: print("A total of %s residues" % mol.OBMol.NumResidues())
    lig = None
    for res in ob.OBResidueIter(mol.OBMol):
        # print res.GetName()
        if res.GetName() == lig_name:
            lig = res
            if verbose: print("Ligand residue name is:", lig.GetName())
            break
    if not lig:
        if verbose:
            print("No ligand residue %s found, please confirm." % lig_name)
        return -1
    else:
        for atom in ob.OBResidueAtomIter(lig):
            # print atom.GetIdx()
            ligAtomList.append(atom)
            ligAtomIdList.append(atom.GetIdx())

    # Set ring_id
    i = 0
    for ring in mol.sssr:
        ring.ring_id = i
        i += 1
        # print ring.ring_id

    # Determine which rings are from ligand.
    ligRingList = []
    ligAroRingList = []
    ligRingIdList = []
    recRingList = []
    recAroRingList = []
    for ring in mol.sssr:
        for atom in ligAtomList:
            if ring.IsMember(atom):
                if ring not in ligRingList:
                    ligRingList.append(ring)
                    ligRingIdList.append(ring.ring_id)
                    if verbose:
                        print("ligand ring_ID: ", ring.ring_id, end=' ')
                    if ring.IsAromatic():
                        if verbose: print("aromatic")
                        ligAroRingList.append(ring)
                    else:
                        if verbose: print("saturated")
    for ring in mol.sssr:
        if ring.ring_id not in ligRingIdList:
            recRingList.append(ring)
            if ring.IsAromatic():
                recAroRingList.append(ring)
    if verbose: print("\nReceptor has ", len(recRingList), " rings,", end=' ')
    if verbose: print(" has ", len(recAroRingList), " aromatic rings.")

    # Find and show the rings
    ligRingCenter = ob.vector3()
    recRingCenter = ob.vector3()
    ligNorm1 = ob.vector3()
    ligNorm2 = ob.vector3()
    recNorm1 = ob.vector3()
    recNorm2 = ob.vector3()
    count = 0
    lig_ring_index = 0
    for ligRing in ligAroRingList:
        lig_ring_index += 1
        ligRing.findCenterAndNormal(ligRingCenter, ligNorm1, ligNorm2)
        rec_ring_index = 0
        for recRing in recAroRingList:
            rec_ring_index += 1
            recRing.findCenterAndNormal(recRingCenter, recNorm1, recNorm2)
            dist = ligRingCenter.distSq(recRingCenter)**0.5
            angle = vecAngle(ligNorm1, recNorm1)
            if (dist < centroid_distance and
                (angle < dih_parallel or angle > dih_tshape)):  # the criteria
                count += 1
                if verbose:
                    print(
                        "Pi-Pi ring pairs: %3s,%3s  Angle(deg.): %5.2f  Distance(A): %.2f"
                        % (recRing.ring_id, ligRing.ring_id, angle, dist))
    if verbose: print("Total Pi-Pi interactions:", count)
    return count
示例#18
0
obmol = mol.OBMol

obres = ""
numofresidue = 0
for res in ob.OBResidueIter(obmol):
    if res.GetName() == ligandname:
        numofresidue += 1
        obres = res

if numofresidue == 1:
    npcoords = numpy.array(coords)
    print "Found ", obres.GetName(), " ", obres.GetIdx(), \
            " chain: ", obres.GetChain()

    near_residues = {}
    for obatom in ob.OBResidueAtomIter(obres):
        atomcoord = numpy.array([obatom.x(), obatom.y(), obatom.z()])
        dist = numpy.sqrt(numpy.sum((npcoords - atomcoord)**2, axis=1))
        print "    %10.3f %10.3f %10.3f %s"%(obatom.x(), \
                obatom.y(), obatom.z(),  obres.GetAtomID(obatom))

        for index in numpy.flatnonzero(dist < args.mindist):
            res = obatoms[index].GetResidue()
            uniqname = res.GetName()+ "_" + str(res.GetIdx()) + "_" + \
                    res.GetChain()
            near_residues[uniqname] = res

    print "Now copying original molecule and removing atoms"
    extract_pdb = ob.OBMol(obmol)
    atomtoremove = []
    for res in ob.OBResidueIter(extract_pdb):
示例#19
0
def parse_mol_info(fname, fcharges, axis, buffa, buffo, pbcbonds, printdih,
                   ignorebonds, ignoreimproper):
    iaxis = {"x": 0, "y": 1, "z": 2}
    if axis in iaxis:
        repaxis = iaxis[axis]
    else:
        print("Error: invalid axis")
        sys.exit(0)

    if fcharges:
        chargesLabel = {}
        with open(fcharges, "r") as f:
            for line in f:
                chargesLabel[line.split()[0]] = float(line.split()[1])

    # set openbabel file format
    base, ext = os.path.splitext(fname)
    obConversion = openbabel.OBConversion()
    obConversion.SetInAndOutFormats(ext[1:], "xyz")
    # trick to disable ring perception and make the ReadFile waaaay faster
    # Source: https://sourceforge.net/p/openbabel/mailman/openbabel-discuss/thread/56e1812d-396a-db7c-096d-d378a077853f%40ipcms.unistra.fr/#msg36225392
    obConversion.AddOption("b", openbabel.OBConversion.INOPTIONS)

    # read molecule to OBMol object
    mol = openbabel.OBMol()
    obConversion.ReadFile(mol, fname)
    mol.ConnectTheDots()  # necessary because of the 'b' INOPTION

    # split the molecules
    molecules = mol.Separate()

    # detect the molecules types
    mTypes = {}
    mapmTypes = {}
    atomIdToMol = {}
    nty = 0
    for i, submol in enumerate(molecules, start=1):
        atomiter = openbabel.OBMolAtomIter(submol)
        atlist = []
        for at in atomiter:
            atlist.append(at.GetAtomicNum())
            atomIdToMol[at.GetId()] = i
        foundType = None

        for ty in mTypes:
            # check if there's already a molecule of this type
            if atlist == mTypes[ty]:
                foundType = ty

        # if not, create a new type
        if not foundType:
            nty += 1
            foundType = nty
            mTypes[nty] = atlist

        mapmTypes[i] = foundType

    # get atomic labels from pdb
    idToAtomicLabel = {}
    if ext[1:] == "pdb":
        for res in openbabel.OBResidueIter(mol):
            for atom in openbabel.OBResidueAtomIter(res):
                if (atomIdToMol[atom.GetId()] > 1) and (len(mTypes) > 1):
                    idToAtomicLabel[
                        atom.GetId()] = res.GetAtomID(atom).strip() + str(
                            mapmTypes[atomIdToMol[atom.GetId()]])
                else:
                    idToAtomicLabel[atom.GetId()] = res.GetAtomID(atom).strip()
    else:
        if not ob3:
            etab = openbabel.OBElementTable()
        for atom in openbabel.OBMolAtomIter(mol):
            if (atomIdToMol[atom.GetId()] > 1) and (len(mTypes) > 1):
                if ob3:
                    idToAtomicLabel[atom.GetId()] = openbabel.GetSymbol(
                        atom.GetAtomicNum()) + str(
                            mapmTypes[atomIdToMol[atom.GetId()]])
                else:
                    idToAtomicLabel[atom.GetId()] = etab.GetSymbol(
                        atom.GetAtomicNum()) + str(
                            mapmTypes[atomIdToMol[atom.GetId()]])
            else:
                if ob3:
                    idToAtomicLabel[atom.GetId()] = openbabel.GetSymbol(
                        atom.GetAtomicNum())
                else:
                    idToAtomicLabel[atom.GetId()] = etab.GetSymbol(
                        atom.GetAtomicNum())

    # print(idToAtomicLabel)

    # identify atom types and get masses
    outMasses = "Masses\n\n"

    massTypes = {}
    mapTypes = {}
    nmassTypes = 0
    atomIterator = openbabel.OBMolAtomIter(mol)
    for atom in atomIterator:
        i = atom.GetId()
        if idToAtomicLabel[i] not in massTypes:
            nmassTypes += 1
            mapTypes[nmassTypes] = idToAtomicLabel[i]
            massTypes[idToAtomicLabel[i]] = nmassTypes
            outMasses += "\t%d\t%.3f\t# %s\n" % (
                nmassTypes, atom.GetAtomicMass(), idToAtomicLabel[i])

    # create atoms list
    outAtoms = "Atoms # full\n\n"

    xmin = float("inf")
    xmax = float("-inf")
    ymin = float("inf")
    ymax = float("-inf")
    zmin = float("inf")
    zmax = float("-inf")
    natoms = 0
    acoords = []
    for mnum, imol in enumerate(molecules, start=1):
        atomIterator = openbabel.OBMolAtomIter(imol)
        for atom in sorted(atomIterator, key=lambda x: x.GetId()):
            natoms += 1
            i = atom.GetId()
            apos = (atom.GetX(), atom.GetY(), atom.GetZ())
            acoords.append(Atom(atom.GetAtomicNum(), apos))

            # look for the maximum and minimum x for the box (improve later with numpy and all coordinates)
            if apos[0] > xmax:
                xmax = apos[0]
            if apos[0] < xmin:
                xmin = apos[0]
            if apos[1] > ymax:
                ymax = apos[1]
            if apos[1] < ymin:
                ymin = apos[1]
            if apos[2] > zmax:
                zmax = apos[2]
            if apos[2] < zmin:
                zmin = apos[2]

            if fcharges:
                outAtoms += "\t%d\t%d\t%d\t%.6f\t%.4f\t%.4f\t%.4f\t# %s\n" % (
                    i + 1, mnum, massTypes[idToAtomicLabel[i]],
                    chargesLabel[idToAtomicLabel[i]], atom.GetX(), atom.GetY(),
                    atom.GetZ(), idToAtomicLabel[i])
            else:
                outAtoms += "\t%d\t%d\t%d\tX.XXXXXX\t%.4f\t%.4f\t%.4f\t# %s\n" % (
                    i + 1, mnum, massTypes[idToAtomicLabel[i]], atom.GetX(),
                    atom.GetY(), atom.GetZ(), idToAtomicLabel[i])

    # define box shape and size
    try:
        fromBounds = False
        rcell = mol.GetData(12)
        cell = openbabel.toUnitCell(rcell)
        v1 = [
            cell.GetCellVectors()[0].GetX(),
            cell.GetCellVectors()[0].GetY(),
            cell.GetCellVectors()[0].GetZ()
        ]
        v2 = [
            cell.GetCellVectors()[1].GetX(),
            cell.GetCellVectors()[1].GetY(),
            cell.GetCellVectors()[1].GetZ()
        ]
        v3 = [
            cell.GetCellVectors()[2].GetX(),
            cell.GetCellVectors()[2].GetY(),
            cell.GetCellVectors()[2].GetZ()
        ]
        boxinfo = [v1, v2, v3]
        orthogonal = True
        for i, array in enumerate(boxinfo):
            for j in range(3):
                if i == j:
                    continue
                if not math.isclose(0., array[j], abs_tol=1e-6):
                    orthogonal = False
    except:
        fromBounds = True
        v1 = [xmax - xmin, 0., 0.]
        v2 = [0., ymax - ymin, 0.]
        v3 = [0., 0., zmax - zmin]
        orthogonal = True

    # add buffer
    if orthogonal:
        buf = []
        boxinfo = [v1, v2, v3]
        for i, val in enumerate(boxinfo[repaxis]):
            if i == repaxis:
                buf.append(val + buffa)
            else:
                buf.append(val)
        boxinfo[repaxis] = buf
        for i in range(3):
            if i == repaxis:
                continue
            buf = []
            for j, val in enumerate(boxinfo[i]):
                if j == i:
                    buf.append(val + buffo)
                else:
                    buf.append(val)
            boxinfo[i] = buf

    # print(boxinfo)

    # Duplicate to get the bonds in the PBC. Taken from (method _crd2bond):
    # https://github.com/tongzhugroup/mddatasetbuilder/blob/66eb0f15e972be0f5534dcda27af253cd8891ff2/mddatasetbuilder/detect.py#L213
    if pbcbonds:
        acoords = Atoms(acoords, cell=boxinfo, pbc=True)
        repatoms = acoords.repeat(
            2
        )[natoms:]  # repeat the unit cell in each direction (len(repatoms) = 7*natoms)
        tree = cKDTree(acoords.get_positions())
        d = tree.query(repatoms.get_positions(), k=1)[0]
        nearest = d < 8.
        ghost_atoms = repatoms[nearest]
        realnumber = np.where(nearest)[0] % natoms
        acoords += ghost_atoms

        write("replicated.xyz",
              acoords)  # write the structure with the replicated atoms

        # write new mol with new bonds
        nmol = openbabel.OBMol()
        nmol.BeginModify()
        for idx, (num, position) in enumerate(
                zip(acoords.get_atomic_numbers(), acoords.positions)):
            a = nmol.NewAtom(idx)
            a.SetAtomicNum(int(num))
            a.SetVector(*position)
        nmol.ConnectTheDots()
        # nmol.PerceiveBondOrders() # super slow becauses it looks for rings
        nmol.EndModify()
    else:
        acoords = Atoms(acoords, cell=boxinfo, pbc=False)
        nmol = openbabel.OBMol()
        nmol.BeginModify()
        for idx, (num, position) in enumerate(
                zip(acoords.get_atomic_numbers(), acoords.positions)):
            a = nmol.NewAtom(idx)
            a.SetAtomicNum(int(num))
            a.SetVector(*position)
        nmol.ConnectTheDots()
        # nmol.PerceiveBondOrders() # super slow becauses it looks for rings
        nmol.EndModify()

    # identify bond types and create bond list
    outBonds = "Bonds # harmonic\n\n"

    bondTypes = {}
    mapbTypes = {}
    nbondTypes = 0
    nbonds = 0
    bondsToDelete = []
    bondIterators = []
    if ignorebonds:
        sepmols = nmol.Separate()
        for smol in sepmols[1:]:
            bondIterators.append(openbabel.OBMolBondIter(smol))
    else:
        bondIterators.append(openbabel.OBMolBondIter(nmol))

    lastidx = 1
    for iterator in bondIterators:
        for i, bond in enumerate(iterator, lastidx):
            b1 = bond.GetBeginAtom().GetId()
            b2 = bond.GetEndAtom().GetId()

            # check if its a bond of the replica only
            if (b1 >= natoms) and (b2 >= natoms):
                bondsToDelete.append(bond)
                continue
            # remap to a real atom if needed
            if b1 >= natoms:
                b1 = realnumber[b1 - natoms]
            if b2 >= natoms:
                b2 = realnumber[b2 - natoms]

            # identify bond type
            btype1 = "%s - %s" % (idToAtomicLabel[b1], idToAtomicLabel[b2])
            btype2 = "%s - %s" % (idToAtomicLabel[b2], idToAtomicLabel[b1])

            if btype1 in bondTypes:
                bondid = bondTypes[btype1]
                bstring = btype1
            elif btype2 in bondTypes:
                bondid = bondTypes[btype2]
                bstring = btype2
            else:
                nbondTypes += 1
                mapbTypes[nbondTypes] = btype1
                bondid = nbondTypes
                bondTypes[btype1] = nbondTypes
                bstring = btype1

            nbonds += 1
            outBonds += "\t%d\t%d\t%d\t%d\t# %s\n" % (nbonds, bondid, b1 + 1,
                                                      b2 + 1, bstring)

        lastidx = i

    # delete the bonds of atoms from other replicas
    for bond in bondsToDelete:
        nmol.DeleteBond(bond)

    # identify angle types and create angle list
    angleTypes = {}
    mapaTypes = {}
    nangleTypes = 0
    nangles = 0
    angleIterators = []

    if ignorebonds:
        sepmols = nmol.Separate()
        for smol in sepmols[1:]:
            smol.FindAngles()
            angleIterators.append(openbabel.OBMolAngleIter(smol))
        prevnumatoms = sepmols[0].NumAtoms()
    else:
        nmol.FindAngles()
        angleIterators.append(openbabel.OBMolAngleIter(nmol))

    outAngles = "Angles # harmonic\n\n"

    lastidx = 1
    for j, iterator in enumerate(angleIterators, 1):
        for i, angle in enumerate(iterator, lastidx):
            if ignorebonds:
                a1 = angle[1] + prevnumatoms
                a2 = angle[0] + prevnumatoms
                a3 = angle[2] + prevnumatoms
            else:
                a1 = angle[1]
                a2 = angle[0]
                a3 = angle[2]

            # remap to a real atom if needed
            if a1 >= natoms:
                a1 = realnumber[a1 - natoms]
            if a2 >= natoms:
                a2 = realnumber[a2 - natoms]
            if a3 >= natoms:
                a3 = realnumber[a3 - natoms]

            atype1 = "%s - %s - %s" % (
                idToAtomicLabel[a1], idToAtomicLabel[a2], idToAtomicLabel[a3])
            atype2 = "%s - %s - %s" % (
                idToAtomicLabel[a3], idToAtomicLabel[a2], idToAtomicLabel[a1])

            if atype1 in angleTypes:
                angleid = angleTypes[atype1]
                astring = atype1
            elif atype2 in angleTypes:
                angleid = angleTypes[atype2]
                astring = atype2
            else:
                nangleTypes += 1
                mapaTypes[nangleTypes] = atype1
                angleid = nangleTypes
                angleTypes[atype1] = nangleTypes
                astring = atype1

            nangles += 1
            outAngles += "\t%d\t%d\t%d\t%d\t%d\t# %s\n" % (
                nangles, angleid, a1 + 1, a2 + 1, a3 + 1, astring)

        lastidx = i
        if ignorebonds:
            prevnumatoms += sepmols[j].NumAtoms()

    # identify dihedral types and create dihedral list
    if printdih:
        dihedralTypes = {}
        mapdTypes = {}
        ndihedralTypes = 0
        ndihedrals = 0
        dihedralIterators = []

        if ignorebonds:
            sepmols = nmol.Separate()
            for smol in sepmols[1:]:
                smol.FindTorsions()
                dihedralIterators.append(openbabel.OBMolTorsionIter(smol))
        else:
            nmol.FindTorsions()
            dihedralIterators.append(openbabel.OBMolTorsionIter(nmol))

        outDihedrals = "Dihedrals # charmmfsw\n\n"

        lastidx = 1
        for iterator in dihedralIterators:
            for i, dihedral in enumerate(iterator, lastidx):
                a1 = dihedral[0]
                a2 = dihedral[1]
                a3 = dihedral[2]
                a4 = dihedral[3]

                # remap to a real atom if needed
                if a1 >= natoms:
                    a1 = realnumber[a1 - natoms]
                if a2 >= natoms:
                    a2 = realnumber[a2 - natoms]
                if a3 >= natoms:
                    a3 = realnumber[a3 - natoms]
                if a4 >= natoms:
                    a4 = realnumber[a4 - natoms]

                dtype1 = "%s - %s - %s - %s" % (
                    idToAtomicLabel[a1], idToAtomicLabel[a2],
                    idToAtomicLabel[a3], idToAtomicLabel[a4])
                dtype2 = "%s - %s - %s - %s" % (
                    idToAtomicLabel[a4], idToAtomicLabel[a3],
                    idToAtomicLabel[a2], idToAtomicLabel[a1])

                if dtype1 in dihedralTypes:
                    dihedralid = dihedralTypes[dtype1]
                    dstring = dtype1
                elif dtype2 in dihedralTypes:
                    dihedralid = dihedralTypes[dtype2]
                    dstring = dtype2
                else:
                    ndihedralTypes += 1
                    mapdTypes[ndihedralTypes] = dtype1
                    dihedralid = ndihedralTypes
                    dihedralTypes[dtype1] = ndihedralTypes
                    dstring = dtype1

                ndihedrals += 1
                outDihedrals += "\t%d\t%d\t%d\t%d\t%d\t%d\t# %s\n" % (
                    ndihedrals, dihedralid, a1 + 1, a2 + 1, a3 + 1, a4 + 1,
                    dstring)

            lastidx = i

        if not ignoreimproper:
            # look for the improper dihedrals
            improperDihedralTypes = {}
            mapiDTypes = {}
            niDihedralTypes = 0
            niDihedrals = 0
            mollist = []

            if ignorebonds:
                sepmols = nmol.Separate()
                for smol in sepmols[1:]:
                    smol.PerceiveBondOrders()
                    mollist.append(smol)
            else:
                nmol.PerceiveBondOrders()
                mollist.append(nmol)

            outImpropers = "Impropers # harmonic\n\n"

            for imol in mollist:
                atomIterator = openbabel.OBMolAtomIter(imol)
                for atom in atomIterator:
                    try:
                        # print(atom.GetHyb(), atom.GetAtomicNum(), atom.GetValence())
                        expDegree = atom.GetValence()
                    except:
                        # print(atom.GetHyb(), atom.GetAtomicNum(), atom.GetExplicitDegree())
                        expDegree = atom.GetExplicitDegree()

                    # returns impropers for atoms with connected to other 3 atoms and SP2 hybridization
                    if atom.GetHyb() == 2 and expDegree == 3:
                        connectedAtoms = []
                        for atom2, depth in openbabel.OBMolAtomBFSIter(
                                imol,
                                atom.GetId() + 1):
                            if depth == 2:
                                connectedAtoms.append(atom2)

                        torsional = [
                            atom.GetId() + 1, connectedAtoms[0].GetId() + 1,
                            connectedAtoms[1].GetId() + 1,
                            connectedAtoms[2].GetId() + 1
                        ]

                        a1 = torsional[0] - 1
                        a2 = torsional[1] - 1
                        a3 = torsional[2] - 1
                        a4 = torsional[3] - 1

                        # remap to a real atom if needed
                        if a1 >= natoms:
                            a1 = realnumber[a1 - natoms]
                        if a2 >= natoms:
                            a2 = realnumber[a2 - natoms]
                        if a3 >= natoms:
                            a3 = realnumber[a3 - natoms]
                        if a4 >= natoms:
                            a4 = realnumber[a4 - natoms]

                        dtype1 = "%s - %s - %s - %s" % (
                            idToAtomicLabel[a1], idToAtomicLabel[a2],
                            idToAtomicLabel[a3], idToAtomicLabel[a4])
                        dtype2 = "%s - %s - %s - %s" % (
                            idToAtomicLabel[a4], idToAtomicLabel[a3],
                            idToAtomicLabel[a2], idToAtomicLabel[a1])

                        if dtype1 in improperDihedralTypes:
                            idihedralid = improperDihedralTypes[dtype1]
                            dstring = dtype1
                        elif dtype2 in improperDihedralTypes:
                            idihedralid = improperDihedralTypes[dtype2]
                            dstring = dtype2
                        else:
                            niDihedralTypes += 1
                            mapiDTypes[niDihedralTypes] = dtype1
                            idihedralid = niDihedralTypes
                            improperDihedralTypes[dtype1] = niDihedralTypes
                            dstring = dtype1

                        niDihedrals += 1
                        outImpropers += "\t%d\t%d\t%d\t%d\t%d\t%d\t# %s\n" % (
                            niDihedrals, idihedralid, a1 + 1, a2 + 1, a3 + 1,
                            a4 + 1, dstring)

    # print header
    if printdih and (ndihedrals > 0):
        if ignoreimproper or (niDihedrals == 0):
            header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\t%d dihedrals\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\t%d dihedral types\n\n" % (
                fname, natoms, nbonds, nangles, ndihedrals, nmassTypes,
                nbondTypes, nangleTypes, ndihedralTypes)
        else:
            header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\t%d dihedrals\n\t%d impropers\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\t%d dihedral types\n\t%d improper types\n\n" % (
                fname, natoms, nbonds, nangles, ndihedrals, niDihedrals,
                nmassTypes, nbondTypes, nangleTypes, ndihedralTypes,
                niDihedralTypes)
    else:
        header = "LAMMPS topology created from %s using pdb2lmp.py - By Henrique Musseli Cezar, 2020\n\n\t%d atoms\n\t%d bonds\n\t%d angles\n\n\t%d atom types\n\t%d bond types\n\t%d angle types\n\n" % (
            fname, natoms, nbonds, nangles, nmassTypes, nbondTypes,
            nangleTypes)

    # add box info
    if fromBounds:
        boxsize = [(xmin, xmax), (ymin, ymax), (zmin, zmax)]
        boxsize[repaxis] = (boxsize[repaxis][0] - buffa / 2.,
                            boxsize[repaxis][1] + buffa / 2.)
        for i in range(3):
            if i == repaxis:
                continue
            boxsize[i] = (boxsize[i][0] - buffo / 2.,
                          boxsize[i][1] + buffo / 2.)
        header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n" % (
            boxsize[0][0], boxsize[0][1], boxsize[1][0], boxsize[1][1],
            boxsize[2][0], boxsize[2][1])
    else:
        if orthogonal:
            header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n" % (
                0., boxinfo[0][0], 0., boxinfo[1][1], 0., boxinfo[2][2])
        else:
            header += "\t%.8f\t%.8f\t xlo xhi\n\t%.8f\t%.8f\t ylo yhi\n\t%.8f\t%.8f\t zlo zhi\n\t%.8f\t%.8f\t%.8f\t xy xz yz\n" % (
                0., boxinfo[0][0], 0., boxinfo[1][1], 0., boxinfo[2][2],
                boxinfo[1][0], boxinfo[2][0], boxinfo[2][1])

    # print Coeffs
    outCoeffs = "Pair Coeffs\n\n"

    for i in range(1, nmassTypes + 1):
        outCoeffs += "\t%d\teps\tsig\t# %s\n" % (i, mapTypes[i])

    outCoeffs += "\nBond Coeffs\n\n"

    for i in range(1, nbondTypes + 1):
        outCoeffs += "\t%d\tK\tr_0\t# %s\n" % (i, mapbTypes[i])

    outCoeffs += "\nAngle Coeffs\n\n"

    for i in range(1, nangleTypes + 1):
        outCoeffs += "\t%d\tK\ttetha_0 (deg)\t# %s\n" % (i, mapaTypes[i])

    if printdih and (ndihedrals > 0):
        outCoeffs += "\nDihedral Coeffs\n\n"

        for i in range(1, ndihedralTypes + 1):
            outCoeffs += "\t%d\tK\tn\tphi_0 (deg)\tw\t# %s\n" % (i,
                                                                 mapdTypes[i])

        if not ignoreimproper and (niDihedralTypes > 0):
            outCoeffs += "\nImproper Coeffs\n\n"

            for i in range(1, niDihedralTypes + 1):
                outCoeffs += "\t%d\tK\txi_0 (deg)\t# %s\n" % (i, mapiDTypes[i])

    if printdih and (ndihedrals > 0):
        if ignoreimproper or (niDihedralTypes == 0):
            return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles + "\n" + outDihedrals
        else:
            return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles + "\n" + outDihedrals + "\n" + outImpropers
    else:
        return header + "\n" + outMasses + "\n" + outCoeffs + "\n" + outAtoms + "\n" + outBonds + "\n" + outAngles
示例#20
0
def getListChanges(pdbmodel):
    # get modification to apply at pdb to apply amber FF and heme parameters from J Comput Chem. 2012 Jan 15;33(2):119-33
    prefnm, extnm = os.path.splitext(pdbmodel)
    if extnm[1:] != 'pdb':
        mutref = pb.readfile(extnm[1:], pdbmodel).next()
        pdbmodel = "%s.pdb" % prefnm
        mutref.write('pdb', pdbmodel, overwrite=True)

    outpdb = "%s_tau.pdb" % prefnm
    reduceCmd = os.path.join(AMBERHOME, 'bin', 'reduce')
    cmd = [reduceCmd, '-HIS', '-FLIPs', '-quiet', pdbmodel]

    red = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)
    optimutpdb, err = red.communicate()

    optimut = pb.readstring('pdb', optimutpdb)

    listchanges = []
    listTer = []
    sCoords = {}
    nhemseq = None
    checkCyp = True
    firstRes = True
    isCyp = False
    cypCoord = True
    ncypseq = None
    for res in ob.OBResidueIter(optimut.OBMol):
        resname = res.GetName()
        resNum = res.GetNum()
        if firstRes:
            nres = resNum
            firstRes = False
        else:
            nres += 1

        #FIX HIS TAUTOMERS
        if resname == 'HIS':
            atmname = []
            for atm in ob.OBResidueAtomIter(res):
                atmname.append(res.GetAtomID(atm).strip())
            if ('HE2' in atmname) and ('HD1' in atmname):
                newResName = "HIP"
            elif 'HE2' in atmname:
                newResName = "HIE"
            elif 'HD1' in atmname:
                newResName = "HID"
            else:
                print "Error in determining the protonation state of HIS %d" % resNum
            listchanges.append((resNum, 'HIS', newResName))

        #GET Fe coordinates for coordinating CYS identification
        elif resname == 'HEM':
            isCyp = True
            nhem = resNum
            nhemseq = nres
            #nhem=nres
            atmname = []
            for atm in ob.OBResidueAtomIter(res):
                if atm.GetType(
                ) == 'FE' or atm.GetType() == 'Fe' or res.GetAtomID(atm).strip(
                ) == 'FE' or res.GetAtomID(atm).strip() == 'Fe':
                    Fe_coord = [atm.GetX(), atm.GetY(), atm.GetZ()]

        #Collect every cysteine S coordinates
        elif resname == 'CYS':
            atmname = []
            for atm in ob.OBResidueAtomIter(res):
                atmName = res.GetAtomID(atm).strip()
                if atmName == 'SG':
                    sCoords[resNum] = {}
                    sCoords[resNum]['coor'] = [
                        atm.GetX(), atm.GetY(),
                        atm.GetZ()
                    ]  #resNum
                    sCoords[resNum]['nseq'] = nres

        if resname == 'CYP':
            ncyp = resNum
            ncypseq = nres
            checkCyp = False

        if resname == 'HIH':
            ncypseq = nres
            checkCyp = False
            cypCoord = False

        for atm in ob.OBResidueAtomIter(res):
            atmName = res.GetAtomID(atm).strip()
            if atmName == "OXT":
                listTer.append(resNum)

    if isCyp:
        #Find the coordinating CYS and add to listchanges
        if cypCoord:
            if checkCyp:
                CYP = {'nres': 0, 'dist': 100}
                for res in sCoords:
                    distS = dist(sCoords[res]['coor'], Fe_coord)
                    print res, distS
                    if distS < CYP['dist']:
                        CYP['dist'] = distS
                        CYP['nres'] = res
                        CYP['nseq'] = sCoords[res]['nseq']

                ncypseq = CYP['nseq']
                listchanges.append((CYP['nres'], 'CYS', 'CYP'))

    optimut.removeh()
    optimut.write('pdb', outpdb, overwrite=True)

    return (os.path.join(os.getcwd(),
                         outpdb), listchanges, nhemseq, ncypseq, cypCoord)