Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #3
0
 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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
 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
Beispiel #7
0
def run_WI_pKa_calc(pdbfile, mutated_res, pKarun_params, do_matrix=None):
    """
    # Calculates the desolvation energy, the background interaction energy and all matrix interactions for
    # a single residue (mutated_res) which is given in the form :0000:RES (e.g. :0035:GLU)
    """
    # Create a temp dir
    #
    import tempfile, os, string
    tempfile.tempdir = os.getcwd()
    dirname = tempfile.mkdtemp(dir='/tmp')
    topdir = os.getcwd()
    os.chdir(dirname)
    if os.environ.has_key('HOSTNAME'):
        print 'Running pKa calculations in ', dirname, 'on', os.environ[
            'HOSTNAME']
    import sys
    sys.stdout.flush()
    #
    # Get pdbfile, topology.h and the charge files
    #
    # Are the files present in the pwd?
    #
    import os, shutil
    for filename in ['TOPOLOGY.H', 'DELRAD.DAT', 'DELCRG.DAT']:
        full_name = os.path.join(topdir, filename)
        destination = os.path.join(dirname, filename)
        if os.path.isfile(full_name):
            shutil.copyfile(full_name, destination)
    #
    # ----
    # Copy the pdb file
    #
    shutil.copyfile(pdbfile,
                    os.path.join(os.getcwd(),
                                 os.path.split(pdbfile)[1]))
    #
    # Find out which group we want to calculate for
    #
    group = None
    import pKarun
    Y = pKarun.pKa_general.pKatools()
    group_list = Y.get_titratable_residues(pdbfile)
    group = []
    for residue, groupnum in group_list:
        if mutated_res == residue:
            group.append(str(groupnum))
    #
    if len(group) == 1:
        #
        # For HIS it seems that we get erratic results for the background interaction energy if the calcs
        # are for only one residue. We therefore add the two previous groups to give more Hbond opt sampling
        #
        if mutated_res.find('HIS') != -1:
            onlygroup = int(group[0])
            if onlygroup > 1:
                group = ['%d' % (onlygroup - 1)] + group
            if onlygroup > 2:
                group = ['%d' % (onlygroup - 2)] + group
    if group == []:
        if mutated_res.split(':')[-1] == 'CYS':
            # Probably a new SS bridge formed..
            return 'SS-bridge', 'SS-bridge'
        raise Exception(
            'Could not find WHAT IF group number for mutated residue: %s' %
            mutated_res)
    #
    # Add this to the parameters
    #
    pKarun_params['subset'] = 1
    pKarun_params['groups'] = string.join(group, ',')
    #
    # Link the pdb file
    #
    pdbfile = os.path.join(topdir, pdbfile)
    #
    # Start the pKa calculation
    #
    X = None
    import pKarun, os
    X = pKarun.pKarun_base.pKarun(os.getcwd(), pdbfile, pKarun_params)
    IO = pKaTool.pKaIO.pKaIO()
    X.clean()
    #
    # Are we do to do a matric calculation or a desolv/backgr calculation?
    #
    if not do_matrix:
        try:
            X.desolv(1)
            desolv = IO.read_desolv(X.desolvfile)
        except:
            desolv = None
        try:
            X.backgr(1)
            backgr = IO.read_backgr(X.backgrfile)
        except:
            backgr = None
    else:
        atomdata = X.matrix(1, style='pKD')
        matrix = IO.read_matrix(X.matrixfile)
        return matrix[mutated_res], atomdata
    #
    # If we cannot calculate one, then warn - this should be changed, and modelling optimised!
    #
    print 'D/B', desolv, backgr
    if desolv is None or backgr is None:
        print '\n\n\nWARNING: Modelling in pdbfile is imperfect - could not estimate intrinsic pKa or interactions\n\n\n'
        return 0.0, 0.0
    else:
        #
        # Check that pKa_IO got NTERM and CTERM right
        #
        if not desolv.has_key(mutated_res):
            import pKD_tools
            group_type = pKD_tools.get_titgroup_type_from_titgroup(mutated_res)
            restype = pKD_tools.get_restype_from_titgroup(mutated_res)
            resid = pKD_tools.get_resid_from_res(mutated_res)
            fixed = False
            if group_type == 'NTERM':
                newgroup = '%s:%s' % (resid, 'CTERM')
                if desolv.has_key(newgroup):
                    desolv[mutated_res] = desolv[newgroup]
                    del desolv[newgroup]
                    backgr[mutated_res] = backgr[newgroup]
                    del backgr[newgroup]
                    fixed = True
            elif group_type == 'CTERM':
                newgroup = '%s:%s' % (resid, 'NTERM')
                if desolv.has_key(newgroup):
                    desolv[mutated_res] = desolv[newgroup]
                    del desolv[newgroup]
                    backgr[mutated_res] = backgr[newgroup]
                    del backgr[newgroup]
                    fixed = True
            else:
                pass
            #
            # Did we fix it?
            #
            if not fixed:
                print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
                print 'Something went wrong in the desolv and backgr calcs - cannot find residue in desolv file'
                print
                desolv = None
                backgr = None
                raise Exception('This must not happen')
    #
    # Get the new pKa file
    #
    os.chdir(topdir)
    import pKarun.pKa_ostools as pKa_ostools
    pKa_ostools.rmr(dirname)
    print 'Returning', desolv, backgr
    return desolv, backgr
Beispiel #8
0
def run_WI_pKa_calc(pdbfile,mutated_res,pKarun_params,do_matrix=None):
    """
    # Calculates the desolvation energy, the background interaction energy and all matrix interactions for
    # a single residue (mutated_res) which is given in the form :0000:RES (e.g. :0035:GLU)
    """
    # Create a temp dir
    #
    import tempfile, os, string
    tempfile.tempdir=os.getcwd()
    dirname=tempfile.mkdtemp(dir='/tmp')
    topdir=os.getcwd()
    os.chdir(dirname)
    if os.environ.has_key('HOSTNAME'):
       print 'Running pKa calculations in ',dirname,'on',os.environ['HOSTNAME']
    import sys
    sys.stdout.flush()
    #
    # Get pdbfile, topology.h and the charge files
    #
    # Are the files present in the pwd?
    #
    import os, shutil
    for filename in ['TOPOLOGY.H','DELRAD.DAT','DELCRG.DAT']:
        full_name=os.path.join(topdir,filename)
        destination=os.path.join(dirname,filename)
        if os.path.isfile(full_name):
            shutil.copyfile(full_name,destination)
    #
    # ----
    # Copy the pdb file 
    #
    shutil.copyfile(pdbfile,os.path.join(os.getcwd(),os.path.split(pdbfile)[1]))
    #
    # Find out which group we want to calculate for
    #
    group=None
    import pKarun
    Y=pKarun.pKa_general.pKatools()
    group_list=Y.get_titratable_residues(pdbfile)
    group=[]
    for residue,groupnum in group_list:
        if mutated_res==residue:
            group.append(str(groupnum))
    #
    if len(group)==1:
        #
        # For HIS it seems that we get erratic results for the background interaction energy if the calcs
        # are for only one residue. We therefore add the two previous groups to give more Hbond opt sampling
        #
        if mutated_res.find('HIS')!=-1:
            onlygroup=int(group[0])
            if onlygroup>1:
                group=['%d' %(onlygroup-1)]+group
            if onlygroup>2:
                group=['%d' %(onlygroup-2)]+group
    if group==[]:
        if mutated_res.split(':')[-1]=='CYS':
            # Probably a new SS bridge formed..
            return 'SS-bridge','SS-bridge'
        raise Exception('Could not find WHAT IF group number for mutated residue: %s' %mutated_res)
    #
    # Add this to the parameters
    #            
    pKarun_params['subset']=1
    pKarun_params['groups']=string.join(group,',')
    #
    # Link the pdb file
    #
    pdbfile=os.path.join(topdir,pdbfile)
    #
    # Start the pKa calculation
    #
    X=None
    import pKarun, os
    X=pKarun.pKarun_base.pKarun(os.getcwd(),pdbfile,pKarun_params)
    IO=pKaTool.pKaIO.pKaIO()
    X.clean()
    #
    # Are we do to do a matric calculation or a desolv/backgr calculation?
    #
    if not do_matrix:
        try:
            X.desolv(1)
            desolv=IO.read_desolv(X.desolvfile)
        except:
            desolv=None
        try:
            X.backgr(1)
            backgr=IO.read_backgr(X.backgrfile)
        except:
            backgr=None
    else:
        atomdata=X.matrix(1,style='pKD')
        matrix=IO.read_matrix(X.matrixfile)
        return matrix[mutated_res],atomdata
    #
    # If we cannot calculate one, then warn - this should be changed, and modelling optimised!
    #
    print 'D/B',desolv,backgr
    if desolv is None or backgr is None:
        print '\n\n\nWARNING: Modelling in pdbfile is imperfect - could not estimate intrinsic pKa or interactions\n\n\n'
        return 0.0,0.0
    else:
        #
        # Check that pKa_IO got NTERM and CTERM right
        #
        if not desolv.has_key(mutated_res):
            import pKD_tools
            group_type=pKD_tools.get_titgroup_type_from_titgroup(mutated_res)
            restype=pKD_tools.get_restype_from_titgroup(mutated_res)
            resid=pKD_tools.get_resid_from_res(mutated_res)
            fixed=False
            if group_type=='NTERM':
                newgroup='%s:%s' %(resid,'CTERM')
                if desolv.has_key(newgroup):
                    desolv[mutated_res]=desolv[newgroup]
                    del desolv[newgroup]
                    backgr[mutated_res]=backgr[newgroup]
                    del backgr[newgroup]
                    fixed=True
            elif group_type=='CTERM':
                newgroup='%s:%s' %(resid,'NTERM')
                if desolv.has_key(newgroup):
                    desolv[mutated_res]=desolv[newgroup]
                    del desolv[newgroup]
                    backgr[mutated_res]=backgr[newgroup]
                    del backgr[newgroup]
                    fixed=True
            else:
                pass
            #
            # Did we fix it?
            #
            if not fixed:
                print '!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
                print 'Something went wrong in the desolv and backgr calcs - cannot find residue in desolv file'
                print                                                                     
                desolv=None
                backgr=None
                raise Exception('This must not happen')
    #
    # Get the new pKa file
    #
    os.chdir(topdir)
    import pKarun.pKa_ostools as pKa_ostools
    pKa_ostools.rmr(dirname)
    print 'Returning',desolv,backgr
    return desolv, backgr