sclab 0.3.0__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sclab might be problematic. Click here for more details.

sclab/__init__.py CHANGED
@@ -6,4 +6,4 @@ __all__ = [
6
6
  "SCLabDashboard",
7
7
  ]
8
8
 
9
- __version__ = "0.3.0"
9
+ __version__ = "0.3.1"
sclab/_sclab.py CHANGED
@@ -171,7 +171,11 @@ class DataLoader(VBox):
171
171
  self.upload = FileUpload(layout=Layout(width="200px"))
172
172
  self.upload_info = Output(layout=Layout(width="95%"))
173
173
  self.upload_row = HBox(
174
- [self.upload_row_label, self.upload, self.upload_info],
174
+ [
175
+ self.upload_row_label,
176
+ self.upload,
177
+ self.upload_info,
178
+ ],
175
179
  layout=Layout(width="100%"),
176
180
  )
177
181
  self.upload.observe(self.on_upload, "value")
@@ -214,8 +218,8 @@ class DataLoader(VBox):
214
218
  VBox.__init__(
215
219
  self,
216
220
  [
217
- self.url_row,
218
- self.upload_row,
221
+ # self.url_row,
222
+ # self.upload_row,
219
223
  self.defined_adatas_row,
220
224
  self.progress_output,
221
225
  ],
@@ -1025,22 +1025,37 @@ class Processor(EventClient):
1025
1025
  else:
1026
1026
  control.value = current_value
1027
1027
 
1028
- def dset_anndata_layers_change_callback(self, layers):
1029
- options = {layer: layer for layer in layers}
1028
+ def dset_anndata_layers_change_callback(self, *args, **kwargs):
1029
+ layer_options = {key: key for key in self.dataset.adata.layers.keys()}
1030
+ obsm_options = {key: key for key in self.dataset.adata.obsm.keys()}
1031
+
1030
1032
  for control in self.all_controls_list:
1031
1033
  if not isinstance(control, Dropdown):
1032
1034
  continue
1033
1035
  description: str = control.description
1036
+
1034
1037
  if description.lower().strip(" :.") == "layer":
1035
1038
  current_value = control.value
1036
- control.options = options
1039
+ control.options = layer_options
1040
+ if current_value not in control.options:
1041
+ control.value = None
1042
+ else:
1043
+ control.value = current_value
1044
+
1045
+ if description.lower().strip(" :.") == "use rep":
1046
+ current_value = control.value
1047
+ control.options = {**layer_options, **obsm_options}
1037
1048
  if current_value not in control.options:
1038
1049
  control.value = None
1039
1050
  else:
1040
1051
  control.value = current_value
1041
1052
 
1042
1053
  def dset_data_dict_change_callback(self, *args, **kwargs):
1043
- options = {v: v for v in self.dataset.adata.obsm.keys()}
1054
+ options = [
1055
+ *self.dataset.adata.layers.keys(),
1056
+ *self.dataset.adata.obsm.keys(),
1057
+ ]
1058
+ options = {v: v for v in options}
1044
1059
  for control in self.all_controls_list:
1045
1060
  if not isinstance(control, Dropdown):
1046
1061
  continue
@@ -10,20 +10,6 @@ class Integration(ProcessorStepBase):
10
10
  description: str = "Integration"
11
11
 
12
12
  def __init__(self, parent: Processor) -> None:
13
- try:
14
- from scanpy.external.pp import harmony_integrate # noqa
15
- except ImportError:
16
- try:
17
- from scanpy.external.pp import scanorama_integrate # noqa
18
- except ImportError:
19
- raise ImportError(
20
- "Integration requires scanorama or harmony to be installed.\n"
21
- "\nInstall with one of:\n"
22
- "\npip install harmony"
23
- "\npip install scanorama"
24
- "\n"
25
- )
26
-
27
13
  cat_metadata = parent.dataset._metadata.select_dtypes(
28
14
  include=["object", "category"]
29
15
  )
@@ -44,8 +30,8 @@ class Integration(ProcessorStepBase):
44
30
  description="Reference Batch",
45
31
  ),
46
32
  flavor=Dropdown(
47
- options=["harmony", "scanorama"],
48
- value="harmony",
33
+ options=["cca", "harmony", "scanorama"],
34
+ value="cca",
49
35
  description="Flavor",
50
36
  ),
51
37
  max_iters=IntText(
@@ -96,6 +82,14 @@ class Integration(ProcessorStepBase):
96
82
  self.broker.std_output.clear_output(wait=False)
97
83
  with self.broker.std_output:
98
84
  match flavor:
85
+ case "cca":
86
+ from sclab.preprocess import cca_integrate
87
+
88
+ cca_integrate(
89
+ **kvargs,
90
+ reference_batch=reference_batch,
91
+ )
92
+
99
93
  case "harmony":
100
94
  from sclab.preprocess import harmony_integrate
101
95
 
@@ -1,6 +1,6 @@
1
1
  import pandas as pd
2
2
  import plotly.express as px
3
- from ipywidgets import Button, Dropdown, IntText
3
+ from ipywidgets import Button, Checkbox, Dropdown, IntText
4
4
 
5
5
  from sclab.dataset.processor import Processor
6
6
  from sclab.dataset.processor.step import ProcessorStepBase
@@ -26,6 +26,7 @@ class PCA(ProcessorStepBase):
26
26
  n_comps=IntText(value=30, description="N comps."),
27
27
  mask_var=Dropdown(options=mask_var_options, description="Genes mask"),
28
28
  **parent.make_selectbatch_drowpdown(description="Reference Batch"),
29
+ zero_center=Checkbox(value=False, description="Zero center"),
29
30
  )
30
31
 
31
32
  super().__init__(
@@ -56,6 +57,7 @@ class PCA(ProcessorStepBase):
56
57
  n_comps: int = 30,
57
58
  mask_var: str | None = None,
58
59
  reference_batch: str | None = None,
60
+ zero_center: bool = False,
59
61
  ):
60
62
  import scanpy as sc
61
63
 
@@ -93,6 +95,9 @@ class PCA(ProcessorStepBase):
93
95
  sc.pp.pca(adata, n_comps=n_comps, mask_var=mask_var, svd_solver="arpack")
94
96
  adata.obsm["X_pca"] = adata.X.dot(adata.varm["PCs"])
95
97
 
98
+ if zero_center:
99
+ adata.obsm["X_pca"] -= adata.obsm["X_pca"].mean(axis=0, keepdims=True)
100
+
96
101
  self.plot_variance_ratio_button.disabled = False
97
102
  self.broker.publish(
98
103
  "dset_data_dict_change", self.parent.dataset.data_dict, "X_pca"
@@ -1,5 +1,7 @@
1
1
  from ._guided_pseudotime import GuidedPseudotime
2
+ from ._transfer_metadata import TransferMetadata
2
3
 
3
4
  __all__ = [
4
5
  "GuidedPseudotime",
6
+ "TransferMetadata",
5
7
  ]
@@ -0,0 +1,186 @@
1
+ from typing import Literal
2
+
3
+ import numpy as np
4
+ from ipywidgets import (
5
+ Checkbox,
6
+ Dropdown,
7
+ FloatText,
8
+ IntText,
9
+ )
10
+ from pandas.api.types import is_numeric_dtype
11
+
12
+ from sclab.dataset.processor import Processor
13
+ from sclab.dataset.processor.step import ProcessorStepBase
14
+
15
+ _2PI = 2 * np.pi
16
+
17
+
18
+ class TransferMetadata(ProcessorStepBase):
19
+ parent: Processor
20
+ name: str = "transfer_metadata"
21
+ description: str = "Transfer Metadata"
22
+
23
+ run_button_description = "Transfer Metadata"
24
+
25
+ def __init__(self, parent: Processor) -> None:
26
+ variable_controls = dict(
27
+ group_key=Dropdown(
28
+ options=[],
29
+ value=None,
30
+ description="Group Key",
31
+ ),
32
+ source_group=Dropdown(
33
+ options=[],
34
+ value=None,
35
+ description="Source Group",
36
+ ),
37
+ column=Dropdown(
38
+ options=[],
39
+ value=None,
40
+ description="Column",
41
+ ),
42
+ periodic=Checkbox(
43
+ value=False,
44
+ description="Periodic",
45
+ ),
46
+ vmin=FloatText(
47
+ value=0,
48
+ description="Vmin",
49
+ continuous_update=False,
50
+ ),
51
+ vmax=FloatText(
52
+ value=1,
53
+ description="Vmax",
54
+ continuous_update=False,
55
+ ),
56
+ min_neighs=IntText(
57
+ value=5,
58
+ min=3,
59
+ description="Min Neighs",
60
+ continuous_update=False,
61
+ ),
62
+ weight_by=Dropdown(
63
+ options=["connectivity", "distance", "constant"],
64
+ value="connectivity",
65
+ description="Weight By",
66
+ ),
67
+ )
68
+
69
+ super().__init__(
70
+ parent=parent,
71
+ fixed_params={},
72
+ variable_controls=variable_controls,
73
+ )
74
+
75
+ self._update_groupby_options()
76
+ self._update_column_options()
77
+ self._update_numeric_column_controls()
78
+
79
+ self.variable_controls["group_key"].observe(
80
+ self._update_source_group_options, "value", "change"
81
+ )
82
+ self.variable_controls["column"].observe(
83
+ self._update_numeric_column_controls, "value", "change"
84
+ )
85
+ self.variable_controls["periodic"].observe(
86
+ self._update_vmin_vmax_visibility, "value", "change"
87
+ )
88
+
89
+ def _update_groupby_options(self, *args, **kwargs):
90
+ metadata = self.parent.dataset._metadata.select_dtypes(include=["category"])
91
+ options = {"": None, **{c: c for c in metadata.columns}}
92
+ self.variable_controls["group_key"].options = options
93
+
94
+ def _update_source_group_options(self, *args, **kwargs):
95
+ group_key = self.variable_controls["group_key"].value
96
+ if group_key is None:
97
+ self.variable_controls["source_group"].options = ("",)
98
+ return
99
+
100
+ options = self.parent.dataset._metadata[group_key].sort_values().unique()
101
+ options = {"": None, **{c: c for c in options}}
102
+ self.variable_controls["source_group"].options = options
103
+
104
+ def _update_column_options(self, *args, **kwargs):
105
+ metadata = self.parent.dataset._metadata.select_dtypes(
106
+ include=["category", "bool", "number"]
107
+ )
108
+ options = {"": None, **{c: c for c in metadata.columns}}
109
+ self.variable_controls["column"].options = options
110
+
111
+ def _update_numeric_column_controls(self, *args, **kwargs):
112
+ column = self.variable_controls["column"].value
113
+ if column is None:
114
+ self._hide_control(self.variable_controls["periodic"])
115
+ self._hide_control(self.variable_controls["vmin"])
116
+ self._hide_control(self.variable_controls["vmax"])
117
+ return
118
+
119
+ series = self.parent.dataset._metadata[column]
120
+ periodic = self.variable_controls["periodic"].value
121
+
122
+ if is_numeric_dtype(series):
123
+ self._show_control(self.variable_controls["periodic"])
124
+ if periodic:
125
+ self._show_control(self.variable_controls["vmin"])
126
+ self._show_control(self.variable_controls["vmax"])
127
+ else:
128
+ self._hide_control(self.variable_controls["periodic"])
129
+ self._hide_control(self.variable_controls["vmin"])
130
+ self._hide_control(self.variable_controls["vmax"])
131
+
132
+ def _update_vmin_vmax_visibility(self, *args, **kwargs):
133
+ periodic = self.variable_controls["periodic"].value
134
+
135
+ if periodic:
136
+ self._show_control(self.variable_controls["vmin"])
137
+ self._show_control(self.variable_controls["vmax"])
138
+ else:
139
+ self._hide_control(self.variable_controls["vmin"])
140
+ self._hide_control(self.variable_controls["vmax"])
141
+
142
+ def _hide_control(self, control):
143
+ control.layout.visibility = "hidden"
144
+ control.layout.height = "0px"
145
+
146
+ def _show_control(self, control):
147
+ control.layout.visibility = "visible"
148
+ control.layout.height = "28px"
149
+
150
+ def function(
151
+ self,
152
+ group_key: str,
153
+ source_group: str,
154
+ column: str,
155
+ periodic: bool = False,
156
+ vmin: float = 0,
157
+ vmax: float = 1,
158
+ min_neighs: int = 5,
159
+ weight_by: Literal["connectivity", "distance", "constant"] = "connectivity",
160
+ **kwargs,
161
+ ):
162
+ from ...preprocess._transfer_metadata import transfer_metadata
163
+
164
+ self.output.clear_output(wait=True)
165
+ with self.output:
166
+ transfer_metadata(
167
+ self.parent.dataset.adata,
168
+ group_key=group_key,
169
+ source_group=source_group,
170
+ column=column,
171
+ periodic=periodic,
172
+ vmin=vmin,
173
+ vmax=vmax,
174
+ min_neighs=min_neighs,
175
+ weight_by=weight_by,
176
+ )
177
+
178
+ new_column = f"transferred_{column}"
179
+
180
+ self.broker.publish(
181
+ "dset_metadata_change", self.parent.dataset.metadata, new_column
182
+ )
183
+
184
+ def dset_metadata_change_callback(self, *args, **kwargs):
185
+ self._update_groupby_options(*args, **kwargs)
186
+ self._update_column_options(*args, **kwargs)
sclab/methods/__init__.py CHANGED
@@ -13,7 +13,7 @@ from ..examples.processor_steps import (
13
13
  Neighbors,
14
14
  Preprocess,
15
15
  )
16
- from ..gui.components import GuidedPseudotime
16
+ from ..gui.components import GuidedPseudotime, TransferMetadata
17
17
 
18
18
  __all__ = [
19
19
  "QC",
@@ -32,17 +32,9 @@ __all__ = [
32
32
  register_sclab_method("Processing")(QC)
33
33
  register_sclab_method("Processing")(Preprocess)
34
34
  register_sclab_method("Processing")(PCA)
35
-
36
- if any(
37
- [
38
- find_spec("harmonypy"),
39
- find_spec("scanorama"),
40
- ]
41
- ):
42
- register_sclab_method("Processing")(Integration)
43
-
44
-
35
+ register_sclab_method("Processing")(Integration)
45
36
  register_sclab_method("Processing")(Neighbors)
37
+ register_sclab_method("Processing")(TransferMetadata)
46
38
  register_sclab_method("Processing")(UMAP)
47
39
  register_sclab_method("Processing")(Cluster)
48
40
 
@@ -1,4 +1,4 @@
1
- from ._cca_integrate import cca_integrate_pair
1
+ from ._cca_integrate import cca_integrate, cca_integrate_pair
2
2
  from ._filter_obs import filter_obs
3
3
  from ._harmony_integrate import harmony_integrate
4
4
  from ._normalize_weighted import normalize_weighted
@@ -7,6 +7,7 @@ from ._transfer_metadata import transfer_metadata
7
7
  from ._transform import pool_neighbors
8
8
 
9
9
  __all__ = [
10
+ "cca_integrate",
10
11
  "cca_integrate_pair",
11
12
  "filter_obs",
12
13
  "harmony_integrate",
sclab/preprocess/_cca.py CHANGED
@@ -19,7 +19,7 @@ def cca(
19
19
  svd_solver: Literal["full", "partial", "randomized"] = "partial",
20
20
  normalize: bool = False,
21
21
  random_state=42,
22
- ):
22
+ ) -> tuple[NDArray, NDArray, NDArray]:
23
23
  """
24
24
  CCA-style integration for two single-cell matrices with unequal numbers of cells.
25
25
 
@@ -4,6 +4,38 @@ from anndata import AnnData
4
4
  from ._cca import cca
5
5
 
6
6
 
7
+ def cca_integrate(
8
+ adata: AnnData,
9
+ key: str,
10
+ *,
11
+ basis: str = "X",
12
+ adjusted_basis: str | None = None,
13
+ reference_batch: str | list[str] | None = None,
14
+ mask_var: str | None = None,
15
+ n_components: int = 30,
16
+ svd_solver: str = "partial",
17
+ normalize: bool = False,
18
+ random_state: int | None = None,
19
+ ):
20
+ n_groups = adata.obs[key].nunique()
21
+ if n_groups == 2:
22
+ cca_integrate_pair(
23
+ adata,
24
+ key,
25
+ adata.obs[key].unique()[0],
26
+ adata.obs[key].unique()[1],
27
+ basis=basis,
28
+ adjusted_basis=adjusted_basis,
29
+ mask_var=mask_var,
30
+ n_components=n_components,
31
+ svd_solver=svd_solver,
32
+ normalize=normalize,
33
+ random_state=random_state,
34
+ )
35
+ else:
36
+ raise NotImplementedError
37
+
38
+
7
39
  def cca_integrate_pair(
8
40
  adata: AnnData,
9
41
  key: str,
@@ -13,7 +45,7 @@ def cca_integrate_pair(
13
45
  basis: str | None = None,
14
46
  adjusted_basis: str | None = None,
15
47
  mask_var: str | None = None,
16
- n_components: int = 50,
48
+ n_components: int = 30,
17
49
  svd_solver: str = "partial",
18
50
  normalize: bool = False,
19
51
  random_state: int | None = None,
@@ -17,8 +17,8 @@ Nat Biotechnol 41, 604-606 (2023). https://doi.org/10.1038/s41587-023-01733-8
17
17
 
18
18
  from collections.abc import Sequence
19
19
 
20
- from anndata import AnnData
21
20
  import numpy as np
21
+ from anndata import AnnData
22
22
 
23
23
  from ._harmony import run_harmony
24
24
 
@@ -28,12 +28,15 @@ def harmony_integrate(
28
28
  key: str | Sequence[str],
29
29
  *,
30
30
  basis: str = "X_pca",
31
- adjusted_basis: str = "X_pca_harmony",
31
+ adjusted_basis: str | None = None,
32
32
  reference_batch: str | list[str] | None = None,
33
33
  **kwargs,
34
34
  ):
35
35
  """Use harmonypy :cite:p:`Korsunsky2019` to integrate different experiments."""
36
36
 
37
+ if adjusted_basis is None:
38
+ adjusted_basis = f"{basis}_harmony"
39
+
37
40
  if isinstance(reference_batch, str):
38
41
  reference_batch = [reference_batch]
39
42
 
@@ -89,9 +89,9 @@ def density(
89
89
  )
90
90
 
91
91
  if plot_density | plot_density_fit | plot_density_fit_derivative | plot_histogram:
92
- from ..utils import plot
92
+ from ..utils.density_nd import density_result_1d
93
93
 
94
- plot.density_result_1d(
94
+ density_result_1d(
95
95
  rslt,
96
96
  data=times[~np.isnan(times)],
97
97
  density_fit_lam=lam,
@@ -207,9 +207,9 @@ def density_dynamics(
207
207
  )
208
208
 
209
209
  if plot_density | plot_density_fit | plot_density_fit_derivative | plot_histogram:
210
- from ..utils import plot
210
+ from ..utils.density_nd import density_result_1d
211
211
 
212
- ax = plot.density_result_1d(
212
+ ax = density_result_1d(
213
213
  rslt,
214
214
  data=times[~np.isnan(times)],
215
215
  density_fit_lam=lam,
@@ -1,6 +1,7 @@
1
1
  from itertools import product
2
2
  from typing import Literal, NamedTuple
3
3
 
4
+ import matplotlib.pyplot as plt
4
5
  import numpy as np
5
6
  from numpy.typing import NDArray
6
7
  from scipy.integrate import trapezoid
@@ -134,3 +135,81 @@ def fit_density_1d(
134
135
  )
135
136
 
136
137
  return rslt, bspl
138
+
139
+
140
+ def density_result_1d(
141
+ rslt: DensityResult,
142
+ data: NDArray | None = None,
143
+ density_fit_lam: float = 1e-6,
144
+ plot_density: bool = False,
145
+ plot_density_fit: bool = True,
146
+ plot_density_fit_derivative: bool = False,
147
+ plot_histogram: bool = False,
148
+ histogram_nbins: int = 50,
149
+ ax: plt.Axes | None = None,
150
+ show: bool = True,
151
+ ):
152
+ if plot_density | plot_density_fit | plot_density_fit_derivative | plot_histogram:
153
+ pass
154
+ else:
155
+ raise ValueError("At least one of the plotting options must be True")
156
+
157
+ tmin, tmax = rslt.grid.min(), rslt.grid.max()
158
+ bspl = fit_smoothing_spline(
159
+ rslt.grid[:, 0],
160
+ rslt.density,
161
+ t_range=(tmin, tmax),
162
+ lam=density_fit_lam,
163
+ periodic=rslt.periodic,
164
+ )
165
+ if ax is None:
166
+ plt.figure(figsize=(10, 3))
167
+ else:
168
+ plt.sca(ax)
169
+
170
+ ax = plt.gca()
171
+ if plot_density:
172
+ ax.plot(rslt.grid.flatten(), rslt.density, color="black", linewidth=0.5)
173
+
174
+ if plot_histogram:
175
+ assert data is not None, "data must be provided if plot_histogram=True"
176
+ # we expand the time vector to make sure that the first and last point
177
+ # are not cut by the boundary. This also helps to avoid the problem of
178
+ # the first and last point having different values (should be periodic).
179
+ tt = np.concatenate([data - tmax, data, data + tmax])
180
+ bins = np.linspace(-tmax, 2 * tmax, histogram_nbins * 3 + 1)
181
+ dd = np.histogram(tt, bins=bins, density=True)[0]
182
+ # we take the middle points of the bins
183
+ xx = bins[:-1] + np.diff(bins) / 2
184
+ # we recover the original time vector and corresponding density
185
+ x = xx[histogram_nbins : 2 * histogram_nbins]
186
+ d = dd[histogram_nbins : 2 * histogram_nbins] * 3 # correct the density
187
+ ax.bar(x, d, width=1 / histogram_nbins, fill=False, linewidth=0.5)
188
+
189
+ x = np.linspace(tmin, tmax, 2**10 + 1)
190
+ if plot_density_fit:
191
+ plt.plot(x, bspl(x), color="blue")
192
+
193
+ ax.set_ylabel("Density", color="blue")
194
+ ax.set_yticks([])
195
+
196
+ ymin, ymax = plt.ylim()
197
+ # add a bit of padding in the y axis (about 10% of current range)
198
+ plt.ylim(ymin, ymax + 0.10 * (ymax - ymin))
199
+
200
+ if plot_density_fit_derivative:
201
+ if plot_density or histogram_nbins or plot_density_fit:
202
+ plt.twinx()
203
+ plt.plot(x, bspl.derivative()(x), color="red")
204
+ plt.hlines(0, tmin, tmax, linestyles="dashed", linewidth=0.5, color="black")
205
+ plt.ylabel("Derivative", color="red")
206
+ plt.gca().set_yticks([])
207
+
208
+ # add padding in the y axis to make zero be in the middle
209
+ ymax = np.abs(plt.ylim()).max() * 1.05
210
+ plt.ylim(-ymax, ymax)
211
+
212
+ if show:
213
+ plt.show()
214
+ else:
215
+ return plt.gca()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sclab
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: sclab
5
5
  Author-email: Argenis Arriojas <ArriojasMaldonado001@umb.edu>
6
6
  Requires-Python: >=3.10,<3.13
@@ -1,7 +1,7 @@
1
- sclab/__init__.py,sha256=c1t2JlHvk3gNl7hJgMnqPYJ0157TYvTSnk4sqnqqOXg,132
1
+ sclab/__init__.py,sha256=8CMvbWDJrjAoC3ycfq28IKCXtE7xhAm_iORs4Jj6yi8,132
2
2
  sclab/_io.py,sha256=5ISxIPbE233UiOt3QEs9fkLO8DLLEe5HrMnZoR-KLYE,2662
3
3
  sclab/_methods_registry.py,sha256=RcffyRuuLzHqsnAdbBL4W1GmZx80d9AxdGjUnx1mbNg,1704
4
- sclab/_sclab.py,sha256=-ukFb0bWX5MPZsKnoXBJ9SvKyQpuTK4VUCzmWYnAVNM,9062
4
+ sclab/_sclab.py,sha256=P7rR82jPPNRp4K9s_GBK0Qcd3xYt7Qc4Zsd-rxiVAK8,9133
5
5
  sclab/dataset/__init__.py,sha256=f9PoXIMAPnC3Var1ODr3mXkotW6u6NRPQvlgcWYXk54,143
6
6
  sclab/dataset/_dataset.py,sha256=wsbWnBHnlGJ779RV1Vv7RfxlEzHCfUZKNT3FTI1mu9g,14248
7
7
  sclab/dataset/_exceptions.py,sha256=g8RJL8PiRmD4--PkOs5CZth_qeaduvieMlKJNkrUIYA,45
@@ -10,7 +10,7 @@ sclab/dataset/plotter/_controls.py,sha256=NBDdtY1wQbIEvE_WToigR5bEEoi3z30_67T_dL
10
10
  sclab/dataset/plotter/_plotter.py,sha256=EXwk6KSM7FOyLLJ8HCgIB_2m730t0kHsVKWfQOxL6kA,37023
11
11
  sclab/dataset/plotter/_utils.py,sha256=ANm_R9PJd33-QJtZzqXCN5pJ_XrJ7AA4AvSHaDRbOMA,11595
12
12
  sclab/dataset/processor/__init__.py,sha256=v8Qbusb6h8oSndv9q-12vzHrz5BDF3N2LCkQG9KC19I,104
13
- sclab/dataset/processor/_processor.py,sha256=H8smeuHPnJVToSxEgGNHUpyNwKYqP-Itp5jMVIgnjbc,41104
13
+ sclab/dataset/processor/_processor.py,sha256=ink2eqi7hMt4DunHD4U1KqkKNQd23yJiDOgsmgZTsb8,41684
14
14
  sclab/dataset/processor/_results_panel.py,sha256=p2xmHgoYfpkPXj-SjRGTmAPAwL1VC8I70iFD_o-90AE,2342
15
15
  sclab/dataset/processor/step/__init__.py,sha256=j8j4oU9NMdWHn6kVjft7Klm6xme8M6wzebxJj_zNehg,179
16
16
  sclab/dataset/processor/step/_basic_processor_step.py,sha256=7NKC4W-I_EU3QBPi5BL9-NwAF_h6_oWl1l_kEk6gSAg,3640
@@ -25,22 +25,23 @@ sclab/examples/processor_steps/_cluster.py,sha256=olbri3HWPBU8p__r9kP9tgWaJoUJ2b
25
25
  sclab/examples/processor_steps/_differential_expression.py,sha256=uEToPiACCgo42oZidAw5DFgWVcDnChWzVRlVzn53K34,11567
26
26
  sclab/examples/processor_steps/_doublet_detection.py,sha256=eFQtRsdvBWJ_v3HH08v-KbjYius-fj1pg1HBm0mjADg,2114
27
27
  sclab/examples/processor_steps/_gene_expression.py,sha256=io_U53TQ3bpclGZ7xjuQHws4Lei5_nMpWTKbvD2zqs0,4216
28
- sclab/examples/processor_steps/_integration.py,sha256=3WtkMZQTn0VNnLn0q5iVaOa3tmC-L_CsBSAM_YlMDzQ,3733
28
+ sclab/examples/processor_steps/_integration.py,sha256=40nIM19VnBALMQXYO9XpYczH7gEcpIUb-DLdYraxzxs,3444
29
29
  sclab/examples/processor_steps/_neighbors.py,sha256=jGpoPtlN8nlcsOqUOiqTPQgGzbpToLAVR1By2SHBo5U,2949
30
- sclab/examples/processor_steps/_pca.py,sha256=a0-d-ayEM2uywgtU6uGAhaoQVW-blTTLjP7h0veSCfE,4566
30
+ sclab/examples/processor_steps/_pca.py,sha256=kULbPPTAMqAgECyycmpf5dpU-FYPJSLbTO-UEkOb5mo,4798
31
31
  sclab/examples/processor_steps/_preprocess.py,sha256=kKqOQWyBC3BFLYVsCWRPwaXHeuWG1s69puvwhDQK5Eg,6809
32
32
  sclab/examples/processor_steps/_qc.py,sha256=3e5TTGPNWbGPJBX0Sx18np8qcrgPznUuJJ-DwCrRZ0U,3684
33
33
  sclab/examples/processor_steps/_umap.py,sha256=Mzxj4LiZfh3WT5lS_BO_lTleC5jMoUm5_km_gvzU_I8,1402
34
34
  sclab/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- sclab/gui/components/__init__.py,sha256=RaCj_yEgWhdxNKDf0mBgQ3qy3VWJ0UB7hF0AkSs2_OI,88
35
+ sclab/gui/components/__init__.py,sha256=X0-cGJmII76qpWHEBe49miS2gPw3esMAwp61z23w_1Q,161
36
36
  sclab/gui/components/_guided_pseudotime.py,sha256=sxI0jmZxD4fxV9CsTJONhINWzIL--YF3nDg0nku2yp8,17670
37
- sclab/methods/__init__.py,sha256=4FbLhU2gKciC6h5HpTbE4AcOjs07NaxspsabHp6V2dY,1237
38
- sclab/preprocess/__init__.py,sha256=3gJJsndE50nvO3xE58o24UdJjmFXPtap2CFr7Czpwsc,511
39
- sclab/preprocess/_cca.py,sha256=_JKFaIRG80HKq8OV867iyK7ozaqMDawAu7PI3CI0JGc,4364
40
- sclab/preprocess/_cca_integrate.py,sha256=D4nymYZNurmVAMUUBi4hBL-nLjGuEL310cvISnWTUVk,1863
37
+ sclab/gui/components/_transfer_metadata.py,sha256=o9t9bQ7tr3G2-vFptUu1IiMxGhvMq-QJb_lF7AsDhQQ,6236
38
+ sclab/methods/__init__.py,sha256=d_n5SCyzwMEBZttXwnhgkx2FnD7AxhAK9yBre6Rynfk,1215
39
+ sclab/preprocess/__init__.py,sha256=zGt-TIDRx3qoKDpFxqnZ9yf2AfP4HBy8ZZSFLx-rGj0,547
40
+ sclab/preprocess/_cca.py,sha256=etDk1s3rKX-r0nkRuUaLTJ7NyalauCpWXyKRq1_EwTc,4400
41
+ sclab/preprocess/_cca_integrate.py,sha256=14Tu6TyH7wfZYAM2EsII1R92PTxfhaYbGx4bLWlMLP0,2706
41
42
  sclab/preprocess/_filter_obs.py,sha256=uYlcljuaq85G44Si8oxrNRcCCX2nFRdT3RN3ArqnwaY,1166
42
43
  sclab/preprocess/_harmony.py,sha256=wpFQXpr13BvljT04I_Rw5JdBvhzvAuinkrRs152CfvQ,13747
43
- sclab/preprocess/_harmony_integrate.py,sha256=75FxdGNDn6D7rsoXWpORxoc8_x-8o4dE9ePV0zh6JC4,1665
44
+ sclab/preprocess/_harmony_integrate.py,sha256=cKN_MyYq9FtwgQZyhgxiFNTZl36YuKLQdEoc7ky-ea4,1737
44
45
  sclab/preprocess/_normalize_weighted.py,sha256=h86rQakNoXoRKOepAEoBbBtHV_F-VMG2-uW_LcaSdWs,1587
45
46
  sclab/preprocess/_subset.py,sha256=8Vc5jty8WzIf8NZ1mleqNJLAp5CRWvEXGVevlT6ekNk,7066
46
47
  sclab/preprocess/_transfer_metadata.py,sha256=HA11JHHpq4ueFTeXlU4K3kHDDUzcUjyvfxpzdPBRNTo,4307
@@ -57,12 +58,12 @@ sclab/scanpy/plotting/palettes.py,sha256=zHTM_CVfKazb32YreRx0-INllFssZP5rY_B7JTe
57
58
  sclab/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
59
  sclab/tools/cellflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
60
  sclab/tools/cellflow/density_dynamics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- sclab/tools/cellflow/density_dynamics/_density_dynamics.py,sha256=dle_pYTWPXXM7O45i_snnOVaxfbZlgPLQg-CmatNNYA,11000
61
+ sclab/tools/cellflow/density_dynamics/_density_dynamics.py,sha256=xzmeIAHLV5xIVERpWMClZViDpJcge_dPsx6GWI0j0R8,11038
61
62
  sclab/tools/cellflow/pseudotime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
63
  sclab/tools/cellflow/pseudotime/_pseudotime.py,sha256=RiwbOduu0InNdh2Rp8DUXG6-r5wL_vVUGTyTkwnYhTY,9842
63
64
  sclab/tools/cellflow/pseudotime/timeseries.py,sha256=ZuMAm9LOKksJy2FzsQg3rdYKtLm1G0rbgO6dOdQuIV0,6326
64
65
  sclab/tools/cellflow/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
- sclab/tools/cellflow/utils/density_nd.py,sha256=BEh5o19u1fd2l15ZMzTHXHJePfo4fjsCbdQmPimdcow,3852
66
+ sclab/tools/cellflow/utils/density_nd.py,sha256=wwYoXOcF2CRxOArW_CQxJjWDE90wiui4NO7EIBG2RGM,6648
66
67
  sclab/tools/cellflow/utils/interpolate.py,sha256=HnpYEBdc4KSPC4QYOglJ2MpipLx3a5ENJQ8uhMnuwRc,9755
67
68
  sclab/tools/cellflow/utils/smoothen.py,sha256=yg2_zBrYKGRmXZY8C3pKmX3xGm0GGMI365IKqhgCmP0,3738
68
69
  sclab/tools/cellflow/utils/times.py,sha256=lV5ZRjCdBaYELGJ1pGdEBeA0w-WD77lOzPC6R7_kUxo,1811
@@ -75,7 +76,7 @@ sclab/tools/labeling/__init__.py,sha256=o-FJWonGNr2h_pB0o3YfnGl_y1kKU06_rYLmTt8k
75
76
  sclab/tools/labeling/sctype.py,sha256=jCsCFnqUgb_s1nTSK-N_5pEL_ZvZw-zUo12fUy9RLfs,8164
76
77
  sclab/utils/__init__.py,sha256=Py3dPN9ptMs6D-f7IGYisoxOS2YuX0O1oyw75nci3Os,72
77
78
  sclab/utils/_write_excel.py,sha256=DBZg9Kx7Ex6VqFrZFDZbSgvzMtu84iEwKo4nI3I2AT0,17017
78
- sclab-0.3.0.dist-info/licenses/LICENSE,sha256=LO7qldZoHIo9hc-HMBqclBh5800kZ9US9xTbLAQdHpg,1523
79
- sclab-0.3.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
80
- sclab-0.3.0.dist-info/METADATA,sha256=3nl-smhJCgBue7Q9XoCMXUzlU9UpQesGMJYZa_3gLFE,4437
81
- sclab-0.3.0.dist-info/RECORD,,
79
+ sclab-0.3.1.dist-info/licenses/LICENSE,sha256=LO7qldZoHIo9hc-HMBqclBh5800kZ9US9xTbLAQdHpg,1523
80
+ sclab-0.3.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
81
+ sclab-0.3.1.dist-info/METADATA,sha256=ZFKIgYqmj_ukAhQlAntHDbhap1-kd3k_fy59FwXHgoE,4437
82
+ sclab-0.3.1.dist-info/RECORD,,
File without changes