def get_desolv_and_backgr_mut(self,mutation,residue=None,measuring_mutated_residue=1): """ # Construct the mutation and get all energies """ import string if self.parent.mutfile_names.has_key(mutation): mutant_pdbfile=self.parent.mutfile_names[mutation] print 'Using this mutant PDB file:',mutant_pdbfile else: mutant_pdbfile,rotamer_quality=make_mutation(self.pdbfile,mutation,self.topdir) if not mutation: return None if not residue: import pKD_tools residue='%s:%s' %(pKD_tools.get_resid_from_mut(mutation),pKD_tools.get_newrestyp_from_mut(mutation)) return self.get_desolv_and_backgr(mutant_pdbfile,residue,measuring_mutated_residue)
def get_desolv_and_backgr_mut(self, mutation, residue=None, measuring_mutated_residue=1): """ # Construct the mutation and get all energies """ import string if self.parent.mutfile_names.has_key(mutation): mutant_pdbfile = self.parent.mutfile_names[mutation] print 'Using this mutant PDB file:', mutant_pdbfile else: mutant_pdbfile, rotamer_quality = make_mutation( self.pdbfile, mutation, self.topdir) if not mutation: return None if not residue: import pKD_tools residue = '%s:%s' % (pKD_tools.get_resid_from_mut(mutation), pKD_tools.get_newrestyp_from_mut(mutation)) return self.get_desolv_and_backgr(mutant_pdbfile, residue, measuring_mutated_residue)
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 make_mutation(pdbfile, mutation, topdir=None): """Model a mutation""" # # Adjust name of pdb file # import os pdbfile = os.path.join(os.getcwd(), pdbfile) if not os.path.isfile(pdbfile): print 'File not found: %s' % pdbfile raise Exception() # # Get the root dir from the pdb file name if it is not specified # if not topdir: split = os.path.split(pdbfile) rootdir = split[0] else: rootdir = topdir # # Make sure we have a dir created # import os dirname = os.path.join(rootdir, '%s.pdbs' % (os.path.split(pdbfile)[1])) if not os.path.exists(dirname): if os.path.lexists(dirname): os.unlink(dirname) os.mkdir(dirname) # # Is this a real mutation? # if not mutation: print 'Make_mutation got this mutation', mutation # # Have we produced this PDB file already? # newfilename = os.path.join(dirname, mutation + '.pdb') rotamer_quality_file = os.path.join(dirname, mutation + '_rotq') if os.path.isfile(newfilename) and os.path.isfile(rotamer_quality_file): # # Yes, just pass that filename and the rotamer quality # fd = open(rotamer_quality_file) rotamer_quality = float(fd.readline()) fd.close() return newfilename, rotamer_quality else: # # No :-(, make the mutation # import Protool, string X = Protool.structureIO() X.readpdb(pdbfile) results = {} # # find the real mutation # newresID = mutation import pKD_tools newres = pKD_tools.get_newrestyp_from_mut(mutation) oldres = pKD_tools.get_oldrestyp_from_mut(mutation) # # If this is not a real mutation, then just return the wt pdbfile # if oldres == newres: return pdbfile, 99.9 # # Import Protool and read the pdb file # import Protool P = Protool.structureIO() pdbfile = os.path.join(os.getcwd(), pdbfile) P.readpdb(pdbfile) # # Initialise the mutate routines # MUT.new_PDB(P) import pKD_tools resid = pKD_tools.get_resid_from_mut(mutation) bump_score = MUT.mutate(resid, newres, orgtype=oldres) if bump_score is None: bump_score = 9999999 # set to very high for impossible mutations # # Write the new file # P.writepdb(newfilename, style='whatif') # # Write the rotamer quality file # fd = open(rotamer_quality_file, 'w') fd.write('%5.3f\n' % bump_score) fd.close() print resid, oldres, '->', newres, 'bump score', bump_score return newfilename, bump_score
def make_mutation(pdbfile,mutation,topdir=None): """Model a mutation""" # # Adjust name of pdb file # import os pdbfile=os.path.join(os.getcwd(),pdbfile) if not os.path.isfile(pdbfile): print 'File not found: %s' %pdbfile raise Exception() # # Get the root dir from the pdb file name if it is not specified # if not topdir: split=os.path.split(pdbfile) rootdir=split[0] else: rootdir=topdir # # Make sure we have a dir created # import os dirname=os.path.join(rootdir,'%s.pdbs' %(os.path.split(pdbfile)[1])) if not os.path.exists(dirname): if os.path.lexists(dirname): os.unlink(dirname) os.mkdir(dirname) # # Is this a real mutation? # if not mutation: print 'Make_mutation got this mutation',mutation # # Have we produced this PDB file already? # newfilename=os.path.join(dirname,mutation+'.pdb') rotamer_quality_file=os.path.join(dirname,mutation+'_rotq') if os.path.isfile(newfilename) and os.path.isfile(rotamer_quality_file): # # Yes, just pass that filename and the rotamer quality # fd=open(rotamer_quality_file) rotamer_quality=float(fd.readline()) fd.close() return newfilename,rotamer_quality else: # # No :-(, make the mutation # import Protool, string X=Protool.structureIO() X.readpdb(pdbfile) results={} # # find the real mutation # newresID=mutation import pKD_tools newres=pKD_tools.get_newrestyp_from_mut(mutation) oldres=pKD_tools.get_oldrestyp_from_mut(mutation) # # If this is not a real mutation, then just return the wt pdbfile # if oldres==newres: return pdbfile, 99.9 # # Import Protool and read the pdb file # import Protool P=Protool.structureIO() pdbfile=os.path.join(os.getcwd(),pdbfile) P.readpdb(pdbfile) # # Initialise the mutate routines # MUT.new_PDB(P) import pKD_tools resid=pKD_tools.get_resid_from_mut(mutation) bump_score=MUT.mutate(resid,newres,orgtype=oldres) if bump_score is None: bump_score=9999999 # set to very high for impossible mutations # # Write the new file # P.writepdb(newfilename,style='whatif') # # Write the rotamer quality file # fd=open(rotamer_quality_file,'w') fd.write('%5.3f\n' %bump_score) fd.close() print resid,oldres,'->',newres,'bump score',bump_score return newfilename,bump_score