<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def sample(self, nsamples, nburn=0, nthin=1, save_hidden_state_trajectory=False, call_back=None):
 """Sample from the BHMM posterior. Parameters nsamples : int The number of samples to generate. nburn : int, optional, default=0 The number of samples to discard to burn-in, following which `nsamples` will be generated. nthin : int, optional, default=1 The number of Gibbs sampling updates used to generate each returned sample. save_hidden_state_trajectory : bool, optional, default=False If True, the hidden state trajectory for each sample will be saved as well. call_back : function, optional, default=None a call back function with no arguments, which if given is being called after each computed sample. This is useful for implementing progress bars. Returns ------- models : list of bhmm.HMM The sampled HMM models from the Bayesian posterior. Examples -------- """


        # Run burn-in.
        for iteration in range(nburn):
            logger().info("Burn-in   %8d / %8d" % (iteration, nburn))
            self._update()

        # Collect data.
        models = list()
        for iteration in range(nsamples):
            logger().info("Iteration %8d / %8d" % (iteration, nsamples))
            # Run a number of Gibbs sampling updates to generate each sample.
            for thin in range(nthin):
                self._update()
            # Save a copy of the current model.
            model_copy = copy.deepcopy(self.model)
            # print "Sampled: \n",repr(model_copy)
            if not save_hidden_state_trajectory:
                model_copy.hidden_state_trajectory = None
            models.append(model_copy)
            if call_back is not None:
                call_back()

        # Return the list of models saved.
        return models