def iter_hbonds_acc(self, parsed_pdb): for hbond in self.iter_triplets_acc(parsed_pdb): if hbond[2].getResname() == 'HOH': hyds = parsed_pdb.contacts(1.1, hbond[0].getCoords()).select('element H D') if hyds is not None: angle_tests = [] for hyd in hyds.iterAtoms(): angle = pr.calcAngle(hbond[0], hyd, hbond[2]) if angle > 90: angle_tests.append(False) else: angle_tests.append(True) if all(angle_tests): distance_acc_hyd = 99 distance_heavy = pr.calcDistance(hbond[0], hbond[2]) angle = 360 yield hbond, angle, distance_acc_hyd, distance_heavy else: distance_acc_hyd = 99 distance_heavy = pr.calcDistance(hbond[0], hbond[2]) angle = 360 yield hbond, angle, distance_acc_hyd, distance_heavy else: angle = pr.calcAngle(hbond[0], hbond[1], hbond[2]) if angle > 90: distance_acc_hyd = pr.calcDistance(hbond[0], hbond[1]) distance_heavy = pr.calcDistance(hbond[0], hbond[2]) yield hbond, angle, distance_acc_hyd, distance_heavy
def checkHBonds(appf,no_d, ox_a, ssindex): #1 Dist(don, acc) < 3.5 da_dist = pr.calcDistance( no_d , ox_a ) if( da_dist >= DONOR_ACCEPTOR_MAXDISTANCE ): return h_don = getHforAtom(appf,no_d) if(h_don == None): return #2 Dist(h_don, acc) < 3.5 ha_dist = pr.calcDistance(h_don, ox_a) if( ha_dist >= HYDROGEN_ACCEPTOR_MAXDISTANCE): return #3 Angle(don, h_don, acc) > 90 dha_ang = pr.calcAngle( no_d, h_don, ox_a ) if( dha_ang < DHA_ANGLE ): return #4 Angle(don, acc, acc_ante) > 90 #daa_ang = pr.calcAngle( no_d, ox_a, acc_ante) #if( daa_ang < DAB_ANGLE ): # return acc_ante = getAntecedent(appf, ox_a) #Get acc_ante if(acc_ante == None): return #5 Angle(h_don, acc, acc_ante) > 90 haa_ang = pr.calcAngle( h_don, ox_a, acc_ante ) if( haa_ang < HAB_ANGLE ): return #We have a valid H-Bond with no_d, ox_a, h_don #print 'HBond elements', h_don.getName(), no_d.getName(), ox_a.getName() #print 'DA dist', da_dist #print 'HA dist', ha_dist #print 'DHA ang', dha_ang #print 'DAA ang', daa_ang #print 'HAA ang', haa_ang beta_ang = getBetaAngle (appf,acc_ante,ox_a,h_don) gamm_ang = getGammaAngle(appf,acc_ante,ox_a,h_don) #PUT DATA INTO COLUMN DATA STRUCTURES # print ssindex #towrite = ",".join([str(h_don.getResnum()),str(h_don.getCoords())]) #fp.write(towrite+"\r\n") NUM_H_BONDS[ssindex] += 1 COLUMN_D_ON [ssindex].append(da_dist) COLUMN_D_OH [ssindex].append(ha_dist) COLUMN_A_NHO [ssindex].append(dha_ang) COLUMN_A_HOC [ssindex].append(haa_ang) COLUMN_BETA [ssindex].append(beta_ang) COLUMN_GAMMA [ssindex].append(gamm_ang) return
def iter_ca_hbonds_don(self, parsed_pdb): for hbond in self.iter_ca_triplets_don(parsed_pdb): angle = pr.calcAngle(hbond[0], hbond[1], hbond[2]) if angle > 90: distance_acc_hyd = pr.calcDistance(hbond[0], hbond[1]) distance_heavy = pr.calcDistance(hbond[0], hbond[2]) yield hbond, angle, distance_acc_hyd, distance_heavy
def check_h_bond_cond_accomplished(acceptors, donors, hbond_cutoff=2.5, angle_cutoff=130): hbonds = [] for acceptor in acceptors: acceptor_name = acceptor.getNames()[0] acceptor_id = acceptor.getResnums()[0] acceptor_resname = acceptor.getResnames()[0] if len(acceptor) > 1: acceptor = acceptor[0] acceptor_name = acceptor.getName() acceptor_id = acceptor.getResnum() acceptor_resname = acceptor.getResname() for donor in donors: triplet = acceptor + donor h_at_distance = triplet.select( "hydrogen within {} of name {}".format(hbond_cutoff, acceptor_name)) try: name_h = h_at_distance.getNames()[0] id_h = h_at_distance.getResnums()[0] id_resname = h_at_distance.getResnames()[0] triplet_sorted = sort_triplet(triplet) angle = prody.calcAngle(triplet_sorted[0], triplet_sorted[1], triplet_sorted[2]) if abs(angle) > angle_cutoff: print("H-bond detected between {}{}-{} and {}{}-{}".format( acceptor_id, acceptor_resname, acceptor_name, id_h, id_resname, name_h)) hbonds.append(triplet_sorted) except AttributeError: pass return hbonds
def check_hbond_angles(acc_hyd_don_list): newlist = [] for triplet in acc_hyd_don_list: acc, hyd, don = triplet angle = pr.calcAngle(acc, hyd, don) if angle > 90: newlist.append(triplet) return newlist
def set_contacts(self, calpha_distance=10.5): """Sets contacts between surface residues. A contact is by default defined as a pair of C alpha atoms with a distance less than 10 angstroms.""" self.nbrs_f = pr.findNeighbors(self.surf_sel_f, calpha_distance) self.nbrs_r = pr.findNeighbors(self.surf_sel_r, calpha_distance) self.contacts_f = list() for nbr in self.nbrs_f: resnum_0 = nbr[0].getResnum() resnum_1 = nbr[1].getResnum() filter = True if np.abs(resnum_0 - resnum_1) > 6: resind_0 = nbr[0].getResindex() resind_1 = nbr[1].getResindex() ca_0 = nbr[0] cb_0 = self.pdb_f.select('name CB and resindex ' + str(resind_0)) ca_1 = nbr[1] cb_1 = self.pdb_f.select('name CB and resindex ' + str(resind_1)) ang1 = pr.calcAngle(ca_0, cb_0, cb_1) ang2 = pr.calcAngle(ca_1, cb_1, cb_0) if (ang1 < 80) or (ang2 < 80): filter = False if filter: self.contacts_f.append((resnum_0, resnum_1)) self.contacts_r = list() for nbr in self.nbrs_r: resnum_0 = nbr[0].getResnum() resnum_1 = nbr[1].getResnum() filter = True if np.abs(resnum_0 - resnum_1) > 6: resind_0 = nbr[0].getResindex() resind_1 = nbr[1].getResindex() ca_0 = nbr[0] cb_0 = self.pdb_r.select('name CB and resindex ' + str(resind_0)) ca_1 = nbr[1] cb_1 = self.pdb_r.select('name CB and resindex ' + str(resind_1)) ang1 = pr.calcAngle(ca_0, cb_0, cb_1) ang2 = pr.calcAngle(ca_1, cb_1, cb_0) if (ang1 < 80) or (ang2 < 80): filter = False if filter: self.contacts_r.append((resnum_0, resnum_1))
def safecalcAngle(a, b, c, radian): """Calculates the angle between 3 coordinates. If any of them are missing, the function raises a MissingAtomsError. """ try: angle = pr.calcAngle(a, b, c, radian=radian)[0] except ValueError as e: raise MissingAtomsError from e return angle
def calculate_hbond(pdbfilename): ''' Geometric criteria of hbond identification given by paper: Protein Eng. 15 (2002) 359. D2-D1-D-H...A-A1 Rule 1: D-A < 3.9 A; Rule 2: H-A < 2.5 A; Rule 3: D-H-A > 90.0 degree; Rule 4: A1-A-D > 90.0 degree; Rule 5: A1-A-H > 90.0 degree. 0,1,2 for each residue (only consider backbone-backbone hbond) In rare cases, nhbond = 3: bifurcated hbond ''' # calculate H-bond import prody structure = prody.parsePDB(pdbfilename) protein = structure.select('protein') hv = protein.getHierView() nres = len([s for s in protein.select('name CA').getResnames()]) NHbond = np.zeros(nres,dtype=int) CObond = np.zeros(nres,dtype=int) nhbond = np.zeros(nres,dtype=int) resTyp = ['' for i in range(nres)] for i, res in enumerate(hv.iterResidues()): resIndex = i resNum = res.getResnum() resTyp[resIndex] = res.getResname() resChainIndex = res.getChid() N = res.select('name N') C = res.select('name C') O = res.select('name O') HN = res.select('name HN') # N-HN for k,res2 in enumerate(hv.iterResidues()): if res2.getResindex() != resIndex: AO = res2.select('name O') if (HN != None) and (AO != None) and (prody.calcDistance(N,AO) <= 3.9): if prody.calcDistance(HN,AO) <= 2.5: # dist_H_O_check if prody.calcAngle(N,HN,AO) > 90: # angle_N_HN_O_check: AC = res2.select('name C') if prody.calcAngle(AC,AO,N) > 90: # angle_C_O_N_check if prody.calcAngle(AC,AO,HN) > 90: # angle_C_O_HN_check NHbond[resIndex] += 1 if NHbond[resIndex] == 1: break # if NHbond[resIndex] == 1 (max), break # C=O for k,res2 in enumerate(hv.iterResidues()): if res2.getResindex() != resIndex: DHN = res2.select('name HN') if (DHN != None) and (O != None) and (prody.calcDistance(DHN,O) <= 2.5): DN = res2.select('name N') if prody.calcDistance(DN,O) <= 3.9: # dist_N_O_check if prody.calcAngle(DN,DHN,O) > 90: # angle_N_HN_O_check if prody.calcAngle(C,O,DN) > 90: # angle_C_O_N_check_ if prody.calcAngle(C,O,DHN) > 90: # angle_C_O_HN_check CObond[resIndex] += 1 if CObond[resIndex] == 2: break # if CObond[resIndex] == 2 (max), break # total nhbond hbond = NHbond+CObond return NHbond, np.where((NHbond == 0)), CObond, np.where((CObond == 0)), resTyp
def CheckMetalsCoordination(structure): """ A function to detect the metal atoms that could be coordinated with the protein. :param structure: :return: """ selection_pattern = "(within 3 of metal) and (not resnum {}) and (not hydrogen) and (not carbon)" coordinated_metals = {} for metal in supported_metals: if structure.select('resname {}'.format(metal)) is not None: print(" * Checking the metals that can be coordinated. (" \ "a constraint should be used if they're really coordinated)") for metal_res in structure.select( 'resname {}'.format(metal)).copy().iterResidues(): coordinated_atoms_list = [] if metal_res.numAtoms() != 1: continue coordinated_atoms = structure.select(selection_pattern.format( metal_res.getResnum()), metal=metal_res) if coordinated_atoms is None: print( " * The metal atom {} isn't coordinated with the protein. Are you sure it's necessary?" ) else: prev_atom = None for at in coordinated_atoms.iterAtoms(): if prev_atom is None: coordinated_atoms_list.append(at) prev_atom = at else: if at.getResnum() == prev_atom.getResnum() and \ (at.getIndex() == prev_atom.getIndex() + 1 or at.getResname() in ['ASP', 'GLU']): if calcDistance(at, metal_res) > calcDistance( prev_atom, metal_res): prev_atom = None continue else: coordinated_atoms_list.pop(-1) coordinated_atoms_list.append(at) prev_atom = at coordinated_metals[ metal_res] = coordinated_atoms_list #, 'angles': angles} coordinated_atoms_ids = {} if coordinated_metals: for metal, atoms_list in coordinated_metals.iteritems(): metal_id = "{} {} {}".format(metal.getResname(), metal.getChid(), metal.getResnum()) atoms_ids = [[ "{} {} {} {}".format(at.getResnum(), at.getResname(), at.getChid(), at.getName()), calcDistance(metal, at)[0] ] for at in atoms_list] if len(atoms_list) in [ x[1] for x in coordination_geometries.itervalues() ]: coordinated_atoms_ids[metal_id] = atoms_ids print(" * The metal atom {0} has the following atoms within coordination " \ "distance:\n{1}".format(metal_id, "\n".join([' * {0}'.format(x[0]) for x in atoms_ids]))) angles = [[at, metal, at2, calcAngle(at, metal, at2)[0]] for idx, at in enumerate(atoms_list) for at2 in atoms_list[idx + 1:]] if len(atoms_list) <= 4: print( " * Checking for a tetrahedric coordination for the atom." ) found_conformation = CheckConformation(angles, 'tetrahedric') if not found_conformation: print( " * WARNING: The angles are too distorted to ascertain this configuration. CHECK IT manually" ) elif 4 < len(atoms_list) <= 6: #or not found_conformation: print( " * WARNING: Checking for an octahedric coordination for the atom." ) found_conformation = CheckConformation(angles, 'octahedric') if not found_conformation: print( " * The angles are too distorted to ascertain this configuration. CHECK IT manually" ) else: print( " * The metal doesn't have a coordination we can validate." ) else: print(" * There are no coordinated metals.") return coordinated_metals
def runThrough(pfile): appf = pr.parsePDB(pfile, model=1, secondary=True, chain='A', altLoc=False) # get secondary structure by aParsedPDBfile[i].getSecstr() nitrox_don = appf.select('element N O') #O can be donor in rare cases, the paper uses this convention oxygen_acc = appf.select('element O') fp = open('old-H.txt','wb') for no_d in nitrox_don: n_secStruct = getSSIndex(no_d) if(n_secStruct < 0): continue for ox_a in oxygen_acc: o_secStruct = getSSIndex(ox_a) if(o_secStruct != n_secStruct): continue #1 Dist(don, acc) < 3.5 da_dist = pr.calcDistance( no_d , ox_a ) if( da_dist >= DONOR_ACCEPTOR_MAXDISTANCE ): continue #2 Dist(h_don, acc) < 3.5 h_don = getHforAtom( appf, no_d ) #Get h_don ha_dist = pr.calcDistance(h_don, ox_a) if( ha_dist >= HYDROGEN_ACCEPTOR_MAXDISTANCE): continue #3 Angle(don, h_don, acc) > 90 dha_ang = pr.calcAngle( no_d, h_don, ox_a ) if( dha_ang < DHA_ANGLE ): continue #4 Angle(don, acc, acc_ante) > 90 acc_ante = getAntecedent(appf, ox_a) #Get acc_ante daa_ang = pr.calcAngle( no_d, ox_a, acc_ante) if( daa_ang < DAB_ANGLE ): continue #5 Angle(h_don, acc, acc_ante) > 90 haa_ang = pr.calcAngle( h_don, ox_a, acc_ante ) if( haa_ang < HAB_ANGLE ): continue #We have a valid H-Bond with no_d, ox_a, h_don # print 'HBond elements', h_don.getName(), no_d.getName(), ox_a.getName() # print 'DA dist', da_dist # print 'HA dist', ha_dist # print 'DHA ang', dha_ang # print 'DAA ang', daa_ang # print 'HAA ang', haa_ang #place holders for beta and gamma for now # beta_ang = 0 # gamm_ang = 0 beta_ang = getBetaAngle (appf,acc_ante,ox_a,h_don) gamm_ang = getGammaAngle(appf,acc_ante,ox_a,h_don) #PUT DATA INTO COLUMN DATA STRUCTURES ssindex = getSSIndex(acc_ante) #if (ssindex == -1): #Not a structure we need # continue towrite = ",".join([str(h_don.getResnum()),str(h_don.getCoords())]) fp.write(towrite+"\r\n") COLUMN_D_ON [ssindex].append(da_dist) COLUMN_D_OH [ssindex].append(ha_dist) COLUMN_A_NHO [ssindex].append(dha_ang) COLUMN_A_HOC [ssindex].append(haa_ang) COLUMN_BETA [ssindex].append(beta_ang) COLUMN_GAMMA [ssindex].append(gamm_ang) fp.close() COLUMN_D_ON_AV = [sum(x)/len(x) for x in COLUMN_D_ON if len(x) > 0] COLUMN_D_OH_AV = [sum(x)/len(x) for x in COLUMN_D_OH if len(x) > 0] COLUMN_A_NHO_AV = [sum(x)/len(x) for x in COLUMN_A_NHO if len(x) > 0] COLUMN_A_HOC_AV = [sum(x)/len(x) for x in COLUMN_A_HOC if len(x) > 0] COLUMN_BETA_AV = [sum(x)/len(x) for x in COLUMN_BETA if len(x) > 0] COLUMN_GAMMA_AV = [sum(x)/len(x) for x in COLUMN_GAMMA if len(x) > 0] TABLE = [COLUMN_D_ON_AV, COLUMN_D_OH_AV, COLUMN_A_NHO_AV, COLUMN_A_HOC_AV, COLUMN_BETA_AV, COLUMN_GAMMA_AV] print ' D_ON D_OH ANGLE(NHO) ANGLE(HOC) BETA GAMMA ' print np.array(TABLE).T
def get_ang2(vdm, ifg, comb): return pr.calcAngle( vdm.ires_sele.select('name ' + ang2[vdm.resname][0]), ifg.sele.select('name ' + comb.vandarotamer_dict['A1']), ifg.sele.select('name ' + comb.vandarotamer_dict['A2']))[0]
def process(self, args=None): if not args: args = self.args # Sfn = args['Sfn'] # Open matrix file in parallel mode # Sf = h5py.File(Sfn, 'r') args['mpi'] = self.mpi extractor = er.PepExtractor(**args) lM = len(self.aplist) dtype = np.dtype([ ('name', 'S10'), ('pnum', '<i4'), ('rnum', '<i4'), ('dist', '<f8'), ('hdist1', '<f8'), ('hdist2', '<f8'), ('BD', '<f8'), ('FL', '<f8'), ('AT', '<f8'), ('dir', 'S3'), ('aln', 'S20') ]) if self.mpi.rank == 0: m = self.aplist[0] lm = len(m) S = extractor.extract_result(m) lS = S.numCoordsets() Sf = h5py.File(args['out'], 'w') out = Sf.create_dataset( 'out', (len(self.plist) * lS * lm, ), dtype=dtype) Sf.close() self.mpi.comm.Barrier() Sf = h5py.File(args['out'], 'r+', driver='mpio', comm=self.mpi.comm) out = Sf['out'] # Init storage for matrices # Get file name # tSfn = 'tmp.' + Sfn # tSfn = args['output'] # stubs = { # 'ACE': 'X', # 'NME': 'Z', # } a = prody.parsePDB(args['receptor']) OG = a.select('resnum 151 name SG') Ob = a.select('resnum 168 and name O') ND1 = a.select('resnum 46 and name NE2') OXH = a.select("name N resnum 149 150 151") t0 = time.time() for cm in range(lM): m = self.aplist[cm] lm = len(m) t1 = time.time() dt = t1 - t0 t0 = t1 print('STEP: %d PERCENT: %.2f%% TIME: %s' % ( cm, float(cm) / lM * 100, dt)) try: S = extractor.extract_result(m) except: print('ERROR: BAD PEPTIDE: %s' % m) continue lS = S.numCoordsets() for S_ in range(lS): S.setACSIndex(S_) tC = S.select('name C') dist = np.inf rnum = None for C in tC.iterAtoms(): rnum = C.getResnum() if rnum == 1: continue O = S.select('resnum %i and name O' % rnum) Nl = S.select('resnum %i and name N' % (rnum)) N = S.select('resnum %i and name N' % (rnum + 1)) C_ = C.getCoords() O_ = O.getCoords()[0] N_ = N.getCoords()[0] dist = prody.calcDistance(C, OG)[0] hdist1 = np.min(prody.calcDistance(OXH, O)) hdist2 = np.min(prody.calcDistance(Ob, Nl)) nC_ = np.cross((C_ - N_), (O_ - C_)) nC_ /= np.linalg.norm(nC_) nC_ = nC_ + C_ nC_ = nC_.reshape(1, 3) nC = C.copy() nC.setCoords(nC_) BD = prody.calcAngle(OG, C, O) FL = prody.calcDihedral(OG, nC, C, O) AT = prody.calcAngle(ND1, OG, C) angle_ = prody.calcDihedral(ND1, OG, C, N) # angle_ = prody.calcDistance(Od, N)[0] \ # - prody.calcDistance(Od, C)[0] if angle_ < 0: DIR = 'F' else: DIR = 'R' s = 'X' + m + 'Z' pref = '' if DIR == 'F': seq = s pref = 6 - rnum else: seq = s[::-1] pref = rnum suf = 12 - (pref + len(seq)) seq = '-' * pref + seq + '-' * suf # outfmt = "%-10s\t%d\t%6.2f\t%6.2f%6.2f\t%6.2f\t" \ # "%6.2f\t%6.2f\t%3s\t%12s\n" # outstr = outfmt % ( # ('%s_%02d' % (m, S_ + 1), # rnum, dist, hdist1, hdist2, BD, FL, AT, # DIR, seq) # ) outdata = (m, S_ + 1, rnum, dist, hdist1, hdist2, BD, FL, AT, DIR, seq) ind = (self.tb + cm) * lS * lm + S_ * lm + rnum - 2 out[ind] = outdata self.database.close() Sf.close()
def process(args): # Sfn = args['Sfn'] # Open matrix file in parallel mode # Sf = h5py.File(Sfn, 'r') extractor = er.PepExtractor(**args) lM = len(extractor.plist) # Init storage for matrices # Get file name # tSfn = 'tmp.' + Sfn # tSfn = args['output'] stubs = { 'ACE': 'X', 'NME': 'Z', } a = prody.parsePDB(args['receptor']) SG = a.select('resnum 241 name OG') O = a.select('resnum 262 and name O') ND1 = a.select('resnum 79 and name NE2') tHN_ = a.select("name N resnum 239 240 241") tHN = np.average(tHN_.getCoords(), axis=0) t0 = time.time() out = open(args['out'], 'w') for cm in range(lM): m = extractor.plist[cm] t1 = time.time() dt = t1 - t0 t0 = t1 print('STEP: %d PERCENT: %.2f%% TIME: %s' % ( cm, float(cm) / lM * 100, dt)) try: S = extractor.extract_result(m) except: print('ERROR: BAD PEPTIDE: %s' % m) continue lS = S.numCoordsets() for S_ in range(lS): S.setACSIndex(S_) tC = S.select('name C') dist = np.inf for c in tC.iterAtoms(): dist_ = prody.calcDistance(c, SG)[0] if dist_ < dist: dist = dist_ rnum = c.getResnum() C = S.select('resnum %i and name C' % rnum) CO = S.select('resnum %i and name O' % rnum) # N = S.select('resnum %i and name N' % rnum_) N_ = S.select('resnum %i and name N' % (rnum + 1)) angleAttack = prody.calcAngle(ND1, SG, C) angle_ = prody.calcDistance(O, N_)[0] - prody.calcDistance(O, C)[0] if angle_ > 0: DIR = 'F' else: DIR = 'R' s = 'X' + m + 'Z' pref = '' if DIR == 'F': seq = s pref = 5 - rnum else: seq = s[::-1] pref = rnum suf = 10 - (pref + len(seq)) seq = '-' * pref + seq + '-' * suf # hangle = prody.calcAngle(tHN, C, N) hdist = np.linalg.norm(tHN - CO.getCoords()) # HN = b.select('resnum %i and name H' % rnum) # N_B = b.select('resnum %i and name N' % (rnum + 1)) # HN_B = b.select('resnum %i and name H' % (rnum + 1)) # distN = prody.calcDistance(O, N)[0] # angleHN = prody.calcAngle(O, HN, N) # distN_B = prody.calcDistance(O, N_B)[0] # angleHN_B = prody.calcAngle(O, HN_B, N_B) outstr = "%-10s\t%6.2f\t%6.2f\t%6.2f\t%3s\t%12s\t%d\n" % ( ('%s_%02d' % (m, S_ + 1), dist, angleAttack, hdist, # distN, angleHN, # distN_B, angleHN_B, DIR, seq, rnum) ) out.write(outstr) # tSf.close() # Sf.close() # os.remove(tSfn) out.close()