Ejemplo n.º 1
0
    def calc_MC_mut_pKas(self,
                         mutations=[],
                         data={},
                         atomdata={},
                         wt_pKas=[],
                         reporter_residues=[],
                         require_pKa=[],
                         for_tabulated=None):
        """
        Calculate pKa values for a mutant
        """
        #
        # Copy mutfile_names from parent
        #
        if hasattr(self.parent, 'mutfile_names'):
            self.mutfile_names = self.parent.mutfile_names.copy()
        #
        # Make backups of files
        #
        self.backgr = self.MC.backgr.copy()
        self.desolv = self.MC.desolv.copy()
        import copy
        self.matrix = copy.deepcopy(self.MC.matrix)
        self.org_matrix = copy.deepcopy(self.MC.matrix)
        mkeys = self.matrix.keys()
        mkeys.sort()
        #
        # Fill in the new interaction energies
        #
        self.MC.matrix, delete_groups = self.add_mutations_to_matrix(
            mutations=mutations,
            target_array=self.MC.matrix,
            source_array=data,
            source_atom_array=atomdata)
        if self.MC.matrix == 'SS-bridge':
            #
            # Before we return we have to restore the arrays again..
            #
            import copy
            self.MC.backgr = self.backgr.copy()
            self.MC.desolv = self.desolv.copy()
            self.MC.matrix = copy.deepcopy(self.matrix)
            return 'SS-bridge', 'SS-bridge'
        #
        # Delete groups from matrix and backgr
        #
        for group in delete_groups:
            if self.MC.backgr.has_key(group):
                del self.MC.backgr[group]
                del self.MC.desolv[group]

        #
        # Calculate the desolvation and background interaction energies for the mutations
        # The pKa_info class keeps track of these...
        # Fill in the new values
        #
        self.O._print('Getting intrinsic pKa data', 4)
        real_mutations = 0
        real_mutation_list = []
        #
        # Array for holding dbackgr and ddesolv values
        #
        d_intpka_vals = {}
        #
        # Loop over all the mutations
        #
        for mutation in mutations:
            #
            # Get the new residue
            #
            if not mutation or mutation == 'None':
                continue
            import pKD_tools
            new_residue = pKD_tools.get_newres_from_mut(mutation)
            if new_residue:
                real_mutations = real_mutations + 1
                real_mutation_list.append(mutation)
                if is_normally_titratable(new_residue):
                    desolv, backgr = self.pKa_info.get_desolv_and_backgr_mut(
                        mutation)
                    if desolv is None or backgr is None:
                        #
                        # Could not get background or desolvation information
                        #
                        # Remember to restore arrays...
                        #
                        self.MC.backgr = self.backgr.copy()
                        self.MC.desolv = self.desolv.copy()
                        import copy
                        self.MC.matrix = copy.deepcopy(self.matrix)
                        self.O._print(
                            'Intpka recalculation failed for %s' % mutation, 3)
                        return None, None
                    self.O._print(
                        '%s, background: %.2f, desolvation: %.2f. net intr dpKa: %.2f'
                        % (mutation, backgr, desolv,
                           (backgr + desolv) / 2.302), 3)
                    import pKD_tools
                    new_residue = pKD_tools.get_newres_from_mut(mutation)
                    self.MC.backgr[new_residue] = backgr
                    self.MC.desolv[new_residue] = desolv
        #
        # done with getting intpkas for mutated residues
        #
        # Check if we have everything
        #
        need_intpka = []
        for group in self.MC.matrix.keys():
            if not self.MC.backgr.has_key(group) or not self.MC.desolv.has_key(
                    group):
                need_intpka.append(group)
        if len(need_intpka) > 0:
            #
            # ok, something is missing, and hat's not allowed
            #
            raise Exception, 'could not find backgr and desolv for one of these groups: %s' % (
                str(need_intpka))
        #
        # Now recalculate intrinsic pKa values
        #
        for mutation in mutations:
            if not mutation or mutation == 'None':
                continue
            #
            #
            # See if the mutation is so close to a reporter group that
            # we have to recalculate the intrinsic pKa value for the reporter group
            #
            if self.parent.params['recalc_intpka']:
                import Design_pKa_help
                DIST = Design_pKa_help.pKa_dist(
                    self.pdbfile,
                    parent=self,
                    save_file=self.parent.params['save_temp_files'])
                for group in require_pKa:
                    #
                    # If we mutate the residue then skip
                    #
                    import pKD_tools
                    if pKD_tools.get_resid_from_mut(
                            mutation) == pKD_tools.get_resid_from_titgroup(
                                group):
                        continue
                    #
                    # Get the distance
                    #
                    dist = DIST.get_min_dist(group, mutation)
                    if dist <= self.parent.params['recalc_intpka_dist']:
                        print '\n\n***Recalculating intrinsic pKa value for %s due to mutation %s, distance: %5.2f A' % (
                            group, mutation, dist)
                        desolv, backgr = self.pKa_info.get_desolv_and_backgr_mut(
                            mutation, group, measuring_mutated_residue=None)
                        #
                        # Insert the energies
                        #
                        if self.MC.backgr.has_key(group):
                            print 'Mutation: %15s denergies for group %s: desolv: %5.2f, backgr: %5.2f' % (
                                mutation, group,
                                desolv - self.MC.desolv[group],
                                backgr - self.MC.backgr[group])
                            if not d_intpka_vals.has_key(mutation):
                                d_intpka_vals[mutation] = {}
                            if not d_intpka_vals[mutation].has_key(group):
                                d_intpka_vals[mutation][group] = {}
                            d_intpka_vals[mutation][group][
                                'backgr'] = backgr - self.MC.backgr[group]
                            d_intpka_vals[mutation][group][
                                'desolv'] = desolv - self.MC.desolv[group]
                        else:
                            print 'Arrrg'
                            groups = self.MC.backgr.keys()
                            groups.sort()
                            print 'I know of these groups', groups
                            raise Exception(
                                'Could not change intpka for group: %s' %
                                group)
                    else:
                        print 'Mutation: %s is too far away (%5.2f A) from group %s to recalculate intrinsic pKa' % (
                            mutation, dist, group)
                        if not d_intpka_vals.has_key(mutation):
                            d_intpka_vals[mutation] = {}
                        if not d_intpka_vals[mutation].has_key(group):
                            d_intpka_vals[mutation][group] = {}
                        d_intpka_vals[mutation][group]['backgr'] = 0.0
                        d_intpka_vals[mutation][group]['desolv'] = 0.0
        #
        # If we recalculate intrinsic pKa values, then add up all the dbackgr and ddesolv values
        #
        if self.parent.params['recalc_intpka']:
            for group in require_pKa:
                #
                # If we mutated the residue then skip
                #
                skip_group = False
                for mutation in mutations:
                    if mutation:
                        import pKD_tools
                        if pKD_tools.get_resid_from_mut(
                                mutation) == pKD_tools.get_resid_from_titgroup(
                                    group):
                            skip_group = True
                            continue
                if skip_group:
                    continue
                #
                # Otherwise adjust background and desolv energies
                #
                ddesolv = 0.0
                dbackgr = 0.0
                for mutation in mutations:
                    if not mutation or mutation == 'None':
                        continue
                    print 'mutation: %s, group: %s, ddesolv: %5.3f, dbackgr: %5.3f' % (
                        mutation, group,
                        d_intpka_vals[mutation][group]['desolv'],
                        d_intpka_vals[mutation][group]['backgr'])
                    ddesolv = ddesolv + d_intpka_vals[mutation][group]['desolv']
                    dbackgr = dbackgr + d_intpka_vals[mutation][group]['backgr']
                self.MC.desolv[group] = self.MC.desolv[group] + ddesolv
                self.MC.backgr[group] = self.MC.backgr[group] + dbackgr
        #
        # Now calculate the new pKa value(s)
        #
        # Loop until we get a pKa value
        #
        got_all_reporter_pKa_values = None
        step = 2.0
        while not got_all_reporter_pKa_values:
            #
            # We try to guess the approximate value of the new pKa value and save time by limiting
            # the pH range we're calculating charges in.
            #
            # We do this only if we calculate for more than one mutation, otherwise
            # we want to calculate for the full range so we can store the results in tabdata
            #
            # We also do not do this when calculating dpKa values using titration curve integration
            #
            pHstep = self.pHstep
            pHstop = self.pHstop
            pHstart = self.pHstart
            if len(wt_pKas
                   ) == 1 and not for_tabulated and not self.parent.params[
                       'use_titration_curves']:
                wt_pKa = float(int(10.0 * wt_pKas[0])) / 10.0
                pHstart = wt_pKa - 1.0 * step
                pHstop = wt_pKa + 1.0 * step
                #
                # Make sure we don't go outside 0.1 - 12.0
                #
                pHstart = max(0.1, pHstart)
                pHstop = min(12.0, pHstop)
            else:
                wt_pKa = -1.0
            #
            # If we are not to combine the calculated pKa value with anything, then we can save some time
            #
            if real_mutations > 1 and not self.parent.params[
                    'use_titration_curves']:
                pHstep = 2.0 * self.pHstep
            #
            # Do the pKa calc
            #
            self.O._print('Calculating pKa values....', text_level=4, tab=1)
            self.O._print('Calculating for %s' % (str(real_mutation_list)),
                          text_level=4,
                          tab=1)
            self.mut_pKas, populations = self.MC.calc_pKas(
                mcsteps=self.MCsteps,
                phstep=pHstep,
                phstart=pHstart,
                phend=pHstop,
                verbose=self.verbose,
                complete_pka=None)
            prot_states = self.MC.prot_states.copy()
            self.O._print('Done', text_level=4, tab=1)
            #
            # Check that we got all the pKa values we need
            # We skip this step if we use titration curves.
            #
            got_all_reporter_pKa_values = 1
            if not self.parent.params['use_titration_curves']:
                for group in require_pKa:
                    if not self.mut_pKas[group] or self.mut_pKas[group] < -90.0:
                        got_all_reporter_pKa_values = None
            #
            # If we are still missing pKa values then increase the size of the pH range
            #
            step = step + 1.0
            #
            # No more than five steps away before we give up
            #
            if step > 5.0:
                got_all_reporter_pKa_values = 1
        #
        # Done with pKa calcs
        #
        # Before we return we have to restore the arrays again..
        #
        import copy
        self.MC.backgr = self.backgr.copy()
        self.MC.desolv = self.desolv.copy()

        self.MC.matrix = copy.deepcopy(self.matrix)
        #
        # Done
        #
        return self.mut_pKas, prot_states
def analyse_one_pdbfile(pdbfile,bigdict=None):
    """Load the MC.tabdata file and the sugelm file to determine the
    effective dielectric constant for single mutations"""
    mcfile=pdbfile+'.MC.tabdata'
    sugelm=pdbfile+'.sugelm_data'
    print 'Loading:'
    print mcfile
    print sugelm
    print
    import os
    if not os.path.isfile(mcfile):
        return [],[],0
    if not os.path.isfile(sugelm):
        return [],[],0
    if bigdict:
        fd=open(bigdict)
        import pickle
        big_dict=pickle.load(fd)
        fd.close()
    #
    # Get the PDB file
    #
    import pKaTool.pKaIO
    P=pKaTool.pKaIO.pKaIO(pdbfile)
    # Matrix
    matrix=P.read_matrix()
    # Intrinsic pKa values for mutated residues
    intpkafile=pdbfile+'.intpka_data'
    fd=open(intpkafile)
    import pickle
    mutant_intpkas=pickle.load(fd)
    fd.close()
    #
    # Read the PDB file
    #
    import Protool
    PDB=Protool.structureIO()
    PDB.readpdb(pdbfile)
    #
    # Start calculating
    #
    mc=getfile(mcfile)
    su=getfile(sugelm)['data']
    print 'Number of mutations in sugelm',len(su.keys())
    print 'Number of mutations in tabdata',len(mc.keys())

    sites={}
    import string
    for mutation in su.keys():
        orgres=mutation.split(':')[:2]
        orgres=string.join(orgres,':')
        sites[orgres]=1
    print 'Number of unique sites',len(sites.keys())
    #
    # Should we do the full solutions or just single mutations?
    #
    if bigdict:
        print 'Getting mutations from bigdict'
        mutations=[]
        for key in big_dict.keys():
            pdbfile_name=os.path.split(pdbfile)[1]
            pos=key.find(pdbfile_name)
            if pos!=-1:
                target=key[pos+len(pdbfile_name):]
                for muts,dpka in big_dict[key]:
                    mutations.append([target,muts,dpka])
    else:
        mutations=mc.keys()
    #
    # Load the wild type PDB file
    #
    X_wt=Protool.structureIO()
    X_wt.readpdb(pdbfile)
    #
    # go on, calculate the difference between the MC result and the phi result
    #
    mutations.sort()
    phi=[]
    real=[]
    ratio=[]
    dist=[]
    epses_dpKa=[]
    epses=[]
    import types
    for mutant in mutations:
        if type(mutant) is types.ListType:
            #
            # Deal with multiple mutations
            #
            sum_phidpka=0.0
            sum_MCdpka=0.0
            mutations=mutant[1]
            target=mutant[0]
            rdpka=mutant[2]
            if len(mutations)<2:
                continue
            for mutation in mutations:
                phidpka,MCdpka=get_phidpka(mutation=mutation,target=target,su=su,mc=mc,matrix=matrix)
                sum_phidpka=sum_phidpka+phidpka
                sum_MCdpka=sum_MCdpka+MCdpka
            phi.append(sum_phidpka)
            real.append(rdpka)
            #if abs(rdpka-sum_phidpka)>1.0:
            #    print 'T: %15s phidpka %5.1f rdpka: %5.1f muts: %s ' %(target,sum_phidpka,rdpka,str(mutations))
        else:
            #
            # This is for looking at single mutations
            #
            import Design_pKa_help
            X=Design_pKa_help.pKa_dist(pdbfile)
            targets=mc[mutant].keys()
            targets.sort()
            #
            # Load the mutant PDB file if we can
            #
            import os
            pdbdir=pdbfile+'.pdbs'
            mutfile=os.path.join(pdbdir,mutant+'.pdb')
            if os.path.isfile(mutfile):
                import Protool
                X_mut=Protool.structureIO_fast()
                X_mut.readpdb(mutfile)
            else:
                X_mut=None
            #
            # Loop over all targets
            #
            for target in targets:
                #
                # Get the distance between the target and the mutatn
                #
                targetnum=':'+target.split(':')[1]
                mutantnum=':'+mutant.split(':')[1]
                distance=X.get_min_dist(target,mutant)
                #
                # Get the delta pKa values
                #
                phidpka,rdpka=get_phidpka(mutation=mutant,target=target,su=su,mc=mc,matrix=matrix)
                if not rdpka:
                    continue
                if abs(phidpka)>=0.0001 and abs(rdpka)<20.0:
                    phi.append(phidpka)
                    real.append(abs(rdpka))
                    dist.append(distance)
                    #
                    # Effective eps
                    #
                    eps_eff,distance_eps=get_effective_eps(target,mutant,abs(rdpka),X_mut=X_mut,X_wt=X_wt,phidpka=phidpka)
                    if eps_eff:
                        epses.append(eps_eff)
                        #epses_dpKa.append(abs(rdpka))
                        epses_dpKa.append(distance_eps)
                    #ratio.append(rdpka/phidpka)
                    #print phidpka,rdpka
    tabdata_muts=len(mutations)
    return phi,real,tabdata_muts,dist,epses_dpKa,epses
Ejemplo n.º 3
0
    def calc_MC_mut_pKas(self,mutations=[],data={},atomdata={},wt_pKas=[],reporter_residues=[],require_pKa=[],for_tabulated=None):
        """
        Calculate pKa values for a mutant
        """
        #
        # Copy mutfile_names from parent
        #
        if hasattr(self.parent,'mutfile_names'):
            self.mutfile_names=self.parent.mutfile_names.copy()
        #
        # Make backups of files 
        #
        self.backgr=self.MC.backgr.copy()
        self.desolv=self.MC.desolv.copy()
        import copy
        self.matrix=copy.deepcopy(self.MC.matrix)
        self.org_matrix=copy.deepcopy(self.MC.matrix)
        mkeys=self.matrix.keys()
        mkeys.sort()
        #
        # Fill in the new interaction energies
        #
        self.MC.matrix,delete_groups=self.add_mutations_to_matrix(mutations=mutations,
                                                                  target_array=self.MC.matrix,
                                                                  source_array=data,
                                                                  source_atom_array=atomdata)
        if self.MC.matrix=='SS-bridge':
            #
            # Before we return we have to restore the arrays again..
            #
            import copy
            self.MC.backgr=self.backgr.copy()
            self.MC.desolv=self.desolv.copy()
            self.MC.matrix=copy.deepcopy(self.matrix)
            return 'SS-bridge','SS-bridge'
        #
        # Delete groups from matrix and backgr
        #
        for group in delete_groups:
            if self.MC.backgr.has_key(group):
                del self.MC.backgr[group]
                del self.MC.desolv[group]
       
        #
        # Calculate the desolvation and background interaction energies for the mutations
        # The pKa_info class keeps track of these...
        # Fill in the new values
        #
        self.O._print('Getting intrinsic pKa data',4)
        real_mutations=0
        real_mutation_list=[]
        #
        # Array for holding dbackgr and ddesolv values
        #
        d_intpka_vals={}
        #
        # Loop over all the mutations
        #
        for mutation in mutations:
            #
            # Get the new residue
            #
            if not mutation or mutation=='None':
                continue
            import pKD_tools
            new_residue=pKD_tools.get_newres_from_mut(mutation)
            if new_residue:
                real_mutations=real_mutations+1
                real_mutation_list.append(mutation)
                if is_normally_titratable(new_residue):
                    desolv,backgr=self.pKa_info.get_desolv_and_backgr_mut(mutation)
                    if desolv is None or backgr is None:
                        #
                        # Could not get background or desolvation information
                        #
                        # Remember to restore arrays...
                        #
                        self.MC.backgr=self.backgr.copy()
                        self.MC.desolv=self.desolv.copy()
                        import copy
                        self.MC.matrix=copy.deepcopy(self.matrix)
                        self.O._print('Intpka recalculation failed for %s' %mutation,3)
                        return None,None
                    self.O._print('%s, background: %.2f, desolvation: %.2f. net intr dpKa: %.2f' %(mutation,backgr,desolv,(backgr+desolv)/2.302),3)
                    import pKD_tools
                    new_residue=pKD_tools.get_newres_from_mut(mutation)
                    self.MC.backgr[new_residue]=backgr
                    self.MC.desolv[new_residue]=desolv
        #
        # done with getting intpkas for mutated residues
        #
        # Check if we have everything
        #
        need_intpka=[]
        for group in self.MC.matrix.keys():
            if not self.MC.backgr.has_key(group) or not self.MC.desolv.has_key(group):
                need_intpka.append(group)
        if len(need_intpka)>0:
            #
            # ok, something is missing, and hat's not allowed
            #
            raise Exception,'could not find backgr and desolv for one of these groups: %s' %(str(need_intpka))
        #
        # Now recalculate intrinsic pKa values
        #
        for mutation in mutations:
            if not mutation or mutation=='None':
                continue
            #
            #
            # See if the mutation is so close to a reporter group that
            # we have to recalculate the intrinsic pKa value for the reporter group
            #
            if self.parent.params['recalc_intpka']:
                import Design_pKa_help
                DIST=Design_pKa_help.pKa_dist(self.pdbfile,parent=self,save_file=self.parent.params['save_temp_files'])
                for group in require_pKa:
                    #
                    # If we mutate the residue then skip
                    #
                    import pKD_tools
                    if pKD_tools.get_resid_from_mut(mutation)==pKD_tools.get_resid_from_titgroup(group):
                        continue
                    #
                    # Get the distance
                    #
                    dist=DIST.get_min_dist(group,mutation)
                    if dist<=self.parent.params['recalc_intpka_dist']:
                        print '\n\n***Recalculating intrinsic pKa value for %s due to mutation %s, distance: %5.2f A' %(group,mutation,dist)
                        desolv,backgr=self.pKa_info.get_desolv_and_backgr_mut(mutation,group,measuring_mutated_residue=None)
                        #
                        # Insert the energies
                        #
                        if self.MC.backgr.has_key(group):
                            print 'Mutation: %15s denergies for group %s: desolv: %5.2f, backgr: %5.2f' %(mutation,group,desolv-self.MC.desolv[group],backgr-self.MC.backgr[group])
                            if not d_intpka_vals.has_key(mutation):
                                d_intpka_vals[mutation]={}
                            if not d_intpka_vals[mutation].has_key(group):
                                d_intpka_vals[mutation][group]={}
                            d_intpka_vals[mutation][group]['backgr']=backgr-self.MC.backgr[group]
                            d_intpka_vals[mutation][group]['desolv']=desolv-self.MC.desolv[group]
                        else:
                            print 'Arrrg'
                            groups= self.MC.backgr.keys()
                            groups.sort()
                            print 'I know of these groups',groups
                            raise Exception('Could not change intpka for group: %s' %group)
                    else:
                        print 'Mutation: %s is too far away (%5.2f A) from group %s to recalculate intrinsic pKa' %(mutation,dist,group)
                        if not d_intpka_vals.has_key(mutation):
                            d_intpka_vals[mutation]={}
                        if not d_intpka_vals[mutation].has_key(group):
                            d_intpka_vals[mutation][group]={}
                        d_intpka_vals[mutation][group]['backgr']=0.0
                        d_intpka_vals[mutation][group]['desolv']=0.0
        #
        # If we recalculate intrinsic pKa values, then add up all the dbackgr and ddesolv values
        #
        if self.parent.params['recalc_intpka']:
            for group in require_pKa:
                #
                # If we mutated the residue then skip
                #
                skip_group=False
                for mutation in mutations:
                    if mutation:
                        import pKD_tools
                        if pKD_tools.get_resid_from_mut(mutation)==pKD_tools.get_resid_from_titgroup(group):
                            skip_group=True
                            continue
                if skip_group:
                    continue
                #
                # Otherwise adjust background and desolv energies
                #
                ddesolv=0.0
                dbackgr=0.0
                for mutation in mutations:
                    if not mutation or mutation=='None':
                        continue
                    print 'mutation: %s, group: %s, ddesolv: %5.3f, dbackgr: %5.3f' %(mutation,group,d_intpka_vals[mutation][group]['desolv'],d_intpka_vals[mutation][group]['backgr'])
                    ddesolv=ddesolv+d_intpka_vals[mutation][group]['desolv']
                    dbackgr=dbackgr+d_intpka_vals[mutation][group]['backgr']
                self.MC.desolv[group]=self.MC.desolv[group]+ddesolv
                self.MC.backgr[group]=self.MC.backgr[group]+dbackgr
        #
        # Now calculate the new pKa value(s)
        #
        # Loop until we get a pKa value
        #
        got_all_reporter_pKa_values=None
        step=2.0
        while not got_all_reporter_pKa_values:
            #
            # We try to guess the approximate value of the new pKa value and save time by limiting
            # the pH range we're calculating charges in.
            #
            # We do this only if we calculate for more than one mutation, otherwise
            # we want to calculate for the full range so we can store the results in tabdata
            #
            # We also do not do this when calculating dpKa values using titration curve integration
            #
            pHstep=self.pHstep
            pHstop=self.pHstop
            pHstart=self.pHstart
            if len(wt_pKas)==1 and not for_tabulated and not self.parent.params['use_titration_curves']:
                wt_pKa=float(int(10.0*wt_pKas[0]))/10.0
                pHstart=wt_pKa-1.0*step
                pHstop=wt_pKa+1.0*step
                #
                # Make sure we don't go outside 0.1 - 12.0
                #
                pHstart=max(0.1,pHstart)
                pHstop=min(12.0,pHstop)
            else:
                wt_pKa=-1.0
            #
            # If we are not to combine the calculated pKa value with anything, then we can save some time
            #
            if real_mutations>1 and not self.parent.params['use_titration_curves']:
                pHstep=2.0*self.pHstep
            #
            # Do the pKa calc
            #
            self.O._print('Calculating pKa values....',text_level=4,tab=1)
            self.O._print('Calculating for %s' %(str(real_mutation_list)),text_level=4,tab=1)
            self.mut_pKas,populations=self.MC.calc_pKas(mcsteps=self.MCsteps,
                                            phstep=pHstep,
                                            phstart=pHstart,
                                            phend=pHstop,
                                            verbose=self.verbose,
                                            complete_pka=None)
            prot_states=self.MC.prot_states.copy()
            self.O._print('Done',text_level=4,tab=1)
            #
            # Check that we got all the pKa values we need
            # We skip this step if we use titration curves.
            #
            got_all_reporter_pKa_values=1
            if not self.parent.params['use_titration_curves']:
                for group in require_pKa:
                    if not self.mut_pKas[group] or self.mut_pKas[group]<-90.0:
                        got_all_reporter_pKa_values=None
            #
            # If we are still missing pKa values then increase the size of the pH range
            #
            step=step+1.0
            #
            # No more than five steps away before we give up
            #
            if step>5.0:
                got_all_reporter_pKa_values=1
        #
        # Done with pKa calcs
        #
        # Before we return we have to restore the arrays again..
        #
        import copy
        self.MC.backgr=self.backgr.copy()
        self.MC.desolv=self.desolv.copy()

        self.MC.matrix=copy.deepcopy(self.matrix)
        #
        # Done
        #
        return self.mut_pKas,prot_states
def analyse_one_pdbfile(pdbfile, bigdict=None):
    """Load the MC.tabdata file and the sugelm file to determine the
    effective dielectric constant for single mutations"""
    mcfile = pdbfile + '.MC.tabdata'
    sugelm = pdbfile + '.sugelm_data'
    print 'Loading:'
    print mcfile
    print sugelm
    print
    import os
    if not os.path.isfile(mcfile):
        return [], [], 0
    if not os.path.isfile(sugelm):
        return [], [], 0
    if bigdict:
        fd = open(bigdict)
        import pickle
        big_dict = pickle.load(fd)
        fd.close()
    #
    # Get the PDB file
    #
    import pKaTool.pKaIO
    P = pKaTool.pKaIO.pKaIO(pdbfile)
    # Matrix
    matrix = P.read_matrix()
    # Intrinsic pKa values for mutated residues
    intpkafile = pdbfile + '.intpka_data'
    fd = open(intpkafile)
    import pickle
    mutant_intpkas = pickle.load(fd)
    fd.close()
    #
    # Read the PDB file
    #
    import Protool
    PDB = Protool.structureIO()
    PDB.readpdb(pdbfile)
    #
    # Start calculating
    #
    mc = getfile(mcfile)
    su = getfile(sugelm)['data']
    print 'Number of mutations in sugelm', len(su.keys())
    print 'Number of mutations in tabdata', len(mc.keys())

    sites = {}
    import string
    for mutation in su.keys():
        orgres = mutation.split(':')[:2]
        orgres = string.join(orgres, ':')
        sites[orgres] = 1
    print 'Number of unique sites', len(sites.keys())
    #
    # Should we do the full solutions or just single mutations?
    #
    if bigdict:
        print 'Getting mutations from bigdict'
        mutations = []
        for key in big_dict.keys():
            pdbfile_name = os.path.split(pdbfile)[1]
            pos = key.find(pdbfile_name)
            if pos != -1:
                target = key[pos + len(pdbfile_name):]
                for muts, dpka in big_dict[key]:
                    mutations.append([target, muts, dpka])
    else:
        mutations = mc.keys()
    #
    # Load the wild type PDB file
    #
    X_wt = Protool.structureIO()
    X_wt.readpdb(pdbfile)
    #
    # go on, calculate the difference between the MC result and the phi result
    #
    mutations.sort()
    phi = []
    real = []
    ratio = []
    dist = []
    epses_dpKa = []
    epses = []
    import types
    for mutant in mutations:
        if type(mutant) is types.ListType:
            #
            # Deal with multiple mutations
            #
            sum_phidpka = 0.0
            sum_MCdpka = 0.0
            mutations = mutant[1]
            target = mutant[0]
            rdpka = mutant[2]
            if len(mutations) < 2:
                continue
            for mutation in mutations:
                phidpka, MCdpka = get_phidpka(mutation=mutation,
                                              target=target,
                                              su=su,
                                              mc=mc,
                                              matrix=matrix)
                sum_phidpka = sum_phidpka + phidpka
                sum_MCdpka = sum_MCdpka + MCdpka
            phi.append(sum_phidpka)
            real.append(rdpka)
            #if abs(rdpka-sum_phidpka)>1.0:
            #    print 'T: %15s phidpka %5.1f rdpka: %5.1f muts: %s ' %(target,sum_phidpka,rdpka,str(mutations))
        else:
            #
            # This is for looking at single mutations
            #
            import Design_pKa_help
            X = Design_pKa_help.pKa_dist(pdbfile)
            targets = mc[mutant].keys()
            targets.sort()
            #
            # Load the mutant PDB file if we can
            #
            import os
            pdbdir = pdbfile + '.pdbs'
            mutfile = os.path.join(pdbdir, mutant + '.pdb')
            if os.path.isfile(mutfile):
                import Protool
                X_mut = Protool.structureIO_fast()
                X_mut.readpdb(mutfile)
            else:
                X_mut = None
            #
            # Loop over all targets
            #
            for target in targets:
                #
                # Get the distance between the target and the mutatn
                #
                targetnum = ':' + target.split(':')[1]
                mutantnum = ':' + mutant.split(':')[1]
                distance = X.get_min_dist(target, mutant)
                #
                # Get the delta pKa values
                #
                phidpka, rdpka = get_phidpka(mutation=mutant,
                                             target=target,
                                             su=su,
                                             mc=mc,
                                             matrix=matrix)
                if not rdpka:
                    continue
                if abs(phidpka) >= 0.0001 and abs(rdpka) < 20.0:
                    phi.append(phidpka)
                    real.append(abs(rdpka))
                    dist.append(distance)
                    #
                    # Effective eps
                    #
                    eps_eff, distance_eps = get_effective_eps(target,
                                                              mutant,
                                                              abs(rdpka),
                                                              X_mut=X_mut,
                                                              X_wt=X_wt,
                                                              phidpka=phidpka)
                    if eps_eff:
                        epses.append(eps_eff)
                        #epses_dpKa.append(abs(rdpka))
                        epses_dpKa.append(distance_eps)
                    #ratio.append(rdpka/phidpka)
                    #print phidpka,rdpka
    tabdata_muts = len(mutations)
    return phi, real, tabdata_muts, dist, epses_dpKa, epses