def AddBond(): """Template written as an example for OTHER people to write their own""" from Pmv.picker import AtomPicker p = AtomPicker(self, numberOfObjects=2, gui=0) p.go(modal=1) atoms = p.getObjects() assert atoms[0].top == atoms[1].top from MolKit.molecule import Bond Bond(atoms[0], atoms[1]) self.lines(atoms[0].top) self.GUI.VIEWER.Redraw()
def buildBondscif(self, ): mmCIF_dict = self.mmCIF_dict nbonds = len(mmCIF_dict["_geom_bond_atom_site_label_1"]) labels1 = mmCIF_dict["_geom_bond_atom_site_label_1"] labels2 = mmCIF_dict["_geom_bond_atom_site_label_2"] if nbonds == 0: return ignoreSym = False if "_geom_bond_site_symmetry_1" in mmCIF_dict: ignoreSym = True for i in range(nbonds): # 1- Get the atoms corresponding of the indices of the pair atm1 = self.mol.allAtoms.get(labels1[i])[0] if len(atm1.bonds) > atm1.maxBonds: continue atm2 = self.mol.allAtoms.get(labels2[i])[0] # 2- Need to make sure that the two atoms are not already # bonded. if atm1.isBonded(atm2): continue if len(atm2.bonds) > atm2.maxBonds: continue if ignoreSym and (mmCIF_dict["_geom_bond_site_symmetry_1"][i] != "." or \ mmCIF_dict["_geom_bond_site_symmetry_2"][i] != "."): continue # 3- Need to make sure that the two atoms of this pairs are not # alternate location. if not atm1.altname is None and not atm2.altname is None: # atm1 and atm2 are alternate locations if atm1.altname == atm2.altname: # Can only be bound if they have the same altname bond = Bond(atm1, atm2, origin='BuiltByCif', check=0) # 4- Create a bonds between the two atoms: else: #bond = Bond(atm1, atm2, origin='Bhtree', check=0) bond = Bond(atm1, atm2, origin='BuiltByCif', check=0)
def parse_MOL2_Bonds(self, bondlines): """ Function to build the bonds object using the bond record of the mol2 file.""" bondlines = map(string.split, bondlines) for bd in bondlines: at1 = self.mol.atmNum[int(bd[1])] at2 = self.mol.atmNum[int(bd[2])] if at1.isBonded(at2): continue bond = Bond(at1, at2, check=0) bond.type = bd[3] try: bond.bondOrder = int(bd[3]) except: if bd[3] == 'ar': bond.bondOrder = 'aromatic' elif bd[3] == 'am': bond.bondOrder = 'amide' else: bond.bondOrder = bd[3] self.mol.bondsflag = 1 self.mol.hasBonds = 1
def parse_MOL2_Bonds(self, bondlines): """ Function to build the bonds object using the bond record of the mol2 file.""" bondlines = map(string.split, bondlines) for bd in bondlines: at1 = self.mol.atmNum[int(bd[1])] at2 = self.mol.atmNum[int(bd[2])] if at1.isBonded(at2): continue bond = Bond(at1, at2, check=0) bond.type = bd[3] try: bond.bondOrder = int(bd[3]) except: if bd[3]=='ar': bond.bondOrder = 'aromatic' elif bd[3]=='am': bond.bondOrder = 'amide' else: bond.bondOrder = bd[3] self.mol.bondsflag = 1 self.mol.hasBonds = 1
def addHydrogens(self, mol): #check for bonds if len(mol.allAtoms.bonds[0]) == 0: mol.buildBondsByDistance() bonds = mol.allAtoms.bonds[0] #could have preset babel_types #so check if allAtoms are already typed try: t = mol.allAtoms.babel_type except: #if all are not pretyped, type them babel = AtomHybridization() babel.assignHybridization(mol.allAtoms) if self.method == 'withBondOrder': mol.rings = RingFinder() mol.rings.findRings2(mol.allAtoms, mol.allAtoms.bonds[0]) mol.rings.bondRings = {} for ind in xrange(len(mol.rings.rings)): r = mol.rings.rings[ind] for b in r['bonds']: if not mol.rings.bondRings.has_key(b): mol.rings.bondRings[b] = [ ind, ] else: mol.rings.bondRings[b].append(ind) bo = BondOrder() bo.assignBondOrder(mol.allAtoms, bonds, mol.rings) mol.allAtoms._bndtyped = 1 # do aromatic here arom = Aromatic(mol.rings) arom.find_aromatic_atoms(mol.allAtoms) hat = AddHydrogens().addHydrogens(mol.allAtoms, method=self.method) bondedAtomDict = {} # key is heavy atom for a in hat: if bondedAtomDict.has_key(a[1]): bondedAtomDict[a[1]].append(a) else: bondedAtomDict[a[1]] = [a] # now create Atom object for hydrogens # and add the to the residues's atom list molNewHs = AtomSet([]) # list of created H atoms for this molecule heavyAtoms = AtomSet([]) # list of atoms that need new radii for heavyAtom, HatmsDscr in bondedAtomDict.items(): #don't add hydrogens to carbons: polar Only!!! if self.htype != 'all' and heavyAtom.element == 'C': continue res = heavyAtom.parent # find where to insert H atom childIndex = res.children.index(heavyAtom) + 1 # loop over H atoms description to be added # start at the end to number correctly l = len(HatmsDscr) for i in range(l - 1, -1, -1): a = HatmsDscr[i] # build H atom's name if len(heavyAtom.name) == 1: name = 'H' + heavyAtom.name else: name = 'H' + heavyAtom.name[1:] # if more than 1 H atom, add H atom index # for instance HD11, HD12, Hd13 (index is 1,2,3) if l > 1: name = name + str(i + 1) # create the H atom object atom = Atom(name, res, top=heavyAtom.top, chemicalElement='H', childIndex=childIndex, assignUniqIndex=0) # set atoms attributes atom._coords = [a[0]] if hasattr(a[1], 'segID'): atom.segID = a[1].segID atom.hetatm = 0 atom.alternate = [] #atom.element = 'H' atom.occupancy = 1.0 atom.conformation = 0 atom.temperatureFactor = 0.0 atom.babel_atomic_number = a[2] atom.babel_type = a[3] atom.babel_organic = 1 atom.radius = 1.2 # create the Bond object bonding Hatom to heavyAtom bond = Bond(a[1], atom, bondOrder=1) # add the created atom the the list molNewHs.append(atom) # in case this new hydrogen atom ever ends up in pmv # HAVE TO CREATE THESE ENTRIES # create the color entries for all geoemtries # available for the heavyAtom for key, value in heavyAtom.colors.items(): atom.colors[key] = (0.0, 1.0, 1.0) atom.opacities[key] = 1.0 mol.allAtoms = mol.chains.residues.atoms if self.renumber: mol.allAtoms.number = range(1, len(mol.allAtoms) + 1) return len(molNewHs)
def getMolecule(self, molInd): molecules = [] if molInd == len(self.molIndex) - 1: lastLine = -1 else: lastLine = self.molIndex[molInd + 1] # lines fotr that molecule lines = self.allLines[self.molIndex[molInd]:lastLine] lineIndex = 0 atomsSeen = {} # dict of atom types and number of atoms seen # parser header molName = lines[lineIndex].strip() lineIndex += 3 # create molecule mol = Protein(name=molName) mol.info = lines[lineIndex + 1] mol.comment = lines[lineIndex + 1] #self.mol.parser = self chain = Chain(id='1', parent=mol, top=mol) res = Residue(type='UNK', number='1', parent=chain, top=mol) mol.levels = [Protein, Chain, Residue, Atom] # parse count line line = lines[lineIndex] assert line[ 33: 39] == " V2000", "Format error: only V2000 is suported, got %s" % line[ 33:39] nba = int(line[0:3]) # number of atoms nbb = int(line[3:6]) # number of bonds nbal = int(line[6:9]) # number of atom lists ccc = int(line[12:15]) # chiral flag: 0=not chiral, 1=chiral sss = int(line[15:18]) # number of stext entries lineIndex += 1 # parse atoms for anum in range(nba): line = lines[lineIndex] element = line[31:34].strip() if element in atomsSeen: atomsSeen[element] += 1 else: atomsSeen[element] = 1 atom = Atom(name='%s_%s' % (element, atomsSeen[element]), parent=res, chemicalElement=element, top=mol) atom._coords = [[ float(line[0:10]), float(line[10:20]), float(line[20:30]) ]] atom._charges['sdf'] = int(line[35:38]) atom.chargeSet = 'sdf' mol.allAtoms.append(atom) atom.massDiff = int(line[34:36]) atom.stereo = int(line[38:41]) atom.hcount = line[41:44] atom.valence = int(line[47:50]) atom.hetatm = 1 atom.occupancy = 0.0 atom.temperatureFactor = 0.0 lineIndex += 1 # parse bonds for bnum in range(nba): line = lines[lineIndex] at1 = mol.allAtoms[int(line[0:3]) - 1] at2 = mol.allAtoms[int(line[3:6]) - 1] if at1.isBonded(at2): continue bond = Bond(at1, at2, check=0) bond.bondOrder = int(line[6:9]) #1 = Single, 2 = Double, #3 = Triple, 4 = Aromatic, #5 = Single or Double, #6 = Single or Aromatic, #7 = Double or Aromatic, 8 = Any bond.stereo = int(line[9:12]) #Single bonds: 0 = not stereo, #1 = Up, 4 = Either, #6 = Down, Double bonds: 0 = Use x-, y-, z-coords #from atom block to determine cis or trans, #3 = Cis or trans (either) double bond bond.topo = int(line[15:18]) # 0 = Either, 1 = Ring, 2 = Chain try: bond.ReactionCenter = int(line[18:21]) except ValueError: bond.ReactionCenter = 0 #0 = unmarked, 1 = a center, -1 = not a center, #Additional: 2 = no change, #4 = bond made/broken, #8 = bond order changes #12 = 4+8 (both made/broken and changes); #5 = (4 + 1), 9 = (8 + 1), and 13 = (12 + 1) # "M END" and properties are not parsed at this point self.mol = mol mname = mol.name strRpr = mname + ':::' mol.allAtoms.setStringRepr(strRpr) strRpr = mname + ':' mol.chains.setStringRepr(strRpr) for c in mol.chains: cname = c.id strRpr = mname + ':' + cname + ':' c.residues.setStringRepr(strRpr) for r in c.residues: rname = r.name strRpr = mname + ':' + cname + ':' + rname + ':' r.atoms.setStringRepr(strRpr) molList = mol.setClass() molList.append(mol) mol.parser = self for n in molList.name: name = n + ',' name = name[:-1] molList.setStringRepr(name) strRpr = name + ':::' molList.allAtoms.setStringRepr(strRpr) return molList
def add_oxt(self, catom): if catom.element != 'C': return mol = catom.top ##check for bonds #if len(mol.allAtoms.bonds[0])==0: # mol.buildBondsByDistance() #check whether residue already has OXT res = catom.parent if 'OXT' in res.atoms.name: print('not adding OXT to ', res.full_name(), '\n', 'it already has an OXT atom') return #check whether catom has a hydrogen to delete hatoms = catom.parent.atoms.get(lambda x: x.name == 'HC') if len(hatoms): hatom = hatoms[0] #check for hbonds if hasattr(hatom, 'hbonds'): #remove hbonds for b in hatom.hbonds: atList = [b.donAt, b.accAt] if b.hAt is not None: atList.append(b.hAt) for at in atList: #hbonds might already be gone if not hasattr(at, 'hbonds'): continue okhbnds = [] for hb in at.hbonds: if hb != b: okhbnds.append(hb) if len(okhbnds): at.hbonds = okhbnds else: delattr(at, 'hbonds') #remove covalent bonds for b in hatom.bonds: at2 = b.atom1 if at2 == hatom: at2 = b.atom2 at2.bonds.remove(b) hatom.parent.remove(hatom, cleanup=1) #have to type atoms before call to add_sp2_hydrogen: if not hasattr(catom, 'babel_type'): print('catom has no babel_type: calling typeAtoms') #self.warningMsg(msg) #typeAtoms does whole molecule babel = AtomHybridization() babel.assignHybridization(mol.allAtoms) #NB: bond_length 1.28 measured from OXT-C bond in 1crn tup1 = self.addh.add_sp2_hydrogen(catom, 1.28) res = catom.parent # find where to insert H atom childIndex = res.children.index(catom) + 1 name = 'OXT' # create the OXT atom object atom = Atom(name, res, top=mol, childIndex=childIndex, assignUniqIndex=0) # set atoms attributes atom._coords = [tup1[0][0]] if hasattr(catom, 'segID'): atom.segID = catom.segID atom.hetatm = 0 atom.alternate = [] atom.element = 'O' atom.occupancy = 1.0 atom.conformation = 0 atom.temperatureFactor = 0.0 atom.babel_atomic_number = 8 atom.babel_type = 'O-' atom.babel_organic = 1 # create the Bond object bonding Hatom to heavyAtom bond = Bond(catom, atom, bondOrder=2) # create the color entries for all geometries # available for the other oxygen atom attached to 'C' oatom = res.atoms.get(lambda x: x.name == 'O')[0] if oatom is not None: for key, value in list(oatom.colors.items()): atom.colors[key] = value #atom.opacities[key] = oatom.opacities[key] # update the allAtoms set in the molecule mol.allAtoms = mol.chains.residues.atoms # update numbers of allAtoms fst = mol.allAtoms[0].number mol.allAtoms.number = list(range(fst, len(mol.allAtoms) + fst)) # update _uniqIndex of this residues atoms res.assignUniqIndex() #return AtomSet([atom]) return atom
print "done" ## db = filter(lambda x:x.bondOrder==2, bonds) ## for b in db: ## print b addh = AddHydrogens() #pdb.run("hat = addh.addHydrogens(allAtoms)") hat = addh.addHydrogens(allAtoms) from MolKit.molecule import Atom, Bond for a in hat: atom = Atom('H', a[1].parent, top=a[1].top) atom._coords = [a[0]] atom.segID = a[1].segID atom.hetatm = 0 atom.alternate = [] atom.element = 'H' atom.number = -1 atom.occupancy = 1.0 atom.conformation = 0 atom.temperatureFactor = 0.0 atom.babel_atomic_number = a[2] atom.babel_type = a[3] atom.babel_organic = 1 bond = Bond(a[1], atom) from Pmv.moleculeViewer import MoleculeViewer mv = MoleculeViewer() mv.addMolecule(mol) mv.lines(mol)
def doit(self, atom1, atom2, **kw): origin = kw['origin'] bondOrder = kw['bondOrder'] bond = Bond(atom1, atom2, origin=origin, bondOrder=bondOrder) event = EditAtomsEvent('coords', AtomSet([atom1, atom2])) self.vf.dispatchEvent(event)