diff --git a/CHANGELOG.md b/CHANGELOG.md index d98cb47d..757283e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Updates +- `ReadPNA_Seurat` now only loads a subset of the available meta data columns to avoid bloating the `meta.data` slot. Detailed meta data can be loaded by setting `detailed_meta_data = TRUE`. + ## [0.20.0] - 2026-08-27 ### Added diff --git a/R/aaa.R b/R/aaa.R index c30b3970..37b27957 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -40,6 +40,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", + "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 d3550bd7..d0b60d80 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(any_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-MoleculeRankPlot.R b/tests/testthat/test-MoleculeRankPlot.R index ac893041..0484a2d4 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") }) # min max threshold diff --git a/tests/testthat/test-ReadPNA_Seurat.R b/tests/testthat/test-ReadPNA_Seurat.R index a64147ed..2f3396da 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", { @@ -32,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( @@ -43,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(