docs: def _mmc_loop(self, rounds, temp=298.15, verbose=True):
          """The main MMC loop.
  
          Parameters
          ----------
          rounds : int
              The number of rounds of optimisation to perform.
          temp : float, optional
              The temperature (in K) used during the optimisation.
          verbose : bool, optional
              If true, prints information about the run to std out.
          """
          # TODO add weighted randomisation of altered variable
          current_round = 0
          while current_round < rounds:
              modifiable = list(filter(
                  lambda p: p.parameter_type is not MMCParameterType.STATIC_VALUE,
                  self.current_parameters))
              chosen_parameter = random.choice(modifiable)
              if chosen_parameter.parameter_type is MMCParameterType.UNIFORM_DIST:
                  chosen_parameter.randomise_proposed_value()
              else:
                  chosen_parameter.randomise_proposed_value()
              proposed_parameters = [
                  p.current_value
                  if p.proposed_value is None else p.proposed_value
                  for p in self.current_parameters]
              model = self.specification(*proposed_parameters)
              model.pack_new_sequences(self.sequences)
              proposed_energy = self.eval_function(model)
              # TODO Add proper logging
              if verbose:
                  sys.stdout.write(
                      '\rRound: {}, Current energy: {}, Proposed energy: {} '
                      '(best {}), {}.       '
                      .format(current_round, float_f(self.current_energy),
                              float_f(proposed_energy), float_f(
                                  self.best_energy),
                              "ACCEPTED" if self.check_move(
                                  proposed_energy, self.current_energy, t=temp)
                              else "DECLINED"
                              ))
                  sys.stdout.flush()
              if self.check_move(proposed_energy, self.current_energy, t=temp):
                  for p in self.current_parameters:
                      p.accept_proposed_value()
                  self.current_energy = proposed_energy
                  if self.current_energy < self.best_energy:
                      self.best_energy = copy.deepcopy(self.current_energy)
                      self.best_parameters = copy.deepcopy(
                          self.current_parameters)
                      self.best_model = model
              else:
                  for p in self.current_parameters:
                      p.reject_proposed_value()
              current_round += 1
          return