def getAromaticRes(receptor): # TODO add acids and amides? aromatic_res = { "PHE": ["A"], "TYR": ["A"], "HIS": ["A", "N", "NA"], "TRP": ["A", "N", "NA"], "ARG": ["N", "C" , "NA"], "DA" : ["A", "NA", "N"], # DNA "DC" : ["A", "N", "NA"], "DT" : ["A", "N", "NA"], "DG" : ["A", "N", "NA"], "A" : ["A", "NA", "N"], # DNA/RNA "C" : ["A", "N", "NA"], "G" : ["A", "N", "NA"], "T" : ["A", "N", "NA"], "U" : ["A", "N", "NA"], } residues = {} special = [] # must be treated as a ligand part for a in receptor: a = a.strip() rtype = a[16:21].strip().upper() # NOTE: we can recognize only all caps! if a.startswith("HETATM"): special.append(a) elif a.startswith('ATOM') and rtype in aromatic_res.keys(): if hf.getAtype(a) in aromatic_res[rtype]: res_id = hf.pmvAtomStrip(a).rsplit(":",1)[0] # A:GLY48:N -> A:GLY48 if not res_id in residues.keys(): residues[res_id] = [] residues[res_id].append(a) if special and DEBUG: print "found potential co-factor: %d" % len(special) for a in special: print a return residues, special # residues = { "A:GLY48" : [ atom, atom, atom..]}
def normalizeWaterScore(self): #pose,entropyPenalty=False): # keep track of the original energy values if self.debug: old_e = self.pose['energy'] old_leff = self.pose['leff'] # rec_displaced waters rec_displaced = 0 for p in self.pose['water_over_rec_penalty']: rec_displaced += p # print p # XXX #print "RECDISP", rec_displaced # XXX # lig_displaced waters lig_displaced = 0 for p in self.pose['water_over_lig_penalty']: lig_displaced += p # clustering-displaced clust_displaced = 0 for p in self.pose['water_cluster_penalty']: clust_displaced += p # count heavy at for lig.efficiency heavy_atoms = 0 for a in self.pose['text']: if hf.isAtom(a) and (not hf.getAtype(a) in ['HD', 'W']): heavy_atoms += 1 # energy correction if self.conservedwaterentropy: # XXX read the penalty from a variable! entropy = (0.2) * len(self.pose['water_bridge']) #print " ENTROPY PENALTY = ", entropy else: entropy = 0 self.pose[ 'energy'] += lig_displaced + rec_displaced + clust_displaced + entropy # lig.efficiency correction self.pose['leff'] = self.pose['energy'] / float(heavy_atoms) if self.debug: #print "\n# PENALTY:\t +%2.3f [rec: %2.3f, lig: %2.3f, clust: %2.3f ]" % (rec_displaced+lig_displaced+clust_displaced, # rec_displaced, lig_displaced, clust_displaced) print " Penalties:" print " - lig overlap : %2.3f" % lig_displaced print " - rec overlap : %2.3f" % rec_displaced print " - cluster penalty : %2.3f" % clust_displaced print " - extra entropy : %2.3f" % entropy print " ENERGY:\t %2.3f [ old: %2.3f ]" % (self.pose['energy'], old_e) print " L.EFF.:\t %2.3f [ old: %2.3f ]\n" % (self.pose['leff'], old_leff)
def weakWaterCleanup(self): # #pose, cutoff_weak = -0.35, cutoff_strong=-0.5, interact_dist=3.5 ): """ clean-up extra_weak waters (increment ['water_rec_over_penalty'], if necessary""" org_waters = len(self.pose['water_bridge']) #ignore_types = ['HD'] lone_water = [] interact_dist = self.interact_dist**2 hb_types = ['OA', 'NA', 'SA', 'N', 'O', 'OA', 'NA', 'SA'] hb_types += hf.METALS for idx in range(len(self.pose['water_bridge'])): water = self.pose['water_bridge'][idx] score = self.pose['water_bridge_scores'][idx] # analyze only waters that are not ranked strong if score >= self.cutoff_strong: atom_pool = [ a for a in self.pose['water_bridge_contacts'][idx] if hf.getAtype(a) in hb_types] if self.debug: hf.writeList('ATOM_POOL_%d_HB_%d.pdb' % (idx, sess), atom_pool, addNewLine=True) lone_water.append(water) try: for a in atom_pool: if (dist(water, a, sq=0)<= interact_dist): #print "FOUND MATE", #print dist(water, a, sq=True) #print a.strip() #print "------------------" raise self.qs #print "NO MATE FOR THIS", score #print water.strip() except: lone_water.remove(water) for w in lone_water: idx = self.pose['water_bridge'].index(w) del self.pose['water_bridge'][idx] del self.pose['water_bridge_contacts'][idx] # EXPERIMENTAL #w_score = self.pose['water_bridge_scores'][idx] #if w_score > # XXX THIS shouldn't happen: # a weakly bound water could be hanging in the bulk, but it should be accounted for # ...? # how to describe the bulk solvent? # combine desolv map + discrete waters? # self.pose['water_over_rec_penalty'].append( -self.pose['water_bridge_scores'].pop(idx) ) # update PDBQT text #print pose['water_over_rec_penalty'] # XXX text_idx = self.pose['text'].index(w) del self.pose['text'][text_idx] if self.debug: print "LONE WATERS # REMOVED: ", (org_waters- len(self.pose['water_bridge']) )
def normalizeWaterScore(self): #pose,entropyPenalty=False): # keep track of the original energy values if self.debug: old_e = self.pose['energy'] old_leff = self.pose['leff'] # rec_displaced waters rec_displaced = 0 for p in self.pose['water_over_rec_penalty']: rec_displaced += p # print p # XXX #print "RECDISP", rec_displaced # XXX # lig_displaced waters lig_displaced = 0 for p in self.pose['water_over_lig_penalty']: lig_displaced += p # clustering-displaced clust_displaced = 0 for p in self.pose['water_cluster_penalty']: clust_displaced += p # count heavy at for lig.efficiency heavy_atoms = 0 for a in self.pose['text']: if hf.isAtom(a) and ( not hf.getAtype(a) in ['HD', 'W'] ): heavy_atoms += 1 # energy correction if self.conservedwaterentropy: # XXX read the penalty from a variable! entropy = (0.2)*len(self.pose['water_bridge']) #print " ENTROPY PENALTY = ", entropy else: entropy = 0 self.pose['energy'] += lig_displaced + rec_displaced + clust_displaced + entropy # lig.efficiency correction self.pose['leff'] = self.pose['energy'] / float( heavy_atoms ) if self.debug: #print "\n# PENALTY:\t +%2.3f [rec: %2.3f, lig: %2.3f, clust: %2.3f ]" % (rec_displaced+lig_displaced+clust_displaced, # rec_displaced, lig_displaced, clust_displaced) print " Penalties:" print " - lig overlap : %2.3f" % lig_displaced print " - rec overlap : %2.3f" % rec_displaced print " - cluster penalty : %2.3f" % clust_displaced print " - extra entropy : %2.3f" % entropy print " ENERGY:\t %2.3f [ old: %2.3f ]" % (self.pose['energy'], old_e) print " L.EFF.:\t %2.3f [ old: %2.3f ]\n" % (self.pose['leff'], old_leff)
def recOverlapWaters(self): # pose, cutoff = CLASH, #ignore_types = ['HD', 'H', 'W'] ): """ INPUT : pdb lig (multi)model and pdb target model OUTPUT: cleaned pdb lig model """ #print "WARNING! missing interactions! Line B1" overlapping = [] atom_pool = [] cutoff = self.clash**2 #cutoff += 0.5 #cutoff = 0 #for a in self.pose['vdw_contacts']: # PDBQT, no-HD # XXX TODO BUG Line B1 for aset in self.pose[ 'water_bridge_contacts']: # PDBQT, no-HD # XXX TODO BUG Line B1 for a in aset: if not hf.getAtype(a) in self.ignore_types: atom_pool.append(a) if self.debug: fp = open('DEBUG_rec_overlap.pdb', 'w') fp.write("REMARK WATERS REMOVED BY RECEPTOR CLASHES") for w in self.pose['water_bridge']: try: # try/except is faster for a in atom_pool: #if hf.dist(w, a, sq=False) < self.clash: if hf.dist(w, a, sq=False) < cutoff: overlapping.append(w) self.pose['text'].remove(w) #print "\n\n\n #### REMOVED", w if self.debug: fp.write(w + "\n") fp.write(a + "\n") raise self.qs except: pass if self.debug: fp.close() print "Processed: %d | Rec-overlap %d" % (len( self.pose['water_bridge']), len(overlapping)) for w in overlapping: idx = self.pose['water_bridge'].index(w) del self.pose['water_bridge_contacts'][idx] self.pose['water_bridge'].remove(w) self.pose['water_over_rec'] = overlapping
def recOverlapWaters(self): # pose, cutoff = CLASH, #ignore_types = ['HD', 'H', 'W'] ): """ INPUT : pdb lig (multi)model and pdb target model OUTPUT: cleaned pdb lig model """ #print "WARNING! missing interactions! Line B1" overlapping = [] atom_pool = [] cutoff = self.clash**2 #cutoff += 0.5 #cutoff = 0 #for a in self.pose['vdw_contacts']: # PDBQT, no-HD # XXX TODO BUG Line B1 for aset in self.pose['water_bridge_contacts']: # PDBQT, no-HD # XXX TODO BUG Line B1 for a in aset: if not hf.getAtype(a) in self.ignore_types: atom_pool.append(a) if self.debug: fp = open('DEBUG_rec_overlap.pdb','w') fp.write("REMARK WATERS REMOVED BY RECEPTOR CLASHES") for w in self.pose['water_bridge']: try: # try/except is faster for a in atom_pool: #if hf.dist(w, a, sq=False) < self.clash: if hf.dist(w, a, sq=False) < cutoff: overlapping.append(w) self.pose['text'].remove(w) #print "\n\n\n #### REMOVED", w if self.debug: fp.write(w+"\n") fp.write(a+"\n") raise self.qs except: pass if self.debug: fp.close() print "Processed: %d | Rec-overlap %d" % (len(self.pose['water_bridge']), len(overlapping) ) for w in overlapping: idx = self.pose['water_bridge'].index(w) del self.pose['water_bridge_contacts'][idx] self.pose['water_bridge'].remove(w) self.pose['water_over_rec'] = overlapping