code: def reconstruct_ancestral_states(tree, character, states, prediction_method=MPPA, model=F81,
                                   params=None, avg_br_len=None, num_nodes=None, num_tips=None,
                                   force_joint=True):
      logging.getLogger('pastml').debug('ACR settings for {}:\n\tMethod:\t{}{}.'
                                        .format(character, prediction_method,
                                                '\n\tModel:\t{}'.format(model)
                                                if model and is_ml(prediction_method) else ''))
      if COPY == prediction_method:
          return {CHARACTER: character, STATES: states, METHOD: prediction_method}
      if not num_nodes:
          num_nodes = sum(1 for _ in tree.traverse())
      if not num_tips:
          num_tips = len(tree)
      if is_ml(prediction_method):
          if avg_br_len is None:
              avg_br_len = np.mean(n.dist for n in tree.traverse() if n.dist)
          freqs, sf, kappa = None, None, None
          if params is not None:
              freqs, sf, kappa = _parse_pastml_parameters(params, states)
          return ml_acr(tree=tree, character=character, prediction_method=prediction_method, model=model, states=states,
                        avg_br_len=avg_br_len, num_nodes=num_nodes, num_tips=num_tips, freqs=freqs, sf=sf, kappa=kappa,
                        force_joint=force_joint)
      if is_parsimonious(prediction_method):
          return parsimonious_acr(tree, character, prediction_method, states, num_nodes, num_tips)
      raise ValueError('Method {} is unknown, should be one of ML ({}), one of MP ({}) or {}'
                       .format(prediction_method, ', '.join(ML_METHODS), ', '.join(MP_METHODS), COPY))