def otherinteractions(resdict, residuechoice, protein, ligand, backboneatomlist): for residue in OBResidueIter(protein): residuename = residue.GetName() if residuename in residuechoice: for atom in OBResidueAtomIter(residue): if not atom.IsHydrogen(): for atomlig in OBMolAtomIter(ligand): if not atomlig.IsHydrogen(): distance = atom.GetDistance(atomlig) if distance <= 4.5: if isnonpolar(atomlig) & isnonpolar(atom): #print "POLAR" resdict[residuename] |= bitarray('1000000') if distance <= 4.0: setformalcharge(atom, backboneatomlist) fakebbatomlist = [] setformalcharge(atomlig, fakebbatomlist) if (atom.GetFormalCharge() > 0) & ( atomlig.GetFormalCharge() < 0): #print "NEGATIVE" resdict[residuename] |= bitarray( '0000010') if (atom.GetFormalCharge() < 0) & ( atomlig.GetFormalCharge() > 0): #print "POSITIVE" resdict[residuename] |= bitarray( '0000001') if distance <= 3.5: if atom.IsHbondDonor( ) & atomlig.IsHbondAcceptor(): for neighborDon in OBAtomAtomIter( atom): if neighborDon.IsHydrogen(): angle = atom.GetAngle( neighborDon, atomlig) if angle > 135.0: resdict[ residuename] |= bitarray( '0001000') # donorresidue = atom.GetResidue() # for atomres in OBResidueAtomIter(donorresidue): # if atomres.IsHydrogen() & atomres.IsConnected(atom): # angle = atom.GetAngle(atomres, atomlig) # if angle>135.0: # resdict[residuename] |= bitarray('0001000') if atom.IsHbondAcceptor( ) & atomlig.IsHbondDonor(): for neighborDon in OBAtomAtomIter( atomlig): if neighborDon.IsHydrogen(): #print True angle = atomlig.GetAngle( neighborDon, atom) #print angle if angle > 135.0: #print "ACCEPTOR" resdict[ residuename] |= bitarray( '0000100')
def hbonddockprot(resdict, residuechoice, protein, ligand): for residue in OBResidueIter(protein): residuename = residue.GetName() if residuename in residuechoice: for atom in OBResidueAtomIter(residue): if not atom.IsHydrogen(): for atomlig in OBMolAtomIter(ligand): if not atomlig.IsHydrogen(): distance = atom.GetDistance(atomlig) if distance <= 3.5: if atom.IsHbondDonor( ) & atomlig.IsHbondAcceptor(): for neighborDon in OBAtomAtomIter(atom): if neighborDon.IsHydrogen(): angle = atom.GetAngle( neighborDon, atomlig) if angle > 135.0: resdict[ residuename] |= bitarray( '0001000') if atom.IsHbondAcceptor( ) & atomlig.IsHbondDonor(): for neighborDon in OBAtomAtomIter(atomlig): if neighborDon.IsHydrogen(): angle = atomlig.GetAngle( neighborDon, atom) if angle > 135.0: resdict[ residuename] |= bitarray( '0000100')
def hydrogen_nbrs(atom): ''' Returns an iterator over all hydrogens of an atom. Required to calculate hydrogen bonds. ''' for nbr in OBAtomAtomIter(atom): if nbr.IsHydrogen(): yield nbr
def neighbors(self): return [Atom(a) for a in OBAtomAtomIter(self.OBAtom)]
def otherinteractions2(resdict, residuechoice, protein, ligand, backboneatomlist): RigidHdonors = ['HIS', 'GLN', 'ASN', 'ARG', 'TRP'] for residue in OBResidueIter(protein): residuename = residue.GetName() if residuename in residuechoice: for atom in OBResidueAtomIter(residue): if not atom.IsHydrogen(): for atomlig in OBMolAtomIter(ligand): print atomlig if not atomlig.IsHydrogen(): distance = atom.GetDistance(atomlig) if distance <= 4.5: if isnonpolar(atomlig) & isnonpolar(atom): resdict[residuename] |= bitarray('1000000') if distance <= 4.0: setformalcharge(atom, backboneatomlist) fakebbatomlist = [] setformalcharge(atomlig, fakebbatomlist) if (atom.GetFormalCharge() > 0) & ( atomlig.GetFormalCharge() < 0): resdict[residuename] |= bitarray( '0000010') if (atom.GetFormalCharge() < 0) & ( atomlig.GetFormalCharge() > 0): resdict[residuename] |= bitarray( '0000001') if distance <= 3.5: if residuename[:3] in RigidHdonors: if atom.IsHbondDonor( ) & atomlig.IsHbondAcceptor(): for neighborDon in OBAtomAtomIter( atom): if neighborDon.IsHydrogen( ): angle = atom.GetAngle( neighborDon, atomlig) if angle > 135.0: resdict[ residuename] |= bitarray( '0001000') elif atom.GetIdx() in backboneatomlist: if atom.IsHbondDonor( ) & atomlig.IsHbondAcceptor(): for neighborDon in OBAtomAtomIter( atom): if neighborDon.IsHydrogen( ): angle = atom.GetAngle( neighborDon, atomlig) if angle > 135.0: resdict[ residuename] |= bitarray( '0001000') if atom.IsHbondAcceptor( ) & atomlig.IsHbondDonor(): for neighborDon in OBAtomAtomIter( atomlig): if neighborDon.IsHydrogen(): angle = atomlig.GetAngle( neighborDon, atom) if angle > 135.0: resdict[ residuename] |= bitarray( '0000100')
def otherinteractions(l_bit, l_res_choices, st_protein, st_lig, l_serial_atom_backbone): for residue in OBResidueIter(st_protein): residuename = residue.GetName() if residuename in l_res_choices: for atom in OBResidueAtomIter(residue): if not atom.IsHydrogen(): for atomlig in OBMolAtomIter(st_lig): if not atomlig.IsHydrogen(): distance = atom.GetDistance(atomlig) if distance <= 4.5: if isnonpolar(atomlig) & isnonpolar(atom): l_bit[residuename] |= bitarray('1000000') if distance <= 4.0: setformalcharge(atom, l_serial_atom_backbone) fakebbatomlist = [] setformalcharge(atomlig, fakebbatomlist) if (atom.GetFormalCharge() > 0) & ( atomlig.GetFormalCharge() < 0): l_bit[residuename] |= bitarray( '0000010') if (atom.GetFormalCharge() < 0) & ( atomlig.GetFormalCharge() > 0): l_bit[residuename] |= bitarray( '0000001') if distance <= 3.5: if atom.IsHbondDonor( ) & atomlig.IsHbondAcceptor(): for neighborDon in OBAtomAtomIter( atom): if neighborDon.IsHydrogen(): for neighborAcc in OBAtomAtomIter( atomlig): angle = neighborAcc.GetAngle( atomlig, neighborDon) if angle > 135.0: l_bit[ residuename] |= bitarray( '0001000') # donorresidue = atom.GetResidue() # for atomres in OBResidueAtomIter(donorresidue): # if atomres.IsHydrogen() & atomres.IsConnected(atom): # angle = atom.GetAngle(atomres, atomlig) # if angle>135.0: # l_bit[residuename] |= bitarray('0001000') if atom.IsHbondAcceptor( ) & atomlig.IsHbondDonor(): for neighborDon in OBAtomAtomIter( atomlig): if neighborDon.IsHydrogen(): for neighborAcc in OBAtomAtomIter( atom): angle = neighborAcc.GetAngle( atom, neighborDon) if angle > 135.0: l_bit[ residuename] |= bitarray( '0000100')
def load_data(self,scaffoldName,options={}): ''' This method loads the scaffold data from a cIdx file <scaffold name>.cIdx and scaffold name>.sdf Args: string scaffoldName: the name of the scaffold Raises: IOError ScaffoldNullPopularity ScaffoldCorrupted Example: load_data("s000000001") ''' verbose =options['verbose'] if options.has_key('verbose') else False debug =options['debug'] if options.has_key('debug') else False #------------ data directly loaded from NPSD without further processing ------------------------------ cIdxf=open(scaffoldName+".cIdx") # Processing the cIdx file Idx=0 configNumber=0 sidechainBlock=0 positionsNumber=0 position=-1 for line in cIdxf: if Idx==0: a=line.strip().split() self.name = a[0] self.popularity = int(a[1]) if not self.popularity: break Idx+=1 continue if Idx==1: a=line.strip().split() self.max_possible_weight = float(a[0]) self.min_possible_weight = float(a[1]) Idx+=1 continue if Idx==2: configNumber=float(line.strip().split()[0]) sidechainBlock=3+configNumber Idx+=1 continue if Idx>=3 and Idx<sidechainBlock: a=line.strip().split() nonHydrogenPositions=int(a[0]) self.configurations.append([int(x) for x in a[1:nonHydrogenPositions+1]]) Idx+=1 continue if Idx>=3 and Idx==sidechainBlock: self.scaffoldLength=int(line.split()[0]) for i in range(0,self.scaffoldLength): self.sidechainlist.append([]) Idx+=1 continue if Idx>=3 and Idx>sidechainBlock: a=line.strip().split('\t') if len(a)==2: #new position position =int(a[0]) sidechainsNumber =int(a[1]) else: self.sidechainlist[position].append([float(a[4]),float(a[3]),a[0]]) Idx+=1 continue Idx+=1 if position+1<self.scaffoldLength: raise ScaffoldCorrupted("Warning: some positions are missing: %d/%d. The file is probably corrupted." %(position+1,self.scaffoldLength)) if not self.popularity: cIdxf.close() raise ScaffoldNullPopularity("Warning: the popularity of this scaffold is 0.") # Loading the scaffold molecule (.sdf file) thanks to pybel self.structure = pybel.readfile("sdf",scaffoldName+".sdf").next() self.scaffold_weight_plus_hydrogens = self.structure.molwt #------------ data obtained by processing ----------------------------------------------------------- c=0 for conf in self.configurations: # we add hydrogens to be able to count them. Nevertheless it doesn't affect the molecular weight which always includes the hydrogens self.structure.OBMol.AddHydrogens() # \we compute the total number of hydrogens total_number_of_hydrogenes =0 for atom in [a for a in self.structure if not a.OBAtom.GetAtomicNum()==1]: if atom.idx-1 in conf: number_of_hydrogenes =len([x for x in OBAtomAtomIter(atom.OBAtom) if x.GetAtomicNum()==1]) total_number_of_hydrogenes +=number_of_hydrogenes # # \Dealing with the mass # we remove the hydrogens because we don't need them anymore self.structure.OBMol.DeleteHydrogens() # we compute the total mass of hydrogens at non hydrogen side chain positions total_hydrogene_mass = total_number_of_hydrogenes * 1.00794 # we compute the mass of the scaffold without the non hydrogen positions hs_weight =self.scaffold_weight_plus_hydrogens - total_hydrogene_mass self.scaffold_weight_rel2configs.append(hs_weight) # # \Dealing with the probability # the condition a.atomicnum>0 is to ensure that we don't count the "atoms" R# that are just used to number the positions on the scaffold hs_probabilities=[1] for atom in [ a for a in self.structure if not a.idx-1 in conf and a.atomicnum>0] : idx =atom.idx-1 # \now we find the hydrogen sidechain in the list and save its probability for sidechain in self.sidechainlist[idx]: smile =sidechain[2] probability =sidechain[1] original_smile = smile # if not H, that SMILE cannot be an hydrogen sidechain if 'H' in smile: for char in smiles_char: #removing all reserved characters from the SMILE. Only atom names remain smile =smile.replace(char,'') # \now we check that only H are present in the string, otherwise it is not a hydrogen side chain ishydrogen = True for char in smile: if not char=='H': ishydrogen=False # if ishydrogen: hs_probabilities.append(probability) # #//end for atom in [ a for a in self.structure if not a.idx-1 in conf and a.atomicnum>0] hs_cumulative_probability = reduce(mul,hs_probabilities) self.scaffold_probability_rel2configs.append(hs_cumulative_probability) c+=1 #//end for conf in self.configurations cIdxf.close() self.number_of_compounds=self.count_compounds()
def pication(rings, pos_charged, protcharged): """Return all pi-Cation interaction between aromatic rings and positively charged groups. For tertiary and quaternary amines, check also the angle between the ring and the nitrogen. """ data = namedtuple( 'pication', 'ring charge distance offset type restype resnr reschain restype_l resnr_l reschain_l protcharged' ) pairings = [] if len(rings) == 0 or len(pos_charged) == 0: return pairings for ring in rings: c = ring.center for p in pos_charged: d = euclidean3d(c, p.center) # Project the center of charge into the ring and measure distance to ring center proj = projection(ring.normal, ring.center, p.center) offset = euclidean3d(proj, ring.center) if not config.MIN_DIST < d < config.PICATION_DIST_MAX or not offset < config.PISTACK_OFFSET_MAX: continue if type(p).__name__ == 'lcharge' and p.fgroup == 'tertamine': # Special case here if the ligand has a tertiary amine, check an additional angle # Otherwise, we might have have a pi-cation interaction 'through' the ligand n_atoms = [ a_neighbor for a_neighbor in OBAtomAtomIter(p.atoms[0].OBAtom) ] n_atoms_coords = [(a.x(), a.y(), a.z()) for a in n_atoms] amine_normal = np.cross( vector(n_atoms_coords[0], n_atoms_coords[1]), vector(n_atoms_coords[2], n_atoms_coords[0])) b = vecangle(ring.normal, amine_normal) # Smallest of two angles, depending on direction of normal a = min(b, 180 - b if not 180 - b < 0 else b) if not a > 30.0: resnr, restype = whichresnumber( ring.atoms[0]), whichrestype(ring.atoms[0]) reschain = whichchain(ring.atoms[0]) resnr_l, restype_l = whichresnumber( p.orig_atoms[0]), whichrestype(p.orig_atoms[0]) reschain_l = whichchain(p.orig_atoms[0]) contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular', restype=restype, resnr=resnr, reschain=reschain, restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l, protcharged=protcharged) pairings.append(contact) break resnr = whichresnumber( p.atoms[0]) if protcharged else whichresnumber(ring.atoms[0]) resnr_l = whichresnumber( ring.orig_atoms[0]) if protcharged else whichresnumber( p.orig_atoms[0]) restype = whichrestype( p.atoms[0]) if protcharged else whichrestype(ring.atoms[0]) restype_l = whichrestype( ring.orig_atoms[0]) if protcharged else whichrestype( p.orig_atoms[0]) reschain = whichchain(p.atoms[0]) if protcharged else whichchain( ring.atoms[0]) reschain_l = whichchain( ring.orig_atoms[0]) if protcharged else whichchain( p.orig_atoms[0]) contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular', restype=restype, resnr=resnr, reschain=reschain, restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l, protcharged=protcharged) pairings.append(contact) return filter_contacts(pairings)
for residue in protein.residues: # if residue.OBResidue.GetAminoAcidProperty(8): # get hydrophobic aa for atom in residue: # get if residue.OBResidue.GetAminoAcidProperty( 8) and atom.atomicnum == 6: protein_hydrophobe.append(atom.coords) protein_hydrophobe_res.append( residue.name[:3] + str(residue.OBResidue.GetNum())) if atom.OBAtom.IsHbondDonor(): protein_donors.append(atom.coords) protein_donors_res.append(residue.name[:3] + str(residue.OBResidue.GetNum())) nbr = [] for nbr_atom in [ pybel.Atom(x) for x in OBAtomAtomIter(atom.OBAtom) ]: if not nbr_atom.OBAtom.IsHbondDonorH(): nbr.append(nbr_atom.coords) protein_donors_nbr.append(nbr) if atom.type in [ 'N3+', 'N2+', 'Ng+' ]: # types from mol2 and Chimera, ref: http://www.cgl.ucsf.edu/chimera/docs/UsersGuide/idatm.html protein_salt_plus.append(atom.coords) protein_salt_plus_res.append( residue.name[:3] + str(residue.OBResidue.GetNum())) if atom.OBAtom.IsHbondAcceptor(): protein_acceptors.append(atom.coords) protein_acceptors_res.append( residue.name[:3] + str(residue.OBResidue.GetNum())) nbr = []