sclab 0.2.5__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 +1 -1
- sclab/_sclab.py +7 -3
- sclab/dataset/_dataset.py +1 -1
- sclab/dataset/processor/_processor.py +19 -4
- sclab/examples/processor_steps/__init__.py +2 -0
- sclab/examples/processor_steps/_doublet_detection.py +68 -0
- sclab/examples/processor_steps/_integration.py +47 -20
- sclab/examples/processor_steps/_neighbors.py +24 -4
- sclab/examples/processor_steps/_pca.py +11 -6
- sclab/examples/processor_steps/_preprocess.py +14 -1
- sclab/examples/processor_steps/_qc.py +22 -6
- sclab/gui/__init__.py +0 -0
- sclab/gui/components/__init__.py +7 -0
- sclab/gui/components/_guided_pseudotime.py +482 -0
- sclab/gui/components/_transfer_metadata.py +186 -0
- sclab/methods/__init__.py +16 -0
- sclab/preprocess/__init__.py +19 -0
- sclab/preprocess/_cca.py +154 -0
- sclab/preprocess/_cca_integrate.py +109 -0
- sclab/preprocess/_filter_obs.py +42 -0
- sclab/preprocess/_harmony.py +421 -0
- sclab/preprocess/_harmony_integrate.py +53 -0
- sclab/preprocess/_normalize_weighted.py +61 -0
- sclab/preprocess/_subset.py +208 -0
- sclab/preprocess/_transfer_metadata.py +137 -0
- sclab/preprocess/_transform.py +82 -0
- sclab/preprocess/_utils.py +96 -0
- sclab/tools/__init__.py +0 -0
- sclab/tools/cellflow/__init__.py +0 -0
- sclab/tools/cellflow/density_dynamics/__init__.py +0 -0
- sclab/tools/cellflow/density_dynamics/_density_dynamics.py +349 -0
- sclab/tools/cellflow/pseudotime/__init__.py +0 -0
- sclab/tools/cellflow/pseudotime/_pseudotime.py +332 -0
- sclab/tools/cellflow/pseudotime/timeseries.py +226 -0
- sclab/tools/cellflow/utils/__init__.py +0 -0
- sclab/tools/cellflow/utils/density_nd.py +215 -0
- sclab/tools/cellflow/utils/interpolate.py +334 -0
- sclab/tools/cellflow/utils/smoothen.py +124 -0
- sclab/tools/cellflow/utils/times.py +55 -0
- sclab/tools/differential_expression/__init__.py +5 -0
- sclab/tools/differential_expression/_pseudobulk_edger.py +304 -0
- sclab/tools/differential_expression/_pseudobulk_helpers.py +277 -0
- sclab/tools/doublet_detection/__init__.py +5 -0
- sclab/tools/doublet_detection/_scrublet.py +64 -0
- sclab/tools/labeling/__init__.py +6 -0
- sclab/tools/labeling/sctype.py +233 -0
- sclab/utils/__init__.py +5 -0
- sclab/utils/_write_excel.py +510 -0
- {sclab-0.2.5.dist-info → sclab-0.3.1.dist-info}/METADATA +6 -2
- sclab-0.3.1.dist-info/RECORD +82 -0
- sclab-0.2.5.dist-info/RECORD +0 -45
- {sclab-0.2.5.dist-info → sclab-0.3.1.dist-info}/WHEEL +0 -0
- {sclab-0.2.5.dist-info → sclab-0.3.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import re
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal, Sequence
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
_column_format_type = Literal[
|
|
11
|
+
"text", "bold", "number", "scientific", "percentage", "nodecimal", "boolean"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def write_excel(
|
|
16
|
+
dataframes: pd.DataFrame | dict[str, pd.DataFrame],
|
|
17
|
+
file_path: str | Path,
|
|
18
|
+
sortby: str | list[str] | None = None,
|
|
19
|
+
sort_ascending: bool | list[bool] = None,
|
|
20
|
+
autofilter: bool = True,
|
|
21
|
+
guess_formats: bool = True,
|
|
22
|
+
guess_widths: bool = True,
|
|
23
|
+
column_formats: dict[str, _column_format_type] | None = None,
|
|
24
|
+
column_widths: dict[str, int] | None = None,
|
|
25
|
+
verbose: bool = False,
|
|
26
|
+
) -> None:
|
|
27
|
+
"""
|
|
28
|
+
Write pandas DataFrame(s) to an Excel file with enhanced formatting and styling.
|
|
29
|
+
|
|
30
|
+
This function provides advanced Excel writing capabilities including automatic format detection,
|
|
31
|
+
column width adjustment, conditional formatting, and table headers with autofilter.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
dataframes : pandas.DataFrame or dict[str, pandas.DataFrame]
|
|
36
|
+
Single DataFrame or dictionary of DataFrames where keys are sheet names.
|
|
37
|
+
file_path : str or pathlib.Path
|
|
38
|
+
Path where the Excel file will be saved.
|
|
39
|
+
sortby : str or None, optional
|
|
40
|
+
Column name to sort the data by. If specified, applies 3-color scale conditional formatting
|
|
41
|
+
to the sorted column. Default is None.
|
|
42
|
+
sort_ascending : bool, optional
|
|
43
|
+
Sort order when sortby is specified. Default is True.
|
|
44
|
+
autofilter : bool, optional
|
|
45
|
+
Whether to add filter buttons to column headers. Default is True.
|
|
46
|
+
guess_formats : bool, optional
|
|
47
|
+
Whether to automatically detect and apply appropriate formats based on column data types.
|
|
48
|
+
Default is True.
|
|
49
|
+
guess_widths : bool, optional
|
|
50
|
+
Whether to automatically estimate and apply column widths based on column name/contents.
|
|
51
|
+
Default is True.
|
|
52
|
+
column_formats : dict[str, str] or None, optional
|
|
53
|
+
Custom format specifications for columns. Keys are column names, values are format types:
|
|
54
|
+
"text", "bold", "number", "scientific", "percentage", "nodecimal", or "boolean".
|
|
55
|
+
Default is None.
|
|
56
|
+
column_widths : dict[str, int] or None, optional
|
|
57
|
+
Custom width specifications for columns. Keys are column names, values are widths in
|
|
58
|
+
Excel units. Default is None.
|
|
59
|
+
verbose : bool, optional
|
|
60
|
+
Whether to print detailed information about column formatting. Default is False.
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
None
|
|
65
|
+
|
|
66
|
+
Notes
|
|
67
|
+
-----
|
|
68
|
+
- If a single DataFrame is provided, it will be written to 'Sheet1'
|
|
69
|
+
- Percentage columns get conditional formatting based on their values
|
|
70
|
+
- The function validates file writability and format specifications before proceeding
|
|
71
|
+
- Column formats and widths are either explicitly specified or automatically detected
|
|
72
|
+
"""
|
|
73
|
+
if not isinstance(sortby, list):
|
|
74
|
+
sortby = [sortby]
|
|
75
|
+
|
|
76
|
+
if sort_ascending is None:
|
|
77
|
+
sort_ascending = [True]
|
|
78
|
+
|
|
79
|
+
if not isinstance(sort_ascending, list):
|
|
80
|
+
sort_ascending = [sort_ascending]
|
|
81
|
+
|
|
82
|
+
if column_formats is None:
|
|
83
|
+
column_formats = {}
|
|
84
|
+
else:
|
|
85
|
+
_validate_column_formats(column_formats)
|
|
86
|
+
|
|
87
|
+
if column_widths is None:
|
|
88
|
+
column_widths = {}
|
|
89
|
+
else:
|
|
90
|
+
_validate_column_widths(column_widths)
|
|
91
|
+
|
|
92
|
+
if not isinstance(dataframes, dict):
|
|
93
|
+
dataframes = {"Sheet1": dataframes}
|
|
94
|
+
|
|
95
|
+
file_path = Path(file_path)
|
|
96
|
+
|
|
97
|
+
if not _is_writable(file_path):
|
|
98
|
+
print(f"File {file_path} is not writable. Please make sure it's not in use.")
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
with pd.ExcelWriter(file_path) as writer:
|
|
102
|
+
for sheet_name, df in dataframes.items():
|
|
103
|
+
df = df.reset_index()
|
|
104
|
+
|
|
105
|
+
_sortby = [c for c in sortby if c in df.columns]
|
|
106
|
+
_sort_ascending = [a for a in sort_ascending if a]
|
|
107
|
+
if not _sort_ascending:
|
|
108
|
+
_sort_ascending = True
|
|
109
|
+
if _sortby:
|
|
110
|
+
df = df.sort_values(by=_sortby, ascending=_sort_ascending)
|
|
111
|
+
|
|
112
|
+
df.to_excel(
|
|
113
|
+
writer, sheet_name=sheet_name, index=False, startrow=1, header=False
|
|
114
|
+
)
|
|
115
|
+
max_row, max_col = df.shape
|
|
116
|
+
|
|
117
|
+
workbook = writer.book
|
|
118
|
+
formats = _get_formats_dict(workbook)
|
|
119
|
+
|
|
120
|
+
worksheet = writer.sheets[sheet_name]
|
|
121
|
+
|
|
122
|
+
for i, col in enumerate(df.columns):
|
|
123
|
+
if col in column_formats:
|
|
124
|
+
column_format = column_formats[col]
|
|
125
|
+
elif guess_formats:
|
|
126
|
+
column_format = _guess_column_format(df[col])
|
|
127
|
+
else:
|
|
128
|
+
column_format = "noformat"
|
|
129
|
+
|
|
130
|
+
if col in column_widths:
|
|
131
|
+
column_width = column_widths[col]
|
|
132
|
+
elif guess_widths:
|
|
133
|
+
try:
|
|
134
|
+
column_width = _guess_column_width(df[col], column_format)
|
|
135
|
+
except ValueError:
|
|
136
|
+
column_width = 10
|
|
137
|
+
else:
|
|
138
|
+
column_width = 10
|
|
139
|
+
|
|
140
|
+
fmt = formats[column_format]
|
|
141
|
+
worksheet.set_column(i, i, column_width, fmt)
|
|
142
|
+
|
|
143
|
+
if verbose:
|
|
144
|
+
_print_column_info(
|
|
145
|
+
i, sheet_name, col, column_format, column_width, max_col
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if column_format == "percentage":
|
|
149
|
+
fmt = _make_percentage_conditional_format()
|
|
150
|
+
worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
151
|
+
|
|
152
|
+
if column_format == "boolean":
|
|
153
|
+
fmt = _make_cell_color_conditional_format(
|
|
154
|
+
"==", "TRUE", formats["cellGreen"]
|
|
155
|
+
)
|
|
156
|
+
worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
157
|
+
|
|
158
|
+
# if col in sortby:
|
|
159
|
+
# fmt = _make_3_color_scale_conditional_format(df[col])
|
|
160
|
+
# worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
161
|
+
|
|
162
|
+
if m := re.match(
|
|
163
|
+
r"^number_(Blue|Green|Red)(Blue|Green|Red)\|?([\-\+\d.]+)?,?([\-\+\d.]+)?,?([\-\+\d.]+)?$",
|
|
164
|
+
column_format,
|
|
165
|
+
):
|
|
166
|
+
min_color = m.group(1)
|
|
167
|
+
max_color = m.group(2)
|
|
168
|
+
|
|
169
|
+
if m.group(3):
|
|
170
|
+
min_value = float(m.group(3))
|
|
171
|
+
else:
|
|
172
|
+
min_value = None
|
|
173
|
+
|
|
174
|
+
if m.group(4):
|
|
175
|
+
mid_value = float(m.group(4))
|
|
176
|
+
else:
|
|
177
|
+
mid_value = None
|
|
178
|
+
|
|
179
|
+
if m.group(5):
|
|
180
|
+
max_value = float(m.group(5))
|
|
181
|
+
else:
|
|
182
|
+
max_value = None
|
|
183
|
+
|
|
184
|
+
fmt = _make_3_color_scale_conditional_format(
|
|
185
|
+
df[col],
|
|
186
|
+
min_color=min_color,
|
|
187
|
+
mid_color="White",
|
|
188
|
+
max_color=max_color,
|
|
189
|
+
min_value=min_value,
|
|
190
|
+
mid_value=mid_value,
|
|
191
|
+
max_value=max_value,
|
|
192
|
+
)
|
|
193
|
+
worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
194
|
+
|
|
195
|
+
if m := re.match(
|
|
196
|
+
r"^number_(Blue|Green|Red)(_desc)?\|?([\-\+\d.]+)?,?([\-\+\d.]+)?$",
|
|
197
|
+
column_format,
|
|
198
|
+
):
|
|
199
|
+
desc = m.group(2) == "_desc"
|
|
200
|
+
if desc:
|
|
201
|
+
min_color = "White"
|
|
202
|
+
max_color = m.group(1)
|
|
203
|
+
else:
|
|
204
|
+
min_color = m.group(1)
|
|
205
|
+
max_color = "White"
|
|
206
|
+
|
|
207
|
+
if m.group(3):
|
|
208
|
+
min_value = float(m.group(3))
|
|
209
|
+
else:
|
|
210
|
+
min_value = None
|
|
211
|
+
|
|
212
|
+
if m.group(4):
|
|
213
|
+
max_value = float(m.group(4))
|
|
214
|
+
else:
|
|
215
|
+
max_value = None
|
|
216
|
+
|
|
217
|
+
fmt = _make_2_color_scale_conditional_format(
|
|
218
|
+
df[col],
|
|
219
|
+
min_color=min_color,
|
|
220
|
+
max_color=max_color,
|
|
221
|
+
min_value=min_value,
|
|
222
|
+
max_value=max_value,
|
|
223
|
+
)
|
|
224
|
+
# print(col, df[col].dtype, df[col].iloc[:5].to_list(), fmt)
|
|
225
|
+
worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
226
|
+
|
|
227
|
+
if column_format == "3color":
|
|
228
|
+
fmt = _make_3_color_scale_conditional_format(df[col])
|
|
229
|
+
worksheet.conditional_format(0, i, max_row, i, fmt)
|
|
230
|
+
|
|
231
|
+
_write_table_header(df.columns, worksheet, formats["header_format"])
|
|
232
|
+
|
|
233
|
+
if autofilter:
|
|
234
|
+
worksheet.autofilter(0, 0, max_row - 1, max_col - 1)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _color(color: str):
|
|
238
|
+
match color:
|
|
239
|
+
case "Blue":
|
|
240
|
+
return "#B3CDE3"
|
|
241
|
+
case "Green":
|
|
242
|
+
return "#B3E3B3"
|
|
243
|
+
case "Red":
|
|
244
|
+
return "#FFB3B3"
|
|
245
|
+
case "White":
|
|
246
|
+
return "#F7F7F7"
|
|
247
|
+
case _:
|
|
248
|
+
raise ValueError(f"Invalid color: {color}")
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _validate_column_formats(column_formats: dict[str, str]):
|
|
252
|
+
assert isinstance(column_formats, dict), "column_formats must be a dict"
|
|
253
|
+
for col, fmt in column_formats.items():
|
|
254
|
+
if re.match(
|
|
255
|
+
r"^number_(Blue|Green|Red)(Blue|Green|Red)?(_desc)?\|?([\-\+\d.]+)?,?([\-\+\d.]+)?,?([\-\+\d.]+)?$",
|
|
256
|
+
fmt,
|
|
257
|
+
):
|
|
258
|
+
continue
|
|
259
|
+
else:
|
|
260
|
+
assert fmt in (
|
|
261
|
+
"text",
|
|
262
|
+
"bold",
|
|
263
|
+
"number",
|
|
264
|
+
"scientific",
|
|
265
|
+
"percentage",
|
|
266
|
+
"nodecimal",
|
|
267
|
+
"boolean",
|
|
268
|
+
), f"Unknown format: {fmt}"
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def _validate_column_widths(column_widths: dict[str, int]):
|
|
272
|
+
assert isinstance(column_widths, dict), "column_widths must be a dict"
|
|
273
|
+
for col, width in column_widths.items():
|
|
274
|
+
assert isinstance(width, int | float), f"Invalid column width: {width}"
|
|
275
|
+
assert width > 0, f"Invalid column width: {width}"
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _is_writable(file_path: str | Path) -> None:
|
|
279
|
+
file_path = Path(file_path)
|
|
280
|
+
|
|
281
|
+
if file_path.exists() and file_path.is_file():
|
|
282
|
+
try:
|
|
283
|
+
with open(file_path, "a"):
|
|
284
|
+
return True
|
|
285
|
+
except PermissionError:
|
|
286
|
+
return False
|
|
287
|
+
|
|
288
|
+
return True
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _get_formats_dict(workbook):
|
|
292
|
+
return defaultdict(
|
|
293
|
+
lambda: workbook.add_format(),
|
|
294
|
+
**{
|
|
295
|
+
"noformat": workbook.add_format(),
|
|
296
|
+
"header_format": workbook.add_format(
|
|
297
|
+
{
|
|
298
|
+
"bold": True,
|
|
299
|
+
"text_wrap": True,
|
|
300
|
+
"valign": "top",
|
|
301
|
+
"fg_color": "#FCFCFC",
|
|
302
|
+
"border": 1,
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
"text": workbook.add_format({"font_name": "Calibri", "font_size": 11}),
|
|
306
|
+
"bold": workbook.add_format({"bold": True}),
|
|
307
|
+
"number": workbook.add_format({"num_format": "0.00"}),
|
|
308
|
+
"scientific": workbook.add_format({"num_format": "0.00E+00"}),
|
|
309
|
+
"percentage": workbook.add_format({"num_format": "0.00%"}),
|
|
310
|
+
"nodecimal": workbook.add_format({"num_format": "0"}),
|
|
311
|
+
"boolean": workbook.add_format(
|
|
312
|
+
{
|
|
313
|
+
"bold": True,
|
|
314
|
+
"valign": "center",
|
|
315
|
+
"align": "center",
|
|
316
|
+
"font_name": "Monospace",
|
|
317
|
+
"font_size": 11,
|
|
318
|
+
}
|
|
319
|
+
),
|
|
320
|
+
**{
|
|
321
|
+
f"cell{color}": workbook.add_format(
|
|
322
|
+
{
|
|
323
|
+
"bg_color": _color(color),
|
|
324
|
+
}
|
|
325
|
+
)
|
|
326
|
+
for color in ["Blue", "Green", "Red", "White"]
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _guess_column_format(column: pd.Series) -> str:
|
|
333
|
+
if pd.api.types.is_bool_dtype(column):
|
|
334
|
+
return "boolean"
|
|
335
|
+
|
|
336
|
+
if pd.api.types.is_numeric_dtype(column):
|
|
337
|
+
if pd.api.types.is_float_dtype(column):
|
|
338
|
+
eps = np.finfo(column.dtype).eps
|
|
339
|
+
|
|
340
|
+
if (column % 1 == 0).all():
|
|
341
|
+
return "nodecimal"
|
|
342
|
+
|
|
343
|
+
if np.log10(column.abs() + eps).max() > 6:
|
|
344
|
+
return "scientific"
|
|
345
|
+
|
|
346
|
+
if np.log10(column.abs() + eps).min() < -3:
|
|
347
|
+
return "scientific"
|
|
348
|
+
|
|
349
|
+
return "number"
|
|
350
|
+
|
|
351
|
+
return "nodecimal"
|
|
352
|
+
|
|
353
|
+
return "text"
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _guess_column_width(
|
|
357
|
+
column: pd.Series,
|
|
358
|
+
column_format: str,
|
|
359
|
+
step: int = 6,
|
|
360
|
+
min_width: int = 10,
|
|
361
|
+
max_width: int = 75,
|
|
362
|
+
) -> int:
|
|
363
|
+
# widths should be multiple of 5, minimum 10 and maximum 75
|
|
364
|
+
colname = str(column.name)
|
|
365
|
+
colname_len = len(colname)
|
|
366
|
+
if len(column) == 0:
|
|
367
|
+
return _round_width(colname_len, step, min_width, max_width)
|
|
368
|
+
|
|
369
|
+
match column_format:
|
|
370
|
+
case "text":
|
|
371
|
+
max_len = int(column.str.len().max())
|
|
372
|
+
return _round_width(max(max_len, colname_len), step, min_width, max_width)
|
|
373
|
+
|
|
374
|
+
case "number" | "nodecimal" | "scientific" | "boolean":
|
|
375
|
+
return _round_width(colname_len, step, min_width, max_width)
|
|
376
|
+
|
|
377
|
+
case x if re.match("^number_.*", x):
|
|
378
|
+
return _round_width(colname_len, step, min_width, max_width)
|
|
379
|
+
|
|
380
|
+
case "percentage":
|
|
381
|
+
return _round_width(max(min_width, colname_len), step, min_width, max_width)
|
|
382
|
+
|
|
383
|
+
case _:
|
|
384
|
+
raise ValueError(f"Unknown format: {column_format}")
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _round_width(value: float, step: int, min_width: int, max_width: int) -> int:
|
|
388
|
+
out = math.ceil(value * 1.4)
|
|
389
|
+
return int(max(min_width, min(max_width, out)))
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _print_column_info(i, sheet_name, col, column_format, column_width, max_col):
|
|
393
|
+
if i == 0:
|
|
394
|
+
print()
|
|
395
|
+
print("-" * 55)
|
|
396
|
+
print(f"| Sheet Name: {sheet_name:<39} |")
|
|
397
|
+
print("-" * 55)
|
|
398
|
+
print(f"| {'Column':<20} | {'Format':<20} | {'Width':>5} |")
|
|
399
|
+
print("-" * 55)
|
|
400
|
+
print(f"| {col[:20]:>20} | {column_format:>20} | {column_width:>5} |")
|
|
401
|
+
if i == max_col - 1:
|
|
402
|
+
print("-" * 55)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def _make_percentage_conditional_format():
|
|
406
|
+
return {
|
|
407
|
+
"type": "data_bar",
|
|
408
|
+
"bar_color": "#76C1E1", # Light blue for the bar color
|
|
409
|
+
"min_type": "num", # Define minimum as a numeric value
|
|
410
|
+
"min_value": 0, # Minimum percentage (0%)
|
|
411
|
+
"max_type": "num", # Define maximum as a numeric value
|
|
412
|
+
"max_value": 1, # Maximum percentage (100%)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def _make_cell_color_conditional_format(criteria, value, fmt):
|
|
417
|
+
return {
|
|
418
|
+
"type": "cell",
|
|
419
|
+
"criteria": criteria,
|
|
420
|
+
"value": value,
|
|
421
|
+
"format": fmt,
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def _make_3_color_scale_conditional_format(
|
|
426
|
+
series: pd.Series,
|
|
427
|
+
scale: float = 1.5,
|
|
428
|
+
min_color: str = "Blue", # soft blue
|
|
429
|
+
mid_color: str = "White", # off-white
|
|
430
|
+
max_color: str = "Red", # soft red
|
|
431
|
+
min_value: int | float | None = None,
|
|
432
|
+
mid_value: int | float | None = None,
|
|
433
|
+
max_value: int | float | None = None,
|
|
434
|
+
):
|
|
435
|
+
values = series.loc[np.isfinite(series)]
|
|
436
|
+
|
|
437
|
+
if min_value is None and mid_value is None and max_value is None:
|
|
438
|
+
bound = values.quantile([0, 1]).abs().max() * scale
|
|
439
|
+
min_value = -bound
|
|
440
|
+
mid_value = 0
|
|
441
|
+
max_value = bound
|
|
442
|
+
|
|
443
|
+
if min_value is None:
|
|
444
|
+
min_value = values.min()
|
|
445
|
+
|
|
446
|
+
if max_value is None:
|
|
447
|
+
max_value = values.max()
|
|
448
|
+
|
|
449
|
+
if mid_value is None:
|
|
450
|
+
mid_value = (values.max() + values.min()) / 2
|
|
451
|
+
|
|
452
|
+
if not min_color.startswith("#"):
|
|
453
|
+
min_color = _color(min_color)
|
|
454
|
+
|
|
455
|
+
if not mid_color.startswith("#"):
|
|
456
|
+
mid_color = _color(mid_color)
|
|
457
|
+
|
|
458
|
+
if not max_color.startswith("#"):
|
|
459
|
+
max_color = _color(max_color)
|
|
460
|
+
|
|
461
|
+
return {
|
|
462
|
+
"type": "3_color_scale",
|
|
463
|
+
"min_type": "num", # Can be "num", "percent", or "percentile"
|
|
464
|
+
"min_value": min_value,
|
|
465
|
+
"min_color": min_color,
|
|
466
|
+
"mid_type": "num",
|
|
467
|
+
"mid_value": mid_value,
|
|
468
|
+
"mid_color": mid_color,
|
|
469
|
+
"max_type": "num",
|
|
470
|
+
"max_value": max_value,
|
|
471
|
+
"max_color": max_color,
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def _make_2_color_scale_conditional_format(
|
|
476
|
+
series: pd.Series,
|
|
477
|
+
min_color: str = "#F7F7F7",
|
|
478
|
+
max_color: str = "#B3E3B3",
|
|
479
|
+
min_value: int | float | None = None,
|
|
480
|
+
max_value: int | float | None = None,
|
|
481
|
+
):
|
|
482
|
+
values = series.loc[np.isfinite(series)]
|
|
483
|
+
|
|
484
|
+
if min_value is None:
|
|
485
|
+
min_value = values.quantile(0.05)
|
|
486
|
+
|
|
487
|
+
if max_value is None:
|
|
488
|
+
max_value = values.quantile(0.95)
|
|
489
|
+
|
|
490
|
+
if not min_color.startswith("#"):
|
|
491
|
+
min_color = _color(min_color)
|
|
492
|
+
|
|
493
|
+
if not max_color.startswith("#"):
|
|
494
|
+
max_color = _color(max_color)
|
|
495
|
+
|
|
496
|
+
return {
|
|
497
|
+
"type": "2_color_scale",
|
|
498
|
+
"min_type": "num",
|
|
499
|
+
"min_value": min_value,
|
|
500
|
+
"min_color": min_color,
|
|
501
|
+
"max_type": "num",
|
|
502
|
+
"max_value": max_value,
|
|
503
|
+
"max_color": max_color,
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
def _write_table_header(column_names: Sequence[str], worksheet, header_format):
|
|
508
|
+
# Write the column headers with the defined format.
|
|
509
|
+
for col_num, value in enumerate(column_names):
|
|
510
|
+
worksheet.write(0, col_num, value, header_format)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sclab
|
|
3
|
-
Version: 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
|
|
@@ -14,16 +14,19 @@ License-File: LICENSE
|
|
|
14
14
|
Requires-Dist: anndata
|
|
15
15
|
Requires-Dist: anywidget
|
|
16
16
|
Requires-Dist: ipywidgets
|
|
17
|
-
Requires-Dist: itables
|
|
17
|
+
Requires-Dist: itables<2.4
|
|
18
18
|
Requires-Dist: matplotlib
|
|
19
19
|
Requires-Dist: numpy<2.2
|
|
20
20
|
Requires-Dist: pandas
|
|
21
21
|
Requires-Dist: plotly<6.0
|
|
22
22
|
Requires-Dist: requests
|
|
23
|
+
Requires-Dist: ripser>=0.6.12
|
|
23
24
|
Requires-Dist: scikit-learn
|
|
24
25
|
Requires-Dist: svgpathtools
|
|
25
26
|
Requires-Dist: tqdm
|
|
26
27
|
Requires-Dist: jupyterlab>=4.3.6 ; extra == "jupyter"
|
|
28
|
+
Requires-Dist: anndata2ri>=1.3 ; extra == "r"
|
|
29
|
+
Requires-Dist: rpy2>=3.5 ; extra == "r"
|
|
27
30
|
Requires-Dist: scanpy[leiden, skmisc]>=1.10 ; extra == "scanpy"
|
|
28
31
|
Requires-Dist: pytest>=8.3.4 ; extra == "test"
|
|
29
32
|
Project-URL: Bug Tracker, https://github.com/umbibio/sclab/issues
|
|
@@ -32,6 +35,7 @@ Project-URL: Documentation, https://github.com/umbibio/sclab/docs
|
|
|
32
35
|
Project-URL: Homepage, https://github.com/umbibio/sclab
|
|
33
36
|
Project-URL: Repository, https://github.com/umbibio/sclab.git
|
|
34
37
|
Provides-Extra: jupyter
|
|
38
|
+
Provides-Extra: r
|
|
35
39
|
Provides-Extra: scanpy
|
|
36
40
|
Provides-Extra: test
|
|
37
41
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
sclab/__init__.py,sha256=8CMvbWDJrjAoC3ycfq28IKCXtE7xhAm_iORs4Jj6yi8,132
|
|
2
|
+
sclab/_io.py,sha256=5ISxIPbE233UiOt3QEs9fkLO8DLLEe5HrMnZoR-KLYE,2662
|
|
3
|
+
sclab/_methods_registry.py,sha256=RcffyRuuLzHqsnAdbBL4W1GmZx80d9AxdGjUnx1mbNg,1704
|
|
4
|
+
sclab/_sclab.py,sha256=P7rR82jPPNRp4K9s_GBK0Qcd3xYt7Qc4Zsd-rxiVAK8,9133
|
|
5
|
+
sclab/dataset/__init__.py,sha256=f9PoXIMAPnC3Var1ODr3mXkotW6u6NRPQvlgcWYXk54,143
|
|
6
|
+
sclab/dataset/_dataset.py,sha256=wsbWnBHnlGJ779RV1Vv7RfxlEzHCfUZKNT3FTI1mu9g,14248
|
|
7
|
+
sclab/dataset/_exceptions.py,sha256=g8RJL8PiRmD4--PkOs5CZth_qeaduvieMlKJNkrUIYA,45
|
|
8
|
+
sclab/dataset/plotter/__init__.py,sha256=pdWhAywnoc1_nnIcD-qNW0U364-yo4k5DwP79y9NVgA,129
|
|
9
|
+
sclab/dataset/plotter/_controls.py,sha256=NBDdtY1wQbIEvE_WToigR5bEEoi3z30_67T_dLSOSIo,20295
|
|
10
|
+
sclab/dataset/plotter/_plotter.py,sha256=EXwk6KSM7FOyLLJ8HCgIB_2m730t0kHsVKWfQOxL6kA,37023
|
|
11
|
+
sclab/dataset/plotter/_utils.py,sha256=ANm_R9PJd33-QJtZzqXCN5pJ_XrJ7AA4AvSHaDRbOMA,11595
|
|
12
|
+
sclab/dataset/processor/__init__.py,sha256=v8Qbusb6h8oSndv9q-12vzHrz5BDF3N2LCkQG9KC19I,104
|
|
13
|
+
sclab/dataset/processor/_processor.py,sha256=ink2eqi7hMt4DunHD4U1KqkKNQd23yJiDOgsmgZTsb8,41684
|
|
14
|
+
sclab/dataset/processor/_results_panel.py,sha256=p2xmHgoYfpkPXj-SjRGTmAPAwL1VC8I70iFD_o-90AE,2342
|
|
15
|
+
sclab/dataset/processor/step/__init__.py,sha256=j8j4oU9NMdWHn6kVjft7Klm6xme8M6wzebxJj_zNehg,179
|
|
16
|
+
sclab/dataset/processor/step/_basic_processor_step.py,sha256=7NKC4W-I_EU3QBPi5BL9-NwAF_h6_oWl1l_kEk6gSAg,3640
|
|
17
|
+
sclab/dataset/processor/step/_processor_step_base.py,sha256=DpbL4F53W1YPI_xHuQ0T3gcvDGwwKG2Xp-n8DkMUf90,4133
|
|
18
|
+
sclab/event/__init__.py,sha256=unkfpmoxitPVZvWcc9YhkUwcXODdcd9cw_toVXVIDMU,126
|
|
19
|
+
sclab/event/_broker.py,sha256=W4GgoBhJS1LxGQv8TYFg71o5jUQPO8BDLrKzahDUyEM,7121
|
|
20
|
+
sclab/event/_client.py,sha256=Kx7pza-CzLySR0JBBneiZQAjtllUnjWKNKSfw3K2ZQE,2362
|
|
21
|
+
sclab/event/_utils.py,sha256=LehiFhn7dopNEaTFERJhs6fiVgXCBvseRxWTSWc6u-k,456
|
|
22
|
+
sclab/examples/__init__.py,sha256=uSu4DMfF2K7xlZbLC_CmANyS3D56khGLMSVt6x9XXiI,68
|
|
23
|
+
sclab/examples/processor_steps/__init__.py,sha256=_b9nLeZhyVex17lk8Vvy44eXbvKhygrPOZXpaM1jfSo,575
|
|
24
|
+
sclab/examples/processor_steps/_cluster.py,sha256=olbri3HWPBU8p__r9kP9tgWaJoUJ2bK48pmHfdvf11c,1120
|
|
25
|
+
sclab/examples/processor_steps/_differential_expression.py,sha256=uEToPiACCgo42oZidAw5DFgWVcDnChWzVRlVzn53K34,11567
|
|
26
|
+
sclab/examples/processor_steps/_doublet_detection.py,sha256=eFQtRsdvBWJ_v3HH08v-KbjYius-fj1pg1HBm0mjADg,2114
|
|
27
|
+
sclab/examples/processor_steps/_gene_expression.py,sha256=io_U53TQ3bpclGZ7xjuQHws4Lei5_nMpWTKbvD2zqs0,4216
|
|
28
|
+
sclab/examples/processor_steps/_integration.py,sha256=40nIM19VnBALMQXYO9XpYczH7gEcpIUb-DLdYraxzxs,3444
|
|
29
|
+
sclab/examples/processor_steps/_neighbors.py,sha256=jGpoPtlN8nlcsOqUOiqTPQgGzbpToLAVR1By2SHBo5U,2949
|
|
30
|
+
sclab/examples/processor_steps/_pca.py,sha256=kULbPPTAMqAgECyycmpf5dpU-FYPJSLbTO-UEkOb5mo,4798
|
|
31
|
+
sclab/examples/processor_steps/_preprocess.py,sha256=kKqOQWyBC3BFLYVsCWRPwaXHeuWG1s69puvwhDQK5Eg,6809
|
|
32
|
+
sclab/examples/processor_steps/_qc.py,sha256=3e5TTGPNWbGPJBX0Sx18np8qcrgPznUuJJ-DwCrRZ0U,3684
|
|
33
|
+
sclab/examples/processor_steps/_umap.py,sha256=Mzxj4LiZfh3WT5lS_BO_lTleC5jMoUm5_km_gvzU_I8,1402
|
|
34
|
+
sclab/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
+
sclab/gui/components/__init__.py,sha256=X0-cGJmII76qpWHEBe49miS2gPw3esMAwp61z23w_1Q,161
|
|
36
|
+
sclab/gui/components/_guided_pseudotime.py,sha256=sxI0jmZxD4fxV9CsTJONhINWzIL--YF3nDg0nku2yp8,17670
|
|
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
|
|
42
|
+
sclab/preprocess/_filter_obs.py,sha256=uYlcljuaq85G44Si8oxrNRcCCX2nFRdT3RN3ArqnwaY,1166
|
|
43
|
+
sclab/preprocess/_harmony.py,sha256=wpFQXpr13BvljT04I_Rw5JdBvhzvAuinkrRs152CfvQ,13747
|
|
44
|
+
sclab/preprocess/_harmony_integrate.py,sha256=cKN_MyYq9FtwgQZyhgxiFNTZl36YuKLQdEoc7ky-ea4,1737
|
|
45
|
+
sclab/preprocess/_normalize_weighted.py,sha256=h86rQakNoXoRKOepAEoBbBtHV_F-VMG2-uW_LcaSdWs,1587
|
|
46
|
+
sclab/preprocess/_subset.py,sha256=8Vc5jty8WzIf8NZ1mleqNJLAp5CRWvEXGVevlT6ekNk,7066
|
|
47
|
+
sclab/preprocess/_transfer_metadata.py,sha256=HA11JHHpq4ueFTeXlU4K3kHDDUzcUjyvfxpzdPBRNTo,4307
|
|
48
|
+
sclab/preprocess/_transform.py,sha256=n2xHJR3T-rRxZneCFH2oMw9RaQcGGBfHpOu1-YP1c1E,2312
|
|
49
|
+
sclab/preprocess/_utils.py,sha256=dLeS_fIvQGZZfesEtbJKtnPmqjqy3fmyTC4GewRD3Fc,3078
|
|
50
|
+
sclab/scanpy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
+
sclab/scanpy/_compat.py,sha256=VEdW4lWLtKmgLSrikRnfvYOz9EOa7e_iDt4Q88X9JKQ,2109
|
|
52
|
+
sclab/scanpy/_settings.py,sha256=UVcJExVHsf_nvyZ5kTrBHPkddHCz7ARCzqAdZAM_A5E,16736
|
|
53
|
+
sclab/scanpy/logging.py,sha256=VwSPeKjpXeopdcgEAlWDz2Wv4IGAAUv8GyMNpMART-0,8453
|
|
54
|
+
sclab/scanpy/readwrite.py,sha256=yixHonShUZ2Ms3Sv3UXw_VXlY00XDApvmyN2mZWFAcs,37025
|
|
55
|
+
sclab/scanpy/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
sclab/scanpy/plotting/_rcmod.py,sha256=pc53dasHh2RFfTHVTbTb8v1z8vW032zjvum-WQLgjXA,1970
|
|
57
|
+
sclab/scanpy/plotting/palettes.py,sha256=zHTM_CVfKazb32YreRx0-INllFssZP5rY_B7JTeaBhA,4782
|
|
58
|
+
sclab/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
+
sclab/tools/cellflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
+
sclab/tools/cellflow/density_dynamics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
+
sclab/tools/cellflow/density_dynamics/_density_dynamics.py,sha256=xzmeIAHLV5xIVERpWMClZViDpJcge_dPsx6GWI0j0R8,11038
|
|
62
|
+
sclab/tools/cellflow/pseudotime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
|
+
sclab/tools/cellflow/pseudotime/_pseudotime.py,sha256=RiwbOduu0InNdh2Rp8DUXG6-r5wL_vVUGTyTkwnYhTY,9842
|
|
64
|
+
sclab/tools/cellflow/pseudotime/timeseries.py,sha256=ZuMAm9LOKksJy2FzsQg3rdYKtLm1G0rbgO6dOdQuIV0,6326
|
|
65
|
+
sclab/tools/cellflow/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
+
sclab/tools/cellflow/utils/density_nd.py,sha256=wwYoXOcF2CRxOArW_CQxJjWDE90wiui4NO7EIBG2RGM,6648
|
|
67
|
+
sclab/tools/cellflow/utils/interpolate.py,sha256=HnpYEBdc4KSPC4QYOglJ2MpipLx3a5ENJQ8uhMnuwRc,9755
|
|
68
|
+
sclab/tools/cellflow/utils/smoothen.py,sha256=yg2_zBrYKGRmXZY8C3pKmX3xGm0GGMI365IKqhgCmP0,3738
|
|
69
|
+
sclab/tools/cellflow/utils/times.py,sha256=lV5ZRjCdBaYELGJ1pGdEBeA0w-WD77lOzPC6R7_kUxo,1811
|
|
70
|
+
sclab/tools/differential_expression/__init__.py,sha256=KKaDzeGGgE1LxnC5aBcPQYcVX_e2h8qAbfMPQVvYlSA,87
|
|
71
|
+
sclab/tools/differential_expression/_pseudobulk_edger.py,sha256=WWqKEA8I1I_YsgjafeznX3tyZoXyu0HV13QkxiYGFgQ,10538
|
|
72
|
+
sclab/tools/differential_expression/_pseudobulk_helpers.py,sha256=raQ0DBBrmrxBbGTKhOyZpZLmeJRX_tWcn3_mzuQctkw,8424
|
|
73
|
+
sclab/tools/doublet_detection/__init__.py,sha256=zWyAPScrHVRaBqWaizVsm2H3oi6yr0OQ5gF-fGY2ZrA,63
|
|
74
|
+
sclab/tools/doublet_detection/_scrublet.py,sha256=koi6MRUS1lWVvdpeNbzpR8njqVFrWEuWoKNMFXQLFec,1953
|
|
75
|
+
sclab/tools/labeling/__init__.py,sha256=o-FJWonGNr2h_pB0o3YfnGl_y1kKU06_rYLmTt8ktlQ,57
|
|
76
|
+
sclab/tools/labeling/sctype.py,sha256=jCsCFnqUgb_s1nTSK-N_5pEL_ZvZw-zUo12fUy9RLfs,8164
|
|
77
|
+
sclab/utils/__init__.py,sha256=Py3dPN9ptMs6D-f7IGYisoxOS2YuX0O1oyw75nci3Os,72
|
|
78
|
+
sclab/utils/_write_excel.py,sha256=DBZg9Kx7Ex6VqFrZFDZbSgvzMtu84iEwKo4nI3I2AT0,17017
|
|
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,,
|
sclab-0.2.5.dist-info/RECORD
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
sclab/__init__.py,sha256=wkce6wEC7pfIGHWjYbTJ0_ZAoXv1zRmeOrtEvuBUp8E,132
|
|
2
|
-
sclab/_io.py,sha256=5ISxIPbE233UiOt3QEs9fkLO8DLLEe5HrMnZoR-KLYE,2662
|
|
3
|
-
sclab/_methods_registry.py,sha256=RcffyRuuLzHqsnAdbBL4W1GmZx80d9AxdGjUnx1mbNg,1704
|
|
4
|
-
sclab/_sclab.py,sha256=-ukFb0bWX5MPZsKnoXBJ9SvKyQpuTK4VUCzmWYnAVNM,9062
|
|
5
|
-
sclab/dataset/__init__.py,sha256=f9PoXIMAPnC3Var1ODr3mXkotW6u6NRPQvlgcWYXk54,143
|
|
6
|
-
sclab/dataset/_dataset.py,sha256=dJeiEfo-f6eM866-d53H6FUF9IR-OK4vwDojSq_og0Q,14248
|
|
7
|
-
sclab/dataset/_exceptions.py,sha256=g8RJL8PiRmD4--PkOs5CZth_qeaduvieMlKJNkrUIYA,45
|
|
8
|
-
sclab/dataset/plotter/__init__.py,sha256=pdWhAywnoc1_nnIcD-qNW0U364-yo4k5DwP79y9NVgA,129
|
|
9
|
-
sclab/dataset/plotter/_controls.py,sha256=NBDdtY1wQbIEvE_WToigR5bEEoi3z30_67T_dLSOSIo,20295
|
|
10
|
-
sclab/dataset/plotter/_plotter.py,sha256=EXwk6KSM7FOyLLJ8HCgIB_2m730t0kHsVKWfQOxL6kA,37023
|
|
11
|
-
sclab/dataset/plotter/_utils.py,sha256=ANm_R9PJd33-QJtZzqXCN5pJ_XrJ7AA4AvSHaDRbOMA,11595
|
|
12
|
-
sclab/dataset/processor/__init__.py,sha256=v8Qbusb6h8oSndv9q-12vzHrz5BDF3N2LCkQG9KC19I,104
|
|
13
|
-
sclab/dataset/processor/_processor.py,sha256=H8smeuHPnJVToSxEgGNHUpyNwKYqP-Itp5jMVIgnjbc,41104
|
|
14
|
-
sclab/dataset/processor/_results_panel.py,sha256=p2xmHgoYfpkPXj-SjRGTmAPAwL1VC8I70iFD_o-90AE,2342
|
|
15
|
-
sclab/dataset/processor/step/__init__.py,sha256=j8j4oU9NMdWHn6kVjft7Klm6xme8M6wzebxJj_zNehg,179
|
|
16
|
-
sclab/dataset/processor/step/_basic_processor_step.py,sha256=7NKC4W-I_EU3QBPi5BL9-NwAF_h6_oWl1l_kEk6gSAg,3640
|
|
17
|
-
sclab/dataset/processor/step/_processor_step_base.py,sha256=DpbL4F53W1YPI_xHuQ0T3gcvDGwwKG2Xp-n8DkMUf90,4133
|
|
18
|
-
sclab/event/__init__.py,sha256=unkfpmoxitPVZvWcc9YhkUwcXODdcd9cw_toVXVIDMU,126
|
|
19
|
-
sclab/event/_broker.py,sha256=W4GgoBhJS1LxGQv8TYFg71o5jUQPO8BDLrKzahDUyEM,7121
|
|
20
|
-
sclab/event/_client.py,sha256=Kx7pza-CzLySR0JBBneiZQAjtllUnjWKNKSfw3K2ZQE,2362
|
|
21
|
-
sclab/event/_utils.py,sha256=LehiFhn7dopNEaTFERJhs6fiVgXCBvseRxWTSWc6u-k,456
|
|
22
|
-
sclab/examples/__init__.py,sha256=uSu4DMfF2K7xlZbLC_CmANyS3D56khGLMSVt6x9XXiI,68
|
|
23
|
-
sclab/examples/processor_steps/__init__.py,sha256=ymEOSOlQANfMcyjUQxFEzzzjoZFv8IejfnEFUfPqwKg,500
|
|
24
|
-
sclab/examples/processor_steps/_cluster.py,sha256=olbri3HWPBU8p__r9kP9tgWaJoUJ2bK48pmHfdvf11c,1120
|
|
25
|
-
sclab/examples/processor_steps/_differential_expression.py,sha256=uEToPiACCgo42oZidAw5DFgWVcDnChWzVRlVzn53K34,11567
|
|
26
|
-
sclab/examples/processor_steps/_gene_expression.py,sha256=io_U53TQ3bpclGZ7xjuQHws4Lei5_nMpWTKbvD2zqs0,4216
|
|
27
|
-
sclab/examples/processor_steps/_integration.py,sha256=Vzl2AdLJmnagPWtNYuqW-AmKbQ8jfRSKdui_DpQX1-8,2729
|
|
28
|
-
sclab/examples/processor_steps/_neighbors.py,sha256=sEhLuuY-dCdwzqIarHpFVgM4tE1bW9Qa18xHOWA84Bk,2206
|
|
29
|
-
sclab/examples/processor_steps/_pca.py,sha256=vit15FqHhWC-VSLSViduFt9V7dwakVvdnDOHxzJHiw0,4585
|
|
30
|
-
sclab/examples/processor_steps/_preprocess.py,sha256=pDPAzcqbHyX2zKrGY7HHNYCzrM-wI6VL7YGwUrkq9os,6172
|
|
31
|
-
sclab/examples/processor_steps/_qc.py,sha256=KPWKxytu5YLXQ42uXe3ARKE36jqj5uidLhtyR-_TVBY,3238
|
|
32
|
-
sclab/examples/processor_steps/_umap.py,sha256=Mzxj4LiZfh3WT5lS_BO_lTleC5jMoUm5_km_gvzU_I8,1402
|
|
33
|
-
sclab/methods/__init__.py,sha256=gqqKIvai7E30IA5f4OnYZcyu5xUDF03GzYDkAZNhzr4,823
|
|
34
|
-
sclab/scanpy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
sclab/scanpy/_compat.py,sha256=VEdW4lWLtKmgLSrikRnfvYOz9EOa7e_iDt4Q88X9JKQ,2109
|
|
36
|
-
sclab/scanpy/_settings.py,sha256=UVcJExVHsf_nvyZ5kTrBHPkddHCz7ARCzqAdZAM_A5E,16736
|
|
37
|
-
sclab/scanpy/logging.py,sha256=VwSPeKjpXeopdcgEAlWDz2Wv4IGAAUv8GyMNpMART-0,8453
|
|
38
|
-
sclab/scanpy/readwrite.py,sha256=yixHonShUZ2Ms3Sv3UXw_VXlY00XDApvmyN2mZWFAcs,37025
|
|
39
|
-
sclab/scanpy/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
-
sclab/scanpy/plotting/_rcmod.py,sha256=pc53dasHh2RFfTHVTbTb8v1z8vW032zjvum-WQLgjXA,1970
|
|
41
|
-
sclab/scanpy/plotting/palettes.py,sha256=zHTM_CVfKazb32YreRx0-INllFssZP5rY_B7JTeaBhA,4782
|
|
42
|
-
sclab-0.2.5.dist-info/licenses/LICENSE,sha256=LO7qldZoHIo9hc-HMBqclBh5800kZ9US9xTbLAQdHpg,1523
|
|
43
|
-
sclab-0.2.5.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
44
|
-
sclab-0.2.5.dist-info/METADATA,sha256=q_ELS5JEz0AuZ9kaN0yHVFM2cHb4pUJ6iXbiMfJHom4,4299
|
|
45
|
-
sclab-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|