def addAtom(mol, name, ADtype, value, coords, ctr): #if debug: print "in addAtom", value, res = mol.chains.residues[0] chemicalElement = ADtype[0] #??? childIndex = ctr - 1 top = mol newAt = Atom(name=name, parent=res, top=mol, chemicalElement=chemicalElement, childIndex=childIndex) newAt.temperatureFactor = value newAt.occupancy = value newAt.number = ctr newAt.conformation = 0 newAt._coords = [list(coords)] newAt.hetatm = 0 #if debug: print "added ", name, ctr, ':', newAt.full_name(),'-', newAt.parent.children.index(newAt) #update allAtoms attribute of this molecule mol.allAtoms = mol.chains.residues.atoms
def build2LevelsTree(self, atomlines): """ Function to build a two level tree. """ print 'try to build a 2 level tree' self.mol = Molecule() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename( os.path.splitext(self.filename)[0]) self.mol.children = AtomSet([]) self.mol.childrenName = 'atoms' self.mol.childrenSetClass = AtomSet self.mol.elementType = Atom self.mol.levels = [Molecule, Atom] ##1/18:self.mol.levels = [Protein, Atom] for atmline in atomlines: atom = Atom(atmline[1], self.mol, chemicalElement=string.split(atmline[5], '.')[0], top=self.mol) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [[ float(atmline[2]), float(atmline[3]), float(atmline[4]) ]] if len(atmline) >= 9: atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = 'mol2' # atom.conformation = 0 atom.hetatm = 0 #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) self.mol.atoms = self.mol.children
def build2LevelsTree (self, atomlines): """ Function to build a two level tree. """ print 'try to build a 2 level tree' self.mol= Molecule() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename(os.path.splitext (self.filename)[0]) self.mol.children = AtomSet([]) self.mol.childrenName = 'atoms' self.mol.childrenSetClass = AtomSet self.mol.elementType = Atom self.mol.levels = [Molecule, Atom] ##1/18:self.mol.levels = [Protein, Atom] for atmline in atomlines: atom = Atom(atmline[1], self.mol, chemicalElement = string.split(atmline[5], '.')[0], top = self.mol) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [ [float(atmline[2]), float(atmline[3]), float(atmline[4]) ] ] if len(atmline)>=9: atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = 'mol2' # atom.conformation = 0 atom.hetatm = 0 #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) self.mol.atoms = self.mol.children
def makeMoleculeFromAtoms(molname, atomSet): """ create a new molecule from a list of atoms mol <- makeMoleculeFromAtoms(molname, atomSet) """ from MolKit.molecule import Atom, AtomSet from MolKit.protein import Protein, Chain, Residue # create the top object mol = Protein(name=molname) # find out all residues residues = atomSet.parent.uniq() # find out all chains chains = residues.parent.uniq() # create all chains chainsd = {} for c in chains: newchain = Chain(c.id, mol, top=mol) chainsd[c] = newchain # create all residues resd = {} for res in residues: newres = Residue(res.name[:3], res.name[3:], res.icode, chainsd[res.parent], top=mol) resd[res] = newres newres.hasCA = 0 newres.hasO = 0 # create all the atoms newats = [] for num, at in enumerate(atomSet): name = at.name res = resd[at.parent] name1 = name if hasattr(at, "altname") and at.altname != None: name = at.name.split("@")[0] if name == 'CA': res.hasCA = 1 if name == 'O' or name == 'OXT' or (len(name) > 3 and name[:3] == 'OCT'): res.hasO = 2 newat = Atom(name, res, at.element, top=mol) if name != name1: newat.name = name1 newat.altname = at.altname newats.append(newat) # set constructotr attributes newat._coords = [] for coords in at._coords: newat._coords.append(coords[:]) newat.conformation = at.conformation newat.chemElem = at.chemElem newat.atomicNumber = at.atomicNumber newat.bondOrderRadius = at.bondOrderRadius newat.covalentRadius = at.covalentRadius newat.vdwRadius = at.vdwRadius newat.maxBonds = at.maxBonds newat.organic = at.organic newat.colors = at.colors.copy() newat.opacities = at.opacities.copy() newat._charges = at._charges.copy() newat.chargeSet = at.chargeSet # set attributes from PDB parser try: # pdbqs do not have this newat.segID = at.segID except AttributeError: pass newat.hetatm = at.hetatm try: # pdbqs do not have this newat.normalname = at.normalname except AttributeError: pass newat.number = num #at.number newat.occupancy = at.occupancy newat.temperatureFactor = at.temperatureFactor newat.altname = at.altname # attribute created by PQR parser if hasattr(at, 'pqrRadius'): newat.pqrRadius = at.pqrRadius # attribute created by F2D parser if hasattr(at, 'hbstatus'): newat.hbstatus = at.hbstatus # attribute created by PDBQ parser if hasattr(at, 'autodock_element'): newat.autodock_element = at.autodock_element # attribute created by PDBQT parser #if hasattr(at, ''): # newat. = at. # attribute created by PDBQS parser if hasattr(at, 'AtVol'): newat.AtVol = at.AtVol newat.AtSolPar = at.AtSolPar mol.allAtoms = AtomSet(newats) return mol
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 parse(self, objClass=Protein): """Parses mmCIF dictionary (self.mmCIF_dict) into MolKit object""" if self.allLines is None and self.filename: self.readFile() if self.allLines is None or len(self.allLines) == 0: return self.mmCIF2Dict() type_symbol = None B_iso_or_equiv = None mmCIF_dict = self.mmCIF_dict fileName, fileExtension = os.path.splitext(self.filename) molName = os.path.basename(fileName) if mmCIF_dict.has_key('_entry.id'): molName = mmCIF_dict['_entry.id'] if mmCIF_dict.has_key('_atom_site.id'): #The description of the data names can be found in the following link #http://mmcif.pdb.org/dictionaries/mmcif_pdbx.dic/Items ids = mmCIF_dict['_atom_site.id'] #1 number group_PDB = mmCIF_dict['_atom_site.group_PDB'] #2 atom/hetatm atom_id = mmCIF_dict['_atom_site.label_atom_id'] #3 name comp_id = mmCIF_dict['_atom_site.label_comp_id'] #4 residue type label_asym_id = mmCIF_dict['_atom_site.label_asym_id'] #5 chain #Note: chain ID from mmCIF file might be different from PDB file seq_id = mmCIF_dict['_atom_site.label_seq_id'] #6 residue number x_coords = mmCIF_dict['_atom_site.Cartn_x'] #7 xcoord y_coords = mmCIF_dict['_atom_site.Cartn_y'] #8 ycoord z_coords = mmCIF_dict['_atom_site.Cartn_z'] #9 zcoord occupancy = mmCIF_dict['_atom_site.occupancy'] #10 B_iso_or_equiv = mmCIF_dict['_atom_site.B_iso_or_equiv'] #11 type_symbol = mmCIF_dict['_atom_site.type_symbol'] elif mmCIF_dict.has_key('_atom_site_label'): #ftp://ftp.iucr.org/pub/cif_core.dic atom_id = mmCIF_dict['_atom_site_label'] len_atoms = len(atom_id) ids = range(len_atoms) group_PDB = len_atoms * ['HETATM'] comp_id = len_atoms * ["CIF"] label_asym_id = len_atoms * ['1'] seq_id = len_atoms * [1] from mglutil.math.crystal import Crystal a = mmCIF_dict['_cell.length_a'] = float( mmCIF_dict['_cell_length_a'].split('(')[0]) b = mmCIF_dict['_cell.length_b'] = float( mmCIF_dict['_cell_length_b'].split('(')[0]) c = mmCIF_dict['_cell.length_c'] = float( mmCIF_dict['_cell_length_c'].split('(')[0]) alpha = mmCIF_dict['_cell.angle_alpha'] = float( mmCIF_dict['_cell_angle_alpha'].split('(')[0]) beta = mmCIF_dict['_cell.angle_beta'] = float( mmCIF_dict['_cell_angle_beta'].split('(')[0]) gamma = mmCIF_dict['_cell.angle_gamma'] = float( mmCIF_dict['_cell_angle_gamma'].split('(')[0]) cryst = Crystal((a, b, c), (alpha, beta, gamma)) x = [] for item in mmCIF_dict['_atom_site_fract_x']: x.append(float(item.split('(')[0])) y = [] for item in mmCIF_dict['_atom_site_fract_y']: y.append(float(item.split('(')[0])) z = [] for item in mmCIF_dict['_atom_site_fract_z']: z.append(float(item.split('(')[0])) x_coords = [] y_coords = [] z_coords = [] B_iso_or_equiv = [] for i in ids: trans = cryst.toCartesian([x[i], y[i], z[i]]) x_coords.append(trans[0]) y_coords.append(trans[1]) z_coords.append(trans[2]) if mmCIF_dict.has_key('_atom_site_U_iso_or_equiv'): B_iso_or_equiv.append( mmCIF_dict['_atom_site_U_iso_or_equiv'][i].split( '(')[0]) if mmCIF_dict.has_key('_atom_site_type_symbol'): type_symbol = mmCIF_dict['_atom_site_type_symbol'] if mmCIF_dict.has_key('_atom_site_occupancy'): occupancy = mmCIF_dict['_atom_site_occupancy'] if mmCIF_dict.has_key('_chemical_name_common'): molName = mmCIF_dict['_chemical_name_common'] elif mmCIF_dict.has_key('_chemical_name_mineral'): molName = mmCIF_dict['_chemical_name_mineral'] if mmCIF_dict.has_key('_symmetry_space_group_name_H-M'): mmCIF_dict['_symmetry.space_group_name_H-M'] = mmCIF_dict[ '_symmetry_space_group_name_H-M'] else: print 'No _atom_site.id or _atom_site_label record is available in %s' % self.filename return None mol = Protein() self.mol = mol self.mol.allAtoms = AtomSet([]) molList = mol.setClass() molList.append(mol) current_chain_id = None current_residue_number = None current_chain = None current_residue = None number_of_atoms = len(ids) self.configureProgressBar(init=1, mode='increment', authtext='parse atoms', max=number_of_atoms) for index in range(number_of_atoms): #make a new atom for the current index chain_id = label_asym_id[index] if chain_id != current_chain_id: #make a new chain #molecule should adopt the current chain if there is one current_chain = Chain(id=chain_id) # FIXME: current_chain should not have allAtoms attribute delattr(current_chain, "allAtoms") current_chain_id = chain_id if current_chain is not None: #REMEMBER TO ADOPT THE LAST ONE!!! mol.adopt(current_chain, setChildrenTop=1) residue_number = seq_id[index] if residue_number != current_residue_number or chain_id != label_asym_id[ index - 1]: #make a new chain: #current_chain should adopt the current residue if there is one #create new residue residue_type = comp_id[index] current_residue = Residue(type=residue_type, number=residue_number) current_residue_number = residue_number if current_residue is not None: #REMEMBER TO ADOPT THE LAST ONE!!! current_chain.adopt(current_residue, setChildrenTop=1) name = atom_id[index] if type_symbol: element = type_symbol[index] else: element = None atom = Atom(name, current_residue, element, top=mol) atom._coords = [[ float(x_coords[index]), float(y_coords[index]), float(z_coords[index]) ]] atom._charges = {} atom.segID = mol.name atom.normalname = name atom.number = int(ids[index]) mol.atmNum[atom.number] = atom atom.occupancy = float(occupancy[index]) if B_iso_or_equiv: atom.temperatureFactor = float(B_iso_or_equiv[index]) atom.altname = None atom.hetatm = 0 if group_PDB[index] == 'HETATM': atom.hetatm = 1 self.updateProgressBar() self.parse_MMCIF_CELL() try: self.parse_MMCIF_HYDBND() except: print >> sys.stderr, "Parsing Hydrogen Bond Record Failed in", self.filename mol.name = molName mol.allAtoms = mol.chains.residues.atoms mol.parser = self mol.levels = [Protein, Chain, Residue, Atom] name = '' for n in molList.name: name = n + ',' name = name[:-1] molList.setStringRepr(name) strRpr = name + ':::' molList.allAtoms.setStringRepr(strRpr) for m in molList: mname = m.name strRpr = mname + ':::' m.allAtoms.setStringRepr(strRpr) strRpr = mname + ':' m.chains.setStringRepr(strRpr) for c in m.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) self.buildBonds() return molList
def parse(self, objClass=Protein): if self.allLines is None and self.filename: self.readFile() if self.allLines is None or len(self.allLines) == 0: return mol = Protein() self.mol = mol molList = mol.setClass() molList.append(mol) current_residue_number = None current_chain = None current_residue = None number_of_atoms = int(self.allLines[1][:5]) self.configureProgressBar(init=1, mode='increment', authtext='parse atoms', max=number_of_atoms) current_chain = Chain(id='GRO', ) # FIX this: The existence of allAtoms attribute (and the fact that it is an empty set rather than all atoms in # the chain) causes getNodesByMolecule() to return wrong values if hasattr(current_chain, "allAtoms"): del current_chain.allAtoms # current_chain = Chain( id='GRO',parent = mol) mol.adopt(current_chain, setChildrenTop=1) for index in range(2, number_of_atoms + 2): residue_number = int(self.allLines[index][:5]) if residue_number != current_residue_number: # # current_chain should adopt the current residue if there is one # create new residue res_type = self.allLines[index][5:10] residue_type = res_type.split(' ')[0] current_residue = Residue(type=residue_type, number=residue_number) current_residue_number = residue_number if current_residue is not None: # REMEMBER TO ADOPT THE LAST ONE!!! current_chain.adopt(current_residue, setChildrenTop=1) n = self.allLines[index][10:15] name = n.split(' ')[-1] element = name if element in list(babel_elements.keys()): element = element else: if residue_type == "System" or residue_type == "SOL": # if element[1] == 'W': # element = 'H' # group is treated as one particle # else: element = element[0] elif element[:2] == 'Me': element = 'C' else: element = element[0] # if len(element)>1: # if type(element[1]) == types.StringType: # # if element[1] == element[1].lower(): # element =element # else: # element = element[0] # # else: # element = element[0] atom = Atom(name, current_residue, element, top=mol) c = self.allLines[index][15:20] cx = self.allLines[index][20:28] cy = self.allLines[index][28:36] cz = self.allLines[index][36:44] x = float(cx) * 10 y = float(cy) * 10 z = float(cz) * 10 atom._coords = [[x, y, z]] atom._charges = [] atom.segID = mol.name atom.normalname = name atom.number = int(self.allLines[index][15:20]) atom.elementType = name[0] mol.atmNum[atom.number] = atom atom.altname = None atom.hetatm = 0 mol.name = os.path.split(os.path.splitext(self.filename)[0])[-1] mol.allAtoms = mol.chains.residues.atoms mol.parser = self mol.levels = [Protein, Chain, Residue, Atom] name = '' for n in molList.name: name = n + ',' name = name[:-1] molList.setStringRepr(name) strRpr = name + ':::' molList.allAtoms.setStringRepr(strRpr) for m in molList: mname = m.name strRpr = mname + ':::' m.allAtoms.setStringRepr(strRpr) strRpr = mname + ':' m.chains.setStringRepr(strRpr) for c in m.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) 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 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 = range(fst, len(mol.allAtoms)+fst) # update _uniqIndex of this residues atoms res.assignUniqIndex() #return AtomSet([atom]) return atom
def makeMoleculeFromAtoms(molname, atomSet): """ create a new molecule from a list of atoms mol <- makeMoleculeFromAtoms(molname, atomSet) """ from MolKit.molecule import Atom, AtomSet from MolKit.protein import Protein, Chain, Residue # create the top object mol = Protein(name=molname) # find out all residues residues = atomSet.parent.uniq() # find out all chains chains = residues.parent.uniq() # create all chains chainsd = {} for c in chains: newchain = Chain(c.id, mol, top=mol) chainsd[c] = newchain # create all residues resd = {} for res in residues: newres = Residue(res.name[:3], res.name[3:], res.icode, chainsd[res.parent], top=mol) resd[res] = newres newres.hasCA = 0 newres.hasO = 0 # create all the atoms newats = [] for num, at in enumerate(atomSet): name = at.name res = resd[at.parent] if name == 'CA': res.hasCA = 1 if name == 'O' or name == 'OXT' or (len(name)>3 and name[:3]=='OCT'): res.hasO = 2 newat = Atom(name, res, at.element, top=mol) newats.append(newat) # set constructotr attributes newat._coords = [] for coords in at._coords: newat._coords.append(coords[:]) newat.conformation = at.conformation newat.chemElem = at.chemElem newat.atomicNumber = at.atomicNumber newat.bondOrderRadius = at.bondOrderRadius newat.covalentRadius = at.covalentRadius newat.vdwRadius = at.vdwRadius newat.maxBonds = at.maxBonds newat.organic = at.organic newat.colors = at.colors.copy() newat.opacities = at.opacities.copy() newat._charges = at._charges.copy() newat.chargeSet = at.chargeSet # set attributes from PDB parser newat.segID = at.segID newat.hetatm = at.hetatm newat.normalname = at.normalname newat.number = num #at.number newat.occupancy = at.occupancy newat.temperatureFactor = at.temperatureFactor newat.altname = at.altname # attribute created by PQR parser if hasattr(at, 'pqrRadius'): newat.pqrRadius = at.pqrRadius # attribute created by F2D parser if hasattr(at, 'hbstatus'): newat.hbstatus = at.hbstatus # attribute created by PDBQ parser if hasattr(at, 'autodock_element'): newat.autodock_element = at.autodock_element # attribute created by PDBQT parser #if hasattr(at, ''): # newat. = at. # attribute created by PDBQS parser if hasattr(at, 'AtVol'): newat.AtVol = at.AtVol newat.AtSolPar = at.AtSolPar mol.allAtoms = AtomSet(newats) return mol
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 parse( self, objClass=Protein ): if self.allLines is None and self.filename: self.readFile() if self.allLines is None or len(self.allLines)==0: return mol = Protein() self.mol = mol molList = mol.setClass() molList.append( mol ) current_residue_number = None current_chain = None current_residue = None number_of_atoms = int(self.allLines[1][:5]) self.configureProgressBar( init=1, mode='increment', authtext='parse atoms', max=number_of_atoms ) current_chain = Chain( id='GRO',) #FIX this: The existence of allAtoms attribute (and the fact that it is an empty set rather than all atoms in the chain) causes getNodesByMolecule() to return wrong values if hasattr(current_chain, "allAtoms"): del(current_chain.allAtoms) #current_chain = Chain( id='GRO',parent = mol) mol.adopt( current_chain, setChildrenTop=1 ) for index in range( 2,number_of_atoms+2 ): residue_number = int(self.allLines[index][:5]) if residue_number!=current_residue_number:# #current_chain should adopt the current residue if there is one #create new residue res_type = self.allLines[index][5:10] residue_type = res_type.split(' ')[0] current_residue = Residue( type=residue_type, number=residue_number ) current_residue_number = residue_number if current_residue is not None: #REMEMBER TO ADOPT THE LAST ONE!!! current_chain.adopt( current_residue, setChildrenTop=1 ) n = self.allLines[index][10:15] name = n.split(' ')[-1] element = name if element in babel_elements.keys(): element = element else: if residue_type == "System" or residue_type == "SOL": #if element[1] == 'W': # element = 'H' # group is treated as one particle #else: element = element[0] elif element[:2] == 'Me': element = 'C' else: element = element[0] #if len(element)>1: # if type(element[1]) == types.StringType: # # if element[1] == element[1].lower(): # element =element # else: # element = element[0] # # else: # element = element[0] atom = Atom( name, current_residue, element, top=mol ) c = self.allLines[index][15:20] cx = self.allLines[index][20:28] cy = self.allLines[index][28:36] cz = self.allLines[index][36:44] x = float(cx)*10 y = float(cy)*10 z = float(cz)*10 atom._coords = [[x, y, z]] atom._charges = [] atom.segID = mol.name atom.normalname = name atom.number = int(self.allLines[index][15:20]) atom.elementType = name[0] mol.atmNum[atom.number] = atom atom.altname = None atom.hetatm = 0 mol.name = os.path.split(os.path.splitext(self.filename)[0])[-1] mol.allAtoms = mol.chains.residues.atoms mol.parser = self mol.levels = [Protein, Chain, Residue, Atom] name = '' for n in molList.name: name = n + ',' name = name[:-1] molList.setStringRepr( name ) strRpr = name + ':::' molList.allAtoms.setStringRepr( strRpr ) for m in molList: mname = m.name strRpr = mname + ':::' m.allAtoms.setStringRepr( strRpr ) strRpr = mname + ':' m.chains.setStringRepr( strRpr ) for c in m.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 ) 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
def nextFrame(self, id): #Player.nextFrame(self, id) id = int(id) if id == self.currentFrameIndex: return if self.hasCounter and self.gui: self.form.ent2.delete(0, 'end') self.form.ent2.insert(0, str(id)) if self.hasSlider: self.form.ifd.entryByName['slider']['widget'].set(id) self.currentFrameIndex = int(id) removeAtoms = AtomSet([]) addAtoms = AtomSet([]) id = int(id) flood = self.floods[id] centers = [] materials = [] radii = [] prev_coords = self.mol.allAtoms.coords lenAtoms = len(prev_coords) #self.residue.atoms = AtomSet([]) index = 0 #h = self.hp.heap() #print h for fl in flood: x = (fl[1] - self.xcent) * self.spacing + self.centerx y = (fl[2] - self.ycent) * self.spacing + self.centery z = (fl[3] - self.zcent) * self.spacing + self.centerz if fl[4] == 7: atomchr = 'P' # note, this will color the NA atom pink (the PDB color for Phosphorus) radius = AAradii[13][0] if fl[4] == 6: atomchr = 'S' radius = AAradii[13][0] if fl[4] == 5: atomchr = 'A' radius = AAradii[10][0] if fl[4] == 4: atomchr = 'O' radius = AAradii[1][0] if fl[4] == 3: atomchr = 'N' radius = AAradii[4][0] if fl[4] == 2: atomchr = 'C' radius = AAradii[10][0] if fl[4] == 1: atomchr = 'H' radius = AAradii[15][0] if not [x, y, z] in prev_coords: a = Atom(atomchr, self.residue, atomchr, top=self.mol) a._coords = [[x, y, z]] a._charges = {} a.hetatm = 1 a.radius = radius #a.number = lenAtoms + 1 addAtoms.append(a) lenAtoms += 1 for key in self.colorKeys: a.colors[key] = AtomElements[atomchr] a.opacities[key] = 1.0 else: centers.append([x, y, z]) # a = Atom(atomchr, self.residue, atomchr, top=self.mol) # a._coords = [[x,y,z]] # a._charges = {} # a.hetatm = 1 # a.number = index # index += 1 #aterials.append(AtomElements[atomchr]) #enters.append([x,y,z]) #adii.append(radius) #self.mol.allAtoms = self.residue.atoms #self.mol.geomContainer.geoms['lines'].protected = False #for com in self.autoLigandCommand.vf.cmdsWithOnAddObj: # com.onAddObjectToViewer(self.mol) #self.autoLigandCommand.vf.displayCPK(self.mol, scaleFactor=0.1) halo_centers = [] for coord in prev_coords: if not coord in centers: index = prev_coords.index(coord) removeAtoms.append(self.mol.allAtoms[index]) self.residue.assignUniqIndex( ) #this is needed to avoid Traceback later on self.mol.allAtoms.stringRepr = None #stringRepr can be very large aousing memory errors event = AddAtomsEvent(objects=addAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) event = DeleteAtomsEvent(objects=removeAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) for atom in removeAtoms: self.residue.atoms.remove(atom) if id == self.maxFrame: self.autoLigandCommand.halo.Set(visible=0) else: self.autoLigandCommand.halo.Set(centers=addAtoms.coords, materials=((1, 1, 0, 0.5), ), radii=0.4)
def __init__(self, command, file): master = command.vf.GUI.ROOT self.autoLigandCommand = command.vf.AutoLigandCommand self.autoLigandCommand.spheres.Set(visible=1) self.autoLigandCommand.halo.Set(visible=1) pkl_file = open(file, 'rb') self.floods = [] try: data = pickle.load(pkl_file) except Exception as inst: print("Error loading ", __file__, "\n", inst) self.xcent = data[0] self.ycent = data[1] self.zcent = data[2] self.centerx = data[3] self.centery = data[4] self.centerz = data[5] self.spacing = data[6] self.centers = [] data = pickle.load(pkl_file) self.floods.append(data[1]) try: while data: data = pickle.load(pkl_file) flood = copy.copy(self.floods[-1]) for item in data[0]: flood.remove(item) for item in data[1]: flood.append(item) self.floods.append(flood) except EOFError: pass pkl_file.close() fileName = os.path.splitext(os.path.split(file)[-1])[0] self.mol = Protein(fileName) self.mol.allAtoms = AtomSet([]) chain = Chain() self.residue = Residue(type="UNK") chain.adopt(self.residue, setChildrenTop=1) self.mol.adopt(chain, setChildrenTop=1) self.mol.parser = None self.filename = file fl = self.floods[0][0] x = (fl[1] - self.xcent) * self.spacing + self.centerx y = (fl[2] - self.ycent) * self.spacing + self.centery z = (fl[3] - self.zcent) * self.spacing + self.centerz if fl[4] == 7: atomchr = 'P' # note, this will color the NA atom pink (the PDB color for Phosphorus) radius = AAradii[13][0] if fl[4] == 6: atomchr = 'S' radius = AAradii[13][0] if fl[4] == 5: atomchr = 'A' radius = AAradii[10][0] if fl[4] == 4: atomchr = 'O' radius = AAradii[1][0] if fl[4] == 3: atomchr = 'N' radius = AAradii[4][0] if fl[4] == 2: atomchr = 'C' radius = AAradii[10][0] if fl[4] == 1: atomchr = 'H' radius = AAradii[15][0] a = Atom(atomchr, self.residue, atomchr, top=self.mol) a._coords = [[x, y, z]] a._charges = {} a.hetatm = 1 a.number = 0 a.radius = radius self.mol.allAtoms = self.residue.atoms self.mol = self.autoLigandCommand.vf.addMolecule(self.mol, False) self.mol.levels = [Protein, Chain, Residue, Atom] self.autoLigandCommand.vf.displayCPK(self.mol, scaleFactor=0.4) self.autoLigandCommand.vf.colorByAtomType(self.mol, ['cpk'], log=0) self.autoLigandCommand.vf.displayLines(self.mol, negate=True, displayBO=False, lineWidth=2, log=0, only=False) self.colorKeys = list(a.colors.keys()) maxLen = len(self.floods) - 1 Player.__init__(self, master=master, endFrame=maxLen, maxFrame=maxLen, titleStr="AutoLigand Flood Player", hasSlider=True) try: # withdrew SetAnim button self.form.ifd.entryByName['setanimB']['widget'].grid_forget() self.form.autoSize() except: pass self.nextFrame(0) self.form.root.protocol('WM_DELETE_WINDOW', self.hide_cb)
def build4LevelsTree(self, subst_chain, atomlines): """ Function to build a 4 level hierarchy Protein-Chain-Residue-Atom. """ self.mol= Protein() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename(os.path.splitext (self.filename)[0]) self.mol.curChain = Chain() self.mol.curRes = Residue() self.mol.levels = [Protein, Chain, Residue, Atom] i = 1 for atmline in atomlines: if len(atmline)>= 10: status = string.split(atmline[9], '|') else: status = None if len(atmline) == 8: tmp = [atmline[5][:5], atmline[5][5:]] atmline[5] = tmp[0] atmline.insert(6, tmp[1]) if status and status[0]=='WATER': chainID = 'W' atmline[7] = 'HOH'+str(i) subst_chain[atmline[7]] = chainID i = i+1 if subst_chain == {}: chainID = 'default' elif not subst_chain.has_key(atmline[7]): if subst_chain.has_key('****'): try: chainID = subst_chain[atmline[7]] except: chainID = 'default' else: chainID = 'default' elif type(subst_chain[atmline[7]]) is types.StringType: # that is to say that only chains has this substructure name. chainID = subst_chain[atmline[7]] elif type(subst_chain[atmline[7]]) is types.ListType: # That is to say that several chains have the same substructure. chainID = subst_chain[atmline[7]][0] subst_chain[atmline[7]] = subst_chain[atmline[7]].remove(chainID) if chainID != self.mol.curChain.id: if not self.mol.chains.id or not chainID in self.mol.chains.id: self.mol.curChain = Chain(chainID, self.mol, top = self.mol) else: self.mol.curChain = self.mol.chains.get(chainID)[0] if len(atmline)<7: # test if the atmline has a res name and resseq: resName = 'RES' resSeq = '1' else: resName = atmline[7][:3] resSeq = atmline[7][3:] if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = string.strip(resName) + string.strip(resSeq) res = self.mol.curChain.get( na ) if res: self.mol.curRes = res[0] else: self.mol.curRes = Residue(resName, resSeq, '', self.mol.curChain, top = self.mol) name = atmline[1] if name == 'CA': self.mol.curRes.hasCA = 1 if name == 'O' : self.mol.curRes.hasO = 2 atom = Atom(name, self.mol.curRes, top = self.mol, chemicalElement = string.split(atmline[5], '.')[0]) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [ [float(atmline[2]), float(atmline[3]), float(atmline[4]) ] ] if len(atmline)>=9: atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = 'mol2' # atom.conformation = 0 atom.hetatm = 0 #Add a data member containing a list of string describing # the Sybyl status bis of the atoms. atom.status = status #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) delattr(self.mol, 'curRes') delattr(self.mol, 'curChain')
def build3LevelsTree(self,atomlines): """ Function to build a 3 levels hierarchy Molecule-substructure-atoms.""" self.mol= Protein() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename(os.path.splitext (self.filename)[0]) self.mol.children = ResidueSet([]) self.mol.childrenName = 'residues' self.mol.childrenSetClass = ResidueSet self.mol.elementType = Residue self.mol.curRes = Residue() self.mol.curRes.hasCA = 0 self.mol.curRes.hasO = 0 self.mol.levels = [Protein, Residue, Atom] for atmline in atomlines: if len(atmline)>= 10: status = string.split(atmline[9], '|') else: status = None resName = atmline[7][:3] resSeq = atmline[7][3:] if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = string.strip(resName) + string.strip(resSeq) res = self.mol.get(na) if res: self.mol.curRes = res[0] else: self.mol.curRes = Residue(resName, resSeq, '', self.mol, top = self.mol) name = atmline[1] if name == 'CA': self.mol.curRes.hasCA = 1 if name == 'O' : self.mol.curRes.hasO = 2 atom = Atom(name, self.mol.curRes, top = self.mol, chemicalElement = string.split(atmline[5], '.')[0]) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [ [float(atmline[2]), float(atmline[3]), float(atmline[4]) ] ] atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = mol2 # atom.conformation = 0 atom.hetatm = 0 #Add a data member containing a list of string describing # the Sybyl status bis of the atoms. atom.status = status #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) self.mol.residues = self.mol.children assert hasattr(self.mol, 'chains') delattr(self.mol, 'chains') delattr(self.mol, 'curRes')
def parse_PDB_ATOM_record(self, rec): """Parse PDB ATOM records using the pdb columns specifications""" self.atomCounter = self.atomCounter + 1 # not sure about altLoc if self.specType == 'i': rec = rec.split() # Handle the alternate location using a flag. altLoc = self.get_Field_Value(rec, 'altLoc') if altLoc != ' ': self.altLoc = altLoc else: self.altLoc = '' # changed from None to '' # check for chains break # self.modlflag = modlflag # chainID = rec[21]+ modlflag hascid = 1 chainID = self.get_Field_Value(rec, 'chainID') if not chainID: hascid = 0 chainID = str(self.chaincounter) ## should be unk??? if chainID != self.mol.curChain.id: # has to check if the chain exists already or not !!! if not self.mol.chains.id or chainID not in self.mol.chains.id or hascid == 0: self.chaincounter = self.chaincounter + 1 if hascid == 0: chainID = str(self.chaincounter) self.mol.curChain = Chain(chainID, self.mol, top=self.mol) self.residueCounter = 0 else: self.mol.curChain = self.mol.chains.get(chainID)[0] # check for residue break resName = self.get_Field_Value(rec, 'resName') resSeq = self.get_Field_Value(rec, 'resSeq').strip() # WARNING reSeq is a STRING noresSeq = 0 if not resSeq and resName == self.mol.curRes.type and resName != 'HOH': noresSeq = 1 resSeq = self.mol.curRes.number if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = resName.strip() + resSeq.strip() res = self.mol.curChain.get(na) if res: self.mol.curRes = res[0] else: self.residueCounter = self.residueCounter + 1 if resName == 'HOH': self.HOHCounter = self.HOHCounter + 1 if not resSeq: if resName == 'HOH': resSeq = self.HOHCounter else: resSeq = self.residueCounter ## FIXME icodes are ignored self.mol.curRes = Residue(resName, resSeq, '', self.mol.curChain, top=self.mol) icode = self.get_Field_Value(rec, 'iCode') if not icode: pass elif icode != ' ': self.mol.curRes.icode = icode # parse atom info # handle atom names (calcium, hydrogen) and find element type # check validity of chemical element column and charge column ## only works if 'name' is in the pdb format! FIX! n = self.get_Field_Value(rec, 'name') el = self.get_Field_Value(rec, 'element') if n: name, element = self.getPDBAtomName(n, el) # if there is not resSeq spec, use first N to figure out new res if noresSeq and name == 'N': At = self.mol.curRes.get('N') if At: self.residueCounter = self.residueCounter + 1 resSeq = self.residueCounter self.mol.curRes = Residue(resName, resSeq, self.mol.curChain, top=self.mol) atom = Atom(name, self.mol.curRes, element, top=self.mol) else: element = el if element: atom = Atom(parent=self.mol.curRes, chemicalElement=element, top=self.mol) else: atom = Atom(parent=self.mol.curRes, top=self.mol) ## elem = string.lower(element) # moved to getPDBAtomName ## if elem =='lp' or elem =='ld': ## element = 'Xx' atom.charge = self.get_Field_Value(rec, 'charge') # should have atom.charge if no charge? # coords are required; where to set default or check? xcoord = self.get_Field_Value(rec, 'x') ycoord = self.get_Field_Value(rec, 'y') zcoord = self.get_Field_Value(rec, 'z') assert xcoord and ycoord and zcoord atom._coords = [[float(xcoord), float(ycoord), float(zcoord)]] atom.segID = self.get_Field_Value(rec, 'segID').strip() if rec[:4] == 'ATOM' or rec[0] == 'ATOM': atom.hetatm = 0 else: atom.hetatm = 1 # atom.alternate = [] atom.element = element num = self.get_Field_Value(rec, 'serial') if num: atom.number = int(num) else: atom.number = self.atomCounter occupancy = self.get_Field_Value(rec, 'occupancy') if occupancy: atom.occupancy = float(occupancy) # must check that it is a number atom.conformation = 0 tempFactor = self.get_Field_Value(rec, 'tempFactor') if tempFactor: atom.temperatureFactor = float(tempFactor) # add in user defined fields to atom attributes for field_name in list(self.recSpecs.UserFieldsDict.keys()): value = self.get_Field_Value(rec, field_name) type = self.recSpecs.get(field_name, 'var_type') if value: if type == 'int': atom.__setattr__(field_name, int(value)) elif type == 'float': atom.__setattr__(field_name, float(value)) else: atom.__setattr__(field_name, value) else: atom.__setattr__(field_name, value) if self.altLoc: # check if the name of the atom is the same than the # name of the previous atom . name = name + '@' + self.altLoc atom.name = name if len(self.mol.curRes.atoms) > 1: # the new atom has been add to the current residue # You have to go to the one before. lastAtom = self.mol.curRes.atoms[-2] altname = lastAtom.name.split('@')[0] if name.split('@')[0] == altname: # Add the new alternate atom to the LastAtom.alternate and # add the lastAtom to the atom.alternate. lastAtom.alternate.append(atom) atom.alternate.append(lastAtom) for l in lastAtom.alternate: if atom.name != l.name: atom.alternate.append(l) l.alternate.append(atom) return atom
def parse(self, objClass=Protein): """Parses mmCIF dictionary (self.mmCIF_dict) into MolKit object""" if self.allLines is None and self.filename: self.readFile() if self.allLines is None or len(self.allLines)==0: return self.mmCIF2Dict() type_symbol = None B_iso_or_equiv = None mmCIF_dict = self.mmCIF_dict fileName, fileExtension = os.path.splitext(self.filename) molName = os.path.basename(fileName) if mmCIF_dict.has_key('_entry.id'): molName = mmCIF_dict['_entry.id'] if mmCIF_dict.has_key('_atom_site.id'): #The description of the data names can be found in the following link #http://mmcif.pdb.org/dictionaries/mmcif_pdbx.dic/Items ids = mmCIF_dict['_atom_site.id'] #1 number group_PDB = mmCIF_dict['_atom_site.group_PDB'] #2 atom/hetatm atom_id = mmCIF_dict['_atom_site.label_atom_id'] #3 name comp_id = mmCIF_dict['_atom_site.label_comp_id'] #4 residue type label_asym_id = mmCIF_dict['_atom_site.label_asym_id'] #5 chain #Note: chain ID from mmCIF file might be different from PDB file seq_id = mmCIF_dict['_atom_site.label_seq_id'] #6 residue number x_coords = mmCIF_dict['_atom_site.Cartn_x'] #7 xcoord y_coords = mmCIF_dict['_atom_site.Cartn_y'] #8 ycoord z_coords = mmCIF_dict['_atom_site.Cartn_z'] #9 zcoord occupancy = mmCIF_dict['_atom_site.occupancy'] #10 B_iso_or_equiv = mmCIF_dict['_atom_site.B_iso_or_equiv']#11 type_symbol = mmCIF_dict['_atom_site.type_symbol'] elif mmCIF_dict.has_key('_atom_site_label'): #ftp://ftp.iucr.org/pub/cif_core.dic atom_id = mmCIF_dict['_atom_site_label'] len_atoms = len(atom_id) ids = range(len_atoms) group_PDB = len_atoms*['HETATM'] comp_id = len_atoms*["CIF"] label_asym_id = len_atoms*['1'] seq_id = len_atoms*[1] from mglutil.math.crystal import Crystal a = mmCIF_dict['_cell.length_a'] = float(mmCIF_dict['_cell_length_a'].split('(')[0]) b = mmCIF_dict['_cell.length_b'] = float(mmCIF_dict['_cell_length_b'].split('(')[0]) c = mmCIF_dict['_cell.length_c'] = float(mmCIF_dict['_cell_length_c'].split('(')[0]) alpha = mmCIF_dict['_cell.angle_alpha'] = float(mmCIF_dict['_cell_angle_alpha'].split('(')[0]) beta = mmCIF_dict['_cell.angle_beta'] = float(mmCIF_dict['_cell_angle_beta'].split('(')[0]) gamma = mmCIF_dict['_cell.angle_gamma'] = float(mmCIF_dict['_cell_angle_gamma'].split('(')[0]) cryst = Crystal((a, b, c), (alpha, beta, gamma)) x = [] for item in mmCIF_dict['_atom_site_fract_x']: x.append(float(item.split('(')[0])) y = [] for item in mmCIF_dict['_atom_site_fract_y']: y.append(float(item.split('(')[0])) z = [] for item in mmCIF_dict['_atom_site_fract_z']: z.append(float(item.split('(')[0])) x_coords = [] y_coords = [] z_coords = [] B_iso_or_equiv = [] for i in ids: trans = cryst.toCartesian([x[i], y[i], z[i]]) x_coords.append(trans[0]) y_coords.append(trans[1]) z_coords.append(trans[2]) if mmCIF_dict.has_key('_atom_site_U_iso_or_equiv'): B_iso_or_equiv.append(mmCIF_dict['_atom_site_U_iso_or_equiv'][i].split('(')[0]) if mmCIF_dict.has_key('_atom_site_type_symbol'): type_symbol = mmCIF_dict['_atom_site_type_symbol'] if mmCIF_dict.has_key('_atom_site_occupancy'): occupancy = mmCIF_dict['_atom_site_occupancy'] if mmCIF_dict.has_key('_chemical_name_common'): molName = mmCIF_dict['_chemical_name_common'] elif mmCIF_dict.has_key('_chemical_name_mineral'): molName = mmCIF_dict['_chemical_name_mineral'] if mmCIF_dict.has_key('_symmetry_space_group_name_H-M'): mmCIF_dict['_symmetry.space_group_name_H-M'] = mmCIF_dict['_symmetry_space_group_name_H-M'] else: print 'No _atom_site.id or _atom_site_label record is available in %s' % self.filename return None mol = Protein() self.mol = mol self.mol.allAtoms = AtomSet([]) molList = mol.setClass() molList.append( mol ) current_chain_id = None current_residue_number = None current_chain = None current_residue = None number_of_atoms = len(ids) self.configureProgressBar(init=1, mode='increment', authtext='parse atoms', max=number_of_atoms) for index in range(number_of_atoms): #make a new atom for the current index chain_id = label_asym_id[index] if chain_id != current_chain_id: #make a new chain #molecule should adopt the current chain if there is one current_chain = Chain(id=chain_id) # FIXME: current_chain should not have allAtoms attribute delattr(current_chain, "allAtoms") current_chain_id = chain_id if current_chain is not None: #REMEMBER TO ADOPT THE LAST ONE!!! mol.adopt(current_chain, setChildrenTop=1) residue_number = seq_id[index] if residue_number != current_residue_number or chain_id != label_asym_id[index-1]: #make a new chain: #current_chain should adopt the current residue if there is one #create new residue residue_type = comp_id[index] current_residue = Residue(type=residue_type, number=residue_number) current_residue_number = residue_number if current_residue is not None: #REMEMBER TO ADOPT THE LAST ONE!!! current_chain.adopt(current_residue, setChildrenTop=1) name = atom_id[index] if type_symbol: element = type_symbol[index] else: element = None atom = Atom( name, current_residue, element, top=mol ) atom._coords = [[float(x_coords[index]), float(y_coords[index]), float(z_coords[index])]] atom._charges = {} atom.segID = mol.name atom.normalname = name atom.number = int(ids[index]) mol.atmNum[atom.number] = atom atom.occupancy = float(occupancy[index]) if B_iso_or_equiv: atom.temperatureFactor = float(B_iso_or_equiv[index]) atom.altname = None atom.hetatm = 0 if group_PDB[index]=='HETATM': atom.hetatm = 1 self.updateProgressBar() self.parse_MMCIF_CELL() try: self.parse_MMCIF_HYDBND() except: print >>sys.stderr,"Parsing Hydrogen Bond Record Failed in",self.filename mol.name = molName mol.allAtoms = mol.chains.residues.atoms mol.parser = self mol.levels = [Protein, Chain, Residue, Atom] name = '' for n in molList.name: name = n + ',' name = name[:-1] molList.setStringRepr(name) strRpr = name + ':::' molList.allAtoms.setStringRepr(strRpr) for m in molList: mname = m.name strRpr = mname + ':::' m.allAtoms.setStringRepr(strRpr) strRpr = mname + ':' m.chains.setStringRepr(strRpr) for c in m.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) self.buildBonds() return molList
def build3LevelsTree(self, atomlines): """ Function to build a 3 levels hierarchy Molecule-substructure-atoms.""" self.mol = Protein() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename( os.path.splitext(self.filename)[0]) self.mol.children = ResidueSet([]) self.mol.childrenName = 'residues' self.mol.childrenSetClass = ResidueSet self.mol.elementType = Residue self.mol.curRes = Residue() self.mol.curRes.hasCA = 0 self.mol.curRes.hasO = 0 self.mol.levels = [Protein, Residue, Atom] for atmline in atomlines: if len(atmline) >= 10: status = string.split(atmline[9], '|') else: status = None resName = atmline[7][:3] resSeq = atmline[7][3:] if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = string.strip(resName) + string.strip(resSeq) res = self.mol.get(na) if res: self.mol.curRes = res[0] else: self.mol.curRes = Residue(resName, resSeq, '', self.mol, top=self.mol) name = atmline[1] if name == 'CA': self.mol.curRes.hasCA = 1 if name == 'O': self.mol.curRes.hasO = 2 atom = Atom(name, self.mol.curRes, top=self.mol, chemicalElement=string.split(atmline[5], '.')[0]) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [[ float(atmline[2]), float(atmline[3]), float(atmline[4]) ]] atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = mol2 # atom.conformation = 0 atom.hetatm = 0 #Add a data member containing a list of string describing # the Sybyl status bis of the atoms. atom.status = status #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) self.mol.residues = self.mol.children assert hasattr(self.mol, 'chains') delattr(self.mol, 'chains') delattr(self.mol, 'curRes')
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 build4LevelsTree(self, subst_chain, atomlines): """ Function to build a 4 level hierarchy Protein-Chain-Residue-Atom. """ self.mol = Protein() self.mol.allAtoms = AtomSet() self.mol.atmNum = {} self.mol.parser = self if self.mol.name == 'NoName': self.mol.name = os.path.basename( os.path.splitext(self.filename)[0]) self.mol.curChain = Chain() self.mol.curRes = Residue() self.mol.levels = [Protein, Chain, Residue, Atom] i = 1 for atmline in atomlines: if len(atmline) >= 10: status = string.split(atmline[9], '|') else: status = None if len(atmline) == 8: tmp = [atmline[5][:5], atmline[5][5:]] atmline[5] = tmp[0] atmline.insert(6, tmp[1]) if status and status[0] == 'WATER': chainID = 'W' atmline[7] = 'HOH' + str(i) subst_chain[atmline[7]] = chainID i = i + 1 if subst_chain == {}: chainID = 'default' elif not subst_chain.has_key(atmline[7]): if subst_chain.has_key('****'): try: chainID = subst_chain[atmline[7]] except: chainID = 'default' else: chainID = 'default' elif type(subst_chain[atmline[7]]) is types.StringType: # that is to say that only chains has this substructure name. chainID = subst_chain[atmline[7]] elif type(subst_chain[atmline[7]]) is types.ListType: # That is to say that several chains have the same substructure. chainID = subst_chain[atmline[7]][0] subst_chain[atmline[7]] = subst_chain[atmline[7]].remove( chainID) if chainID != self.mol.curChain.id: if not self.mol.chains.id or not chainID in self.mol.chains.id: self.mol.curChain = Chain(chainID, self.mol, top=self.mol) else: self.mol.curChain = self.mol.chains.get(chainID)[0] if len(atmline) < 7: # test if the atmline has a res name and resseq: resName = 'RES' resSeq = '1' else: resName = atmline[7][:3] resSeq = atmline[7][3:] if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = string.strip(resName) + string.strip(resSeq) res = self.mol.curChain.get(na) if res: self.mol.curRes = res[0] else: self.mol.curRes = Residue(resName, resSeq, '', self.mol.curChain, top=self.mol) name = atmline[1] if name == 'CA': self.mol.curRes.hasCA = 1 if name == 'O': self.mol.curRes.hasO = 2 atom = Atom(name, self.mol.curRes, top=self.mol, chemicalElement=string.split(atmline[5], '.')[0]) #atom.element = atmline[5][0] atom.element = atom.chemElem atom.number = int(atmline[0]) self.mol.atmNum[atom.number] = atom atom._coords = [[ float(atmline[2]), float(atmline[3]), float(atmline[4]) ]] if len(atmline) >= 9: atom._charges['mol2'] = float(atmline[8]) atom.chargeSet = 'mol2' # atom.conformation = 0 atom.hetatm = 0 #Add a data member containing a list of string describing # the Sybyl status bis of the atoms. atom.status = status #add altname so buildBondsByDist doesn't croak atom.altname = None self.mol.allAtoms.append(atom) delattr(self.mol, 'curRes') delattr(self.mol, 'curChain')
def nextFrame(self, id): #Player.nextFrame(self, id) id = int(id) if id == self.currentFrameIndex: return if self.hasCounter and self.gui: self.form.ent2.delete(0,'end') self.form.ent2.insert(0, str(id)) if self.hasSlider: self.form.ifd.entryByName['slider']['widget'].set(id) self.currentFrameIndex = int(id) removeAtoms = AtomSet([]) addAtoms = AtomSet([]) id = int(id) flood = self.floods[id] centers = [] materials = [] radii = [] prev_coords = self.mol.allAtoms.coords lenAtoms = len(prev_coords) #self.residue.atoms = AtomSet([]) index = 0 #h = self.hp.heap() #print h for fl in flood: x = (fl[1] - self.xcent)*self.spacing + self.centerx y = (fl[2] - self.ycent)*self.spacing + self.centery z = (fl[3] - self.zcent)*self.spacing + self.centerz if fl[4] == 7: atomchr = 'P' # note, this will color the NA atom pink (the PDB color for Phosphorus) radius = AAradii[13][0] if fl[4] == 6: atomchr = 'S' radius = AAradii[13][0] if fl[4] == 5: atomchr = 'A' radius = AAradii[10][0] if fl[4] == 4: atomchr = 'O' radius = AAradii[1][0] if fl[4] == 3: atomchr = 'N' radius = AAradii[4][0] if fl[4] == 2: atomchr = 'C' radius = AAradii[10][0] if fl[4] == 1: atomchr = 'H' radius = AAradii[15][0] if not [x,y,z] in prev_coords: a = Atom(atomchr, self.residue, atomchr, top=self.mol) a._coords = [[x,y,z]] a._charges = {} a.hetatm = 1 a.radius = radius #a.number = lenAtoms + 1 addAtoms.append(a) lenAtoms += 1 for key in self.colorKeys: a.colors[key]=AtomElements[atomchr] a.opacities[key]=1.0 else: centers.append([x,y,z]) # a = Atom(atomchr, self.residue, atomchr, top=self.mol) # a._coords = [[x,y,z]] # a._charges = {} # a.hetatm = 1 # a.number = index # index += 1 #aterials.append(AtomElements[atomchr]) #enters.append([x,y,z]) #adii.append(radius) #self.mol.allAtoms = self.residue.atoms #self.mol.geomContainer.geoms['lines'].protected = False #for com in self.autoLigandCommand.vf.cmdsWithOnAddObj: # com.onAddObjectToViewer(self.mol) #self.autoLigandCommand.vf.displayCPK(self.mol, scaleFactor=0.1) halo_centers = [] for coord in prev_coords: if not coord in centers: index = prev_coords.index(coord) removeAtoms.append(self.mol.allAtoms[index]) self.residue.assignUniqIndex() #this is needed to avoid Traceback later on self.mol.allAtoms.stringRepr = None #stringRepr can be very large aousing memory errors event = AddAtomsEvent(objects=addAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) event = DeleteAtomsEvent(objects=removeAtoms) #self.autoLigandCommand.vf.dispatchEvent(event) self.autoLigandCommand.vf.displayCPK.updateGeom(event) for atom in removeAtoms: self.residue.atoms.remove(atom) if id == self.maxFrame: self.autoLigandCommand.halo.Set(visible=0) else: self.autoLigandCommand.halo.Set(centers=addAtoms.coords, materials=((1,1,0,0.5),), radii=0.4)
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 parse_PDB_ATOM_record(self, rec): """Parse PDB ATOM records using the pdb columns specifications""" self.atomCounter = self.atomCounter + 1 # not sure about altLoc if self.specType=='i': rec = string.split(rec) # Handle the alternate location using a flag. altLoc = self.get_Field_Value(rec, 'altLoc') if altLoc!= ' ': self.altLoc = altLoc else: self.altLoc = '' # changed from None to '' # check for chains break #self.modlflag = modlflag #chainID = rec[21]+ modlflag hascid = 1 chainID = self.get_Field_Value(rec, 'chainID') if not chainID: hascid = 0 chainID = str(self.chaincounter) ## should be unk??? if chainID != self.mol.curChain.id : # has to check if the chain exists already or not !!! if not self.mol.chains.id or not chainID in self.mol.chains.id or \ hascid==0: self.chaincounter = self.chaincounter + 1 if hascid==0: chainID = str(self.chaincounter) self.mol.curChain = Chain(chainID, self.mol, top=self.mol) self.residueCounter = 0 else: self.mol.curChain = self.mol.chains.get(chainID)[0] # check for residue break resName = self.get_Field_Value(rec, 'resName') resSeq = string.strip(self.get_Field_Value(rec, 'resSeq')) #WARNING reSeq is a STRING noresSeq = 0 if not resSeq and resName==self.mol.curRes.type and resName!='HOH': noresSeq = 1 resSeq = self.mol.curRes.number if resSeq != self.mol.curRes.number or \ resName != self.mol.curRes.type: # check if this residue already exists na = string.strip(resName) + string.strip(resSeq) res = self.mol.curChain.get( na ) if res: self.mol.curRes = res[0] else: self.residueCounter = self.residueCounter + 1 if resName=='HOH': self.HOHCounter = self.HOHCounter + 1 if not resSeq: if resName=='HOH': resSeq = self.HOHCounter else: resSeq = self.residueCounter ## FIXME icodes are ignored self.mol.curRes = Residue(resName, resSeq, '', self.mol.curChain, top=self.mol) icode = self.get_Field_Value(rec, 'iCode') if not icode: pass elif icode != ' ': self.mol.curRes.icode = icode # parse atom info # handle atom names (calcium, hydrogen) and find element type # check validity of chemical element column and charge column ## only works if 'name' is in the pdb format! FIX! n = self.get_Field_Value(rec, 'name') el = self.get_Field_Value(rec, 'element') if n: name, element = self.getPDBAtomName(n, el) # if there is not resSeq spec, use first N to figure out new res if noresSeq and name=='N': At = self.mol.curRes.get('N') if At: self.residueCounter = self.residueCounter + 1 resSeq = self.residueCounter self.mol.curRes = Residue(resName, resSeq, self.mol.curChain, top=self.mol) atom = Atom(name, self.mol.curRes, element, top=self.mol) else: element = el if element: atom = Atom(parent = self.mol.curRes, chemicalElement = element, top=self.mol) else: atom = Atom(parent = self.mol.curRes, top=self.mol) ## elem = string.lower(element) # moved to getPDBAtomName ## if elem =='lp' or elem =='ld': ## element = 'Xx' atom.charge = self.get_Field_Value(rec, 'charge') #should have atom.charge if no charge? # coords are required; where to set default or check? xcoord = self.get_Field_Value(rec, 'x') ycoord = self.get_Field_Value(rec, 'y') zcoord = self.get_Field_Value(rec, 'z') assert xcoord and ycoord and zcoord atom._coords = [ [ float(xcoord), float(ycoord), float(zcoord) ] ] atom.segID = string.strip(self.get_Field_Value(rec, 'segID')) if rec[:4]=='ATOM' or rec[0]=='ATOM': atom.hetatm = 0 else: atom.hetatm = 1 #atom.alternate = [] atom.element = element num = self.get_Field_Value(rec, 'serial') if num: atom.number = int(num) else: atom.number = self.atomCounter occupancy = self.get_Field_Value(rec, 'occupancy') if occupancy: atom.occupancy = float(occupancy) # must check that it is a number atom.conformation = 0 tempFactor = self.get_Field_Value(rec, 'tempFactor') if tempFactor: atom.temperatureFactor = float(tempFactor) # add in user defined fields to atom attributes for field_name in self.recSpecs.UserFieldsDict.keys(): value = self.get_Field_Value(rec, field_name) type = self.recSpecs.get(field_name, 'var_type') if value: if type=='int': atom.__setattr__(field_name, int(value)) elif type=='float': atom.__setattr__(field_name, float(value)) else: atom.__setattr__(field_name, value) else: atom.__setattr__(field_name, value) if self.altLoc : # check if the name of the atom is the same than the #name of the previous atom . name = name + '@'+self.altLoc atom.name = name if len(self.mol.curRes.atoms)>1: # the new atom has been add to the current residue # You have to go to the one before. lastAtom = self.mol.curRes.atoms[-2] altname = string.split(lastAtom.name, '@')[0] if string.split(name, '@')[0] == altname: # Add the new alternate atom to the LastAtom.alternate and # add the lastAtom to the atom.alternate. lastAtom.alternate.append(atom) atom.alternate.append(lastAtom) for l in lastAtom.alternate: if atom.name != l.name: atom.alternate.append(l) l.alternate.append(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 )