def delAtom(self,index): """ delAtom(self,index): deletes one atom from self, and updates all x2i information """ if index < 0 or index >= self.natoms: # if atom doesn't exist: cu.die('BgfFile.delAtom: Atom at index "%d" does not exist' % index) del self.a2i[self.a[index].aNo] # delete the a2i record delaNo = self.a[index].aNo del self.a[index] # delete the atom self.natoms -= 1 # update no.of atoms for i in range(index, self.natoms): # decrement/update all the a2i atom = self.a[i] # records that come after this self.a2i[atom.aNo] = i # index number """ for i in range(0, len(self.a)): atom = self.a[i] ano = index + 1 if delaNo in atom.CONECT: atom.CONECT.remove(delaNo) """ self.max_aNo = max( self.a2i.keys() ) # ... update constants ... self.min_aNo = min( self.a2i.keys() ) #
def disconnect(self,other,strict=False): """ disconnect(self, other, strict=False): removes the bond between the atoms 'self' and 'other' if strict is True, dies when no bond is found between the atoms""" # remove other from self's list for n in range(len(self.CONECT)): if self.CONECT[n] == other.aNo: del self.CONECT[n] if self.ORDER: del self.ORDER[n] break else: if strict: cu.die("atoms %d is not connected to %d"%(self.aNo,other.aNo)) # remove self from other's list for n in range(len(other.CONECT)): if other.CONECT[n] == self.aNo: del other.CONECT[n] if other.ORDER: del other.ORDER[n] break else: if strict: cu.die("atoms %d is not connected to %d"%(other.aNo,self.aNo))
def rmsd(myBGF1,myBGF2,safe=1,noH=0,scOnly=0): """ rmsd(myBGF1,myBGF2,safe=1,noH=0,scOnly=0): returns the RMSD (in A) between the two BgfFile objects, myBGF1 and myBGF2, that share the same structure. if 'safe' is set to 0, atom-by-atom similarity comparison will not be carried out between myBGF1 and myBGF2. if 'noH' is set to 1, hydrogens will not be included in the RMSD calculation if 'scOnly' is set to 1, sidechain-only RMSD will be returned """ natoms = myBGF1.natoms if natoms != myBGF2.natoms: # check natoms cu.die("BGF: rmsd: BgfFile objects don't contain the same number of atoms: %d =/= %d"%(natoms,myBGF2.natoms)) atomCount = 0 sumOfSqrDist = 0.0 for i in range(natoms): atom1 = myBGF1.a[i] atom2 = myBGF2.a[i] if safe and (atom1 != atom2): # check atoms cu.die("BGF: rmsd: Atom number %d refers to different atoms in the BgfFile objects provided."%i) if noH and atom1.is_hydrogen(): continue if scOnly and atom1.is_sidechain(): continue atomCount += 1 sumOfSqrDist += sqrDistance(atom1, atom2) myRMSD = math.sqrt(sumOfSqrDist / atomCount) return myRMSD
def __radd__(self,other): """ __radd__(self,other): reverse __add__ works only if the second object is a BgfFile """ if isinstance(other,BgfFile): # execute if second object is a BgfFile return BgfFile.__add__(other,self) elif isinstance(other,BgfAtom): # die if second object is a BgfAtom cu.die("Cannot add a BgfFile to a BgfAtom object")
def readBgfLine(self,line): """ readBgfLine(self,line): enters info from ATOM/HETATM, CONECT and ORDER lines into a BgfAtom object """ line = line.strip() line = line.replace("-", " -") if line[0:6] == 'ATOM ' or line[0:6] == 'HETATM': if line[0:6] == 'HETATM': self.aTag = 1 l_line = line.split() try: self.aNo = int(l_line[1]) self.aName = l_line[2] self.rName = l_line[3] self.chain = l_line[4] self.rNo = int(l_line[5]) self.x = float(l_line[6]) self.y = float(l_line[7]) self.z = float(l_line[8]) self.ffType = l_line[9] self.bonds = int(l_line[10]) self.lpair = int(l_line[11]) self.charge = float(l_line[12]) except: print("Error occured while reading the line: " + line) sys.exit(0) elif line[0:6] == 'CONECT' or line[0:6] == 'ORDER ': if not self.aNo: cu.die('readBgfLine: Cannot read CONECT/ORDER data prior to ATOM data!') elif int(line[7:12]) != self.aNo: cu.die('readBgfLine: The line read does not refer to the atom, "%d":\n%s' % (self.aNo, line)) else: # using re.split is OK in the following lines since aNo cannot be 6 digits if line[0:6] == 'CONECT': conectInfoString = line[12:].strip() if conectInfoString: self.CONECT = cu.list2intList( re.split(r'\s+', conectInfoString) ) else: #elif line[0:6] == 'ORDER ': if not self.CONECT: cu.die('readBgfLine: Cannot read ORDER data prior to CONECT data!') else: self.ORDER = cu.list2intList( re.split(r'\s+', line[12:].strip()) ) if len(self.CONECT) != len(self.ORDER): cu.die('readBgfLine: CONECT and ORDER line elements do not match:\n%s%s' % \ (self.CONECTline(), line) ) else: cu.die('readBgfLine: Line provided does not carry any atom information:\n%s' % (line,))
def getAtom(self, atomNo): """ getAtom(self, atomNo): returns the BgfAtom specified by the atom number (internal index)""" index = self.a2i.get(atomNo, (-1)) # return: if index < 0: cu.die("getAtom: No such atom number, %s, in BgfFile object!" % atomNo) else: return self.a[index]
def readBgfFromLines(self,lines,safe=0): """ readBgfFromLines(self,lines,safe=0): reads a list of BGF lines and populates basic fields if 'safe' is set, data after the charges are not read """ aCount = 0 # counts atoms for line in lines: tag = re.split(r'\s+', line)[0] parse = line.split() if tag == 'ATOM' or tag == 'HETATM': # REMARK: maybe safe mode won't work since line is parsed if safe: line = line[:80] # do not read anything after 80 chars atom = BgfAtom() atom.readBgfLine(line.strip()) self.format = max(self.format, guessBGFformat(atom)) self.a.append(atom) self.a2i[atom.aNo] = aCount self.max_aNo = max(atom.aNo, self.max_aNo) self.min_aNo = min(atom.aNo, self.min_aNo) aCount += 1 elif tag == 'PERIOD': if len(parse) == 2: self.PERIOD = parse[1] else: self.PERIOD = "" elif tag == 'CRYSTX': if len(parse) > 2: self.CRYSTX = [ float(parse[1]), float(parse[2]), float(parse[3]), float(parse[4]), float(parse[5]), float(parse[6]) ] else: self.CRYSTX = [] elif tag == 'FORCEFIELD': if len(parse) == 2: self.FF = str.strip(parse[1]) else: self.FF = '' elif tag == 'AXES': if len(parse) == 2: self.AXES = str.strip(parse[1]) elif tag == 'SGNAME': if len(line) > 8: self.SGNAME = line[7:] elif tag == 'CELLS': if len(parse) > 2: self.CELLS = parse[1:] elif tag == 'CONECT' or tag == 'ORDER': aNo = getAtomNumberFromLine(line) self.a[ self.a2i[aNo] ].readBgfLine(line) elif tag == 'REMARK': self.REMARK.append( line.strip()[7:] ) elif tag == 'FORMAT': if re.search(r'^FORMAT ATOM', line): self.FORMAT['ATOM'] = line.strip() elif re.search(r'^FORMAT CONECT', line): self.FORMAT['CONECT'] = line.strip() elif re.search(r'^FORMAT ORDER', line): self.FORMAT['ORDER'] = line.strip() else: cu.die("readBgfFromLines: Unkown FORMAT line:\n%s" % line) elif tag == 'DESCRP': self.DESCRP = line[7:].strip() elif tag == 'BIOGRF': self.BIOGRF = line[7:].strip() # appended to prevent the errors from XTLGRP keyword. @ 110808 elif tag == 'XTLGRF': self.BIOGRF = line[7:].strip() elif tag == 'FORCEFIELD': self.FF = line.strip() elif tag == 'REM' or \ tag == 'PHI' or \ tag == 'PSI': # these are fields in the rotamer library self.OTHER.append(line) elif tag == 'END': break elif parse == []: continue; else: cu.warn("readBgfFromLines: Encountered unknown field:\n%s" % line) line = line.strip() if line: self.OTHER.append(line) self.natoms = aCount