def reroot(self, root='least-squares', force_positive=True, covariation=None):
        """
        Find best root and re-root the tree to the new root

        Parameters
        ----------

         root : str
            Which method should be used to find the best root. Available methods are:

            :code:`best`, `least-squares` - minimize squared residual or likelihood of root-to-tip regression

            :code:`min_dev` - minimize variation of root-to-tip distance

            :code:`oldest` - reroot on the oldest node

            :code:`<node_name>` - reroot to the node with name :code:`<node_name>`

            :code:`[<node_name1>, <node_name2>, ...]` - reroot to the MRCA of these nodes

          force_positive : bool
            only consider positive rates when searching for the optimal root

          covariation : bool
             account for covariation in root-to-tip regression
        """
        if type(root) is list and len(root)==1:
            root=str(root[0])

        if root=='best':
            root='least-squares'

        use_cov = self.use_covariation if covariation is None else covariation

        self.logger("TreeTime.reroot: with method or node: %s"%root,0)
        for n in self.tree.find_clades():
            n.branch_length=n.mutation_length

        if (type(root) is str) and \
           (root in rerooting_mechanisms or root in deprecated_rerooting_mechanisms):
            if root in deprecated_rerooting_mechanisms:
                if "ML" in root:
                    use_cov=True
                self.logger('TreeTime.reroot: rerooting mechanisms %s has been renamed to %s'
                             %(root, deprecated_rerooting_mechanisms[root]), 1, warn=True)
                root = deprecated_rerooting_mechanisms[root]

            self.logger("TreeTime.reroot: rerooting will %s covariance and shared ancestry."%("account for" if use_cov else "ignore"),0)
            new_root = self._find_best_root(covariation=use_cov,
                                            slope = 0.0 if root.startswith('min_dev') else None,
                                            force_positive=force_positive and (not root.startswith('min_dev')))
        else:
            if isinstance(root,Phylo.BaseTree.Clade):
                new_root = root
            elif isinstance(root, list):
                new_root = self.tree.common_ancestor(*root)
            elif root in self._leaves_lookup:
                new_root = self._leaves_lookup[root]
            elif root=='oldest':
                new_root = sorted([n for n in self.tree.get_terminals()
                                   if n.raw_date_constraint is not None],
                                   key=lambda x:np.mean(x.raw_date_constraint))[0]
            else:
                self.logger('TreeTime.reroot -- ERROR: unsupported rooting mechanisms or root not found',0,warn=True)
                return ttconf.ERROR

            #this forces a bifurcating root, as we want. Branch lengths will be reoptimized anyway.
            #(Without outgroup_branch_length, gives a trifurcating root, but this will mean
            #mutations may have to occur multiple times.)
            self.tree.root_with_outgroup(new_root, outgroup_branch_length=new_root.branch_length/2)
            self.get_clock_model(covariation=use_cov)


        if new_root == ttconf.ERROR:
            return ttconf.ERROR

        self.logger("TreeTime.reroot: Tree was re-rooted to node "
                    +('new_node' if new_root.name is None else new_root.name), 2)

        self.tree.root.branch_length = self.one_mutation
        self.tree.root.clock_length = self.one_mutation
        self.tree.root.raw_date_constraint = None
        if hasattr(new_root, 'time_before_present'):
            self.tree.root.time_before_present = new_root.time_before_present
        if hasattr(new_root, 'numdate'):
            self.tree.root.numdate = new_root.numdate
        # set root.gamma bc root doesn't have a branch_length_interpolator but gamma is needed
        if not hasattr(self.tree.root, 'gamma'):
            self.tree.root.gamma = 1.0
        for n in self.tree.find_clades():
            n.mutation_length = n.branch_length
            if not hasattr(n, 'clock_length'):
                n.clock_length = n.branch_length
        self.prepare_tree()

        self.get_clock_model(covariation=self.use_covariation)

        return ttconf.SUCCESS
Find best root and re-root the tree to the new root

        Parameters
        ----------

         root : str
            Which method should be used to find the best root. Available methods are:

            :code:`best`, `least-squares` - minimize squared residual or likelihood of root-to-tip regression

            :code:`min_dev` - minimize variation of root-to-tip distance

            :code:`oldest` - reroot on the oldest node

            :code:`<node_name>` - reroot to the node with name :code:`<node_name>`

            :code:`[<node_name1>, <node_name2>, ...]` - reroot to the MRCA of these nodes

          force_positive : bool
            only consider positive rates when searching for the optimal root

          covariation : bool
             account for covariation in root-to-tip regression