From 96ae891ca193848870a0cd9f1983a10e77817b54 Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Tue, 28 Jul 2026 12:55:04 +0200 Subject: [PATCH 1/2] reuse the precomputed spatial clustering `downstream` threw away the `spatial_cluster` that process_datasets/generate_sim_spatialcluster had just computed and ran BayesSpace again. BayesSpace is stochastic and unseeded, so the two runs disagree: on the positive control clustering_ari averages 0.55 with a per-dataset range of 0.14-0.92, while the best simulator averages 0.22. The metric was measuring its own noise more than the simulators. `reclassify_simsce()` was called but its result never used -- ARI and NMI do not care about label permutations -- so that call goes as well. --- src/metrics/downstream/script.R | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/metrics/downstream/script.R b/src/metrics/downstream/script.R index f03009c8..0f0dcb6e 100644 --- a/src/metrics/downstream/script.R +++ b/src/metrics/downstream/script.R @@ -43,13 +43,20 @@ crosscor_cosine <- generate_cosine(real_moransI, sim_moransI) crosscor_mantel <- generate_mantel(real_moransI, sim_moransI) cat("spatial clustering evaluation\n") -# reclassify the clustering result -real_cluster <- input_real_sp$obs[, c("spatial_cluster")] -sim_cluster <- generate_sim_spatialCluster(input_real_sp, input_simulated_sp) -location <- rownames(input_simulated_sp) -sim_new_cluster <- reclassify_simsce(location, real_cluster, sim_cluster) +# the simulated clustering was already computed by +# process_datasets/generate_sim_spatialcluster; recomputing it here would give a +# different answer every time, since BayesSpace is stochastic and unseeded +real_cluster <- input_real_sp$obs[["spatial_cluster"]] +sim_cluster <- input_simulated_sp$obs[["spatial_cluster"]] -# ART and NMI +if (is.null(sim_cluster)) { + stop( + "The simulated dataset has no 'spatial_cluster' column. ", + "Did it pass through process_datasets/generate_sim_spatialcluster?" + ) +} + +# ARI and NMI clustering_ari <- aricode::ARI(real_cluster, sim_cluster) clustering_nmi <- aricode::NMI(real_cluster, sim_cluster) From e351a0c11fd8dd27303e4dc00d230d6e2d36efca Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Tue, 28 Jul 2026 14:23:41 +0200 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33c66d8d..e2ec54e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,12 @@ Bug fixes: mismatched spots. - `generate_sim_spatialcluster`: check that the simulated dataset still lines up with the real one, through a new `check_alignment()` helper. + - `downstream`: reuse the `spatial_cluster` that + `process_datasets/generate_sim_spatialcluster` already computed, instead of + running `BayesSpace::spatialCluster()` a second time. Saves an MCMC run per + method per dataset and makes the metric report the clustering the pipeline + stored. This does not make `clustering_ari` reproducible: both before and + after, a fixed reference is compared against one unseeded run. - `generate_cosine()`: filter the Moran's I values rather than the objects holding them, so that a single NaN no longer takes the whole metric with it. `crosscor_cosine` was NA for 32 of 99 runs.