11from concurrent .futures import ThreadPoolExecutor , as_completed
22
3- # create circular kernel:
4- # draw outlines around artist:
53import matplotlib .patheffects as PathEffects
64import matplotlib .pyplot as plt
75import numpy as np
86import pandas as pd
97import tqdm
10- from scipy .ndimage import gaussian_filter , maximum_filter
8+ from scipy .ndimage import gaussian_filter
119from sklearn .decomposition import PCA
1210from sklearn .neighbors import NearestNeighbors
1311
14- from ._ssam2 import kde_2d
12+ from ._ssam2 import find_local_maxima , kde_2d
1513
1614
17- def _draw_outline (ax , artist , lw = 2 , color = "black" ):
15+ def _draw_outline (artist , lw = 2 , color = "black" ):
16+ "Draws outlines around the (text) artists for better legibility."
1817 _ = artist .set_path_effects (
1918 [PathEffects .withStroke (linewidth = lw , foreground = color ), PathEffects .Normal ()]
2019 )
@@ -43,33 +42,12 @@ def _plot_scalebar(
4342 )
4443
4544 if edge_color is not None :
46- _draw_outline (ax , plot_artist [0 ], lw = 5 , color = edge_color )
47- _draw_outline (ax , text_artist , lw = 5 , color = edge_color )
45+ _draw_outline (plot_artist [0 ], lw = 5 , color = edge_color )
46+ _draw_outline (text_artist , lw = 5 , color = edge_color )
4847
4948 return plot_artist , text_artist
5049
5150
52- def _create_circular_kernel (r ):
53- """
54- Creates a circular kernel of radius r.
55-
56- Parameters
57- ----------
58- r : int
59- The radius of the kernel.
60-
61- Returns
62- -------
63- kernel : np.array
64- A 2d array of the circular kernel.
65-
66- """
67-
68- span = np .linspace (- 1 , 1 , r * 2 )
69- X , Y = np .meshgrid (span , span )
70- return (X ** 2 + Y ** 2 ) ** 0.5 <= 1
71-
72-
7351def _get_kl_divergence (p , q ):
7452 # mask = (p!=0) * (q!=0)
7553 output = np .zeros (p .shape )
@@ -78,7 +56,7 @@ def _get_kl_divergence(p, q):
7856 return output
7957
8058
81- def _determine_localmax (distribution , min_distance = 3 , min_expression = 5 ):
59+ def _determine_localmax_and_sample (distribution , min_distance = 3 , min_expression = 5 ):
8260 """
8361 Returns a list of local maxima in a kde of the data frame.
8462
@@ -99,12 +77,8 @@ def _determine_localmax(distribution, min_distance=3, min_expression=5):
9977 A list of y coordinates of local maxima.
10078
10179 """
102- localmax_kernel = _create_circular_kernel (min_distance )
103- localmax_projection = distribution == maximum_filter (
104- distribution , footprint = localmax_kernel
105- )
10680
107- rois_x , rois_y = np . where (( distribution > min_expression ) & localmax_projection )
81+ rois_x , rois_y = find_local_maxima ( distribution , min_distance , min_expression )
10882
10983 return rois_x , rois_y , distribution [rois_x , rois_y ]
11084
@@ -148,15 +122,15 @@ def _min_to_max(arr, arr_min=None, arr_max=None):
148122
149123# define a function that fits expression data to into the umap embeddings:
150124def _transform_embeddings (
151- expression , pca , embedder_2d , embedder_3d , colors_min_max = [None , None ]
125+ expression ,
126+ pca ,
127+ embedder_2d ,
128+ embedder_3d ,
152129):
153130 factors = pca .transform (expression )
154131
155132 embedding = embedder_2d .transform (factors )
156133 embedding_color = embedder_3d .transform (factors )
157- # embedding_color = embedder_3d.transform(embedding)
158-
159- # embedding_color = _min_to_max(embedding_color,colors_min_max[0],colors_min_max[1])
160134
161135 return embedding , embedding_color
162136
@@ -192,12 +166,12 @@ def _plot_embeddings(
192166 )
193167
194168 text_artists = []
195- for i in range ( len ( celltypes ) ):
169+ for i , celltype in enumerate ( celltypes ):
196170 if not np .isnan (celltype_centers [i , 0 ]):
197171 t = ax .text (
198172 np .nan_to_num ((celltype_centers [i , 0 ])),
199173 np .nan_to_num (celltype_centers [i , 1 ]),
200- celltypes [ i ] ,
174+ celltype ,
201175 color = "k" ,
202176 fontsize = 12 ,
203177 )
@@ -364,6 +338,9 @@ def _compute_divergence_embedded(
364338 metric = "cosine_similarity" ,
365339 pca_divergence = 0.8 ,
366340):
341+ """This is a legacy function, replaced by _compute_divergence_patched. It contains other similarity measures than cosine similarity.
342+ To be integrated into the patch-based divergence computation later.
343+ """
367344 signal = _create_histogram (
368345 df ,
369346 genes ,
@@ -381,9 +358,6 @@ def _compute_divergence_embedded(
381358 df_top = df [df .z_delim < df .z ]
382359 df_bot = df [df .z_delim > df .z ]
383360
384- # dr_bottom = np.zeros((df_bottom.shape[0],df_bottom.shape[1], pca.components_.shape[0]))
385- # dr_top = np.zeros((df_bottom.shape[0],df_bottom.shape[1], pca.components_.shape[0]))
386-
387361 hists_top = np .zeros ((mask .sum (), pca .components_ .shape [0 ]))
388362 hists_bot = np .zeros ((mask .sum (), pca .components_ .shape [0 ]))
389363
@@ -481,8 +455,6 @@ def pearson_cross_correlation(a, b):
481455
482456
483457def _compute_embedding_vectors (subset_df , signal_mask , factor ):
484- # for i,g in tqdm.tqdm(enumerate(genes),total=len(genes)):
485-
486458 if len (subset_df ) < 2 :
487459 return None , None
488460
0 commit comments