def run(self, root=None, infer_gtr=True, relaxed_clock=None, n_iqd = None,<EOL>resolve_polytomies=True, max_iter=<NUM_LIT:0>, Tc=None, fixed_clock_rate=None,<EOL>time_marginal=False, sequence_marginal=False, branch_length_mode='<STR_LIT>',<EOL>vary_rate=False, use_covariation=False, **kwargs):
<EOL>self.use_covariation = use_covariation<EOL>if (self.tree is None) or (self.aln is None and self.seq_len is None):<EOL><INDENT>self.logger("<STR_LIT>", <NUM_LIT:0>)<EOL>return ttconf.ERROR<EOL><DEDENT>if (self.aln is None):<EOL><INDENT>branch_length_mode='<STR_LIT:input>'<EOL><DEDENT>self._set_branch_length_mode(branch_length_mode)<EOL>seq_kwargs = {"<STR_LIT>":sequence_marginal or (self.branch_length_mode=='<STR_LIT>'),<EOL>"<STR_LIT>":"<STR_LIT:root>"}<EOL>tt_kwargs = {'<STR_LIT>':fixed_clock_rate, '<STR_LIT>':False}<EOL>tt_kwargs.update(kwargs)<EOL>seq_LH = <NUM_LIT:0><EOL>if "<STR_LIT>" in kwargs:<EOL><INDENT>seq_kwargs["<STR_LIT>"] = kwargs["<STR_LIT>"]<EOL><DEDENT>if "<STR_LIT>" in kwargs:<EOL><INDENT>time_marginal=kwargs["<STR_LIT>"]<EOL><DEDENT>if self.branch_length_mode=='<STR_LIT:input>':<EOL><INDENT>if self.aln:<EOL><INDENT>self.infer_ancestral_sequences(infer_gtr=infer_gtr, **seq_kwargs)<EOL>self.prune_short_branches()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self.optimize_sequences_and_branch_length(infer_gtr=infer_gtr,<EOL>max_iter=<NUM_LIT:1>, prune_short=True, **seq_kwargs)<EOL><DEDENT>avg_root_to_tip = np.mean([x.dist2root for x in self.tree.get_terminals()])<EOL>if n_iqd or root=='<STR_LIT>':<EOL><INDENT>if "<STR_LIT>" in kwargs and kwargs["<STR_LIT>"]:<EOL><INDENT>plot_rtt=True<EOL><DEDENT>else:<EOL><INDENT>plot_rtt=False<EOL><DEDENT>reroot_mechanism = '<STR_LIT>' if root=='<STR_LIT>' else root<EOL>if self.clock_filter(reroot=reroot_mechanism, n_iqd=n_iqd, plot=plot_rtt)==ttconf.ERROR:<EOL><INDENT>return ttconf.ERROR<EOL><DEDENT><DEDENT>elif root is not None:<EOL><INDENT>if self.reroot(root=root)==ttconf.ERROR:<EOL><INDENT>return ttconf.ERROR<EOL><DEDENT><DEDENT>if self.branch_length_mode=='<STR_LIT:input>':<EOL><INDENT>if self.aln:<EOL><INDENT>self.infer_ancestral_sequences(**seq_kwargs)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self.optimize_sequences_and_branch_length(max_iter=<NUM_LIT:1>, prune_short=False,<EOL>**seq_kwargs)<EOL><DEDENT>self.logger("<STR_LIT>",<NUM_LIT:0>)<EOL>self.make_time_tree(**tt_kwargs)<EOL>if self.aln:<EOL><INDENT>seq_LH = self.tree.sequence_marginal_LH if seq_kwargs['<STR_LIT>'] else self.tree.sequence_joint_LH<EOL><DEDENT>self.LH =[[seq_LH, self.tree.positional_joint_LH, <NUM_LIT:0>]]<EOL>if root is not None and max_iter:<EOL><INDENT>if self.reroot(root='<STR_LIT>' if root=='<STR_LIT>' else root)==ttconf.ERROR:<EOL><INDENT>return ttconf.ERROR<EOL><DEDENT><DEDENT>niter = <NUM_LIT:0><EOL>ndiff = <NUM_LIT:0><EOL>need_new_time_tree=False<EOL>while niter < max_iter:<EOL><INDENT>self.logger("<STR_LIT>"%(niter+<NUM_LIT:1>,max_iter),<NUM_LIT:0>)<EOL>if Tc:<EOL><INDENT>if Tc=='<STR_LIT>' and niter<max_iter-<NUM_LIT:1>:<EOL><INDENT>tmpTc='<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>tmpTc=Tc<EOL><DEDENT>self.add_coalescent_model(tmpTc, **kwargs)<EOL>need_new_time_tree = True<EOL><DEDENT>if relaxed_clock:<EOL><INDENT>print("<STR_LIT>", relaxed_clock)<EOL>self.relaxed_clock(**relaxed_clock)<EOL>need_new_time_tree = True<EOL><DEDENT>n_resolved=<NUM_LIT:0><EOL>if resolve_polytomies:<EOL><INDENT>n_resolved = self.resolve_polytomies()<EOL>if n_resolved:<EOL><INDENT>self.prepare_tree()<EOL>if self.branch_length_mode!='<STR_LIT:input>': <EOL><INDENT>self.optimize_sequences_and_branch_length(prune_short=False,<EOL>max_iter=<NUM_LIT:0>, **seq_kwargs)<EOL><DEDENT>need_new_time_tree = True<EOL><DEDENT><DEDENT>if need_new_time_tree:<EOL><INDENT>self.make_time_tree(**tt_kwargs)<EOL>if self.aln:<EOL><INDENT>ndiff = self.infer_ancestral_sequences('<STR_LIT>',**seq_kwargs)<EOL><DEDENT><DEDENT>else: <EOL><INDENT>if self.aln:<EOL><INDENT>ndiff = self.infer_ancestral_sequences('<STR_LIT>',**seq_kwargs)<EOL><DEDENT>self.make_time_tree(**tt_kwargs)<EOL><DEDENT>self.tree.coalescent_joint_LH = self.merger_model.total_LH() if Tc else <NUM_LIT:0.0><EOL>if self.aln:<EOL><INDENT>seq_LH = self.tree.sequence_marginal_LH if seq_kwargs['<STR_LIT>'] else self.tree.sequence_joint_LH<EOL><DEDENT>self.LH.append([seq_LH, self.tree.positional_joint_LH, self.tree.coalescent_joint_LH])<EOL>niter+=<NUM_LIT:1><EOL>if ndiff==<NUM_LIT:0> and n_resolved==<NUM_LIT:0> and Tc!='<STR_LIT>':<EOL><INDENT>self.logger("<STR_LIT>",<NUM_LIT:0>)<EOL>break<EOL><DEDENT><DEDENT>if vary_rate:<EOL><INDENT>if type(vary_rate)==float:<EOL><INDENT>res = self.calc_rate_susceptibility(rate_std=vary_rate, params=tt_kwargs)<EOL><DEDENT>elif self.clock_model['<STR_LIT>']:<EOL><INDENT>res = self.calc_rate_susceptibility(params=tt_kwargs)<EOL><DEDENT>else:<EOL><INDENT>res = ttconf.ERROR<EOL><DEDENT>if res==ttconf.ERROR:<EOL><INDENT>self.logger("<STR_LIT>", <NUM_LIT:1>, warn=True)<EOL><DEDENT><DEDENT>if time_marginal:<EOL><INDENT>self.logger("<STR_LIT>", <NUM_LIT:0>)<EOL>tt_kwargs['<STR_LIT>']=time_marginal<EOL>self.make_time_tree(**tt_kwargs)<EOL><DEDENT>bad_branches =[n for n in self.tree.get_terminals()<EOL>if n.bad_branch and n.raw_date_constraint]<EOL>if bad_branches:<EOL><INDENT>self.logger("<STR_LIT>"<EOL>"<STR_LIT>",<NUM_LIT:0>,warn=True)<EOL>for n in bad_branches:<EOL><INDENT>self.logger("<STR_LIT>"%(n.name, str(n.raw_date_constraint), n.numdate),<NUM_LIT:0>,warn=True)<EOL><DEDENT><DEDENT>return ttconf.SUCCESS<EOL>
Run TreeTime reconstruction. Based on the input parameters, it divides
the analysis into semi-independent jobs and conquers them one-by-one,
gradually optimizing the tree given the temporal constarints and leaf
node sequences.

Parameters
----------
root : str
   Try to find better root position on a given tree. If string is passed,
   the root will be searched according to the specified method. If none,
   use tree as-is.

   See :py:meth:`treetime.TreeTime.reroot` for available rooting methods.

infer_gtr : bool
   If True, infer GTR model

relaxed_clock : dic
   If not None, use autocorrelated molecular clock model. Specify the
   clock parameters as :code:`{slack:<slack>, coupling:<coupling>}` dictionary.

n_iqd : int
   If not None, filter tree nodes which do not obey the molecular clock
   for the particular tree. The nodes, which deviate more than
   :code:`n_iqd` interquantile intervals from the molecular clock
   regression will be marked as 'BAD' and not used in the TreeTime
   analysis

resolve_polytomies : bool
   If True, attempt to resolve multiple mergers

max_iter : int
   Maximum number of iterations to optimize the tree

Tc : float, str
   If not None, use coalescent model to correct the branch lengths by
   introducing merger costs.

   If Tc is float, it is interpreted as the coalescence time scale

   If Tc is str, it should be one of (:code:`opt`, :code:`const`, :code:`skyline`)

fixed_clock_rate : float
   Fixed clock rate to be used. If None, infer clock rate from the molecular clock.

time_marginal : bool
   If True, perform a final round of marginal reconstruction of the node's positions.

sequence_marginal : bool, optional
    use marginal reconstruction for ancestral sequences

branch_length_mode : str
   Should be one of: :code:`joint`, :code:`marginal`, :code:`input`.

   If 'input', rely on the branch lengths in the input tree and skip directly
   to the maximum-likelihood ancestral sequence reconstruction.
   Otherwise, perform preliminary sequence reconstruction using parsimony
   algorithm and do branch length optimization

vary_rate : bool or float, optional
    redo the time tree estimation for rates +/- one standard deviation.
    if a float is passed, it is interpreted as standard deviation,
    otherwise this standard deviation is estimated from the root-to-tip regression

use_covariation : bool, optional
    default False, if False, rate estimates will be performed using simple
    regression ignoring phylogenetic covaration between nodes.

**kwargs
   Keyword arguments needed by the downstream functions


Returns
-------
TreeTime error/succces code : str
    return value depending on success or error