def test_custom_function(self, adata: AnnData, backward: bool): vk = VelocityKernel(adata, backward=backward) vk.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme=CustomFuncHessian()) assert vk.params["scheme"] == str(CustomFuncHessian())
def test_estimate_softmax_scale(self, adata: AnnData): vk = VelocityKernel(adata) vk.compute_transition_matrix(mode="deterministic", show_progress_bar=False, softmax_scale=None) assert isinstance(vk.params["softmax_scale"], float)
def test_custom_function_stochastic_no_hessian(self, adata: AnnData): vk = VelocityKernel(adata) vk.compute_transition_matrix(mode="stochastic", scheme=CustomFunc(), softmax_scale=4, n_samples=10) assert vk.params["mode"] == "monte_carlo" assert vk.params["scheme"] == str(CustomFunc())
def test_row_normalized_dense_norm(self, adata: AnnData): vk = VelocityKernel(adata) vk.compute_transition_matrix(mode="deterministic", softmax_scale=4) T_det = vk.transition_matrix vk.compute_transition_matrix(mode="sampling") T_sam = vk.transition_matrix np.testing.assert_allclose(T_det.sum(1), 1, rtol=_rtol) np.testing.assert_allclose(T_sam.sum(1), 1, rtol=_rtol)
def test_constant_wrong_parentheses(self, adata: AnnData): k = VelocityKernel(adata).compute_transition_matrix( softmax_scale=4) + ( ConnectivityKernel(adata).compute_transition_matrix() + ConnectivityKernel(adata).compute_transition_matrix()) k.compute_transition_matrix() c1, c2, c3 = _is_bin_mult(k[0]), _is_bin_mult(k[1]), _is_bin_mult(k[2]) assert c1.transition_matrix == 1 / 3 assert c2.transition_matrix == 1 / 3 assert c3.transition_matrix == 1 / 3
def test_function_and_string_key(self, adata: AnnData, key: str, fn: Callable): vk_k = VelocityKernel(adata) vk_fn = VelocityKernel(adata) vk_k.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme=key) vk_fn.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme=fn) np.testing.assert_allclose(vk_k.transition_matrix.A, vk_fn.transition_matrix.A)
def test_transition_probabilities_bwd(self, adata: AnnData): # test whether transition probabilities in cellrank match those from scvelo, backward case sigma_test = 3 # compute transition probabilities using cellrank vk = VelocityKernel(adata, backward=True) vk.compute_transition_matrix(softmax_scale=sigma_test, mode="deterministic") T_cr = vk.transition_matrix pearson_correlation = vk.pearson_correlations T_exp = np.expm1(pearson_correlation * sigma_test) T_exp.data += 1 T_exp = _normalize(T_exp) np.testing.assert_allclose(T_exp.A, T_cr.A) # don't use data, can be reordered
def test_pearson_correlations_fwd(self, adata: AnnData): # test whether pearson correlations in cellrank match those from scvelo, forward case backward = False # compute pearson correlations using scvelo velo_graph = adata.uns["velocity_graph"] + adata.uns[ "velocity_graph_neg"] # compute pearson correlations using cellrank vk = VelocityKernel(adata, backward=backward) vk.compute_transition_matrix(mode="deterministic", softmax_scale=4) pearson_correlations_cr = vk.pearson_correlations pc_r = velo_graph.copy() pc_r.data = np.array( pearson_correlations_cr[(velo_graph != 0)]).squeeze() assert np.max(np.abs((pc_r - velo_graph).data)) < _rtol
def test_mc_and_second_order_fwd(self, adata: AnnData): vk_mc = VelocityKernel(adata, backward=False) vk_mc.compute_transition_matrix( mode="monte_carlo", show_progress_bar=False, n_samples=1000, n_jobs=4, softmax_scale=4, ) vk_s = VelocityKernel(adata, backward=False) vk_s.compute_transition_matrix(mode="stochastic", show_progress_bar=False, n_jobs=4, softmax_scale=4) val = np.mean( np.abs(vk_mc.transition_matrix.data - vk_s.transition_matrix.data)) assert val < 1e-3, val
def test_combination_correct_parameters(self, adata: AnnData): from cellrank.tl.kernels import CosineScheme k = VelocityKernel(adata).compute_transition_matrix( softmax_scale=4, seed=42, scheme="cosine", ) + (ConnectivityKernel(adata).compute_transition_matrix( density_normalize=False) + ConnectivityKernel(adata).compute_transition_matrix( density_normalize=True)) k.compute_transition_matrix() assert isinstance(k.params, dict) assert len(k.params) == 3 assert {"dnorm": True} in k.params.values() assert {"dnorm": False} in k.params.values() assert { "softmax_scale": 4, "mode": "deterministic", "seed": 42, "scheme": str(CosineScheme()), } in k.params.values()
def test_implementations_differ(self, adata: AnnData, backward: bool): vk_dot = VelocityKernel(adata, backward=backward) vk_dot.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme="dot_product") vk_cos = VelocityKernel(adata, backward=backward) vk_cos.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme="cosine") vk_cor = VelocityKernel(adata, backward=backward) vk_cor.compute_transition_matrix(mode="deterministic", softmax_scale=4, scheme="correlation") np.testing.assert_allclose(vk_dot.transition_matrix.sum(1), 1.0) np.testing.assert_allclose(vk_cor.transition_matrix.sum(1), 1.0) np.testing.assert_allclose(vk_cor.transition_matrix.sum(1), 1.0) assert not np.allclose(vk_dot.transition_matrix.A, vk_cos.transition_matrix.A) assert not np.allclose(vk_cos.transition_matrix.A, vk_cor.transition_matrix.A) assert not np.allclose(vk_cor.transition_matrix.A, vk_dot.transition_matrix.A)
def test_uninitialized_both(self, adata: AnnData): k = VelocityKernel(adata) + ConnectivityKernel(adata) with pytest.raises(RuntimeError): k.compute_transition_matrix()
def test_not_callable_object(self, adata: AnnData): vk = VelocityKernel(adata) with pytest.raises(TypeError, match="Expected `scheme` to be a function object"): vk.compute_transition_matrix(scheme=CustomFunc)
def test_row_normalized_dense_norm_stoch(self, adata: AnnData): vk = VelocityKernel(adata) vk.compute_transition_matrix(mode="stochastic", softmax_scale=4) T_stoch = vk.transition_matrix np.testing.assert_allclose(T_stoch.sum(1), 1, rtol=_rtol)
def test_custom_function_not_sum_to_1(self, adata: AnnData): vk = VelocityKernel(adata) with pytest.raises(ValueError, match=r"Matrix is not row-stochastic."): vk.compute_transition_matrix(scheme=InvalidFuncProbs())
def test_row_normalized(self, adata: AnnData): vk = VelocityKernel(adata) vk.compute_transition_matrix(density_normalize=False, softmax_scale=4) T = vk.transition_matrix np.testing.assert_allclose(T.sum(1), 1, rtol=_rtol)
def test_custom_function_invalid_hessian(self, adata: AnnData): vk = VelocityKernel(adata) with pytest.raises(ValueError, match=r"Expected full Hessian matrix"): vk.compute_transition_matrix(mode="stochastic", scheme=InvalidFuncHessianShape(), softmax_scale=4)
def transition_matrix( adata: AnnData, backward: bool = False, vkey: str = "velocity", xkey: str = "Ms", gene_subset: Optional[Iterable] = None, mode: str = VelocityMode.DETERMINISTIC.s, backward_mode: str = BackwardMode.TRANSPOSE.s, scheme: str = Scheme.CORRELATION.s, softmax_scale: Optional[float] = None, weight_connectivities: Optional[float] = 0.2, density_normalize: bool = True, key: Optional[str] = None, **kwargs, ) -> KernelExpression: """ Compute a transition matrix based on a combination of RNA Velocity and transcriptomic similarity. To learn more about the way in which the transition matrices are computed, see :class:`cellrank.tl.kernels.VelocityKernel` for the velocity-based transition matrix and :class:`cellrank.tl.kernels.ConnectivityKernel` for the transcriptomic-similarity-based transition matrix. Parameters ---------- %(adata)s %(backward)s vkey Key from ``adata.layers`` to access the velocities. xkey Key in ``adata.layers`` where expected gene expression counts are stored. gene_subset List of genes to be used to compute transition probabilities. By default, genes from ``adata.var['velocity_genes']`` are used. %(velocity_mode)s %(velocity_backward_mode_high_lvl)s %(velocity_scheme)s %(softmax_scale)s weight_connectivities Weight given to transcriptomic similarities as opposed to velocities. Must be in `[0, 1]`. density_normalize Whether to use density correction when computing the transition probabilities based on connectivities. Density correction is done as by [Haghverdi16]_. %(write_to_adata.parameters)s **kwargs Keyword arguments for :meth:`cellrank.tl.kernels.VelocityKernel.compute_transition_matrix`. Returns ------- :class:`cellrank.tl.KernelExpression` A kernel expression object containing the computed transition matrix. %(write_to_adata)s """ # initialise the velocity kernel and compute transition matrix vk = VelocityKernel(adata, backward=backward, vkey=vkey, xkey=xkey, gene_subset=gene_subset) vk.compute_transition_matrix( softmax_scale=softmax_scale, mode=mode, backward_mode=backward_mode, scheme=scheme, **kwargs, ) if weight_connectivities is not None: if 0 < weight_connectivities < 1: logg.info( f"Using a connectivity kernel with weight `{weight_connectivities}`" ) ck = ConnectivityKernel( adata, backward=backward).compute_transition_matrix( density_normalize=density_normalize) final = ((1 - weight_connectivities) * vk + weight_connectivities * ck).compute_transition_matrix() elif weight_connectivities == 0: final = vk elif weight_connectivities == 1: final = ConnectivityKernel( adata, backward=backward).compute_transition_matrix( density_normalize=density_normalize) else: raise ValueError( f"Parameter `weight_connectivities` must be in range `[0, 1]`, found `{weight_connectivities}`." ) else: final = vk final.write_to_adata(key=key) return final
def test_not_callable(self, adata: AnnData): vk = VelocityKernel(adata) with pytest.raises(TypeError, match="Expected `scheme` to be a function, found"): vk.compute_transition_matrix(scheme=1311)
for key in samples: scv.tl.velocity_graph(samples[key], mode_neighbors='connectivities', compute_uncertainties=True) # Forward direction (final states) outdir = 'results/trajectory/cellrank/forward' if not os.path.exists(outdir): os.makedirs(outdir) scv.settings.figdir = outdir for key in samples: vk = VelocityKernel(samples[key]) vk.compute_transition_matrix(softmax_scale=None) g = GPCCA(vk) g.compute_schur(n_components=20) g.plot_spectrum(real_only=False, save="{}_eigenvalues.png".format(key)) if key == "H508_EV" or key == "HT29_EV": g.plot_schur(use=4, cluster_key=clusters, show=False, dpi=300, save='{}_schur.png'.format(key)) g.compute_metastable_states(n_states=4, cluster_key=clusters) g.plot_metastable_states(show=False, dpi=300, save='{}_metastable.png'.format(key)) g.plot_metastable_states( same_plot=False,
def test_invalid_string_key(self, adata: AnnData): vk = VelocityKernel(adata) with pytest.raises(ValueError): vk.compute_transition_matrix(scheme="foobar")