| Package | Responsibility | Primary representations |
|---|---|---|
| SpaMTPData | Discoverable experiment resources and a small synthetic example | Cardinal, SpatialExperiment, auxiliary files; labelled historical archives |
| SpaMTPdb | Versioned annotation and pathway resources | Independent tables/lists with checksums and provenance |
| SpaMTP | Analysis, annotation, plotting and explicit conversion | Existing Bioconductor S4 containers and public accessors |
The data packages do not import SpaMTP or Seurat. SpaMTP imports SpaMTPdb and suggests SpaMTPData for demonstrations; there is no circular runtime dependency. Use SpaMTP >= 0.99.4, SpaMTPdb >= 0.99.3 and SpaMTPData >= 0.99.4 together. The package versions are not the same thing as RaMP or experiment-data versions.
The first experiment and small chemical table are explicitly synthetic teaching inputs. Later sections load the complete pinned RaMP resources and real brain datasets, downloading them when no verified local copy or cache is available. All R code blocks are evaluated when building this article.
spe <- SpaMTPData::spaMTPExampleData()
stopifnot(methods::is(spe, "SpatialExperiment"))
SummarizedExperiment::assayNames(spe)
## [1] "counts"
SummarizedExperiment::rowData(spe)$mz
## [1] 149.0444 171.0264 181.0707 203.0526 166.0863 500.0500
SingleCellExperiment::altExpNames(spe)
## [1] "transcriptome"Counts/intensities, feature metadata, pixel metadata and coordinates
have separate public accessors. The paired transcriptome already has
matching pixel names and is stored in altExp(). Independent
measurements must first be spatially aligned and mapped; they cannot be
paired merely by renaming columns.
spe <- normalizeSMData(spe, "LogNormalize", verbose = FALSE)
spe <- runMetabolicPCA(spe, npcs = 2, slot = "logcounts")
## Warning in (function (A, nv = 5, nu = nv, maxit = 1000, work = nv + 16, : did not converge--results
## might be invalid!; try increasing maxit or work
plotSpatialFeature(spe, features = "peak1", assayName = "logcounts",
labels = "Synthetic peak 1", pointSize = 4)The registry is lightweight package metadata. Both access paths below describe the same resource release and use the coordinated camelCase API.
registry <- SpaMTPdb::spaMTPdbResources(version = "3.0.7")
stopifnot(identical(registry, spaMTPDatabaseInfo(version = "3.0.7")))
registry[registry$resource %in% c("chem_props", "smiles_features", "pathway"),
c("resource", "version", "r_data_class", "bytes", "md5")]
## resource version r_data_class bytes md5
## 1 chem_props 3.0.7 data.frame 12925616 42865f00ea7445f72bcd2f66b2b315a9
## 5 pathway 3.0.7 data.frame 1933008 054f527072d3d29d4ff56c5b5e27ede5
## 16 smiles_features 3.0.7 data.frame 4252016 f492e18843643ef17b037b91f7988ecbFor a production analysis, loadSpaMTPDatabase() uses the
same resource reader and retains database provenance. A staged official
file must match its size and checksum; offline = TRUE can
also reuse a verified download cache.
This small custom table contains two neutral masses and explicit illustrative identifiers. It is supplied as a custom database rather than being placed under an official resource filename with an incorrect checksum.
custom <- data.frame(
id = c("demo-2HG", "demo-glucose"),
name = c("2-hydroxyglutarate", "glucose"),
formula = c("C5H8O5", "C6H12O6"),
exactmass = c(148.037173366, 180.063388104)
)
index <- buildMZAnnotationIndex(custom, adducts = "M+H", polarity = "positive")
annotated <- annotateSM(spe, index = index, adducts = "M+H",
ppm_error = 5, return.only.annotated = FALSE, verbose = FALSE)
stopifnot(identical(dim(annotated), dim(spe)),
identical(colnames(SingleCellExperiment::altExp(annotated, "transcriptome")),
colnames(spe)))
SummarizedExperiment::rowData(annotated)[,
c("mz", "all_IsomerNames", "all_Scores")]
## DataFrame with 6 rows and 3 columns
## mz all_IsomerNames all_Scores
## <numeric> <character> <character>
## peak1 149.044 2-hydroxyglutarate 1
## peak2 171.026 No Annotation No Annotation
## peak3 181.071 glucose 1
## peak4 203.053 No Annotation No Annotation
## peak5 166.086 No Annotation No Annotation
## peak6 500.050 No Annotation No Annotation
annotationInfo(annotated)
## $schema_version
## [1] 2
##
## $engine
## [1] "indexed-chemical-v2"
##
## $ramp_version
## [1] "3.0.7"
##
## $generated_at
## [1] "2026-10-14 02:15:40 UTC"
##
## $candidates
## [1] 2
##
## $assay
## [1] "main"
##
## $raw_mz_column
## [1] "raw_mz"
##
## $polarity
## [1] "positive"
##
## $maldi_matrix
## [1] "unspecified"
##
## $ppm
## [1] 5
##
## $min_score
## [1] 0
##
## $adducts
## [1] "M+H"
##
## $database
## [1] "pre-built annotation index"These accurate-mass candidates are hypotheses, not confirmed identifications or calibrated probabilities. The full annotation tutorial explains index reuse, contextual scoring and interpretation.
The published experiment registry records what the source files
actually contain. The default resource release, 1.1.0,
supplies seven native SpatialExperiment datasets with new URLs and
hashes in Zenodo record
22733262. Historical Seurat files remain explicitly available in
release 1.0.0.
native_metadata <- SpaMTPData::spaMTPData("mouse_brain_fmp10", metadata = TRUE)
stopifnot(native_metadata$version == "1.1.0",
native_metadata$r_data_class == "SpatialExperiment",
!native_metadata$requires_conversion)archive <- SpaMTPData::spaMTPData("mouse_brain_fmp10",
version = "1.0.0", metadata = TRUE)
archive[, c("resource", "version", "r_data_class", "requires_conversion")]
## resource version r_data_class requires_conversion
## 2 mouse_brain_fmp10 1.0.0 Seurat TRUE
stopifnot(identical(intersect(c("Seurat", "SeuratObject"), loadedNamespaces()),
seuratBefore))The one-time preparation recipe shipped by SpaMTPData creates a separate native RDS for each of the seven historical archives. The published files can now be retrieved directly; no Seurat conversion is needed when using them:
native <- SpaMTPData::spaMTPData("mouse_brain_dhb_striatum", version = "1.1.0")
native <- normalizeSMData(native, verbose = FALSE)
SingleCellExperiment::altExpNames(native) # SPT
## [1] "SPT"
stopifnot(identical(dim(native), c(2075L, 876L)),
identical(intersect(c("Seurat", "SeuratObject"), loadedNamespaces()), seuratBefore))The native files have their own checksum/provenance manifest and do
not replace the original archive URLs or checksums. They preserve counts
and any complete data layer; the latter is not
automatically relabelled as logcounts. Optical rasters,
polygons and Seurat graphs/weights/reductions are omitted. Source
annotations, including historical db_3, retain their
original interpretation and are not upgraded to new scored
annotations.
To work with a historical archive instead, conversion remains explicit. Only this boundary example loads the suggested SeuratObject package; the preceding native analysis does not require it.
stopifnot(requireNamespace("SeuratObject", quietly = TRUE))
legacy <- SpaMTPData::spaMTPData("mouse_brain_fmp10",
version = "1.0.0")
converted_archive <- seuratToSpatialExperiment(legacy, assay = "Spatial", image = "fov")
stopifnot(methods::is(converted_archive, "SpatialExperiment"),
identical(dim(converted_archive), c(1538L, 3005L)))Select coordinates, layers and images deliberately. Optical rasters, graphs and reductions are not transferred. See modern data access for the conversion contract and the native workflow for further analysis. Older PascalCase resource calls must be updated along with the coordinated companion package versions.
sessionInfo()
## R version 4.6.1 (2026-06-24)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 26.04.1 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
## [4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Etc/UTC
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] rmarkdown_2.32 SpaMTP_0.99.11 BiocStyle_2.41.0
##
## loaded via a namespace (and not attached):
## [1] splines_4.6.1 later_1.4.8 filelock_1.0.3
## [4] tibble_3.3.1 lifecycle_1.0.5 httr2_1.3.0
## [7] sf_1.1-3 edgeR_4.99.7 globals_0.20.0
## [10] lattice_0.23-1 crosstalk_1.2.2 magrittr_2.0.5
## [13] SpaMTPdb_0.99.4 limma_3.99.2 plotly_4.12.1
## [16] sass_0.4.10 jquerylib_0.1.4 yaml_2.3.12
## [19] metapod_1.21.0 httpuv_1.6.17 otel_0.2.0
## [22] spam_2.11-4 sp_2.2-4 cowplot_1.2.0
## [25] DBI_1.3.0 buildtools_1.0.0 RColorBrewer_1.1-3
## [28] abind_1.4-8 GenomicRanges_1.65.4 purrr_1.2.2
## [31] BiocGenerics_0.59.12 rappdirs_0.3.4 SpaMTPData_0.99.5
## [34] IRanges_2.47.5 S4Vectors_0.51.10 ggrepel_0.9.8
## [37] irlba_2.4.1 listenv_1.1.0 maketools_1.3.2
## [40] pheatmap_1.0.13 units_1.0-1 RSpectra_0.16-2
## [43] matter_2.15.0 dqrng_0.4.1 parallelly_1.48.0
## [46] codetools_0.2-20 DelayedArray_0.39.8 scuttle_1.23.2
## [49] tidyselect_1.2.1 farver_2.1.2 ScaledMatrix_1.21.0
## [52] viridis_0.6.5 matrixStats_1.5.0 stats4_4.6.1
## [55] BiocFileCache_3.3.0 Seqinfo_1.3.2 jsonlite_2.0.0
## [58] CardinalIO_1.11.0 BiocNeighbors_2.7.3 e1071_1.7-17
## [61] progressr_1.0.0 scater_1.41.2 tools_4.6.1
## [64] Rcpp_1.1.2 glue_1.8.1 gridExtra_2.3.1
## [67] SparseArray_1.13.4 BiocBaseUtils_1.15.1 xfun_0.61
## [70] MatrixGenerics_1.25.0 dplyr_1.2.1 withr_3.0.3
## [73] BiocManager_1.30.27 fastmap_1.2.0 bluster_1.23.1
## [76] digest_0.6.39 rsvd_1.0.5 R6_2.6.1
## [79] mime_0.13 RSQLite_3.53.3 utf8_1.2.6
## [82] tidyr_1.3.2 generics_0.1.4 data.table_1.18.6.1
## [85] FNN_1.1.4.1 class_7.3-24 httr_1.4.9
## [88] htmlwidgets_1.6.4 S4Arrays_1.13.2 ontologyIndex_2.12
## [91] pkgconfig_2.0.3 gtable_0.3.6 blob_1.3.0
## [94] S7_0.2.2 SingleCellExperiment_1.35.2 XVector_0.53.0
## [97] sys_3.4.3 htmltools_0.5.9 dotCall64_1.2
## [100] fgsea_1.39.2 ProtGenerics_1.45.0 SeuratObject_5.4.0
## [103] scales_1.4.0 Biobase_2.73.2 png_0.1-9
## [106] SpatialExperiment_1.23.0 scran_1.41.1 knitr_1.52
## [109] rjson_0.2.23 nlme_3.1-171 curl_8.0.0
## [112] proxy_0.4-29 cachem_1.1.0 stringr_1.6.0
## [115] Cardinal_3.15.0 BiocVersion_3.24.0 KernSmooth_2.23-27
## [118] parallel_4.6.1 vipor_0.4.7 AnnotationDbi_1.75.2
## [121] pillar_1.11.1 grid_4.6.1 vctrs_0.7.3
## [124] promises_1.5.0 BiocSingular_1.29.2 dbplyr_2.6.0
## [127] beachmat_2.29.3 xtable_1.8-8 cluster_2.1.8.3
## [130] beeswarm_0.4.0 evaluate_1.0.5 magick_2.9.1
## [133] cli_3.6.6 locfit_1.5-9.12 compiler_4.6.1
## [136] rlang_1.3.0 crayon_1.5.3 future.apply_1.20.2
## [139] labeling_0.4.3 mclust_6.1.3 classInt_0.4-11
## [142] naturalsort_0.1.3 ggbeeswarm_0.7.3 stringi_1.8.9
## [145] viridisLite_0.4.3 BiocParallel_1.47.0 Biostrings_2.81.9
## [148] Matrix_1.7-6 ExperimentHub_3.3.2 bit64_4.8.6
## [151] future_1.76.0 ggplot2_4.0.3 KEGGREST_1.53.6
## [154] statmod_1.5.2 shiny_1.14.0 SummarizedExperiment_1.43.0
## [157] AnnotationHub_4.3.2 igraph_2.3.4 memoise_2.0.1
## [160] bslib_0.12.0 fastmatch_1.1-8 bit_4.6.0