scib-metrics 0.5.2__tar.gz → 0.5.4__tar.gz
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.
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.pre-commit-config.yaml +1 -1
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/CHANGELOG.md +12 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/PKG-INFO +1 -1
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/pyproject.toml +1 -1
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/benchmark/_core.py +2 -6
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_kbet.py +47 -46
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/test_benchmarker.py +14 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.codecov.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.cruft.json +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.editorconfig +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/build.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/release.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_linux.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_linux_cuda.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_linux_pre.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_macos.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_macos_m1.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.github/workflows/test_windows.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.gitignore +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/.readthedocs.yaml +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/LICENSE +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/README.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/Makefile +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/_static/.gitkeep +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/_static/css/custom.css +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/_templates/.gitkeep +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/_templates/autosummary/class.rst +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/_templates/class_no_inherited.rst +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/api.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/changelog.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/conf.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/contributing.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/extensions/.gitkeep +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/extensions/typed_returns.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/index.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/notebooks/large_scale.ipynb +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/notebooks/lung_example.ipynb +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/references.bib +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/references.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/template_usage.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/docs/tutorials.md +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/setup.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/_settings.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/_types.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/benchmark/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_graph_connectivity.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_isolated_labels.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_lisi.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_nmi_ari.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_pcr_comparison.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/metrics/_silhouette.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/nearest_neighbors/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/nearest_neighbors/_dataclass.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/nearest_neighbors/_jax.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/nearest_neighbors/_pynndescent.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_diffusion_nn.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_dist.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_kmeans.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_lisi.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_pca.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_pcr.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_silhouette.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/utils/_utils.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/test_metrics.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/test_neighbors.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/test_pcr_comparison.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/utils/__init__.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/utils/data.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/utils/sampling.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/utils/test_pca.py +0 -0
- {scib_metrics-0.5.2 → scib_metrics-0.5.4}/tests/utils/test_pcr.py +0 -0
|
@@ -10,6 +10,18 @@ and this project adheres to [Semantic Versioning][].
|
|
|
10
10
|
|
|
11
11
|
## 0.6.0 (unreleased)
|
|
12
12
|
|
|
13
|
+
## 0.5.4 (2025-04-23)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Apply default values for benchmarker metrics {pr}`203`.
|
|
18
|
+
|
|
19
|
+
## 0.5.3 (2025-02-17)
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
|
|
23
|
+
- Reverted a change that was needed for scib-autotune in scvi-tools {pr}`189`.
|
|
24
|
+
|
|
13
25
|
## 0.5.2 (2025-02-13)
|
|
14
26
|
|
|
15
27
|
### Added
|
|
@@ -136,8 +136,8 @@ class Benchmarker:
|
|
|
136
136
|
batch_key: str,
|
|
137
137
|
label_key: str,
|
|
138
138
|
embedding_obsm_keys: list[str],
|
|
139
|
-
bio_conservation_metrics: BioConservation | None,
|
|
140
|
-
batch_correction_metrics: BatchCorrection | None,
|
|
139
|
+
bio_conservation_metrics: BioConservation | None = BioConservation(),
|
|
140
|
+
batch_correction_metrics: BatchCorrection | None = BatchCorrection(),
|
|
141
141
|
pre_integrated_embedding_obsm_key: str | None = None,
|
|
142
142
|
n_jobs: int = 1,
|
|
143
143
|
progress_bar: bool = True,
|
|
@@ -282,10 +282,6 @@ class Benchmarker:
|
|
|
282
282
|
|
|
283
283
|
# Compute scores
|
|
284
284
|
per_class_score = df.groupby(_METRIC_TYPE).mean().transpose()
|
|
285
|
-
if "Batch correction" not in per_class_score.columns:
|
|
286
|
-
per_class_score["Batch correction"] = 0.5
|
|
287
|
-
if "Bio conservation" not in per_class_score.columns:
|
|
288
|
-
per_class_score["Bio conservation"] = 0.5
|
|
289
285
|
# This is the default scIB weighting from the manuscript
|
|
290
286
|
if self._batch_correction_metrics is not None and self._bio_conservation_metrics is not None:
|
|
291
287
|
per_class_score["Total"] = (
|
|
@@ -138,8 +138,14 @@ def kbet_per_label(
|
|
|
138
138
|
conn_graph = X.knn_graph_connectivities
|
|
139
139
|
|
|
140
140
|
# prepare call of kBET per cluster
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
clusters = []
|
|
142
|
+
clusters, counts = np.unique(labels, return_counts=True)
|
|
143
|
+
skipped = clusters[counts > 10]
|
|
144
|
+
clusters = clusters[counts <= 10]
|
|
145
|
+
kbet_scores = {"cluster": list(skipped), "kBET": [np.nan] * len(skipped)}
|
|
146
|
+
logger.info(f"{len(skipped)} clusters consist of a single batch or are too small. Skip.")
|
|
147
|
+
|
|
148
|
+
for clus in clusters:
|
|
143
149
|
# subset by label
|
|
144
150
|
mask = labels == clus
|
|
145
151
|
conn_graph_sub = conn_graph[mask, :][:, mask]
|
|
@@ -147,60 +153,55 @@ def kbet_per_label(
|
|
|
147
153
|
n_obs = conn_graph_sub.shape[0]
|
|
148
154
|
batches_sub = batches[mask]
|
|
149
155
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
quarter_mean = np.floor(np.mean(pd.Series(batches_sub).value_counts()) / 4).astype("int")
|
|
157
|
+
k0 = np.min([70, np.max([10, quarter_mean])])
|
|
158
|
+
# check k0 for reasonability
|
|
159
|
+
if k0 * n_obs >= size_max:
|
|
160
|
+
k0 = np.floor(size_max / n_obs).astype("int")
|
|
161
|
+
|
|
162
|
+
n_comp, labs = scipy.sparse.csgraph.connected_components(conn_graph_sub, connection="strong")
|
|
163
|
+
|
|
164
|
+
if n_comp == 1: # a single component to compute kBET on
|
|
165
|
+
try:
|
|
166
|
+
diffusion_n_comps = np.min([diffusion_n_comps, n_obs - 1])
|
|
167
|
+
nn_graph_sub = diffusion_nn(conn_graph_sub, k=k0, n_comps=diffusion_n_comps)
|
|
168
|
+
# call kBET
|
|
169
|
+
score, _, _ = kbet(
|
|
170
|
+
nn_graph_sub,
|
|
171
|
+
batches=batches_sub,
|
|
172
|
+
alpha=alpha,
|
|
173
|
+
)
|
|
174
|
+
except ValueError:
|
|
175
|
+
logger.info("Diffusion distance failed. Skip.")
|
|
176
|
+
score = 0 # i.e. 100% rejection
|
|
160
177
|
|
|
161
|
-
|
|
178
|
+
else:
|
|
179
|
+
# check the number of components where kBET can be computed upon
|
|
180
|
+
comp_size = pd.Series(labs).value_counts()
|
|
181
|
+
# check which components are small
|
|
182
|
+
comp_size_thresh = 3 * k0
|
|
183
|
+
idx_nonan = np.flatnonzero(np.in1d(labs, comp_size[comp_size >= comp_size_thresh].index))
|
|
184
|
+
|
|
185
|
+
# check if 75% of all cells can be used for kBET run
|
|
186
|
+
if len(idx_nonan) / len(labs) >= 0.75:
|
|
187
|
+
# create another subset of components, assume they are not visited in a diffusion process
|
|
188
|
+
conn_graph_sub_sub = conn_graph_sub[idx_nonan, :][:, idx_nonan]
|
|
189
|
+
conn_graph_sub_sub.sort_indices()
|
|
162
190
|
|
|
163
|
-
if n_comp == 1: # a single component to compute kBET on
|
|
164
191
|
try:
|
|
165
|
-
diffusion_n_comps = np.min([diffusion_n_comps,
|
|
166
|
-
|
|
192
|
+
diffusion_n_comps = np.min([diffusion_n_comps, conn_graph_sub_sub.shape[0] - 1])
|
|
193
|
+
nn_results_sub_sub = diffusion_nn(conn_graph_sub_sub, k=k0, n_comps=diffusion_n_comps)
|
|
167
194
|
# call kBET
|
|
168
195
|
score, _, _ = kbet(
|
|
169
|
-
|
|
170
|
-
batches=batches_sub,
|
|
196
|
+
nn_results_sub_sub,
|
|
197
|
+
batches=batches_sub[idx_nonan],
|
|
171
198
|
alpha=alpha,
|
|
172
199
|
)
|
|
173
200
|
except ValueError:
|
|
174
201
|
logger.info("Diffusion distance failed. Skip.")
|
|
175
202
|
score = 0 # i.e. 100% rejection
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
# check the number of components where kBET can be computed upon
|
|
179
|
-
comp_size = pd.Series(labs).value_counts()
|
|
180
|
-
# check which components are small
|
|
181
|
-
comp_size_thresh = 3 * k0
|
|
182
|
-
idx_nonan = np.flatnonzero(np.in1d(labs, comp_size[comp_size >= comp_size_thresh].index))
|
|
183
|
-
|
|
184
|
-
# check if 75% of all cells can be used for kBET run
|
|
185
|
-
if len(idx_nonan) / len(labs) >= 0.75:
|
|
186
|
-
# create another subset of components, assume they are not visited in a diffusion process
|
|
187
|
-
conn_graph_sub_sub = conn_graph_sub[idx_nonan, :][:, idx_nonan]
|
|
188
|
-
conn_graph_sub_sub.sort_indices()
|
|
189
|
-
|
|
190
|
-
try:
|
|
191
|
-
diffusion_n_comps = np.min([diffusion_n_comps, conn_graph_sub_sub.shape[0] - 1])
|
|
192
|
-
nn_results_sub_sub = diffusion_nn(conn_graph_sub_sub, k=k0, n_comps=diffusion_n_comps)
|
|
193
|
-
# call kBET
|
|
194
|
-
score, _, _ = kbet(
|
|
195
|
-
nn_results_sub_sub,
|
|
196
|
-
batches=batches_sub[idx_nonan],
|
|
197
|
-
alpha=alpha,
|
|
198
|
-
)
|
|
199
|
-
except ValueError:
|
|
200
|
-
logger.info("Diffusion distance failed. Skip.")
|
|
201
|
-
score = 0 # i.e. 100% rejection
|
|
202
|
-
else: # if there are too many too small connected components, set kBET score to 0
|
|
203
|
-
score = 0 # i.e. 100% rejection
|
|
203
|
+
else: # if there are too many too small connected components, set kBET score to 0
|
|
204
|
+
score = 0 # i.e. 100% rejection
|
|
204
205
|
|
|
205
206
|
kbet_scores["cluster"].append(clus)
|
|
206
207
|
kbet_scores["kBET"].append(score)
|
|
@@ -21,6 +21,20 @@ def test_benchmarker():
|
|
|
21
21
|
bm.plot_results_table()
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def test_benchmarker_default():
|
|
25
|
+
ad, emb_keys, batch_key, labels_key = dummy_benchmarker_adata()
|
|
26
|
+
bm = Benchmarker(
|
|
27
|
+
ad,
|
|
28
|
+
batch_key,
|
|
29
|
+
labels_key,
|
|
30
|
+
emb_keys,
|
|
31
|
+
)
|
|
32
|
+
bm.benchmark()
|
|
33
|
+
results = bm.get_results()
|
|
34
|
+
assert isinstance(results, pd.DataFrame)
|
|
35
|
+
bm.plot_results_table()
|
|
36
|
+
|
|
37
|
+
|
|
24
38
|
def test_benchmarker_custom_metric_booleans():
|
|
25
39
|
bioc = BioConservation(
|
|
26
40
|
isolated_labels=False, nmi_ari_cluster_labels_leiden=False, silhouette_label=False, clisi_knn=True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scib_metrics-0.5.2 → scib_metrics-0.5.4}/src/scib_metrics/nearest_neighbors/_pynndescent.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|