Ejemplo n.º 1
0
    def __init__( self, scorefxn, steps, temp, cooling_rate ):
        ''' '''
        assert isScoreFxn( scorefxn )

        self._log = ""
        
        self._scorefxn = scorefxn
        self._steps = steps # MC steps per annealing cycle
        self._temperature = temp

        # declare objects
        self.__fragidx_pose = FragIdxPose()
        self._initialization = "random"

        self._cooling_rate = cooling_rate
        self._anneal_temp = 0.0

        # recover_low ( quench )
        self._quench = False
        self._lowest_score_pose = FragIdxPose()

        self._record_trajectory = False
Ejemplo n.º 2
0
    def __init__(self, score_table, wts, null_frag_score, pose={}):
        """
        1. Score methods:
            function call operations
            > Given a pose, return the total_score
            > Given a frag_idx, return the score relatively to the rest of the residues in the pose (update the pose?)

        2. Evaluation method:
            return stats for evaluation/debug purposes
            > Per-residue stats: decomposite scores for each residue level
            > Summarize score: overall results for a pose

        """

        assert isScoreTable(score_table)
        assert isWeights(wts)

        self._score_table = score_table
        self._wts = wts
        self._null_frag_score = null_frag_score

        # Private Member
        self.__pose = FragIdxPose()  # selected_frags_dict
Ejemplo n.º 3
0
class SimulatedAnnealing:
    ''' 
    1. easy to dump the object as a resulting model, and the trajectory?
    2. linear cooling rate
    '''
    def __init__( self, scorefxn, steps, temp, cooling_rate ):
        ''' '''
        assert isScoreFxn( scorefxn )

        self._log = ""
        
        self._scorefxn = scorefxn
        self._steps = steps # MC steps per annealing cycle
        self._temperature = temp

        # declare objects
        self.__fragidx_pose = FragIdxPose()
        self._initialization = "random"

        self._cooling_rate = cooling_rate
        self._anneal_temp = 0.0

        # recover_low ( quench )
        self._quench = False
        self._lowest_score_pose = FragIdxPose()

        self._record_trajectory = False


    def set_annealing_temperature( self ):
        ''' '''
        self._anneal_temp  = round( self._temperature*self._cooling_rate, 1 )
        self._temperature -= self._anneal_temp


    def run( self, runid ):
        ''' run id is a identification for a model to dump '''
        self.__fragidx_pose.clear()
        self.__fragidx_pose.initialization( self._scorefxn.get_density_score_dict(), self._initialization ) # default initialize by random
        #print self.__fragidx_pose.show_state( "initialization" )

        mc = MonteCarlo( self._scorefxn, self._temperature )
        mc.apply( self.__fragidx_pose, self._steps ) # to prevent a silly bug that at the very first state SCORE==0, such that you wouldn't lower than that during high temperatures sampling
        self._lowest_score_pose = self.__fragidx_pose.clone()

        tracker = TrajectoryTracker( runid )
        tag = "model_" + str( runid )

        while self._temperature >=0 : # it would never reach this criteria
            if self._quench: 
                self.recover_low() # retrieve the lowest-score pose from previous runs

            mc.apply( self.__fragidx_pose, self._steps )

            residual_pose = self._scorefxn.residualize_pose() # residual_pose will be filled with
            #print residual_pose.show_state( tag + "_" + str( self._temperature ) )

            self.set_annealing_temperature() # update self._temperature
            if self._temperature == mc.get_temperature(): break

            mc.set_temperature( self._temperature )

            if self._record_trajectory: tracker.save( self._temperature, self.__fragidx_pose )

        tracker.save( self._temperature, self._scorefxn.residualize_pose() )
        tracker.dump_pickle( tag )
        residual_pose.show_state( tag + "_final", True ) # True for verbose showing all residues states


    def set_to_quench( self ):
        self._quench = True 


    def record_trajectory( self ):
        self._record_trajectory = True


    def recover_low( self ): # recover_low
        ''' 
        last accept score pose, and lowest score pose; the MC.recover_low has this is because it uses Metropolis to thermally accept pose
        '''
        # this is for the first around
        # need to think about a better way to initiate it
        if not self._lowest_score_pose._initialized: 
            self._lowest_score_pose._initialized = self.__fragidx_pose

        # .total_score() method will re-evaluate pose whenever it is called
        if self.__fragidx_pose.total_score() > self._lowest_score_pose.total_score():
            stdout.write("recover previous found lowest-score pose with score: %s\n" % self._lowest_score_pose.total_score() )
            self.__fragidx_pose = self._lowest_score_pose.clone() 
        else:
            stdout.write("found a newer lowest-score pose\n")
            self._lowest_score_pose = self.__fragidx_pose.clone()


    def dump( self, id ):
        return


    def quench( self ):
        return 
Ejemplo n.º 4
0
class ScoreFunction:
    """ 
    The ScoreFucntion object must initialize by having object ScoreTable read in as Dictionary.
    > 130909: should I move pose storage out of the class? 

    """

    def __init__(self, score_table, wts, null_frag_score, pose={}):
        """
        1. Score methods:
            function call operations
            > Given a pose, return the total_score
            > Given a frag_idx, return the score relatively to the rest of the residues in the pose (update the pose?)

        2. Evaluation method:
            return stats for evaluation/debug purposes
            > Per-residue stats: decomposite scores for each residue level
            > Summarize score: overall results for a pose

        """

        assert isScoreTable(score_table)
        assert isWeights(wts)

        self._score_table = score_table
        self._wts = wts
        self._null_frag_score = null_frag_score

        # Private Member
        self.__pose = FragIdxPose()  # selected_frags_dict

    def __call__(self, input):
        """ 
        Two operations:
        1. scorefxn( pose ):  #
            ** noteworthy: the pose object here is Pose
            > assign Residue object for each position, and 
            > return a total score of it
        2. scorefxn( frag_idx ): 
            > return frag score for the frag_idx to a pose

        """
        assert isPose(input) or isFragIdx(input)

        if isPose(input):  # a residual pose
            """ 1. update the residue of the verbose_pose to be composed of Residue objects
                2. return a total score """

            residual_pose = input
            self.update_pose(residual_pose)  # the frag_idx in the input has been update to self.__pose

            # use the new ScoreTable to rescore it residual_pose
            output_pose = Pose()
            for frag_idx in self.__pose:
                output_pose.update_residue(self.score_evaluator(frag_idx, True))

            return output_pose

        elif isFragIdx(input):
            """ return a residue score """
            return self.score_evaluator(input)

    def residualize_pose(self):
        """ Pose() has methods to evaluate the state """
        residual_pose = Pose()

        for frag_idx in self.__pose:
            residual_pose.update_residue(self.score_evaluator(frag_idx, True))

        return residual_pose

    def get_density_score_dict(self):
        return self._score_table.get_density_score_dict()

    def get_candidate_frags(self, pos):
        """ return candidate fragid objects from a position as a list """
        return self._score_table.get_candidate_frags(pos)

    def clone(self):
        """ would it work? don't know yet """
        return copy.deepcopy(self)

    def update_score_table(self, new_score_table):
        assert isScoreTable(new_score_table)
        self._score_table = new_score_table

    def update_pose(self, pose):
        """ simply assign the coming pose to the in-object pose """
        assert isFragIdxPose(pose) or isPose(pose)

        if isFragIdxPose(pose):
            self.__pose = pose

        elif isPose(pose):
            for residue in pose:
                pos = residue._frag_id._pos
                # print pos, residue._score
                frag_idx = self._score_table.frag_to_index(residue._frag_id())
                self.__pose.update_residue(pos, frag_idx)

    def set_weights(self, new_wts):
        """ This is in particular useful when you want to interactive use this class to rescore by changing the weights """
        assert isWeights(new_wts)
        self._wts = new_wts

    def set_null_frag_score(self, new_null_frag_score):
        """ This is being used whenever low acceptance rate of MonteCarlo object - lower the null_frag_score """
        assert new_null_frag_score
        self._null_frag_score = new_null_frag_score

    #### the main method to score ####
    def score_evaluator(self, candidate_frag_idx, verbose=False):
        """ 
        Given a candidate_frag_idx, return a frag_score of the fragment to the selected ones,
        1. null_frag - return null_frag_score
        2. frag - return frag_score
        """
        assert isFragIdxPose(
            self.__pose
        )  # is a Pose instance, and has been initialized; this is because when instance ScoreFunction class, you don't have to give it a Pose class

        # skip null fragment: this is for when calculating total_score
        if isNullFrag(candidate_frag_idx):
            if verbose:
                candidate_frag_id = FragID(self._score_table.index_to_frag(candidate_frag_idx))  # make FragID object
                return Residue(candidate_frag_id, self._null_frag_score)
            else:
                return self._null_frag_score

        density_score, all_overlap_score, all_closab_score, all_clash_score = (0.0,) * 4

        # one-body score:
        try:
            density_score = self._score_table.density_score_lookup(candidate_frag_idx)
            density_score *= self._wts._density_score_wt
            rmsd = self._score_table.rmsd_lookup(candidate_frag_idx)

        except KeyError:
            stderr.write("Error: %s does not have density score\n" % candidate_frag_idx)
            exit()

        # two-body score: the candidate_frag to the rest selected ones
        """ for each candidate placement, calculate frag_score against all selected frags """

        for selected_frag_idx in self.__pose:  # pose as an iterator of positions

            if selected_frag_idx == candidate_frag_idx:
                continue  # no two-body score to itself
            if isNullFrag(selected_frag_idx):
                continue  # you don't need to compare to null fragment

            # overlap using table to do a fast lookup
            if self._score_table.overlapping_check_table_lookup(candidate_frag_idx, selected_frag_idx):
                # The reason why you don't need to look up clash score for overlapping fragments is because it has been considered while calculating overlap_score
                try:
                    overlap_score = self._score_table.overlap_score_lookup(candidate_frag_idx, selected_frag_idx)
                    overlap_score *= self._wts._overlap_score_wt
                    all_overlap_score += overlap_score

                except KeyError:
                    stderr.write(
                        "WARNING: %s %s don't have overlap score\n"
                        % (
                            self._score_table.index_to_frag(candidate_frag_idx),
                            self._score_table.index_to_frag(selected_frag_id),
                        )
                    )
                    continue
            else:
                try:
                    closab_score = self._score_table.closab_score_lookup(candidate_frag_idx, selected_frag_idx)
                    closab_score *= self._wts._closab_score_wt
                    all_closab_score += closab_score

                    clash_score = self._score_table.clash_score_lookup(candidate_frag_idx, selected_frag_idx)
                    clash_score *= self._wts._clash_score_wt
                    all_clash_score += clash_score

                except KeyError:
                    stderr.write(
                        "WARNING: %s %s don't have nonoverlap score\n"
                        % (
                            self._score_table.index_to_frag(candidate_frag_idx),
                            self._score_table.index_to_frag(selected_frag_id),
                        )
                    )
                    continue

        #### end of calculating "the candidate_frag" to the selected ones ####
        frag_score = density_score + all_overlap_score + all_closab_score + all_clash_score

        if verbose:
            """ This is to be used at the very end of stage of simulation to dump residual decomposed scores; 
                preferably will only be called in scorefxn.show_state() """
            candidate_frag_id = FragID(self._score_table.index_to_frag(candidate_frag_idx))  # make FragID object
            residue = Residue(
                candidate_frag_id, frag_score, density_score, all_overlap_score, all_closab_score, all_clash_score, rmsd
            )  # missing Boltzmann
            return residue
        else:
            return frag_score