From 330e63636f5487cb61befae64c90013104d91f57 Mon Sep 17 00:00:00 2001 From: ludvigla Date: Mon, 22 Jun 2026 14:27:53 +0200 Subject: [PATCH 1/4] Filter cell meta data in ReadPNA_Seurat --- CHANGELOG.md | 3 +++ R/aaa.R | 10 ++++++++++ R/load_data_pna.R | 9 +++++++++ man/ReadPNA_Seurat.Rd | 6 ++++++ tests/testthat/test-ReadPNA_Seurat.R | 4 ++++ 5 files changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5937a4f..0d0def60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Updates +- `ReadPNA_Seurat` now only loads a subset of the available meta data columns to avoid bloating the `meta.data` slot. Users can enable loading of detailed meta data by setting `detailed_meta_data = TRUE`. + ### Fixes - Fixed a bug in `ProximityScores.Seurat` that would (on some systems) throw an error when setting the connection to the lazy table of proximity scores. - Fixed bug in `AnnotateCells` (method "nmf") where cells with 0 value prediction scores crashed the function. Such cells are now labeled as "Unknown". diff --git a/R/aaa.R b/R/aaa.R index 7e2be90b..5484d6f7 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -33,6 +33,16 @@ globalVariables( ) +#' Default columns to pull from cell metadata table __adata__obs in PXL files +#' +#' @noRd +CELL_META_COLS <- c( + "n_umi", "n_edges", "n_antibodies", "isotype_fraction", + "average_k_core", "reads_in_component", "tau", "tau_type", + "n_umi1", "n_umi2", "sample" +) + + #' Check global option for verbosity #' #' By setting the global option \code{options(pixelatorR.verbose = FALSE)}, diff --git a/R/load_data_pna.R b/R/load_data_pna.R index 8794dbeb..0f6ee911 100644 --- a/R/load_data_pna.R +++ b/R/load_data_pna.R @@ -51,6 +51,10 @@ ReadPNA_counts <- function( #' be loaded into the \code{PNAAssay}/\code{PNAAssay5}. If you only intend to analyze #' abundance data or PNA graphs, you can set this parameter to \code{FALSE} to use less #' memory. This parameter only have an effect if \code{return_pna_assay = TRUE}. +#' @param detailed_meta_data Logical specifying whether to load detailed meta data. +#' If \code{FALSE} (default), only a subset of the meta data columns will be loaded, +#' including those used for quality control. The additional columns are mostly useful +#' for troubleshooting. #' @param ... Additional parameters passed to \code{\link[SeuratObject]{CreateSeuratObject}} #' @inheritParams ReadPNA_counts #' @inheritParams ReadPNA_proximity @@ -75,6 +79,7 @@ ReadPNA_Seurat <- function( return_pna_assay = TRUE, load_proximity_scores = TRUE, calc_log2_ratio = TRUE, + detailed_meta_data = FALSE, verbose = TRUE, ... ) { @@ -86,6 +91,7 @@ ReadPNA_Seurat <- function( assert_single_value(return_pna_assay, type = "bool") assert_single_value(load_proximity_scores, type = "bool") assert_single_value(calc_log2_ratio, type = "bool") + assert_single_value(detailed_meta_data, type = "bool") assert_single_value(verbose, type = "bool") # Setup connection to PXL file @@ -158,6 +164,9 @@ ReadPNA_Seurat <- function( # Extract meta data meta_data <- db$cell_meta() + if (!detailed_meta_data) { + meta_data <- meta_data %>% select(all_of(CELL_META_COLS)) + } if (!all(rownames(meta_data) == colnames(seur_obj))) { cli::cli_abort( diff --git a/man/ReadPNA_Seurat.Rd b/man/ReadPNA_Seurat.Rd index 690c3f5b..11b5afe9 100644 --- a/man/ReadPNA_Seurat.Rd +++ b/man/ReadPNA_Seurat.Rd @@ -10,6 +10,7 @@ ReadPNA_Seurat( return_pna_assay = TRUE, load_proximity_scores = TRUE, calc_log2_ratio = TRUE, + detailed_meta_data = FALSE, verbose = TRUE, ... ) @@ -33,6 +34,11 @@ memory. This parameter only have an effect if \code{return_pna_assay = TRUE}.} \item{calc_log2_ratio}{A logical specifying whether to calculate and add a log2ratio column to the output table. Default is \code{TRUE}} +\item{detailed_meta_data}{Logical specifying whether to load detailed meta data. +If \code{FALSE} (default), only a subset of the meta data columns will be loaded, +including those used for quality control. The additional columns are mostly useful +for troubleshooting.} + \item{verbose}{Print messages} \item{...}{Additional parameters passed to \code{\link[SeuratObject]{CreateSeuratObject}}} diff --git a/tests/testthat/test-ReadPNA_Seurat.R b/tests/testthat/test-ReadPNA_Seurat.R index a64147ed..56625aaa 100644 --- a/tests/testthat/test-ReadPNA_Seurat.R +++ b/tests/testthat/test-ReadPNA_Seurat.R @@ -20,6 +20,10 @@ for (assay_version in c("v3", "v5")) { expect_no_error(suppressWarnings(seur_obj <- ReadPNA_Seurat(pxl_file, return_pna_assay = FALSE, verbose = FALSE))) expect_s4_class(seur_obj[["PNA"]], ifelse(assay_version == "v3", "Assay", "Assay5")) + + # Including detailed meta data + expect_no_error(suppressWarnings(seur_obj_detailed_meta <- ReadPNA_Seurat(pxl_file, detailed_meta_data = TRUE, verbose = FALSE))) + expect_true(ncol(seur_obj_detailed_meta[[]]) > ncol(seur_obj[[]])) }) test_that("ReadPNA_Seurat fails with invalid input", { From 4b6a9410bfb8036797fa64d6e96ad9de2491a8b7 Mon Sep 17 00:00:00 2001 From: ludvigla Date: Mon, 22 Jun 2026 17:11:48 +0200 Subject: [PATCH 2/4] Addressed PR comments --- R/aaa.R | 2 +- R/load_data_pna.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/aaa.R b/R/aaa.R index 5484d6f7..79ce072e 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -38,7 +38,7 @@ globalVariables( #' @noRd CELL_META_COLS <- c( "n_umi", "n_edges", "n_antibodies", "isotype_fraction", - "average_k_core", "reads_in_component", "tau", "tau_type", + "average_k_core", "reads_in_component", "n_umi1", "n_umi2", "sample" ) diff --git a/R/load_data_pna.R b/R/load_data_pna.R index 0f6ee911..cb10ae79 100644 --- a/R/load_data_pna.R +++ b/R/load_data_pna.R @@ -165,7 +165,7 @@ ReadPNA_Seurat <- function( # Extract meta data meta_data <- db$cell_meta() if (!detailed_meta_data) { - meta_data <- meta_data %>% select(all_of(CELL_META_COLS)) + meta_data <- meta_data %>% select(any_of(CELL_META_COLS)) } if (!all(rownames(meta_data) == colnames(seur_obj))) { From f2ca06ce19df3d025b8e4ad16c081f2852172215 Mon Sep 17 00:00:00 2001 From: ludvigla Date: Mon, 22 Jun 2026 17:17:19 +0200 Subject: [PATCH 3/4] Fixed failing test --- tests/testthat/test-ReadPNA_Seurat.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-ReadPNA_Seurat.R b/tests/testthat/test-ReadPNA_Seurat.R index 56625aaa..2f3396da 100644 --- a/tests/testthat/test-ReadPNA_Seurat.R +++ b/tests/testthat/test-ReadPNA_Seurat.R @@ -36,7 +36,7 @@ for (assay_version in c("v3", "v5")) { test_that("ReadPNA_Seurat fails when X collapses to a vector (1 cell)", { # Inject an error by subsetting X to have only one cell - trace(ReadPNA_Seurat, tracer = quote(X <- X[, 1]), at = 13, print = FALSE) + trace(ReadPNA_Seurat, tracer = quote(X <- X[, 1, drop = FALSE]), at = 14, print = FALSE) on.exit(untrace(ReadPNA_Seurat), add = TRUE) expect_error( @@ -47,7 +47,7 @@ for (assay_version in c("v3", "v5")) { test_that("ReadPNA_Seurat fails when X is a 1-column matrix", { # Inject an error by subsetting X to have only one cell, keeping it as a matrix - trace(ReadPNA_Seurat, tracer = quote(X <- X[, 1, drop = FALSE]), at = 13, print = FALSE) + trace(ReadPNA_Seurat, tracer = quote(X <- X[, 1, drop = FALSE]), at = 14, print = FALSE) on.exit(untrace(ReadPNA_Seurat), add = TRUE) expect_error( From 59275f7d8cee789e7e388c23353faa6aee3bc114 Mon Sep 17 00:00:00 2001 From: ludvigla Date: Mon, 22 Jun 2026 19:11:54 +0200 Subject: [PATCH 4/4] Removed tau_type from test --- tests/testthat/test-MoleculeRankPlot.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-MoleculeRankPlot.R b/tests/testthat/test-MoleculeRankPlot.R index 789466c8..0fa3e484 100644 --- a/tests/testthat/test-MoleculeRankPlot.R +++ b/tests/testthat/test-MoleculeRankPlot.R @@ -3,6 +3,7 @@ pxl_file_mpx <- minimal_mpx_pxl_file() seur_obj_mpx <- ReadMPX_Seurat(pxl_file_mpx) pxl_file_pna <- minimal_pna_pxl_file() seur_obj_pna <- ReadPNA_Seurat(pxl_file_pna) +seur_obj_pna$sample_id <- c("S1", "S1", "S2", "S2", "S3") test_that("MoleculeRankPlot works for Seurat objects", { expect_no_error({ @@ -17,7 +18,7 @@ test_that("MoleculeRankPlot works for Seurat objects", { }) expect_s3_class(moleculerank_plot, "ggplot") expect_no_error({ - moleculerank_plot <- MoleculeRankPlot(seur_obj_pna, group_by = "tau_type") + moleculerank_plot <- MoleculeRankPlot(seur_obj_pna, group_by = "sample_id") }) })