diff --git a/.github/workflows/release_checks.yaml b/.github/workflows/release_checks.yaml index c1a5c2f63..ed46d2933 100644 --- a/.github/workflows/release_checks.yaml +++ b/.github/workflows/release_checks.yaml @@ -63,6 +63,9 @@ jobs: extra-packages: any::rcmdcheck any::pkgdown + any::testthat + # Only install hard / required dependencies + dependencies: '"hard"' # Installed packages are cached by default - force an upgrade to the # latest version of all dependencies. upgrade: 'TRUE' diff --git a/DESCRIPTION b/DESCRIPTION index d124bcae8..e062a9884 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: Seurat -Version: 5.3.1.9999 +Version: 5.4.0 Title: Tools for Single Cell Genomics Description: A toolkit for quality control, analysis, and exploration of single cell RNA sequencing data. 'Seurat' aims to enable users to identify and interpret sources of heterogeneity from single cell transcriptomic measurements, and to integrate diverse types of single cell data. See Satija R, Farrell J, Gennert D, et al (2015) , Macosko E, Basu A, Satija R, et al (2015) , Stuart T, Butler A, et al (2019) , and Hao, Hao, et al (2020) for more details. Authors@R: c( @@ -59,7 +59,6 @@ Imports: irlba, jsonlite, KernSmooth, - leidenbase, lifecycle, lmtest, MASS, @@ -110,6 +109,7 @@ Suggests: harmony, hdf5r, IRanges, + leidenbase, limma, magrittr, MAST, diff --git a/NEWS.md b/NEWS.md index 6e2f36283..b9b7dd23e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,11 +1,18 @@ -# Unreleased +# Seurat 5.4.0 ### Additions -- Added support for Space Ranger 4.0 outputs - updated `Load10X_Spatial`, `Read10X_Image`, spatial visualization functions (`SpatialPlot`, `SingleSpatialPlot`, `SpatialDimPlot`, `SpatialFeaturePlot`), added helpers (`Read10X_Segmentations`, `Read10X_HD_GeoJson`, `Format10X_GeoJson_CellID`) +- Added support for 10x Space Ranger 4.0 outputs (Visium data with segmentations) + - Updated data loading functions `Load10X_Spatial`, `Read10X_Image`, + - Updated `GetTissueCoordinates.VisiumV2` + - Updated spatial visualization functions `SpatialPlot`, `SingleSpatialPlot`, `SpatialDimPlot`, `SpatialFeaturePlot` + - Added helper functions `Read10X_Segmentations`, `Read10X_HD_GeoJson`, `Format10X_GeoJson_CellID` - Added function `InteractiveSpatialPlot` to allow users to interactively lasso-select cells from a spatial Seurat object (Visium, SlideSeq, or Vizgen data) ### Fixes -- Reverted #10062 in favor of fetching both grouping variables and dimensionality reduction embeddings with `FetchData`; added warning to alert users when column names of metadata and dimensionality reduction embeddings conflict +- Updated loading & visualization functions (see above for list) for Visium objects -- see [#10125](https://github.com/satijalab/seurat/pull/10215) for details + - For binned Visium data, `x` now correctly corresponds to `imagecol` from tissue positions; `y` now correctly corresponds to `imagerow` from tissue positions; these are now consistent with 10X's coordinate system (with the origin being the top left). +- Reverted [#10062](https://github.com/satijalab/seurat/pull/10062) in favor of fetching both grouping variables and dimensionality reduction embeddings with `FetchData` as previously; added warning to alert users when column names of metadata and dimensionality reduction embeddings conflict +- Added color retrieval logic in `LabelClusters` for consistent cluster label coloring ([#10198](https://github.com/satijalab/seurat/pull/10198)) # Seurat 5.3.1 diff --git a/R/clustering.R b/R/clustering.R index a8dcdb1fc..8ec62006f 100644 --- a/R/clustering.R +++ b/R/clustering.R @@ -1802,6 +1802,12 @@ RunLeiden <- function( # Run clustering with `leidenbase`. if (leiden_method == "leidenbase") { + # Check if leidenbase is available + if (!requireNamespace("leidenbase", quietly = TRUE)) { + stop("Package 'leidenbase' is required for leiden_method = 'leidenbase'. ", + "Please install it with: install.packages('leidenbase')") + } + partition <- leidenbase::leiden_find_partition( input, partition_type = partition.type, diff --git a/R/data.R b/R/data.R index 167785071..08d49d9ad 100644 --- a/R/data.R +++ b/R/data.R @@ -8,7 +8,7 @@ #' \item{g2m.genes}{Genes associated with G2M-phase} #' } #' @concept data -#' @source \url{https://www.science.org/doi/abs/10.1126/science.aad0501} +#' @source `https://doi.org/10.1126/science.aad0501` #' "cc.genes" @@ -41,7 +41,7 @@ #' \item{g2m.genes}{Genes associated with G2M-phase} #' } #' @concept data -#' @source \url{https://www.science.org/doi/abs/10.1126/science.aad0501} +#' @source `https://doi.org/10.1126/science.aad0501` #' #' @seealso \code{\link{cc.genes}} #' diff --git a/cran-comments.md b/cran-comments.md index e69de29bb..a83811bf3 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -0,0 +1,47 @@ +# Seurat v5.4.0 + +## Test environments +* Ubuntu 20.04 (local) (R 4.3.2) +* macOS 15.6.1 (local) (R 4.5.1) +* Ubuntu 24.04 (GitHub Actions Runner): R-oldrelease, R-release +* [win-builder](https://win-builder.r-project.org/): R-oldrelease, R-release, R-devel + +## R CMD check results +**Status: OK** + +``` +* checking CRAN incoming feasibility ... [42s] NOTE +Maintainer: 'Rahul Satija ' + +Suggests or Enhances not in mainstream repositories: + BPCells, presto +Availability using Additional_repositories specification: + BPCells yes https://bnprks.r-universe.dev + presto yes https://satijalab.r-universe.dev +``` + +The maintainer remains Rahul Satija and the email is correct. BPCells and presto are hosted on R-universe and used conditionally in Seurat. + +``` +* checking package dependencies ... NOTE +Packages suggested but not available for checking: 'BPCells', 'presto' +``` + +BPCells and presto are hosted on R-universe and used conditionally in Seurat. + +``` +* checking DESCRIPTION meta-information ... NOTE +Author field differs from that derived from Authors@R +``` + +There seems to be a slight difference in ORCID formatting between Author and Authors@R; the information in both is the same. + +``` +* checking Rd cross-references ... NOTE +Package unavailable to check Rd xrefs: 'BPCells' +``` + +BPCells is listed under "Suggests"; it is hosted on R-universe and used conditionally in Seurat. + +## Reverse dependency check results +We checked 80 reverse dependencies (40 from CRAN + 40 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package, and saw no new problems. diff --git a/man/PrepSCTFindMarkers.Rd b/man/PrepSCTFindMarkers.Rd index 4c29d71c0..b30093c2e 100644 --- a/man/PrepSCTFindMarkers.Rd +++ b/man/PrepSCTFindMarkers.Rd @@ -32,7 +32,7 @@ render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read -\href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +\href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \section{Parallelization with \pkg{future}}{ diff --git a/man/ReadAkoya.Rd b/man/ReadAkoya.Rd index 9c0041368..c0577c237 100644 --- a/man/ReadAkoya.Rd +++ b/man/ReadAkoya.Rd @@ -77,7 +77,7 @@ render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read -\href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +\href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \concept{preprocessing} diff --git a/man/ReadNanostring.Rd b/man/ReadNanostring.Rd index bbdc764f4..b89002dbb 100644 --- a/man/ReadNanostring.Rd +++ b/man/ReadNanostring.Rd @@ -118,7 +118,7 @@ render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read -\href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +\href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \section{Parallelization with \pkg{future}}{ diff --git a/man/ReadVitessce.Rd b/man/ReadVitessce.Rd index 6558ac87c..414516f08 100644 --- a/man/ReadVitessce.Rd +++ b/man/ReadVitessce.Rd @@ -80,7 +80,7 @@ render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read -\href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +\href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \examples{ diff --git a/man/ReadVizgen.Rd b/man/ReadVizgen.Rd index 443a04555..3c5bd94af 100644 --- a/man/ReadVizgen.Rd +++ b/man/ReadVizgen.Rd @@ -115,7 +115,7 @@ render status updates and progress bars. To enable progress updates, wrap the function call in \code{\link[progressr]{with_progress}} or run \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running this function. For more details about \pkg{progressr}, please read -\href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +\href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} } \section{Parallelization with \pkg{future}}{ diff --git a/man/cc.genes.Rd b/man/cc.genes.Rd index 16f7b2471..26227bcd0 100644 --- a/man/cc.genes.Rd +++ b/man/cc.genes.Rd @@ -12,7 +12,7 @@ A list of two vectors } } \source{ -\url{https://www.science.org/doi/abs/10.1126/science.aad0501} +`https://doi.org/10.1126/science.aad0501` } \usage{ cc.genes diff --git a/man/cc.genes.updated.2019.Rd b/man/cc.genes.updated.2019.Rd index b796aeefc..5aabdccdc 100644 --- a/man/cc.genes.updated.2019.Rd +++ b/man/cc.genes.updated.2019.Rd @@ -12,7 +12,7 @@ A list of two vectors } } \source{ -\url{https://www.science.org/doi/abs/10.1126/science.aad0501} +`https://doi.org/10.1126/science.aad0501` } \usage{ cc.genes.updated.2019 diff --git a/man/roxygen/templates/section-progressr.R b/man/roxygen/templates/section-progressr.R index fdcde574f..d918e1c37 100644 --- a/man/roxygen/templates/section-progressr.R +++ b/man/roxygen/templates/section-progressr.R @@ -5,4 +5,4 @@ #' the function call in \code{\link[progressr]{with_progress}} or run #' \code{\link[progressr:handlers]{handlers(global = TRUE)}} before running #' this function. For more details about \pkg{progressr}, please read -#' \href{https://progressr.futureverse.org/articles/progressr-intro.html}{\code{vignette("progressr-intro")}} +#' \href{https://progressr.futureverse.org/articles/progressr-01-intro.html}{\code{vignette("progressr-intro")}} diff --git a/tests/testthat/test_differential_expression.R b/tests/testthat/test_differential_expression.R index 060d485e1..99c9a8d9f 100644 --- a/tests/testthat/test_differential_expression.R +++ b/tests/testthat/test_differential_expression.R @@ -16,6 +16,7 @@ results.sct <- suppressWarnings(FindMarkers(object = sct.obj, ident.1 = 0, ident test_that("Default settings work as expected with pseudocount = 1", { + skip_on_cran() expect_error(FindMarkers(object = pbmc_small)) expect_error(FindMarkers(object = pbmc_small, ident.1 = "test")) expect_error(FindMarkers(object = pbmc_small, ident.1 = 0, ident.2 = "test")) @@ -60,6 +61,7 @@ tymp.results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, f vargenes.results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, features = VariableFeatures(object = pbmc_small), verbose = FALSE, base = exp(1),pseudocount.use = 1)) test_that("features parameter behaves correctly ", { + skip_on_cran() expect_equal(nrow(x = tymp.results), 1) expect_equal(tymp.results[1, "p_val"], 3.227445e-07, tolerance = 1e-12) expect_equal(tymp.results[1, "avg_logFC"], -2.188179, tolerance = 1e-6) @@ -80,6 +82,7 @@ test_that("features parameter behaves correctly ", { results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = Cells(x = pbmc_small)[1:40], ident.2 = Cells(x = pbmc_small)[41:80], verbose = FALSE, base = exp(1),pseudocount.use = 1)) test_that("passing cell names works", { + skip_on_cran() expect_equal(nrow(x = results), 216) expect_equal(results[1, "p_val"], 0.0001690882) expect_equal(results[1, "avg_logFC"], -1.967123, tolerance = 1e-6) @@ -93,6 +96,7 @@ results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, ident. results.clr <- suppressWarnings(FindMarkers(object = clr.obj, ident.1 = 0, ident.2 = 1, verbose = FALSE, base = exp(1), pseudocount.use = 0.1)) results.sct <- suppressWarnings(FindMarkers(object = sct.obj, ident.1 = 0, ident.2 = 1, verbose = FALSE, base = exp(1), pseudocount.use = 0.1, vst.flavor = "v1")) test_that("setting pseudocount.use works", { + skip_on_cran() expect_equal(nrow(x = results), 222) expect_equal(results[1, "avg_logFC"], -2.640848, tolerance = 1e-6) expect_equal(nrow(x = results.clr), 214) @@ -105,6 +109,7 @@ results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, ident. results.clr <- suppressWarnings(FindMarkers(object = clr.obj, ident.1 = 0, ident.2 = 1, verbose = FALSE, base = exp(1), pseudocount.use = 1, mean.fxn = rowMeans)) results.sct <- suppressWarnings(FindMarkers(object = sct.obj, ident.1 = 0, ident.2 = 1, verbose = FALSE, base = exp(1), pseudocount.use = 1, mean.fxn = rowMeans, vst.flaovr = "v1")) test_that("setting mean.fxn works", { + skip_on_cran() expect_equal(nrow(x = results), 216) expect_equal(results[1, "avg_logFC"], -4.204346, tolerance = 1e-6) expect_equal(results.clr[1, "avg_logFC"], -1.353025, tolerance = 1e-6) @@ -152,6 +157,7 @@ test_that("only.pos works", { results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, ident.2 = 1, max.cells.per.ident = 20, verbose = FALSE, base = exp(1),pseudocount.use = 1)) test_that("max.cells.per.ident works", { + skip_on_cran() expect_equal(nrow(x = results), 222) expect_equal(results[1, "p_val"], 3.428568e-08, tolerance = 1e-13) expect_equal(results[1, "avg_logFC"], -2.638242, tolerance = 1e-6) @@ -180,6 +186,7 @@ Idents(object = t2) <- "groups" results2 <- suppressWarnings(FindMarkers(object = t2, ident.1 = "g1", ident.2 = "g2", verbose = FALSE, base = exp(1), pseudocount.use = 1)) test_that("group.by works", { + skip_on_cran() expect_equal(nrow(x = results), 190) expect_equal(results, results2) expect_equal(results[1, "p_val"], 0.02870319) @@ -196,6 +203,7 @@ Idents(object = t2) <- "groups" results2 <- suppressWarnings(FindMarkers(object = t2, ident.1 = "g1", ident.2 = "g2", verbose = FALSE, base = exp(1), pseudocount.use = 1)) test_that("subset.ident works", { + skip_on_cran() expect_equal(nrow(x = results), 183) expect_equal(results, results2) expect_equal(results[1, "p_val"], 0.01293720) @@ -208,6 +216,7 @@ test_that("subset.ident works", { results <- suppressWarnings(FindMarkers(object = pbmc_small, ident.1 = 0, ident.2 = 1, reduction = "pca", verbose = FALSE, base = exp(1), pseudocount.use = 1)) test_that("reduction works", { + skip_on_cran() expect_equal(results[1, "p_val"], 1.664954e-10, tolerance = 1e-15) expect_equal(results[1, "avg_diff"], -2.810453669, tolerance = 1e-6) expect_equal(results[1, "p_val_adj"], 3.163412e-09, tolerance = 1e-14) @@ -368,6 +377,7 @@ test_that("BPCells FindMarkers gives same results", { # ------------------------------------------------------------------------------- test_that("FindAllMarkers works as expected", { + skip_on_cran() pbmc_copy <- pbmc_small Idents(pbmc_copy) <- "orig.ident" diff --git a/tests/testthat/test_find_clusters.R b/tests/testthat/test_find_clusters.R index 9fa0311f3..8b7098cc2 100644 --- a/tests/testthat/test_find_clusters.R +++ b/tests/testthat/test_find_clusters.R @@ -52,8 +52,12 @@ test_that("Smoke test for `FindClusters`", { expect_no_error(FindClusters(test_case, algorithm = 3)) # The leiden algorithm requires that `random.seed` be greater than 0, # which is the default for `FindClusters` so a warning should be raised. - expect_warning(FindClusters(test_case, algorithm = 4)) - expect_no_warning(FindClusters(test_case, algorithm = 4, random.seed = 1)) + # Test with igraph method expect_warning(FindClusters(test_case, algorithm = 4, leiden_method = "igraph")) expect_no_warning(FindClusters(test_case, algorithm = 4, leiden_method = "igraph", random.seed = 1)) + + # Test leidenbase method if available + skip_if_not_installed("leidenbase") + expect_warning(FindClusters(test_case, algorithm = 4, leiden_method = "leidenbase")) + expect_no_warning(FindClusters(test_case, algorithm = 4, leiden_method = "leidenbase", random.seed = 1)) }) diff --git a/tests/testthat/test_preprocessing.R b/tests/testthat/test_preprocessing.R index a7c8403af..11b85a9ed 100644 --- a/tests/testthat/test_preprocessing.R +++ b/tests/testthat/test_preprocessing.R @@ -557,6 +557,7 @@ object2 <- CreateSeuratObject(counts = pbmc.test, meta.data = fake.meta.data2) test_that("`SCTransform` is consistent for multi-layer inputs", { + skip_on_cran() clip.range = c(-1.632993, 1.632993) test_case_v3 <- SplitObject(object2, split.by = "Condition")