def recover_dynamics(data, var_names='<STR_LIT:all>', max_iter=<NUM_LIT:100>, learning_rate=None, add_key='<STR_LIT>', t_max=None, use_raw=False,<EOL>min_loss=True, fix_scaling=None, load_pars=None, return_model=False, plot_results=False, copy=False, **kwargs):
adata = data.copy() if copy else data<EOL>logg.info('<STR_LIT>', r=True)<EOL>if var_names is '<STR_LIT:all>':<EOL><INDENT>var_names = adata.var_names.tolist()<EOL><DEDENT>else:<EOL><INDENT>var_names = make_unique_list(var_names, allow_array=True)<EOL>var_names = [name for name in var_names if name in adata.var_names]<EOL><DEDENT>if '<STR_LIT>' in var_names and '<STR_LIT>' in adata.var.keys():<EOL><INDENT>var_names = [name for name in var_names if adata[:, name].var.velocity_genes.values]<EOL><DEDENT>alpha, beta, gamma, t_, scaling = read_pars(adata)<EOL>idx = []<EOL>L, P, T = [], [], adata.layers['<STR_LIT>'] if '<STR_LIT>' in adata.layers.keys() else np.zeros(adata.shape) * np.nan<EOL>for i, gene in enumerate(var_names):<EOL><INDENT>dm = DynamicsRecovery(adata, gene, use_raw=use_raw, load_pars=load_pars, fix_scaling=fix_scaling)<EOL>if max_iter > <NUM_LIT:1>:<EOL><INDENT>dm.fit(max_iter, learning_rate, **kwargs)<EOL><DEDENT>ix = np.where(adata.var_names == gene)[<NUM_LIT:0>][<NUM_LIT:0>]<EOL>idx.append(ix)<EOL>alpha[ix], beta[ix], gamma[ix], t_[ix], scaling[ix] = dm.pars[:, np.argmin(dm.loss) if min_loss else -<NUM_LIT:1>]<EOL>T[:, ix] = dm.t<EOL>L.append(dm.loss)<EOL>if plot_results and i < <NUM_LIT:4>:<EOL><INDENT>P.append(dm.pars)<EOL><DEDENT><DEDENT>T_max = np.percentile(T, <NUM_LIT>, axis=<NUM_LIT:0>) - np.percentile(T, <NUM_LIT:5>, axis=<NUM_LIT:0>)<EOL>m = t_max / T_max if t_max is not None else np.ones(adata.n_vars)<EOL>alpha, beta, gamma, T, t_ = alpha / m, beta / m, gamma / m, T * m, t_ * m<EOL>write_pars(adata, [alpha, beta, gamma, t_, scaling])<EOL>adata.layers['<STR_LIT>'] = T<EOL>cur_len = adata.varm['<STR_LIT>'].shape[<NUM_LIT:1>] if '<STR_LIT>' in adata.varm.keys() else <NUM_LIT:2><EOL>max_len = max(np.max([len(l) for l in L]), cur_len)<EOL>loss = np.ones((adata.n_vars, max_len)) * np.nan<EOL>if '<STR_LIT>' in adata.varm.keys():<EOL><INDENT>loss[:, :cur_len] = adata.varm['<STR_LIT>']<EOL><DEDENT>loss[idx] = np.vstack([np.concatenate([l, np.ones(max_len-len(l)) * np.nan]) for l in L])<EOL>adata.varm['<STR_LIT>'] = loss<EOL>logg.info('<STR_LIT>', time=True, end='<STR_LIT:U+0020>' if settings.verbosity > <NUM_LIT:2> else '<STR_LIT:\n>')<EOL>logg.hint('<STR_LIT>' <EOL>'<STR_LIT>' + add_key + '<STR_LIT>' + '<STR_LIT>')<EOL>if plot_results:  <EOL><INDENT>figsize = [<NUM_LIT:12>, <NUM_LIT:5>]  <EOL>fontsize = rcParams['<STR_LIT>']<EOL>fig, axes = pl.subplots(nrows=len(var_names[:<NUM_LIT:4>]), ncols=<NUM_LIT:6>, figsize=figsize)<EOL>pl.subplots_adjust(wspace=<NUM_LIT>, hspace=<NUM_LIT:0.5>)<EOL>for i, gene in enumerate(var_names[:<NUM_LIT:4>]):<EOL><INDENT>P[i] *= np.array([<NUM_LIT:1> / m[idx[i]], <NUM_LIT:1> / m[idx[i]], <NUM_LIT:1> / m[idx[i]], m[idx[i]], <NUM_LIT:1>])[:, None]<EOL>for j, pij in enumerate(P[i]):<EOL><INDENT>axes[i][j].plot(pij)<EOL><DEDENT>axes[i][len(P[i])].plot(L[i])<EOL>if i == <NUM_LIT:0>:<EOL><INDENT>for j, name in enumerate(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>axes[i][j].set_title(name, fontsize=fontsize)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return dm if return_model else adata if copy else None<EOL>
Estimates velocities in a gene-specific manner

    Arguments
    ---------
    data: :class:`~anndata.AnnData`
        Annotated data matrix.

    Returns
    -------
    Returns or updates `adata`