def atomsToVec(atoms): a1 = hf.atomCoord(atoms[1]) a2 = hf.atomCoord(atoms[2]) a3 = hf.atomCoord(atoms[3]) centroid = hf.avgCoord(atoms) pvector = hf.calcPlane(a1, a2, a3) v1 = hf.vector(centroid, a1) v2 = hf.vector(centroid, a2) normal1 = hf.normalize(cross(v1 ,v2)) normal2 = hf.normalize(cross(v2 ,v1)) centroid_norm1 = hf.normalize(hf.vector(centroid, normal1)) centroid_norm2 = hf.normalize(hf.vector(centroid, normal2)) return {"centroid":centroid,"plane":hf.normalize(pvector),"normal":[normal1, normal2],\ 'cnormal' : [centroid_norm1, centroid_norm2]}
def getWaterGridEnergy(self): # cutoff_weak = -0.35, # weak water e.cutoff # cutoff_strong = -0.5, # strong water e.cutoff # desolvEntropy=-0.2, # desolvation entropy # mapdistrange = 0.5): # TODO to be used to 'minimize' the water position too? # looking for the best spot for a water # and increase the energy accordingly? # calculate the score for bridging waters; self.pose['water_bridge_scores'] = [] for w in self.pose['water_bridge']: points, best_point = self.getMapPoints(coords=hf.atomCoord(w), distance=self.mapdistrange) self.pose['water_bridge_scores'].append(best_point) # calculate ligand-overlapping penalties self.pose['water_over_lig_penalty'] = [] for w in self.pose['water_over_lig']: points, best_point = self.getMapPoints(coords=atomCoord(w), distance=self.mapdistrange) self.pose['water_over_lig_penalty'].append(-best_point) # calculate rec-overlapping penalties self.pose['water_over_rec_penalty'] = [] for w in self.pose['water_over_rec']: self.pose['water_over_rec_penalty'].append(-self.desolvEntropy)
def getWaterGridEnergy(self): # cutoff_weak = -0.35, # weak water e.cutoff # cutoff_strong = -0.5, # strong water e.cutoff # desolvEntropy=-0.2, # desolvation entropy # mapdistrange = 0.5): # TODO to be used to 'minimize' the water position too? # looking for the best spot for a water # and increase the energy accordingly? # calculate the score for bridging waters; self.pose['water_bridge_scores'] = [] for w in self.pose['water_bridge']: points, best_point = self.getMapPoints( coords = hf.atomCoord(w), distance = self.mapdistrange) self.pose['water_bridge_scores'].append(best_point) # calculate ligand-overlapping penalties self.pose['water_over_lig_penalty'] = [] for w in self.pose['water_over_lig']: points, best_point = self.getMapPoints( coords = atomCoord(w), distance = self.mapdistrange) self.pose['water_over_lig_penalty'].append( -best_point) # calculate rec-overlapping penalties self.pose['water_over_rec_penalty'] = [] for w in self.pose['water_over_rec']: self.pose['water_over_rec_penalty'].append(-self.desolvEntropy)
def clusterWaters(self): #pose, clust_tolerance=2.0, desolvEntropy=0): # cluster waters # XXX # energy from the cluster? # once 3 waters are reclustered (3->1) # two desolvEntropy penalties should be issued? # XXX unclustered_waters = self.pose[ 'water_bridge'][:] # XXX NOT SURE IT"S NECESSARY # cluster waters water_clusters = hf.clusterAtoms(unclustered_waters, tol=self.clust_tol) # calculate clustering energy self.pose['water_cluster_penalty'] = [] remove_from_text = [] for pop in water_clusters: if len(pop) > 1: this_cluster_centroid = hf.avgCoord(pop) this_cluster_penalty = -self.desolvEntropy * (len(pop) - 1) this_cluster_energy = 0 this_cluster_contacts = [] closest_to_centroid = None closest_dist = 999999 for w in pop: # get the w_index + w_score idx = self.pose['water_bridge'].index(w) this_cluster_energy += self.pose['water_bridge_scores'][ idx] remove_from_text.append(w) # find water closest to centroid (to be conserved) # get the distance from the cluster average centr_dist = hf.quickdist(hf.atomCoord(w), this_cluster_centroid, sq=False) a = [hf.makePdb(coord=this_cluster_centroid)] #writeList('centroid.pdb', a) if centr_dist <= closest_dist: closest_dist = centr_dist closest_to_centroid = w del self.pose['water_bridge'][idx] del self.pose['water_bridge_scores'][idx] # update contacts for a in self.pose['water_bridge_contacts'][idx]: if not a in this_cluster_contacts: this_cluster_contacts.append(a) del self.pose['water_bridge_contacts'][idx] # update PDBQT text # XXX DEBUGGINGH #print type(remove_from_text), remove_from_text[0] #writeList('REMOVING_WATERS.pdb', remove_from_text) #writeList('current_ligand.pdbqt', pose['text']) for w in remove_from_text: if not w == closest_to_centroid: try: text_idx = self.pose['text'].index(w) del self.pose['text'][text_idx] except: pass # use the closest to be updated with clustering coords closest_index = self.pose['text'].index(closest_to_centroid) water = self.pose['text'][closest_index] coord_text = "%8.3f%8.3f%8.3f" % (this_cluster_centroid[0], this_cluster_centroid[1], this_cluster_centroid[2]) cluster_water = water[0:30] + coord_text + water[ 54:] # XXX ugly, but it works... self.pose['text'][closest_index] = cluster_water # update water_bridge list+score, water_cluster_penalty list self.pose['water_bridge'].append(cluster_water) self.pose['water_bridge_scores'].append(this_cluster_energy) self.pose['water_cluster_penalty'].append(this_cluster_penalty) self.pose['water_bridge_contacts'].append( this_cluster_contacts) if self.debug: print "CLUSTER SIZE", len(pop) print "CLUSTER ENRG", this_cluster_energy print "CLUSTER PENL", this_cluster_penalty #print "CLUSTER FINL", clust_energy+clust_penalty print "=============="
def clusterWaters(self): #pose, clust_tolerance=2.0, desolvEntropy=0): # cluster waters # XXX # energy from the cluster? # once 3 waters are reclustered (3->1) # two desolvEntropy penalties should be issued? # XXX unclustered_waters = self.pose['water_bridge'][:] # XXX NOT SURE IT"S NECESSARY # cluster waters water_clusters = hf.clusterAtoms(unclustered_waters, tol=self.clust_tol) # calculate clustering energy self.pose['water_cluster_penalty'] = [] remove_from_text = [] for pop in water_clusters: if len(pop)>1: this_cluster_centroid = hf.avgCoord(pop) this_cluster_penalty = -self.desolvEntropy * (len(pop)-1) this_cluster_energy = 0 this_cluster_contacts = [] closest_to_centroid = None closest_dist = 999999 for w in pop: # get the w_index + w_score idx = self.pose['water_bridge'].index(w) this_cluster_energy += self.pose['water_bridge_scores'][idx] remove_from_text.append(w) # find water closest to centroid (to be conserved) # get the distance from the cluster average centr_dist = hf.quickdist( hf.atomCoord(w), this_cluster_centroid, sq = False) a = [ hf.makePdb(coord=this_cluster_centroid) ] #writeList('centroid.pdb', a) if centr_dist <= closest_dist: closest_dist = centr_dist closest_to_centroid = w del self.pose['water_bridge'][idx] del self.pose['water_bridge_scores'][idx] # update contacts for a in self.pose['water_bridge_contacts'][idx]: if not a in this_cluster_contacts: this_cluster_contacts.append(a) del self.pose['water_bridge_contacts'][idx] # update PDBQT text # XXX DEBUGGINGH #print type(remove_from_text), remove_from_text[0] #writeList('REMOVING_WATERS.pdb', remove_from_text) #writeList('current_ligand.pdbqt', pose['text']) for w in remove_from_text: if not w == closest_to_centroid: try: text_idx = self.pose['text'].index(w) del self.pose['text'][text_idx] except: pass # use the closest to be updated with clustering coords closest_index = self.pose['text'].index(closest_to_centroid) water = self.pose['text'][closest_index] coord_text = "%8.3f%8.3f%8.3f" % (this_cluster_centroid[0], this_cluster_centroid[1], this_cluster_centroid[2]) cluster_water = water[0:30]+coord_text+water[54:] # XXX ugly, but it works... self.pose['text'][closest_index] = cluster_water # update water_bridge list+score, water_cluster_penalty list self.pose['water_bridge'].append(cluster_water) self.pose['water_bridge_scores'].append(this_cluster_energy) self.pose['water_cluster_penalty'].append(this_cluster_penalty) self.pose['water_bridge_contacts'].append(this_cluster_contacts) if self.debug: print "CLUSTER SIZE", len(pop) print "CLUSTER ENRG", this_cluster_energy print "CLUSTER PENL", this_cluster_penalty #print "CLUSTER FINL", clust_energy+clust_penalty print "=============="