def calc_matrix(self, group): """Calculate the charge-charge interaction matrix for a mutation""" # # Find the mutation # import pKD_tools resid = pKD_tools.get_resid_from_res(group) new_resname = pKD_tools.get_restype_from_titgroup(group) pdb_resname = self.parent.PI.resname(resid) if pdb_resname == new_resname or new_resname in [ 'CTERM', 'NTERM', None ]: return None, None, None mutation = '%s:%s:%s' % (resid, pdb_resname, new_resname) # # Calculate the matrix # import Design_pKa_help if self.parent.mutfile_names.has_key(mutation): newfilename = self.parent.mutfile_names[mutation] bump_score = 0.0 print 'Using PDB file:', newfilename else: newfilename, bump_score = Design_pKa_help.make_mutation( pdbfile=self.pdbfile, mutation=mutation, topdir=self.parent.topdir) if bump_score <= self.parent.params[ 'mutation_quality'] and not bump_score is False and not bump_score is None: # # Re-calculate # print 'Calculating matrix for %s' % mutation self.parent.close_stdout() matrix, atomdata = Design_pKa_help.run_WI_pKa_calc( pdbfile=newfilename, mutated_res='%s:%s' % (resid, new_resname), pKarun_params=self.parent.pKarun_params, do_matrix=True) self.parent.open_stdout() return matrix, atomdata, mutation else: return None, None, None
def calc_matrix(self,group): """Calculate the charge-charge interaction matrix for a mutation""" # # Find the mutation # import pKD_tools resid=pKD_tools.get_resid_from_res(group) new_resname=pKD_tools.get_restype_from_titgroup(group) pdb_resname=self.parent.PI.resname(resid) if pdb_resname==new_resname or new_resname in ['CTERM','NTERM',None]: return None,None,None mutation='%s:%s:%s' %(resid,pdb_resname,new_resname) # # Calculate the matrix # import Design_pKa_help if self.parent.mutfile_names.has_key(mutation): newfilename=self.parent.mutfile_names[mutation] bump_score=0.0 print 'Using PDB file:',newfilename else: newfilename,bump_score=Design_pKa_help.make_mutation(pdbfile=self.pdbfile,mutation=mutation,topdir=self.parent.topdir) if bump_score<=self.parent.params['mutation_quality'] and not bump_score is False and not bump_score is None: # # Re-calculate # print 'Calculating matrix for %s' %mutation self.parent.close_stdout() matrix,atomdata=Design_pKa_help.run_WI_pKa_calc(pdbfile=newfilename, mutated_res='%s:%s' %(resid,new_resname), pKarun_params=self.parent.pKarun_params, do_matrix=True) self.parent.open_stdout() return matrix,atomdata,mutation else: return None,None,None
def pdb2pka_sugelm(self): """Explore all possible mutations and calculate a phimap for each using pdb2pka (APBS)""" import Protool P=Protool.structureIO() P.readpdb(self.pdbfile) P.RemoveALT() #import Protool.mutate #MUT=Protool.mutate.Mutate(P) # # Construct arrays # import pKD_dict self.data=pKD_dict.pKD_dict() self.atom_data=pKD_dict.pKD_dict() # # Create dir for mutant PDB files # import os mutdir=os.path.join(self.topdir,self.pdbfile+'.pdbs') if not os.path.isdir(mutdir): os.mkdir(mutdir) # # Loop over all residues # residues=P.residues.keys() residues.sort() for residue in residues: orgres=P.resname(residue) print 'Calculating for %s %s' %(residue,P.resname(residue)) # # If neutral mutate to Asp, Glu, Lys, Arg, His # targets=[] for res in ['ARG','LYS','HIS','ASP','GLU']: if P.resname(residue)!=res: targets.append(res) #if orgres=='GLU': # targets.append('GLN') #elif orgres=='ASP': # targets.append('ASN') #elif orgres=='HIS': # targets.append('PHE') #elif orgres=='ARG' or P.resname(residue)=='LYS': # targets.append('MET') # # Target identified. Now model each # for target in targets: import pKD_tools resid=pKD_tools.get_resid_from_res(residue) orgres=P.resname(residue) filename=os.path.join(mutdir,'%s:%s:%s.pdb' %(residue,orgres,target)) mutation='%s:%s:%s' %(residue,orgres,target) if not os.path.isfile(filename): import Design_pKa_help Design_pKa_help.make_mutation(self.pdbfile,mutation) NP=Protool.structureIO() NP.readpdb(filename) NP.writepdb(filename,TER=None) # # Calculate the interaction energies # protein,routines,forcefield,apbs_setup,lig_titgrps = pdb2pka.pre_init(pdbfilename=filename, ff='parse', ligand=None, verbose=1) mypkaRoutines = pdb2pka.pKaRoutines(protein, routines, forcefield,apbs_setup) # # Find our group # sp=residue.split(':') chainid=sp[0] resnum=int(sp[1]) mypkaRoutines.findTitratableGroups() this_pKa=None for pKa in mypkaRoutines.pKas: print pKa.residue.resSeq,resnum print pKa.residue.chainID,chainid print pKa.residue.name,target print pKa.pKaGroup.name,target print '--------------' print 'ChainID',pKa.residue.chainID if pKa.residue.resSeq==resnum and pKa.residue.chainID==chainid and pKa.residue.name==target and pKa.pKaGroup.name==target: #print 'Found group',pKa.residue.resSeq,pKa.pKaGroup.name this_pKa=pKa break if not this_pKa: raise Exception,'Could not find inserted titratable group' mypkaRoutines.get_interaction_energies_setup(this_pKa,mode='pKD') matrix=mypkaRoutines.matrix # # Dig the interaction energies out of the pdb2pka array # for titration1 in matrix[this_pKa].keys(): for state1 in matrix[this_pKa][titration1].keys(): grp_sub=matrix[this_pKa][titration1][state1] if mypkaRoutines.is_charged(this_pKa,titration1,state1): for pKa2 in grp_sub.keys(): import string chainID2=pKa.residue.chainID resid2='%s:%s' %(chainID2,string.zfill(pKa2.residue.resSeq,4)) for titration2 in grp_sub[pKa2].keys(): for state2 in grp_sub[pKa2][titration2].keys(): if mypkaRoutines.is_charged(pKa2,titration2,state2): # # Both states are charged, so now we can pull the # interaction energies out # if not self.data.has_key(mutation): self.data[mutation]={} self.data[mutation][resid2]=grp_sub[pKa2][titration2][state2] # # Get the potentials at all atoms too # all_pots=mypkaRoutines.all_potentials[this_pKa][titration1][state1] sub_all_pots=all_pots[pKa2][titration2][state2] for atom in sub_all_pots.keys(): resid=mutation import pKD_tools resid2=pKD_tools.get_resid_from_res(atom) atomname=atom.split(':')[-1] #atom.name if atomname[0]=='H' or atomname in ['N','C','O']: continue # Skip all H atoms and all non-CA backbone atoms to save memory if not self.atom_data.has_key(resid): self.atom_data[resid]={} if not self.atom_data[resid].has_key(resid2): self.atom_data[resid][resid2]={} self.atom_data[resid][resid2][atomname]=abs(sub_all_pots[atom]) return self.data,self.atom_data
def add_mutations_to_matrix(self, mutations, target_array, source_array, source_atom_array): """ # Add the mutations in mutations to the matrix "target_array". # Find new interactions in source_array """ import string # # Store the wild type groups # wt_groups = target_array.keys() # # Make sure that we print something sensible # pr_mutations = [] for mut in mutations: if mut: pr_mutations.append(mut) if pr_mutations == []: pr_mutations = ['No mutations'] self.O._print( 'I am calculating for these mutations: ' + string.join(pr_mutations, '+') + '...', 4, 0) # # Now find the best solution # delete_groups = [] self.O._print('Phase I: Delete original residues if present in matrix', 4) for mutation in mutations: if mutation is None: continue # # Get the old titratable group # import pKD_tools resid = pKD_tools.get_resid_from_mut(mutation) new_residue = pKD_tools.get_newres_from_mut(mutation) for group in target_array.keys(): resid_titgroup = pKD_tools.get_resid_from_res(group) titgroup_type = pKD_tools.get_titgroup_type_from_titgroup( group) restype = pKD_tools.get_restype_from_titgroup(group) # # Delete if the residue was changed # if resid == resid_titgroup: #restype is None for CTERM and NTERM if restype != new_residue and restype: delete_groups.append(group) # # Look in all partner groups # for group2 in target_array[group].keys(): resid_titgroup = pKD_tools.get_resid_from_res(group2) titgroup_type = pKD_tools.get_titgroup_type_from_titgroup( group2) restype = pKD_tools.get_restype_from_titgroup(group2) if resid == resid_titgroup: if restype != new_residue and restype: delete_groups.append(group2) # # Delete, delete, delete # for group in delete_groups: if target_array.has_key(group): del target_array[group] for group in target_array.keys(): for group2 in delete_groups: if target_array[group].has_key(group2): del target_array[group][group2] # # Fill in the new values # self.O._print('Phase II: Add placeholders for new residues', 4) for mutation in mutations: if mutation: import pKD_tools newresidue = pKD_tools.get_newres_from_mut(mutation) if newresidue: # # Only include charged residues # if is_normally_titratable(newresidue): target_array[newresidue] = {} self.O._print('Added to matrix:' + newresidue, 4, tab=1) else: raise Exception, 'something is seriously wrong' # # Fill in the interactions # self.O._print('Phase III: Add all missing interactions...', 4) null = [0.0, 0.0, 0.0, 0.0] could_not_fill = [] import copy target_groups = target_array.keys() target_groups.sort() # # Start finding the interactions # import types self.O._print('Finding missing interactions for:', 4) for group in target_groups: self.O._print(group, 4, tab=1) for group2 in target_groups: if not target_array[group].has_key(group2): source_name1 = group source_name2 = group2 # # See if we can find an interaction # filled = None # # If we don't have the mutation in source array then check if we should make it # mutation_producing_group1 = self.get_source_array_entry( group, source_array, wt_groups) mutation_producing_group2 = self.get_source_array_entry( group2, source_array, wt_groups) for this_group, mut in [[group, mutation_producing_group1], [ group2, mutation_producing_group2 ]]: if mut == 'Missing': print 'Calculating matrix for', this_group matrix, atom_array, mutation = self.calc_matrix( this_group) if matrix == 'SS-bridge': return matrix, matrix if matrix and atom_array: rotq = source_array[mutation][ 'Rotamer quality'] source_array[mutation] = matrix source_array[mutation][ 'Rotamer quality'] = rotq source_atom_array[mutation] = atom_array mutation_producing_group1 = self.get_source_array_entry( group, source_array, wt_groups) mutation_producing_group2 = self.get_source_array_entry( group2, source_array, wt_groups) if not mutation_producing_group1 and not mutation_producing_group2: print 'This interaction should not be missing' print 'G1/G2', group, group2 raise Exception('Fatal error in code') # # Copy interaction to target[group][group2] # if source_array.has_key(mutation_producing_group1): if source_array[mutation_producing_group1].has_key( source_name2): source = source_array[mutation_producing_group1][ source_name2] if type(source) is types.FloatType: source = [source, 0.0, 0.0, 0.0] #print 'Converted source to list1' target_array[group][group2] = source filled = 1 elif source_array[mutation_producing_group1].has_key( group2): source = source_array[mutation_producing_group1][ group2] if type(source) is types.FloatType: source = [source, 0.0, 0.0, 0.0] #print 'Converted source to list2' target_array[group][group2] = source filled = 1 # # Copy interaction to target[group][group2] # if source_array.has_key( mutation_producing_group2) and not filled: if source_array[mutation_producing_group2].has_key( source_name1): source = source_array[mutation_producing_group2][ source_name1] if type(source) is types.FloatType: source = [source, 0.0, 0.0, 0.0] #print 'Converted source to list3' target_array[group][group2] = source filled = 1 elif source_array[mutation_producing_group2].has_key( group): source = source_array[mutation_producing_group2][ group] import types if type(source) is types.FloatType: source = [source, 0.0, 0.0, 0.0] #print 'Converted source to list4' target_array[group][group2] = source filled = 1 # # Maybe we can fill this interaction from the original matrix? # if mutation_producing_group1 is None and mutation_producing_group2 is None: if self.org_matrix.has_key(group): if self.org_matrix[group].has_key(source_name2): # # Org matrix has all values # target_array[group][group2] = copy.copy( self.org_matrix[group][source_name2]) filled = 1 # # Log interactions that could not be filled # if not filled and group != group2: could_not_fill.append([group, group2]) elif not filled and group == group2: # # set diagonal elements to null # target_array[group][group2] = null target_array[group2][group] = null # # ------------------------------------------------------------------------------ # # Fill unresolved interactions # self.O._print('\nPhase IV: Filling unresolved interactions', 4) for unresolved in could_not_fill: # # If we could not find an interaction energy in the residue-residue interaction data # then look for it in the atom_based array # group = unresolved[0] group2 = unresolved[1] import string filled = None mutation_producing_group1 = self.get_source_array_entry( group, source_atom_array, wt_groups) if source_atom_array.has_key( mutation_producing_group1) and not filled: # # Trying to find interaction [group][group22] # if group != group2: self.O._print('trying to fill from atomdata1', 4) import pKD_tools resid2 = pKD_tools.get_resid_from_res(group2) type1 = pKD_tools.get_titgroup_type_from_titgroup(group) type2 = pKD_tools.get_titgroup_type_from_titgroup(group2) if source_atom_array[mutation_producing_group1].has_key( resid2): energy = self.get_correct_energy( source_atom_array[mutation_producing_group1] [resid2], type1, type2) target_array[group][group2] = [energy, 0.0, 0.0, 0.0] self.O._print( 'Added energy %5.3f for %s and %s' % (energy, group, group2), 4) filled = 1 # # Array 2 # mutation_producing_group2 = self.get_source_array_entry( group2, source_atom_array, wt_groups) if source_atom_array.has_key( mutation_producing_group2) and not filled: # # Trying to find interaction [group2][group] # if group != group2: self.O._print('trying to fill from atomdata2', 4) import pKD_tools resid1 = pKD_tools.get_resid_from_res(group) type1 = pKD_tools.get_titgroup_type_from_titgroup(group) type2 = pKD_tools.get_titgroup_type_from_titgroup(group2) if source_atom_array[mutation_producing_group2].has_key( resid1): energy = self.get_correct_energy( source_atom_array[mutation_producing_group2] [resid1], type1, type2) target_array[group2][group] = [energy, 0.0, 0.0, 0.0] self.O._print( 'Added energy %5.3f for %s and %s' % (energy, group2, group), 4) filled = 1 # # Is it the same group? - if so then zero energy of course... # if group == group2: target_array[group][group] = [0.0, 0.0, 0.0, 0.0] filled = 1 # # If we could not fill an interaction then it's because we have # never calculated a phimap for the mutation # if not filled: newg1 = pKD_tools.get_newrestyp_from_mut( mutation_producing_group1) newg2 = pKD_tools.get_newrestyp_from_mut( mutation_producing_group2) if newg1 == 'CYS' or newg2 == 'CYS': return 'SS-bridge', 'SS-bridge' print 'Could not fill: %s-%s' % (group, group2) print print 'I cannot predict dpKa values for this mutation because modelling of one' print 'or more mutations produced bumps in the structure.' print 'If you want to allow bumps when modelling mutations, then adjust the value of ' print 'the mutation_quality parameter.' print 'The current maximum bump for a mutation is %5.3f' % ( self.parent.params['mutation_quality']) print print 'In a future version we will include a structure relaxation protocol that can be used to model' print '"difficult" mutations' print print 'Bump values for mutations in this run:' import Design_pKa_help for mutation in mutations: pdbfile, bump_value = Design_pKa_help.make_mutation( pdbfile=self.parent.pdbfile, mutation=mutation, topdir=self.parent.topdir) print '%10s, bump: %5.3f' % (mutation, bump_value) print raise Exception('Cannot model mutant %s' % mutation) # # Do another pass with delete groups to make sure we didn't fill in an interaction we shouldn't have # self.O._print( 'Phase V: Making sure that all unwanted groups have been deleted', 4) for group in delete_groups: if target_array.has_key(group): del target_array[group] for group in target_array.keys(): for group2 in delete_groups: if target_array[group].has_key(group2): del target_array[group][group2] # # Return results # self.O._print('Copying return arrays', 4) return target_array.copy(), delete_groups
def add_mutations_to_matrix(self,mutations,target_array,source_array,source_atom_array): """ # Add the mutations in mutations to the matrix "target_array". # Find new interactions in source_array """ import string # # Store the wild type groups # wt_groups=target_array.keys() # # Make sure that we print something sensible # pr_mutations=[] for mut in mutations: if mut: pr_mutations.append(mut) if pr_mutations==[]: pr_mutations=['No mutations'] self.O._print('I am calculating for these mutations: '+string.join(pr_mutations,'+')+'...',4,0) # # Now find the best solution # delete_groups=[] self.O._print('Phase I: Delete original residues if present in matrix',4) for mutation in mutations: if mutation is None: continue # # Get the old titratable group # import pKD_tools resid=pKD_tools.get_resid_from_mut(mutation) new_residue=pKD_tools.get_newres_from_mut(mutation) for group in target_array.keys(): resid_titgroup=pKD_tools.get_resid_from_res(group) titgroup_type=pKD_tools.get_titgroup_type_from_titgroup(group) restype=pKD_tools.get_restype_from_titgroup(group) # # Delete if the residue was changed # if resid==resid_titgroup: #restype is None for CTERM and NTERM if restype!=new_residue and restype: delete_groups.append(group) # # Look in all partner groups # for group2 in target_array[group].keys(): resid_titgroup=pKD_tools.get_resid_from_res(group2) titgroup_type=pKD_tools.get_titgroup_type_from_titgroup(group2) restype=pKD_tools.get_restype_from_titgroup(group2) if resid==resid_titgroup: if restype!=new_residue and restype: delete_groups.append(group2) # # Delete, delete, delete # for group in delete_groups: if target_array.has_key(group): del target_array[group] for group in target_array.keys(): for group2 in delete_groups: if target_array[group].has_key(group2): del target_array[group][group2] # # Fill in the new values # self.O._print('Phase II: Add placeholders for new residues',4) for mutation in mutations: if mutation: import pKD_tools newresidue=pKD_tools.get_newres_from_mut(mutation) if newresidue: # # Only include charged residues # if is_normally_titratable(newresidue): target_array[newresidue]={} self.O._print('Added to matrix:'+newresidue,4,tab=1) else: raise Exception,'something is seriously wrong' # # Fill in the interactions # self.O._print('Phase III: Add all missing interactions...',4) null=[0.0,0.0,0.0,0.0] could_not_fill=[] import copy target_groups=target_array.keys() target_groups.sort() # # Start finding the interactions # import types self.O._print('Finding missing interactions for:',4) for group in target_groups: self.O._print(group,4,tab=1) for group2 in target_groups: if not target_array[group].has_key(group2): source_name1=group source_name2=group2 # # See if we can find an interaction # filled=None # # If we don't have the mutation in source array then check if we should make it # mutation_producing_group1=self.get_source_array_entry(group,source_array,wt_groups) mutation_producing_group2=self.get_source_array_entry(group2,source_array,wt_groups) for this_group,mut in [[group,mutation_producing_group1],[group2,mutation_producing_group2]]: if mut=='Missing': print 'Calculating matrix for', this_group matrix,atom_array,mutation=self.calc_matrix(this_group) if matrix=='SS-bridge': return matrix,matrix if matrix and atom_array: rotq=source_array[mutation]['Rotamer quality'] source_array[mutation]=matrix source_array[mutation]['Rotamer quality']=rotq source_atom_array[mutation]=atom_array mutation_producing_group1=self.get_source_array_entry(group,source_array,wt_groups) mutation_producing_group2=self.get_source_array_entry(group2,source_array,wt_groups) if not mutation_producing_group1 and not mutation_producing_group2: print 'This interaction should not be missing' print 'G1/G2',group,group2 raise Exception('Fatal error in code') # # Copy interaction to target[group][group2] # if source_array.has_key(mutation_producing_group1): if source_array[mutation_producing_group1].has_key(source_name2): source=source_array[mutation_producing_group1][source_name2] if type(source) is types.FloatType: source=[source,0.0,0.0,0.0] #print 'Converted source to list1' target_array[group][group2]=source filled=1 elif source_array[mutation_producing_group1].has_key(group2): source=source_array[mutation_producing_group1][group2] if type(source) is types.FloatType: source=[source,0.0,0.0,0.0] #print 'Converted source to list2' target_array[group][group2]=source filled=1 # # Copy interaction to target[group][group2] # if source_array.has_key(mutation_producing_group2) and not filled: if source_array[mutation_producing_group2].has_key(source_name1): source=source_array[mutation_producing_group2][source_name1] if type(source) is types.FloatType: source=[source,0.0,0.0,0.0] #print 'Converted source to list3' target_array[group][group2]=source filled=1 elif source_array[mutation_producing_group2].has_key(group): source=source_array[mutation_producing_group2][group] import types if type(source) is types.FloatType: source=[source,0.0,0.0,0.0] #print 'Converted source to list4' target_array[group][group2]=source filled=1 # # Maybe we can fill this interaction from the original matrix? # if mutation_producing_group1 is None and mutation_producing_group2 is None: if self.org_matrix.has_key(group): if self.org_matrix[group].has_key(source_name2): # # Org matrix has all values # target_array[group][group2]=copy.copy( self.org_matrix[group][source_name2]) filled=1 # # Log interactions that could not be filled # if not filled and group!=group2: could_not_fill.append([group,group2]) elif not filled and group==group2: # # set diagonal elements to null # target_array[group][group2]=null target_array[group2][group]=null # # ------------------------------------------------------------------------------ # # Fill unresolved interactions # self.O._print('\nPhase IV: Filling unresolved interactions',4) for unresolved in could_not_fill: # # If we could not find an interaction energy in the residue-residue interaction data # then look for it in the atom_based array # group=unresolved[0] group2=unresolved[1] import string filled=None mutation_producing_group1=self.get_source_array_entry(group,source_atom_array,wt_groups) if source_atom_array.has_key(mutation_producing_group1) and not filled: # # Trying to find interaction [group][group22] # if group!=group2: self.O._print('trying to fill from atomdata1',4) import pKD_tools resid2=pKD_tools.get_resid_from_res(group2) type1=pKD_tools.get_titgroup_type_from_titgroup(group) type2=pKD_tools.get_titgroup_type_from_titgroup(group2) if source_atom_array[mutation_producing_group1].has_key(resid2): energy=self.get_correct_energy(source_atom_array [mutation_producing_group1][resid2],type1,type2) target_array[group][group2]=[energy,0.0,0.0,0.0] self.O._print('Added energy %5.3f for %s and %s' %(energy,group,group2),4) filled=1 # # Array 2 # mutation_producing_group2=self.get_source_array_entry(group2,source_atom_array,wt_groups) if source_atom_array.has_key(mutation_producing_group2) and not filled: # # Trying to find interaction [group2][group] # if group!=group2: self.O._print('trying to fill from atomdata2',4) import pKD_tools resid1=pKD_tools.get_resid_from_res(group) type1=pKD_tools.get_titgroup_type_from_titgroup(group) type2=pKD_tools.get_titgroup_type_from_titgroup(group2) if source_atom_array[mutation_producing_group2].has_key(resid1): energy=self.get_correct_energy(source_atom_array [mutation_producing_group2][resid1],type1,type2) target_array[group2][group]=[energy,0.0,0.0,0.0] self.O._print('Added energy %5.3f for %s and %s' %(energy,group2,group),4) filled=1 # # Is it the same group? - if so then zero energy of course... # if group==group2: target_array[group][group]=[0.0,0.0,0.0,0.0] filled=1 # # If we could not fill an interaction then it's because we have # never calculated a phimap for the mutation # if not filled: newg1=pKD_tools.get_newrestyp_from_mut(mutation_producing_group1) newg2=pKD_tools.get_newrestyp_from_mut(mutation_producing_group2) if newg1=='CYS' or newg2=='CYS': return 'SS-bridge','SS-bridge' print 'Could not fill: %s-%s' %(group,group2) print print 'I cannot predict dpKa values for this mutation because modelling of one' print 'or more mutations produced bumps in the structure.' print 'If you want to allow bumps when modelling mutations, then adjust the value of ' print 'the mutation_quality parameter.' print 'The current maximum bump for a mutation is %5.3f' %(self.parent.params['mutation_quality']) print print 'In a future version we will include a structure relaxation protocol that can be used to model' print '"difficult" mutations' print print 'Bump values for mutations in this run:' import Design_pKa_help for mutation in mutations: pdbfile,bump_value=Design_pKa_help.make_mutation(pdbfile=self.parent.pdbfile,mutation=mutation,topdir=self.parent.topdir) print '%10s, bump: %5.3f' %(mutation,bump_value) print raise Exception('Cannot model mutant %s' %mutation) # # Do another pass with delete groups to make sure we didn't fill in an interaction we shouldn't have # self.O._print('Phase V: Making sure that all unwanted groups have been deleted',4) for group in delete_groups: if target_array.has_key(group): del target_array[group] for group in target_array.keys(): for group2 in delete_groups: if target_array[group].has_key(group2): del target_array[group][group2] # # Return results # self.O._print('Copying return arrays',4) return target_array.copy(), delete_groups
def pdb2pka_sugelm(self): """Explore all possible mutations and calculate a phimap for each using pdb2pka (APBS)""" import Protool P = Protool.structureIO() P.readpdb(self.pdbfile) P.RemoveALT() #import Protool.mutate #MUT=Protool.mutate.Mutate(P) # # Construct arrays # import pKD_dict self.data = pKD_dict.pKD_dict() self.atom_data = pKD_dict.pKD_dict() # # Create dir for mutant PDB files # import os mutdir = os.path.join(self.topdir, self.pdbfile + '.pdbs') if not os.path.isdir(mutdir): os.mkdir(mutdir) # # Loop over all residues # residues = P.residues.keys() residues.sort() for residue in residues: orgres = P.resname(residue) print 'Calculating for %s %s' % (residue, P.resname(residue)) # # If neutral mutate to Asp, Glu, Lys, Arg, His # targets = [] for res in ['ARG', 'LYS', 'HIS', 'ASP', 'GLU']: if P.resname(residue) != res: targets.append(res) #if orgres=='GLU': # targets.append('GLN') #elif orgres=='ASP': # targets.append('ASN') #elif orgres=='HIS': # targets.append('PHE') #elif orgres=='ARG' or P.resname(residue)=='LYS': # targets.append('MET') # # Target identified. Now model each # for target in targets: import pKD_tools resid = pKD_tools.get_resid_from_res(residue) orgres = P.resname(residue) filename = os.path.join( mutdir, '%s:%s:%s.pdb' % (residue, orgres, target)) mutation = '%s:%s:%s' % (residue, orgres, target) if not os.path.isfile(filename): import Design_pKa_help Design_pKa_help.make_mutation(self.pdbfile, mutation) NP = Protool.structureIO() NP.readpdb(filename) NP.writepdb(filename, TER=None) # # Calculate the interaction energies # protein, routines, forcefield, apbs_setup, lig_titgrps = pdb2pka.pre_init( pdbfilename=filename, ff='parse', ligand=None, verbose=1) mypkaRoutines = pdb2pka.pKaRoutines(protein, routines, forcefield, apbs_setup) # # Find our group # sp = residue.split(':') chainid = sp[0] resnum = int(sp[1]) mypkaRoutines.findTitratableGroups() this_pKa = None for pKa in mypkaRoutines.pKas: print pKa.residue.resSeq, resnum print pKa.residue.chainID, chainid print pKa.residue.name, target print pKa.pKaGroup.name, target print '--------------' print 'ChainID', pKa.residue.chainID if pKa.residue.resSeq == resnum and pKa.residue.chainID == chainid and pKa.residue.name == target and pKa.pKaGroup.name == target: #print 'Found group',pKa.residue.resSeq,pKa.pKaGroup.name this_pKa = pKa break if not this_pKa: raise Exception, 'Could not find inserted titratable group' mypkaRoutines.get_interaction_energies_setup(this_pKa, mode='pKD') matrix = mypkaRoutines.matrix # # Dig the interaction energies out of the pdb2pka array # for titration1 in matrix[this_pKa].keys(): for state1 in matrix[this_pKa][titration1].keys(): grp_sub = matrix[this_pKa][titration1][state1] if mypkaRoutines.is_charged(this_pKa, titration1, state1): for pKa2 in grp_sub.keys(): import string chainID2 = pKa.residue.chainID resid2 = '%s:%s' % ( chainID2, string.zfill(pKa2.residue.resSeq, 4)) for titration2 in grp_sub[pKa2].keys(): for state2 in grp_sub[pKa2][ titration2].keys(): if mypkaRoutines.is_charged( pKa2, titration2, state2): # # Both states are charged, so now we can pull the # interaction energies out # if not self.data.has_key(mutation): self.data[mutation] = {} self.data[mutation][ resid2] = grp_sub[pKa2][ titration2][state2] # # Get the potentials at all atoms too # all_pots = mypkaRoutines.all_potentials[ this_pKa][titration1][state1] sub_all_pots = all_pots[pKa2][ titration2][state2] for atom in sub_all_pots.keys(): resid = mutation import pKD_tools resid2 = pKD_tools.get_resid_from_res( atom) atomname = atom.split(':')[ -1] #atom.name if atomname[ 0] == 'H' or atomname in [ 'N', 'C', 'O' ]: continue # Skip all H atoms and all non-CA backbone atoms to save memory if not self.atom_data.has_key( resid): self.atom_data[resid] = {} if not self.atom_data[ resid].has_key(resid2): self.atom_data[resid][ resid2] = {} self.atom_data[resid][resid2][ atomname] = abs( sub_all_pots[atom]) return self.data, self.atom_data