├── tests ├── testthat.R └── testthat │ ├── test-findNeighbors.R │ ├── test-sliceImage.R │ ├── test-colocalized.R │ ├── test-spatial.R │ ├── test-summarize.R │ ├── test-crossValidate.R │ ├── test-SpatialResults.R │ ├── test-readMSIData.R │ ├── test-SpectralImagingArrays.R │ ├── test-spectrapply.R │ ├── test-bin.R │ ├── test-MSImagingArrays.R │ ├── test-MSImagingExperiment.R │ └── test-SpectralImagingExperiment.R ├── vignettes └── Cardinal-class-diagram.png ├── man ├── reexports.Rd ├── MassDataFrame-class.Rd ├── features.Rd ├── pixels.Rd ├── sliceImage.Rd ├── selectROI.Rd ├── subset.Rd ├── findNeighbors.Rd ├── reduceBaseline.Rd ├── ResultsList-class.Rd ├── normalize.Rd ├── smooth.Rd ├── recalibrate.Rd ├── SpatialNMF.Rd ├── PositionDataFrame-class.Rd ├── colocalized.Rd ├── spectrapply.Rd ├── SpatialPCA.Rd ├── estimateDomain.Rd ├── XDataFrame-class.Rd ├── SpectraArrays-class.Rd ├── writeMSIData.Rd ├── spatialWeights.Rd ├── summarize.Rd ├── spatialDists.Rd ├── bin.Rd ├── SpectralImagingArrays-class.Rd ├── deprecated.Rd ├── plot-image.Rd ├── SpatialCV.Rd ├── peakPick.Rd ├── SpatialFastmap.Rd ├── MSImagingArrays-class.Rd ├── Cardinal-package.Rd ├── SpatialKMeans.Rd ├── peakAlign.Rd ├── SpatialDGMM.Rd ├── peakProcess.Rd ├── process.Rd ├── plot-spectra.Rd ├── MSImagingExperiment-class.Rd └── SpectralImagingExperiment-class.Rd ├── .gitignore ├── inst └── CITATION ├── DESCRIPTION ├── R ├── findNeighbors.R ├── sliceImage.R ├── crossValidate.R ├── stats-NMF.R ├── spatialDists.R ├── stats-PCA.R ├── spatialWeights.R ├── selectROI.R ├── estimateDomain.R ├── AllClasses.R ├── spectrapply.R ├── stats-spatialFastmap.R ├── options.R ├── summarize.R ├── colocalized.R └── stats-spatialKMeans.R └── README.md /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(Cardinal) 3 | 4 | test_check("Cardinal") 5 | -------------------------------------------------------------------------------- /vignettes/Cardinal-class-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuwisdelu/Cardinal/HEAD/vignettes/Cardinal-class-diagram.png -------------------------------------------------------------------------------- /man/reexports.Rd: -------------------------------------------------------------------------------- 1 | \name{reexports} 2 | \alias{reexports} 3 | 4 | \alias{SnowfastParam} 5 | 6 | \alias{cpal} 7 | \alias{cpals} 8 | \alias{dpal} 9 | \alias{dpals} 10 | 11 | \alias{as_facets} 12 | \alias{as_layers} 13 | 14 | \title{Re-exported objects from Cardinal} 15 | 16 | \description{ 17 | These functions are re-exported from Cardinal for user convenience. Please see the documentation in their original packages. 18 | } 19 | -------------------------------------------------------------------------------- /tests/testthat/test-findNeighbors.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("findNeighbors") 5 | 6 | test_that("findNeighbors", { 7 | 8 | pos <- expand.grid(x=1:9, y=1:9) 9 | pos <- PositionDataFrame(coord=pos) 10 | 11 | nb <- findNeighbors(pos, r=1) 12 | nb2 <- findNeighbors(pos, r=1, metric="euclidean") 13 | nb3 <- findNeighbors(pos, r=2, metric="euclidean") 14 | nb4 <- findNeighbors(pos, r=1, matrix=TRUE) 15 | 16 | expect_equal(nb[[1L]], c(1, 2, 10, 11)) 17 | expect_equal(nb2[[1L]], c(1, 2, 10)) 18 | expect_equal(nb3[[1L]], c(1, 2, 3, 10, 11, 19)) 19 | expect_is(nb4, "sparse_mat") 20 | expect_equal(nb4[1,1], 1) 21 | expect_equal(nb4[1,2], 1) 22 | expect_equal(nb4[1,10], 1) 23 | expect_equal(nb4[1,11], 1) 24 | 25 | }) 26 | 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac directory 2 | *.DS_Store 3 | 4 | # Log files 5 | *.log 6 | 7 | # C files 8 | *.o 9 | *.so 10 | 11 | # History files 12 | .Rhistory 13 | .Rapp.history 14 | 15 | # Session Data files 16 | .RData 17 | .RDataTmp 18 | 19 | # User-specific files 20 | .Ruserdata 21 | 22 | # Example code in package build process 23 | *-Ex.R 24 | 25 | # Output files from R CMD build 26 | /*.tar.gz 27 | 28 | # Output files from R CMD check 29 | /*.Rcheck/ 30 | 31 | # profiling 32 | *.out 33 | 34 | # testing 35 | *_snaps/ 36 | 37 | # produced vignettes 38 | *.html 39 | *.pdf 40 | 41 | # knitr and R markdown default cache directories 42 | *_cache/ 43 | /cache/ 44 | 45 | # Temporary files created by R markdown 46 | *.utf8.md 47 | *.knit.md 48 | 49 | # R Environment Variables 50 | .Renviron 51 | .Rbuildignore 52 | .Rprofile 53 | renv/ -------------------------------------------------------------------------------- /tests/testthat/test-sliceImage.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("sliceImage") 5 | 6 | test_that("sliceImage", { 7 | 8 | path <- CardinalIO::exampleImzMLFile("continuous") 9 | s <- readImzML(path) 10 | s1 <- s 11 | s2 <- s 12 | runNames(s1) <- "run0" 13 | runNames(s2) <- "run1" 14 | s <- cbind(s1, s2) 15 | 16 | mz <- mz(s)[1:2] 17 | rs1 <- sliceImage(s, i=1) 18 | rs2 <- sliceImage(s, i=1:2) 19 | rs3 <- sliceImage(s, mz=mz[1L]) 20 | rs4 <- sliceImage(s, mz=mz) 21 | rs5 <- sliceImage(s, mz=mz, run=1) 22 | 23 | expect_equivalent(dim(rs1), c(3,3,2)) 24 | expect_equivalent(dim(rs2), c(3,3,2,2)) 25 | expect_equivalent(dim(rs3), c(3,3,2)) 26 | expect_equivalent(dim(rs4), c(3,3,2,2)) 27 | expect_equal(rs1, rs2[,,,1L]) 28 | expect_equal(rs1, rs3) 29 | expect_equal(rs2, rs4) 30 | expect_equal(rs3, rs4[,,,1L]) 31 | expect_equal(rs5, rs4[,,1L,]) 32 | 33 | }) 34 | -------------------------------------------------------------------------------- /tests/testthat/test-colocalized.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("colocalized") 5 | 6 | test_that("colocalized", { 7 | 8 | set.seed(1, kind="L'Ecuyer-CMRG") 9 | s <- simulateImage(preset=2, dim=c(10L, 10L), 10 | centroided=TRUE) 11 | s$class <- makeFactor(circle=s$circle, square=s$square, 12 | bg=!s$circle & !s$square) 13 | 14 | co <- colocalized(s, i=1:2) 15 | co1 <- colocalized(s, mz=412.42) 16 | co2 <- colocalized(s, mz=589.53) 17 | co3 <- colocalized(s, i=3, sort.by="MOC") 18 | co4 <- colocalized(s, i=4, sort.by="Dice") 19 | co5 <- colocalized(s, ref=s$class, sort.by="none") 20 | 21 | expect_length(co, 2L) 22 | expect_equal(co[[1L]], co1) 23 | expect_equal(co[[2L]], co2) 24 | expect_false(is.unsorted(rev(co1$cor))) 25 | expect_false(is.unsorted(rev(co2$cor))) 26 | expect_false(is.unsorted(rev(co3$MOC))) 27 | expect_false(is.unsorted(rev(co4$Dice))) 28 | expect_length(co5, 3L) 29 | expect_equal(names(co5), levels(s$class)) 30 | expect_false(is.unsorted(co5$mz)) 31 | 32 | }) 33 | 34 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite the Cardinal package in publications use:") 2 | 3 | citEntry(entry="article", 4 | title = "Cardinal v.3: a versatile open-source software for mass spectrometry imaging analysis", 5 | author = personList( 6 | person(given="Kyle Ariel", family="Bemis"), 7 | person(given="Melanie Christine", family="Foell"), 8 | person(given="Dan", family="Guo"), 9 | person(given="Sai Srikanth", family="Lakkimsetty"), 10 | person(given="Olga", family="Vitek")), 11 | journal = "Nature Methods", 12 | number = "20", 13 | pages = "1883-1886", 14 | year = "2023", 15 | doi = "10.1038/s41592-023-02070-z", 16 | textVersion = paste("Bemis, K. A., Foell, M. C., Guo D., Lakkimsetty, S. S., and Vitek, O.", 17 | "Cardinal v.3: a versatile open-source software for mass spectrometry imaging analysis.", 18 | "Nature Methods 20, 1883-1886 (2023).", "doi:10.1038/s41592-023-02070-z") 19 | ) 20 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: Cardinal 2 | Type: Package 3 | Title: A mass spectrometry imaging toolbox for statistical analysis 4 | Version: 3.13.0 5 | Date: 2015-1-12 6 | Authors@R: person("Kylie Ariel", "Bemis", 7 | email = "k.bemis@northeastern.edu", 8 | role = c("aut", "cre")) 9 | Description: Implements statistical & computational tools for analyzing 10 | mass spectrometry imaging datasets, including methods for efficient 11 | pre-processing, spatial segmentation, and classification. 12 | License: Artistic-2.0 | file LICENSE 13 | Depends: R (>= 4.4), BiocParallel, BiocGenerics, 14 | ProtGenerics, S4Vectors, methods, stats, stats4 15 | Imports: CardinalIO, Biobase, EBImage, graphics, grDevices, 16 | irlba, Matrix, matter (>= 2.7.10), nlme, parallel, utils 17 | Suggests: BiocStyle, testthat, knitr, rmarkdown, emmeans, lme4, lmerTest 18 | VignetteBuilder: knitr 19 | biocViews: Software, Infrastructure, Proteomics, Lipidomics, 20 | MassSpectrometry, ImagingMassSpectrometry, ImmunoOncology, 21 | Normalization, Clustering, Classification, Regression 22 | URL: http://www.cardinalmsi.org 23 | BugReports: https://github.com/kuwisdelu/Cardinal/issues 24 | -------------------------------------------------------------------------------- /man/MassDataFrame-class.Rd: -------------------------------------------------------------------------------- 1 | \name{MassDataFrame-class} 2 | \docType{class} 3 | 4 | \alias{class:MassDataFrame} 5 | \alias{MassDataFrame} 6 | \alias{MassDataFrame-class} 7 | 8 | \alias{mz,MassDataFrame-method} 9 | \alias{mz<-,MassDataFrame-method} 10 | \alias{[,MassDataFrame,ANY,ANY,ANY-method} 11 | \alias{coerce,DFrame,MassDataFrame-method} 12 | 13 | \title{MassDataFrame: Extended data frame with key columns} 14 | 15 | \description{ 16 | A data frame for mass spectrometry feature metadata with a required column for m/z values. 17 | } 18 | 19 | \usage{ 20 | MassDataFrame(mz, \dots, row.names = FALSE) 21 | } 22 | 23 | \arguments{ 24 | \item{mz}{A sorted vector of m/z values.} 25 | 26 | \item{\dots}{Arguments passed to the \code{DataFrame()}.} 27 | 28 | \item{row.names}{Either a vector of row names or a logical value indicating whether row names should be generated automatically (from the m/z values).} 29 | } 30 | 31 | \section{Methods}{ 32 | \describe{ 33 | \item{\code{mz(object, ...)}, \code{mz(object, ...) <- value}:}{Get or set the m/z values.} 34 | } 35 | } 36 | 37 | \author{Kylie A. Bemis} 38 | 39 | \seealso{ 40 | \code{\link{XDataFrame}}, 41 | \code{\link{PositionDataFrame}} 42 | } 43 | 44 | \examples{ 45 | ## Create an MassDataFrame object 46 | MassDataFrame(mz=sort(500 * runif(10)), label=LETTERS[1:10]) 47 | } 48 | 49 | \keyword{classes} 50 | -------------------------------------------------------------------------------- /R/findNeighbors.R: -------------------------------------------------------------------------------- 1 | 2 | #### Find spatial neighbors #### 3 | ## ----------------------------- 4 | 5 | setMethod("findNeighbors", "ANY", 6 | function(x, r = 1, groups = NULL, 7 | metric = "maximum", p = 2, matrix = FALSE, ...) 8 | { 9 | .findNeighbors(x, r=r, groups=groups, 10 | metric=metric, p=p, matrix=matrix) 11 | }) 12 | 13 | setMethod("findNeighbors", "SpectralImagingData", 14 | function(x, r = 1, groups = run(x), ...) 15 | { 16 | findNeighbors(coord(x), r=r, groups=groups, ...) 17 | }) 18 | 19 | setMethod("findNeighbors", "PositionDataFrame", 20 | function(x, r = 1, groups = run(x), ...) 21 | { 22 | findNeighbors(coord(x), r=r, groups=groups, ...) 23 | }) 24 | 25 | .findNeighbors <- function(x, r, groups, metric, p, matrix) 26 | { 27 | x <- as.matrix(x) 28 | if ( is.null(groups) ) { 29 | groups <- rep.int(1L, nrow(x)) 30 | } else { 31 | groups <- rep_len(groups, nrow(x)) 32 | } 33 | nb <- kdsearch(x, x, tol=r) 34 | ds <- rowdist_at(x, ix=seq_len(nrow(x)), iy=nb, metric=metric, p=p) 35 | for ( i in seq_len(nrow(x)) ) 36 | { 37 | ok <- ds[[i]] <= r & groups[nb[[i]]] %in% groups[i] 38 | nb[[i]] <- nb[[i]][ok] 39 | ds[[i]] <- ds[[i]][ok] 40 | } 41 | if ( matrix ) { 42 | ones <- lapply(nb, function(i) rep_len(1L, length(i))) 43 | sparse_mat(index=nb, data=ones, 44 | nrow=length(nb), ncol=length(nb), offset=1L) 45 | } else { 46 | nb 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /man/features.Rd: -------------------------------------------------------------------------------- 1 | \name{features} 2 | 3 | \alias{features} 4 | \alias{features,MSImagingExperiment-method} 5 | \alias{features,SpectralImagingExperiment-method} 6 | 7 | \title{Find feature indices} 8 | 9 | \description{ 10 | Search for the row indices of a spectral imaging dataset that correspond to specificor features, based on a set of conditions. 11 | } 12 | 13 | \usage{ 14 | \S4method{features}{MSImagingExperiment}(object, \dots, mz, tolerance = NA, units = c("ppm", "mz"), 15 | env = NULL) 16 | 17 | \S4method{features}{SpectralImagingExperiment}(object, \dots, env = NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{object}{A spectral imaging dataset.} 22 | 23 | \item{\dots}{Expressions that evaluate to logical vectors in the environment of \code{featureData()}.} 24 | 25 | \item{mz}{The m/z values of features to include.} 26 | 27 | \item{tolerance}{The tolerance for matching features to m/z values.} 28 | 29 | \item{units}{The units for the above tolerance.} 30 | 31 | \item{env}{The enclosing environment for evaluating \code{\dots}.} 32 | } 33 | 34 | \author{ 35 | Kylie A. Bemis 36 | } 37 | 38 | \examples{ 39 | set.seed(1, kind="L'Ecuyer-CMRG") 40 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10)) 41 | 42 | features(mse, mz > 800, mz < 1800) 43 | features(mse, mz=metadata(mse)$design$featureData$mz) 44 | } 45 | 46 | \keyword{utilities} 47 | 48 | -------------------------------------------------------------------------------- /man/pixels.Rd: -------------------------------------------------------------------------------- 1 | \name{pixels} 2 | 3 | \alias{pixels} 4 | \alias{pixels,SpectralImagingExperiment-method} 5 | \alias{pixels,SpectralImagingArrays-method} 6 | \alias{pixels,SpectralImagingData-method} 7 | 8 | \title{Find pixel indices} 9 | 10 | \description{ 11 | Search for the column indices of a spectral imaging dataset that correspond to specific pixels, based on a set of conditions. 12 | } 13 | 14 | \usage{ 15 | \S4method{pixels}{SpectralImagingExperiment}(object, \dots, coord, run, tolerance = NA, 16 | env = NULL) 17 | 18 | \S4method{pixels}{SpectralImagingArrays}(object, \dots, coord, run, tolerance = NA, 19 | env = NULL) 20 | 21 | \S4method{pixels}{SpectralImagingData}(object, \dots, env = NULL) 22 | } 23 | 24 | \arguments{ 25 | \item{object}{A spectral imaging dataset.} 26 | 27 | \item{\dots}{Expressions that evaluate to logical vectors in the environment of \code{pixelData()}.} 28 | 29 | \item{coord}{The coordinates of the pixels to include.} 30 | 31 | \item{run}{The run of the pixels to include.} 32 | 33 | \item{tolerance}{The tolerance for matching pixels to coordinates.} 34 | 35 | \item{env}{The enclosing environment for evaluating \code{\dots}.} 36 | } 37 | 38 | \author{ 39 | Kylie A. Bemis 40 | } 41 | 42 | \examples{ 43 | set.seed(1, kind="L'Ecuyer-CMRG") 44 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10)) 45 | 46 | pixels(mse, x > 6, y > 6) 47 | pixels(mse, coord=expand.grid(x=1:3, y=1:3)) 48 | } 49 | 50 | \keyword{utilities} 51 | 52 | -------------------------------------------------------------------------------- /tests/testthat/test-spatial.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("spatialWeights + spatialDists") 5 | 6 | test_that("spatialWeights", { 7 | 8 | set.seed(1) 9 | x <- matrix(runif(81 * 6), nrow=81, ncol=6) 10 | co <- as.matrix(expand.grid(x=1:9, y=1:9)) 11 | nb <- findNeighbors(co, r=1) 12 | wts <- spatialWeights(co, r=1, weights="gaussian") 13 | sd <- 3 / 4 14 | 15 | d1 <- matter::rowdist(co[nb[[1]],,drop=FALSE], co[1,,drop=FALSE]) 16 | w1 <- exp(-d1^2 / (2 * sd^2)) 17 | 18 | d2 <- matter::rowdist(co[nb[[2]],,drop=FALSE], co[2,,drop=FALSE]) 19 | w2 <- exp(-d2^2 / (2 * sd^2)) 20 | 21 | expect_equal(wts[[1L]], as.vector(w1)) 22 | expect_equal(wts[[2L]], as.vector(w2)) 23 | 24 | awts <- spatialWeights(x, co, r=1, weights="adaptive") 25 | swts <- spatialWeights(x, co, r=1, weights="adaptive", 26 | matrix=TRUE) 27 | 28 | expect_equal(lengths(wts), lengths(awts)) 29 | expect_equal(nrow(swts), nrow(x)) 30 | expect_equal(ncol(swts), nrow(x)) 31 | 32 | }) 33 | 34 | test_that("spatialDists", { 35 | 36 | set.seed(1) 37 | x <- matrix(runif(81 * 6), nrow=81, ncol=6) 38 | y <- matrix(runif(5 * 6), nrow=5, ncol=6) 39 | co <- as.matrix(expand.grid(x=1:9, y=1:9)) 40 | nb <- findNeighbors(co, r=1) 41 | wts <- spatialWeights(co, r=1) 42 | dxy <- spatialDists(x, y, co, r=1) 43 | 44 | ds <- matter::rowDists(x, y, BPPARAM=getCardinalBPPARAM()) 45 | FUN <- function(nb, w) colSums(w * ds[nb,,drop=FALSE]) / sum(w) 46 | 47 | expect_equal(dxy, t(mapply(FUN, nb, wts))) 48 | 49 | }) 50 | 51 | -------------------------------------------------------------------------------- /man/sliceImage.Rd: -------------------------------------------------------------------------------- 1 | \name{sliceImage} 2 | 3 | \alias{sliceImage} 4 | 5 | \title{Slice an image} 6 | 7 | \description{ 8 | Slice a spectral imaging dataset as a "data cube". 9 | } 10 | 11 | \usage{ 12 | sliceImage(x, i = features(x, ...), ..., run = NULL, 13 | simplify = TRUE, drop = TRUE) 14 | } 15 | 16 | \arguments{ 17 | \item{x}{A spectral imaging dataset.} 18 | 19 | \item{i}{The indices of features to slice for the images.} 20 | 21 | \item{\dots}{Conditions describing features to slice, passed to \code{features()}.} 22 | 23 | \item{run}{The names of experimental runs to include, or the index of the levels of the runs to include.} 24 | 25 | \item{simplify}{The image slices be returned as a list, or simplified to an array?} 26 | 27 | \item{drop}{Should redundant array dimensions be dropped? If TRUE, dimensions with only one level are dropped using \code{drop}.} 28 | } 29 | 30 | \value{ 31 | A list or array of the sliced image(s). If multiple images are sliced and \code{simplify=TRUE}, then the \emph{last} dimension will be the features. 32 | } 33 | 34 | \author{ 35 | Kylie A. Bemis 36 | } 37 | 38 | \examples{ 39 | set.seed(1, kind="L'Ecuyer-CMRG") 40 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10), centroided=TRUE) 41 | peaks <- mz(metadata(mse)$design$featureData) 42 | 43 | # slice image for first feature 44 | sliceImage(mse, 1) 45 | 46 | # slice by m/z-value 47 | sliceImage(mse, mz=peaks[1]) 48 | 49 | # slice multiple 50 | sliceImage(mse, mz=peaks[1:3]) 51 | } 52 | 53 | \keyword{manip} 54 | -------------------------------------------------------------------------------- /R/sliceImage.R: -------------------------------------------------------------------------------- 1 | 2 | #### Slice a spectral image #### 3 | ## ------------------------------ 4 | 5 | sliceImage <- function(x, i = features(x, ...), ..., 6 | run = NULL, simplify = TRUE, drop = TRUE) 7 | { 8 | if ( is.null(run) ) { 9 | coord <- coord(x) 10 | runs <- run(x) 11 | xi <- spectra(x)[i,,drop=FALSE] 12 | } else { 13 | if ( !is.character(run) && !is.factor(run) ) 14 | run <- runNames(x)[run] 15 | j <- run(x) %in% run 16 | coord <- coord(x)[j,,drop=FALSE] 17 | runs <- droplevels(run(x)[j]) 18 | xi <- spectra(x)[i,j,drop=FALSE] 19 | } 20 | ndim <- length(coord) 21 | FUN <- function(y) 22 | { 23 | rs <- lapply(levels(runs), 24 | function(irun) 25 | { 26 | vals <- y[runs %in% irun] 27 | co <- coord[runs %in% irun,,drop=FALSE] 28 | if ( ndim == 2L ) { 29 | to_raster(co$x, co$y, vals) 30 | } else if ( ndim == 3L ) { 31 | to_raster3(co$x, co$y, co$z, vals) 32 | } else { 33 | .Error("number of coordinates must be 2 or 3") 34 | } 35 | }) 36 | names(rs) <- levels(runs) 37 | if ( simplify ) 38 | rs <- simplify2array(rs) 39 | rs 40 | } 41 | ans <- apply(xi, 1L, FUN, simplify=FALSE) 42 | if ( is.null(run) ) { 43 | names(ans) <- featureNames(x) 44 | } else { 45 | names(ans) <- featureNames(x)[j] 46 | } 47 | if ( simplify ) { 48 | ans <- simplify2array(ans) 49 | dnms <- c(coordNames(x), "run", "feature") 50 | dim(ans) <- setNames(dim(ans), dnms) 51 | if ( drop ) 52 | ans <- drop(ans) 53 | } 54 | ans 55 | } 56 | 57 | slice <- function(x, ...) 58 | { 59 | .Deprecated("sliceImage") 60 | sliceImage(x, ...) 61 | } 62 | -------------------------------------------------------------------------------- /tests/testthat/test-summarize.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("summarize") 5 | 6 | test_that("summarizeFeatures", { 7 | 8 | path <- CardinalIO::exampleImzMLFile("continuous") 9 | mse <- readImzML(path, memory=TRUE) 10 | g <- makeFactor(A=mse$y==1, B=mse$y==2, C=mse$y==3) 11 | 12 | mse <- summarizeFeatures(mse) 13 | mse <- summarizeFeatures(mse, groups=g) 14 | 15 | expect_equal(fData(mse)$mean, rowMeans(mse)) 16 | expect_equal(fData(mse)$A.mean, rowMeans(mse[,g=="A"])) 17 | expect_equal(fData(mse)$B.mean, rowMeans(mse[,g=="B"])) 18 | expect_equal(fData(mse)$C.mean, rowMeans(mse[,g=="C"])) 19 | 20 | path2 <- CardinalIO::exampleImzMLFile("processed") 21 | mse2 <- readImzML(path2, memory=TRUE) 22 | 23 | expect_error(mse2 <- summarizeFeatures(mse2)) 24 | expect_error(mse2 <- summarizeFeatures(mse2, groups=g)) 25 | 26 | }) 27 | 28 | test_that("summarizePixels", { 29 | 30 | path <- CardinalIO::exampleImzMLFile("continuous") 31 | mse <- readImzML(path, memory=TRUE) 32 | g <- makeFactor(light=mz(mse) < 400, heavy=mz(mse) >= 400) 33 | 34 | mse <- summarizePixels(mse) 35 | mse <- summarizePixels(mse, "sum", groups=g) 36 | 37 | expect_equal(pData(mse)$tic, colSums(mse)) 38 | expect_equivalent(pData(mse)$light.sum, colSums(mse[g=="light",])) 39 | expect_equivalent(pData(mse)$heavy.sum, colSums(mse[g=="heavy",])) 40 | 41 | path2 <- CardinalIO::exampleImzMLFile("processed") 42 | mse2 <- readImzML(path2, memory=TRUE) 43 | 44 | mse2 <- summarizePixels(mse2) 45 | 46 | expect_equal(pData(mse2)$tic, spectrapply(mse2, sum)) 47 | expect_error(mse2 <- summarizePixels(mse2, groups=g)) 48 | 49 | }) 50 | 51 | -------------------------------------------------------------------------------- /tests/testthat/test-crossValidate.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("crossValidate") 5 | 6 | test_that("crossValidate", { 7 | 8 | set.seed(1, kind="L'Ecuyer-CMRG") 9 | ms <- simulateImage(preset=4, dim=c(10L, 10L), nrun=2, 10 | centroided=TRUE) 11 | ms$class <- makeFactor(A=ms$circleA, B=ms$circleB) 12 | ms$folds <- makeFactor( 13 | fold1=run(ms) %in% c("runA1", "runB1"), 14 | fold2=run(ms) %in% c("runA2", "runB2")) 15 | 16 | ncomp <- 1:3 17 | ans <- crossValidate(PLS, ms, ms$class, 18 | ncomp=ncomp, folds=ms$folds) 19 | ans2 <- crossValidate(OPLS, ms, ms$class, 20 | ncomp=ncomp, folds=ms$folds) 21 | ans_mi <- crossValidate(PLS, ms, ms$class, 22 | ncomp=ncomp, folds=ms$folds, bags=run(ms)) 23 | ans2_mi <- crossValidate(OPLS, ms, ms$class, 24 | ncomp=ncomp, folds=ms$folds, bags=run(ms)) 25 | 26 | expect_length(ans$scores, nlevels(ms$folds)) 27 | expect_length(ans2$scores, nlevels(ms$folds)) 28 | expect_length(ans_mi$scores, nlevels(ms$folds)) 29 | expect_length(ans2_mi$scores, nlevels(ms$folds)) 30 | expect_equal(nrow(ans$average), length(ncomp)) 31 | expect_equal(nrow(ans2$average), length(ncomp)) 32 | expect_equal(nrow(ans_mi$average), length(ncomp)) 33 | expect_equal(nrow(ans2_mi$average), length(ncomp)) 34 | 35 | s <- seq(0, 1, length.out=6) 36 | ans3 <- crossValidate(spatialShrunkenCentroids, ms, ms$class, 37 | s=s, folds=ms$folds, keep.models=TRUE) 38 | ans3_mi <- crossValidate(spatialShrunkenCentroids, ms, ms$class, 39 | s=s, folds=ms$folds, bags=run(ms), keep.models=TRUE) 40 | 41 | expect_length(ans3$scores, nlevels(ms$folds)) 42 | expect_equal(nrow(ans3$average), length(s)) 43 | 44 | }) 45 | 46 | -------------------------------------------------------------------------------- /man/selectROI.Rd: -------------------------------------------------------------------------------- 1 | \name{selectROI} 2 | 3 | \alias{selectROI} 4 | \alias{selectROI,SpectralImagingExperiment-method} 5 | \alias{makeFactor} 6 | 7 | \title{Select regions-of-interest in an image} 8 | 9 | \description{ 10 | Manually select regions-of-interest or pixels on an imaging dataset. The \code{selectROI} method uses the built-in \code{\link{locator}} function. It can be used with an existing image plot, or a new image will be plotted if \code{image} arguments are passed via \code{...}. 11 | 12 | The regions of interest are returned as logical vectors indicating which pixels have been selected. These logical vectors can be combined into factors using the \code{makeFactor} function. 13 | } 14 | 15 | \usage{ 16 | \S4method{selectROI}{SpectralImagingExperiment}(object, \dots, mode = c("region", "pixels")) 17 | 18 | makeFactor(\dots, ordered = FALSE) 19 | } 20 | \arguments{ 21 | \item{object}{A spectral imaging dataset.} 22 | 23 | \item{mode}{The mode of selection: "region" to select a region-of-interest as a polygon, or "pixels" to select individual pixels.} 24 | 25 | \item{\dots}{Additional arguments to be passed to \code{\link{image}} for \code{selectROI}, or name-value pairs of logical vectors to be combined by \code{makeFactor}.} 26 | 27 | \item{ordered}{Should the resulting factor be ordered or not?} 28 | } 29 | 30 | \value{ 31 | A \code{logical} vector of length equal to the number of pixels for \code{selectROI}. 32 | 33 | A factor of the same length as the logical vectors for \code{makeFactor}. 34 | } 35 | 36 | \author{ 37 | Kylie A. Bemis 38 | } 39 | 40 | \seealso{ 41 | \code{\link[Cardinal]{image}} 42 | } 43 | 44 | \keyword{iplot} 45 | -------------------------------------------------------------------------------- /R/crossValidate.R: -------------------------------------------------------------------------------- 1 | 2 | #### Perform cross-validation #### 3 | ## ------------------------------- 4 | 5 | crossValidate <- function(fit., x, y, folds = run(x), ..., 6 | predict. = predict, keep.models = FALSE, 7 | trainProcess = peakProcess, trainArgs = list(), 8 | testProcess = peakProcess, testArgs = list(), 9 | verbose = getCardinalVerbose(), chunkopts = list(), 10 | BPPARAM = getCardinalBPPARAM()) 11 | { 12 | if ( !is.function(fit.) ) 13 | .Defunct(msg="crossValidate() signature has changed, see ?crossValidate") 14 | ans <- cv_do(fit., x=x, y=y, folds=folds, transpose=TRUE, 15 | predict.=predict., keep.models=keep.models, mi=FALSE, 16 | trainProcess=trainProcess, trainArgs=trainArgs, 17 | testProcess=testProcess, testArgs=testArgs, 18 | verbose=verbose, chunkopts=chunkopts, 19 | BPPARAM=BPPARAM, ...) 20 | as(SpatialResults(ans, x), "SpatialCV") 21 | } 22 | 23 | setMethod("fitted", "SpatialCV", 24 | function(object, type = c("response", "class"), ...) 25 | { 26 | type <- match.arg(type) 27 | fitted(object@model, type=type, ...) 28 | }) 29 | 30 | setMethod("image", c(x = "SpatialCV"), 31 | function(x, i = 1L, type = c("response", "class"), 32 | layout = NULL, free = "", ...) 33 | { 34 | type <- match.arg(type) 35 | y <- fitted(x, type=type, simplify=FALSE) 36 | FUN <- function(yi, ...) .plot_image_results(x, yi, ...) 37 | images <- lapply(y[i], FUN, ...) 38 | if ( is.null(names(images)) ) 39 | names(images) <- paste0("i = ", i) 40 | if ( !is.null(layout) ) { 41 | layout <- rep_len(layout, 2L) 42 | nrow <- layout[1L] 43 | ncol <- layout[2L] 44 | as_facets(images, nrow=nrow, ncol=ncol, free=free) 45 | } else { 46 | as_facets(images, free=free) 47 | } 48 | }) 49 | -------------------------------------------------------------------------------- /man/subset.Rd: -------------------------------------------------------------------------------- 1 | \name{subsetFeatures} 2 | 3 | \alias{subsetFeatures} 4 | \alias{subsetPixels} 5 | \alias{subset,SpectralImagingArrays-method} 6 | \alias{subset,SpectralImagingExperiment-method} 7 | 8 | \title{Subset a spectral imaging dataset} 9 | 10 | \description{ 11 | Returns a subset of the dataset that meets the conditions. 12 | } 13 | 14 | \usage{ 15 | \S4method{subset}{SpectralImagingArrays}(x, subset, \dots) 16 | 17 | \S4method{subset}{SpectralImagingExperiment}(x, select, subset, \dots) 18 | 19 | subsetFeatures(x, \dots) 20 | 21 | subsetPixels(x, \dots) 22 | } 23 | 24 | \arguments{ 25 | \item{x}{A spectral imaging dataset.} 26 | 27 | \item{select}{Logical expression to be evaluated in the object's \code{featureData()} indicating which rows (features) to keep.} 28 | 29 | \item{subset}{Logical expression to be evaluated in the object's \code{pixelData()} indicating which columns (pixels) to keep.} 30 | 31 | \item{\dots}{Conditions describing rows (features) or columns (pixels) to be retained. Passed to \code{features()} and \code{pixels()} methods to obtain the subset indices.} 32 | } 33 | 34 | \value{ 35 | An object of the same class as \code{x} with the appropriate subsetting applied to it. 36 | } 37 | 38 | \author{ 39 | Kylie A. Bemis 40 | } 41 | 42 | \examples{ 43 | set.seed(1, kind="L'Ecuyer-CMRG") 44 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10)) 45 | 46 | # subset features to mass range 1000 - 1500 47 | subsetFeatures(mse, 1000 < mz, mz < 1500) 48 | 49 | # select pixels to coordinates x = 1..3, y = 1..3 50 | subsetPixels(mse, x <= 3, y <= 3) 51 | 52 | # subset both features + pixels 53 | subset(mse, 1000 < mz & mz < 1500, x <= 3 & y <= 3) 54 | } 55 | 56 | \keyword{manip} 57 | -------------------------------------------------------------------------------- /man/findNeighbors.Rd: -------------------------------------------------------------------------------- 1 | \name{findNeighbors} 2 | 3 | \alias{findNeighbors} 4 | \alias{findNeighbors,ANY-method} 5 | \alias{findNeighbors,SpectralImagingData-method} 6 | \alias{findNeighbors,PositionDataFrame-method} 7 | 8 | \title{Find spatial neighbors} 9 | 10 | \description{ 11 | Find the indices of spatial neighbors for all observations in a dataset. 12 | } 13 | 14 | \usage{ 15 | \S4method{findNeighbors}{ANY}(x, r = 1, groups = NULL, 16 | metric = "maximum", p = 2, matrix = FALSE, \dots) 17 | 18 | \S4method{findNeighbors}{SpectralImagingData}(x, r = 1, groups = run(x), \dots) 19 | 20 | \S4method{findNeighbors}{PositionDataFrame}(x, r = 1, groups = run(x), \dots) 21 | } 22 | 23 | \arguments{ 24 | \item{x}{An imaging dataset or data frame with spatial dimensions.} 25 | 26 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor.} 27 | 28 | \item{groups}{A vector coercible to a factor giving which observations should be treated as spatially-independent. Observations in the same group are assumed to have a spatial relationship.} 29 | 30 | \item{metric}{Distance metric to use when finding the nearest neighbors. Supported metrics include "euclidean", "maximum", "manhattan", and "minkowski".} 31 | 32 | \item{p}{The power for the Minkowski distance.} 33 | 34 | \item{matrix}{Should the neighbors be returned as a sparse adjacency matrix instead of a list?} 35 | 36 | \item{\dots}{Additional arguments passed to the next call.} 37 | } 38 | 39 | \value{ 40 | Either a list of indices of neighbors or a sparse adjacency matrix (\code{\linkS4class{sparse_mat}}). 41 | } 42 | 43 | \author{ 44 | Kylie A. Bemis 45 | } 46 | 47 | \seealso{ 48 | \code{\link{spatialWeights}} 49 | } 50 | 51 | \examples{ 52 | pdata <- PositionDataFrame(coord=expand.grid(x=1:8, y=1:8)) 53 | 54 | # find spatial neighbors 55 | findNeighbors(pdata, r=1) 56 | } 57 | 58 | \keyword{spatial} 59 | -------------------------------------------------------------------------------- /tests/testthat/test-SpatialResults.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("SpatialResults") 5 | 6 | test_that("SpatialResults + ResultsList", { 7 | 8 | require(datasets) 9 | fit1 <- lm(mpg ~ disp, data=mtcars) 10 | fit2 <- lm(mpg ~ disp + wt, data=mtcars) 11 | fit3 <- lm(mpg ~ disp + hp, data=mtcars) 12 | 13 | n <- 100 14 | mz <- seq(500, 510, length.out=n) 15 | mdf <- MassDataFrame(mz=mz, A=seq_len(n), B=rev(seq_len(n))) 16 | Coord <- expand.grid(x=1:9, y=1:9) 17 | n <- nrow(Coord) 18 | pdf <- PositionDataFrame(coord=Coord, A=seq_len(n), B=rev(seq_len(n))) 19 | sr <- SpatialResults(fit1, featureData=mdf, pixelData=pdf) 20 | 21 | expect_equal(modelData(sr), fit1) 22 | expect_equal(length(sr), length(fit1)) 23 | expect_equal(names(sr), names(fit1)) 24 | expect_equal(sr[["coefficients"]], fit1[["coefficients"]]) 25 | expect_equal(sr$coefficients, fit1$coefficients) 26 | expect_equal(coef(sr), coef(fit1)) 27 | expect_equal(resid(sr), resid(fit1)) 28 | expect_equal(fitted(sr), fitted(fit1)) 29 | expect_equal(featureData(sr), mdf) 30 | expect_equal(featureNames(sr), rownames(mdf)) 31 | expect_equal(pixelData(sr), pdf) 32 | expect_equal(pixelNames(sr), rownames(pdf)) 33 | expect_equal(coord(sr), coord(pdf)) 34 | expect_equal(coordNames(sr), coordNames(pdf)) 35 | expect_equal(run(sr), run(pdf)) 36 | expect_equal(runNames(sr), runNames(pdf)) 37 | expect_equal(nrun(sr), nrun(pdf)) 38 | 39 | rl <- ResultsList(fit1=fit1, fit2=fit2) 40 | mcols(rl) <- DataFrame(NumParams=c(1, 2)) 41 | rl2 <- ResultsList(fit3=fit3) 42 | mcols(rl2) <- DataFrame(NumParams=2) 43 | rl3 <- c(rl, rl2) 44 | 45 | expect_true(validObject(rl)) 46 | expect_is(rl, "ResultsList") 47 | expect_is(rl3, "ResultsList") 48 | expect_equal(mcols(rl3), rbind(mcols(rl), mcols(rl2))) 49 | 50 | rl4 <- ResultsList(sr) 51 | 52 | expect_true(validObject(rl4)) 53 | expect_is(rl4, "ResultsList") 54 | expect_equal(rl4[[1L]], sr) 55 | 56 | }) 57 | 58 | -------------------------------------------------------------------------------- /man/reduceBaseline.Rd: -------------------------------------------------------------------------------- 1 | \name{reduceBaseline} 2 | 3 | \alias{reduceBaseline} 4 | \alias{reduceBaseline,SpectralImagingData-method} 5 | 6 | \title{Reduce baselines in spectra} 7 | 8 | \description{ 9 | Apply deferred baseline reduction to spectra. 10 | } 11 | 12 | \usage{ 13 | \S4method{reduceBaseline}{SpectralImagingData}(object, 14 | method = c("locmin", "hull", "snip", "median"), \dots) 15 | } 16 | 17 | \arguments{ 18 | \item{object}{A spectral imaging dataset.} 19 | 20 | \item{method}{The baseline estimation method to use. See \code{\link[matter]{estbase}} for details.} 21 | 22 | \item{\dots}{Additional arguments passed to the baseline estimation function.} 23 | } 24 | 25 | \details{ 26 | The supported baseline estimation methods are: 27 | 28 | \itemize{ 29 | 30 | \item{"locmin": Interpolate from local minima using \code{\link{estbase_loc}}.} 31 | 32 | \item{"hull": Convex hull estimation using \code{\link{estbase_hull}}.} 33 | 34 | \item{"snip": Sensitive nonlinear iterative peak (SNIP) clipping using \code{\link{estbase_snip}}.} 35 | 36 | \item{"median": Running medians using \code{\link{estbase_med}}.} 37 | } 38 | } 39 | 40 | \note{ 41 | The baseline reduction is deferred until \code{process()} is called. 42 | } 43 | 44 | \value{ 45 | An object of the same class with the processing step queued. 46 | } 47 | 48 | \author{ 49 | Kylie A. Bemis 50 | } 51 | 52 | \seealso{ 53 | \code{\link{normalize}}, 54 | \code{\link{smooth}}, 55 | \code{\link{reduceBaseline}}, 56 | \code{\link{peakPick}}, 57 | \code{\link{process}} 58 | } 59 | 60 | \examples{ 61 | set.seed(1, kind="L'Ecuyer-CMRG") 62 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3), baseline=1) 63 | 64 | # queue baseline reduction 65 | mse2 <- reduceBaseline(mse, method="locmin") 66 | plot(mse2, i=4) 67 | 68 | # apply baseline reduction 69 | mse2 <- process(mse2) 70 | } 71 | 72 | \keyword{ts} 73 | -------------------------------------------------------------------------------- /man/ResultsList-class.Rd: -------------------------------------------------------------------------------- 1 | \name{ResultsList-class} 2 | \docType{class} 3 | 4 | \alias{class:ResultsList} 5 | \alias{ResultsList} 6 | \alias{ResultsList-class} 7 | 8 | \alias{show,ResultsList-method} 9 | \alias{fitted,ResultsList-method} 10 | \alias{predict,ResultsList-method} 11 | \alias{topFeatures,ResultsList-method} 12 | \alias{plot,ResultsList,ANY-method} 13 | \alias{plot,ResultsList,missing-method} 14 | \alias{image,ResultsList-method} 15 | 16 | \title{ResultsList: List of modeling results} 17 | 18 | \description{ 19 | The \code{ResultsList} class provides a container for modeling results with spatial metadata. Specialized subclasses include \code{MeansTest} for linear model testing, \code{SegmentationTest} for segmentation-based testing, and \code{ContrastTest} for post-hoc contrast analysis. 20 | } 21 | 22 | \usage{ 23 | ## Instance creation 24 | ResultsList(\dots, mcols = NULL) 25 | 26 | ## Additional methods documented below 27 | } 28 | 29 | \arguments{ 30 | \item{\dots}{The modeling results.} 31 | 32 | \item{mcols}{The metadata columns.} 33 | } 34 | 35 | \section{Methods}{ 36 | All methods for \code{\linkS4class{SimpleList}} also work on \code{ResultsList} objects. Additional methods are documented below: 37 | 38 | \describe{ 39 | \item{\code{fitted(object, ...)}:}{Extract fitted values from each modeling results object in the list.} 40 | 41 | \item{\code{predict(object, ...)}:}{Predict on each modeling results object in the list.} 42 | 43 | \item{\code{topFeatures(object, ...)}:}{Rank top features for each modeling results object in the list.} 44 | 45 | \item{\code{plot(x, i = 1L, ...)}:}{Plot the \code{i}th modeling results.} 46 | 47 | \item{\code{image(x, i = 1L, ...)}:}{Display images for the \code{i}th modeling results.} 48 | } 49 | } 50 | 51 | \author{Kylie A. Bemis} 52 | 53 | \seealso{ 54 | \code{\linkS4class{SpatialResults}}, 55 | \code{\link{meansTest}}, 56 | \code{\link{segmentationTest}} 57 | } 58 | 59 | \keyword{classes} 60 | -------------------------------------------------------------------------------- /tests/testthat/test-readMSIData.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("read/write imzML and Analyze 7.5") 5 | 6 | test_that("read/write continuous", { 7 | 8 | path <- CardinalIO::exampleImzMLFile("continuous") 9 | mse <- readImzML(path) 10 | 11 | expect_true(is(mse, "MSImagingExperiment")) 12 | 13 | path2 <- paste0(tempfile(), ".imzML") 14 | writeImzML(mse, path2) 15 | mse2 <- readImzML(path2) 16 | 17 | expect_true(is(mse2, "MSImagingExperiment")) 18 | expect_equivalent(mz(mse), mz(mse2)) 19 | expect_equivalent(spectra(mse)[,1L], spectra(mse2)[,1L]) 20 | 21 | pData(mse2)$test <- seq_len(ncol(mse2)) 22 | fData(mse2)$test <- seq_len(nrow(mse2)) 23 | metadata(mse2) <- list(processing1="normalization") 24 | 25 | path3 <- paste0(tempfile(), ".imzML") 26 | writeImzML(mse2, path3) 27 | mse3 <- readImzML(path3) 28 | 29 | expect_equal(pData(mse2), pData(mse3)) 30 | expect_equal(fData(mse2), fData(mse3)) 31 | expect_equal(metadata(mse2), metadata(mse3)) 32 | 33 | path4 <- paste0(tempfile(), ".img") 34 | writeAnalyze(mse, path4) 35 | mse4 <- readAnalyze(path4) 36 | 37 | expect_true(is(mse4, "MSImagingExperiment")) 38 | expect_equal(mz(mse), mz(mse4)) 39 | expect_equal(spectra(mse)[,1L], spectra(mse4)[,1L]) 40 | 41 | }) 42 | 43 | test_that("read/write processed", { 44 | 45 | path <- CardinalIO::exampleImzMLFile("processed") 46 | msa <- readImzML(path) 47 | 48 | expect_true(is(msa, "MSImagingArrays")) 49 | 50 | path2 <- paste0(tempfile(), ".imzML") 51 | writeImzML(msa, path2) 52 | msa2 <- readImzML(path2) 53 | 54 | expect_true(is(msa2, "MSImagingArrays")) 55 | expect_equivalent(mz(msa)[[1L]], mz(msa2)[[1L]]) 56 | expect_equivalent(intensity(msa)[[1L]], intensity(msa2)[[1L]]) 57 | 58 | pData(msa2)$test <- seq_len(length(msa2)) 59 | metadata(msa2) <- list(processing1="normalization") 60 | 61 | path3 <- paste0(tempfile(), ".imzML") 62 | writeImzML(msa2, path3) 63 | msa3 <- readImzML(path3) 64 | 65 | expect_equal(pData(msa2), pData(msa3)) 66 | expect_equal(metadata(msa2), metadata(msa3)) 67 | 68 | }) 69 | -------------------------------------------------------------------------------- /man/normalize.Rd: -------------------------------------------------------------------------------- 1 | \name{normalize} 2 | 3 | \alias{normalize} 4 | \alias{normalize,MSImagingExperiment_OR_Arrays-method} 5 | \alias{normalize,SpectralImagingData-method} 6 | 7 | \title{Normalize spectra} 8 | 9 | \description{ 10 | Apply deferred normalization to spectra. 11 | } 12 | 13 | \usage{ 14 | \S4method{normalize}{MSImagingExperiment_OR_Arrays}(object, 15 | method = c("tic", "rms", "reference"), 16 | scale = NA, ref = NULL, \dots) 17 | 18 | \S4method{normalize}{SpectralImagingData}(object, 19 | method = c("tic", "rms", "reference"), \dots) 20 | } 21 | 22 | \arguments{ 23 | \item{object}{A spectral imaging dataset.} 24 | 25 | \item{method}{The normalization method to use. See \code{\link[matter]{rescale}} for details.} 26 | 27 | \item{scale}{The scaling value to use for the normalized spectra.} 28 | 29 | \item{ref}{The reference peaks to use for normalization.} 30 | 31 | \item{\dots}{Additional arguments passed to the normalization function.} 32 | } 33 | 34 | \details{ 35 | The supported normalization methods are: 36 | 37 | \itemize{ 38 | 39 | \item{"tic": Total ion current normalization using \code{\link{rescale_sum}}.} 40 | 41 | \item{"rms": Root-mean-squared normalization using \code{\link{rescale_rms}}.} 42 | 43 | \item{"reference": Normalization according to a reference feature using \code{\link{rescale_ref}}.} 44 | } 45 | } 46 | 47 | \note{ 48 | The normalization is deferred until \code{process()} is called. 49 | } 50 | 51 | \value{ 52 | An object of the same class with the processing step queued. 53 | } 54 | 55 | \author{ 56 | Kylie A. Bemis 57 | } 58 | 59 | \seealso{ 60 | \code{\link{smooth}}, 61 | \code{\link{recalibrate}}, 62 | \code{\link{reduceBaseline}}, 63 | \code{\link{peakPick}}, 64 | \code{\link{process}} 65 | } 66 | 67 | \examples{ 68 | set.seed(1, kind="L'Ecuyer-CMRG") 69 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 70 | 71 | # queue normalization 72 | mse2 <- normalize(mse, method="tic") 73 | 74 | # apply normalization 75 | mse2 <- process(mse2) 76 | } 77 | 78 | \keyword{ts} 79 | -------------------------------------------------------------------------------- /man/smooth.Rd: -------------------------------------------------------------------------------- 1 | \name{smooth} 2 | 3 | \alias{smooth} 4 | \alias{smooth,SpectralImagingData-method} 5 | 6 | \title{Smooth spectra} 7 | 8 | \description{ 9 | Apply deferred smoothing to spectra. 10 | } 11 | 12 | \usage{ 13 | \S4method{smooth}{SpectralImagingData}(x, 14 | method = c("gaussian", "bilateral", "adaptive", 15 | "diff", "guide", "pag", "sgolay", "ma"), \dots) 16 | } 17 | 18 | \arguments{ 19 | \item{x}{A spectral imaging dataset.} 20 | 21 | \item{method}{The smoothing method to use. See \code{\link[matter]{filt1}} for details.} 22 | 23 | \item{\dots}{Additional arguments passed to the smoothing function.} 24 | } 25 | 26 | \details{ 27 | The supported smoothing methods are: 28 | 29 | \itemize{ 30 | 31 | \item{"gaussian": Gaussian smoothing using \code{\link{filt1_gauss}}.} 32 | 33 | \item{"bilateral": Bilateral filter using \code{\link{filt1_bi}}.} 34 | 35 | \item{"adaptive": Adaptive bilateral filter using \code{\link{filt1_adapt}}.} 36 | 37 | \item{"diff": Nonlinear diffusion smoothing using \code{\link{filt1_diff}}.} 38 | 39 | \item{"guide": Guided filter using \code{\link{filt1_guide}}.} 40 | 41 | \item{"pag": Peak-aware guided filter using \code{\link{filt1_pag}}.} 42 | 43 | \item{"sgolay": Savitzky-Golar filter using \code{\link{filt1_sg}}.} 44 | 45 | \item{"ma": Moving average filter using \code{\link{filt1_ma}}.} 46 | } 47 | } 48 | 49 | \note{ 50 | The smoothing is deferred until \code{process()} is called. 51 | } 52 | 53 | \value{ 54 | An object of the same class with the processing step queued. 55 | } 56 | 57 | \author{ 58 | Kylie A. Bemis 59 | } 60 | 61 | \seealso{ 62 | \code{\link{normalize}}, 63 | \code{\link{recalibrate}}, 64 | \code{\link{reduceBaseline}}, 65 | \code{\link{peakPick}}, 66 | \code{\link{process}} 67 | } 68 | 69 | \examples{ 70 | set.seed(1, kind="L'Ecuyer-CMRG") 71 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 72 | 73 | # queue smoothing 74 | mse2 <- smooth(mse, method="gaussian", width=11) 75 | plot(mse2, i=4) 76 | 77 | # apply smoothing 78 | mse2 <- process(mse2) 79 | } 80 | 81 | \keyword{ts} 82 | \keyword{smooth} 83 | -------------------------------------------------------------------------------- /R/stats-NMF.R: -------------------------------------------------------------------------------- 1 | 2 | #### Nonnegative matrix factorization #### 3 | ## --------------------------------------- 4 | 5 | setMethod("NMF", "ANY", 6 | function(x, ncomp = 3, method = c("als", "mult"), 7 | verbose = getCardinalVerbose(), ...) 8 | { 9 | method <- match.arg(method) 10 | msg <- "estimating nonnegative matrix factorization " 11 | if ( method == "als" ) { 12 | .Log(msg, "using alternating least squares", 13 | message=verbose) 14 | ans <- nnmf_als(x, k=max(ncomp), verbose=verbose, ...) 15 | } else if ( method == "mult" ) { 16 | .Log(msg, "using multiplicative updates", 17 | message=verbose) 18 | ans <- nnmf_mult(x, k=max(ncomp), verbose=verbose, ...) 19 | } else { 20 | .Error("unsupported method: ", method) 21 | } 22 | .Log("returning nonnegative matrix factorization", 23 | message=verbose) 24 | ans 25 | }) 26 | 27 | setMethod("NMF", "SpectralImagingExperiment", 28 | function(x, ncomp = 3, method = c("als", "mult"), ...) 29 | { 30 | if ( length(processingData(x)) > 0L ) 31 | .Warn("queued processing steps will be ignored") 32 | ans <- NMF(spectra(x), ncomp=ncomp, method=method, transpose=TRUE, ...) 33 | as(SpatialResults(ans, x), "SpatialNMF") 34 | }) 35 | 36 | setMethod("predict", "SpatialNMF", 37 | function(object, newdata, ...) 38 | { 39 | if ( !is(newdata, "SpectralImagingExperiment") ) 40 | .Error("'newdata' must inherit from 'SpectralImagingExperiment'") 41 | if ( length(processingData(newdata)) > 0L ) 42 | .Warn("queued processing steps will be ignored") 43 | predict(object@model, newdata=spectra(newdata), ...) 44 | }) 45 | 46 | setMethod("plot", c(x = "SpatialNMF", y = "missing"), 47 | function(x, type = c("activation", "x"), ..., xlab, ylab) 48 | { 49 | type <- match.arg(type) 50 | if ( type == "activation" ) { 51 | if ( missing(xlab) ) 52 | xlab <- NULL 53 | if ( missing(ylab) ) 54 | ylab <- "Loadings" 55 | callNextMethod(x, y=x$activation, xlab=xlab, ylab=ylab, ...) 56 | } else { 57 | callNextMethod(x, y=x$x, xlab=xlab, ylab=ylab, 58 | reducedDims=TRUE, ...) 59 | } 60 | }) 61 | 62 | setMethod("image", c(x = "SpatialNMF"), 63 | function(x, type = "x", ...) 64 | { 65 | type <- match.arg(type) 66 | callNextMethod(x, y=x$x, ...) 67 | }) 68 | 69 | -------------------------------------------------------------------------------- /R/spatialDists.R: -------------------------------------------------------------------------------- 1 | 2 | #### Find spatial neighbors #### 3 | ## ----------------------------- 4 | 5 | setMethod("spatialDists", "ANY", 6 | function(x, y, coord, r = 1, byrow = TRUE, 7 | metric = "euclidean", p = 2, weights = NULL, 8 | neighbors = findNeighbors(coord, r=r), 9 | neighbors.weights = spatialWeights(coord, r=r), 10 | verbose = getCardinalVerbose(), chunkopts = list(), 11 | BPPARAM = getCardinalBPPARAM(), ...) 12 | { 13 | .spatialDists(x, y, byrow=byrow, 14 | metric=metric, p=p, weights=weights, 15 | neighbors=neighbors, neighbors.weights=neighbors.weights, 16 | verbose=verbose, chunkopts=chunkopts, 17 | BPPARAM=BPPARAM) 18 | }) 19 | 20 | setMethod("spatialDists", "SpectralImagingExperiment", 21 | function(x, y, r = 1, 22 | neighbors = findNeighbors(x, r=r), 23 | neighbors.weights = spatialWeights(x, r=r), ...) 24 | { 25 | spatialDists(spectra(x), y, byrow=FALSE, 26 | neighbors=neighbors, 27 | neighbors.weights=neighbors.weights, ...) 28 | }) 29 | 30 | setMethod("spatialDists", "PositionDataFrame", 31 | function(x, y, r = 1, 32 | neighbors = findNeighbors(x, r=r), 33 | neighbors.weights = spatialWeights(x, r=r), ...) 34 | { 35 | spatialDists(as.matrix(dropkeys(x)), y, byrow=TRUE, 36 | neighbors=neighbors, 37 | neighbors.weights=neighbors.weights, ...) 38 | }) 39 | 40 | .spatialRowDists <- function(x, y, ...) { 41 | spatialDists(x, y, byrow=TRUE, ...) 42 | } 43 | 44 | .spatialColDists <- function(x, y, ...) { 45 | spatialDists(x, y, byrow=FALSE, ...) 46 | } 47 | 48 | .spatialDists <- function(x, y, metric, p, weights, 49 | neighbors, neighbors.weights, byrow, 50 | verbose, chunkopts, BPPARAM) 51 | { 52 | if ( byrow ) { 53 | ds <- rowDists(x, y, 54 | metric=metric, p=p, weights=weights, 55 | verbose=verbose, chunkopts=chunkopts, 56 | BPPARAM=BPPARAM) 57 | } else { 58 | ds <- colDists(x, y, 59 | metric=metric, p=p, weights=weights, 60 | verbose=verbose, chunkopts=chunkopts, 61 | BPPARAM=BPPARAM) 62 | } 63 | FUN <- function(nb, w) colSums(w * ds[nb,,drop=FALSE]) / sum(w) 64 | ans <- mapply(FUN, neighbors, neighbors.weights) 65 | if ( is.matrix(ans) ) { 66 | ans <- t(ans) 67 | } else { 68 | ans <- as.matrix(ans) 69 | } 70 | dimnames(ans) <- dimnames(y) 71 | ans 72 | } 73 | 74 | -------------------------------------------------------------------------------- /man/recalibrate.Rd: -------------------------------------------------------------------------------- 1 | \name{recalibrate} 2 | 3 | \alias{recalibrate} 4 | \alias{recalibrate,MSImagingExperiment_OR_Arrays-method} 5 | \alias{recalibrate,SpectralImagingData-method} 6 | 7 | \title{Recalibrate spectra} 8 | 9 | \description{ 10 | Apply deferred recalibration to spectra. 11 | } 12 | 13 | \usage{ 14 | \S4method{recalibrate}{MSImagingExperiment_OR_Arrays}(object, ref, 15 | method = c("locmax", "dtw", "cow"), 16 | tolerance = NA, units = c("ppm", "mz"), \dots) 17 | 18 | \S4method{recalibrate}{SpectralImagingData}(object, ref, 19 | method = c("locmax", "dtw", "cow"), 20 | tolerance = NA, units = c("relative", "absolute"), \dots) 21 | } 22 | 23 | \arguments{ 24 | \item{object}{A spectral imaging dataset.} 25 | 26 | \item{ref}{The domain (m/z) values or indices of reference peaks to use for the recalibration.} 27 | 28 | \item{method}{The recalibration method to use. See \code{\link[matter]{warp1}} for details.} 29 | 30 | \item{tolerance}{The tolerance for how much a peak can be shifted in either direction.} 31 | 32 | \item{units}{The units for the above tolerance.} 33 | 34 | \item{\dots}{Additional arguments passed to the recalibration function.} 35 | } 36 | 37 | \details{ 38 | The supported recalibration methods are: 39 | 40 | \itemize{ 41 | 42 | \item{"locmax": Align to local maxima using \code{\link{warp1_loc}}.} 43 | 44 | \item{"dtw": Dynamic time warping using \code{\link{warp1_dtw}}.} 45 | 46 | \item{"cow": Correlation optimized warping using \code{\link{warp1_cow}}.} 47 | } 48 | } 49 | 50 | \note{ 51 | The recalibration is deferred until \code{process()} is called. 52 | } 53 | 54 | \value{ 55 | An object of the same class with the processing step queued. 56 | } 57 | 58 | \author{ 59 | Kylie A. Bemis 60 | } 61 | 62 | \seealso{ 63 | \code{\link{normalize}}, 64 | \code{\link{smooth}}, 65 | \code{\link{recalibrate}}, 66 | \code{\link{peakPick}}, 67 | \code{\link{process}} 68 | } 69 | 70 | \examples{ 71 | set.seed(1, kind="L'Ecuyer-CMRG") 72 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3), sdmz=250) 73 | plot(mse, i=c(2,4,5), superpose=TRUE, xlim=c(1260,1320)) 74 | 75 | # queue recalibration 76 | peaks <- estimateReferencePeaks(mse) 77 | mse2 <- recalibrate(mse, ref=peaks, method="locmax", tolerance=500) 78 | 79 | # apply recalibration 80 | mse2 <- process(mse2) 81 | plot(mse2, i=c(2,4,5), superpose=TRUE, xlim=c(1260,1320)) 82 | } 83 | 84 | \keyword{ts} 85 | -------------------------------------------------------------------------------- /R/stats-PCA.R: -------------------------------------------------------------------------------- 1 | 2 | #### Principal components analysis #### 3 | ## ------------------------------------ 4 | 5 | setMethod("PCA", "ANY", 6 | function(x, ncomp = 3, 7 | center = TRUE, scale = FALSE, 8 | verbose = getCardinalVerbose(), chunkopts = list(), 9 | BPPARAM = getCardinalBPPARAM(), ...) 10 | { 11 | ans <- prcomp_lanczos(x, k=max(ncomp), 12 | center=center, scale.=scale, 13 | verbose=verbose, chunkopts=chunkopts, 14 | BPPARAM=BPPARAM, ...) 15 | .Log("returning principal components", 16 | message=verbose) 17 | ans 18 | }) 19 | 20 | setMethod("PCA", "SpectralImagingExperiment", 21 | function(x, ncomp = 3, 22 | center = TRUE, scale = FALSE, ...) 23 | { 24 | if ( length(processingData(x)) > 0L ) 25 | .Warn("queued processing steps will be ignored") 26 | ans <- PCA(spectra(x), ncomp=ncomp, transpose=TRUE, 27 | center=center, scale=scale, ...) 28 | as(SpatialResults(ans, x), "SpatialPCA") 29 | }) 30 | 31 | setMethod("predict", "SpatialPCA", 32 | function(object, newdata, 33 | BPPARAM = getCardinalBPPARAM(), ...) 34 | { 35 | if ( !is(newdata, "SpectralImagingExperiment") ) 36 | .Error("'newdata' must inherit from 'SpectralImagingExperiment'") 37 | if ( length(processingData(newdata)) > 0L ) 38 | .Warn("queued processing steps will be ignored") 39 | if ( nrow(newdata) != nrow(object$rotation) ) 40 | .Error("'newdata' does not have the correct number of dimensions") 41 | if ( (!isFALSE(object$center) || !isFALSE(object$scale)) ) { 42 | x <- rowscale(spectra(newdata), 43 | center=object$center, scale=object$scale, 44 | verbose=FALSE, BPPARAM=BPPARAM, ...) 45 | } else { 46 | x <- spectra(newdata) 47 | } 48 | crossprod(x, object$rotation) 49 | }) 50 | 51 | setMethod("plot", c(x = "SpatialPCA", y = "missing"), 52 | function(x, type = c("rotation", "scree", "x"), ..., xlab, ylab) 53 | { 54 | type <- match.arg(type) 55 | if ( missing(xlab) ) 56 | xlab <- NULL 57 | if ( type == "rotation" ) { 58 | if ( missing(ylab) ) 59 | ylab <- "Loadings" 60 | callNextMethod(x, y=x$rotation, xlab=xlab, ylab=ylab, ...) 61 | } else if ( type == "x" ) { 62 | callNextMethod(x, y=x$x, xlab=xlab, ylab=ylab, 63 | reducedDims=TRUE, ...) 64 | } else { 65 | if ( missing(ylab) ) 66 | ylab <- "Variances" 67 | panel_grid(c(1L,1L)) 68 | screeplot(x@model, main="", ...) 69 | title(xlab=xlab, ylab=ylab, outer=TRUE) 70 | } 71 | }) 72 | 73 | setMethod("image", c(x = "SpatialPCA"), 74 | function(x, type = "x", ...) 75 | { 76 | type <- match.arg(type) 77 | callNextMethod(x, y=x$x, ...) 78 | }) 79 | 80 | -------------------------------------------------------------------------------- /man/SpatialNMF.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialNMF} 2 | 3 | \alias{SpatialNMF} 4 | \alias{class:SpatialNMF} 5 | \alias{SpatialNMF-class} 6 | 7 | \alias{NMF} 8 | \alias{NMF,ANY-method} 9 | \alias{NMF,SpectralImagingExperiment-method} 10 | \alias{predict,SpatialNMF-method} 11 | \alias{plot,SpatialNMF,missing-method} 12 | \alias{image,SpatialNMF-method} 13 | 14 | \title{Non-negative matrix factorization} 15 | 16 | \description{ 17 | Compute nonnegative matrix factorization using alternating least squares or multiplicative updates. 18 | } 19 | 20 | \usage{ 21 | \S4method{NMF}{ANY}(x, ncomp = 3, method = c("als", "mult"), 22 | verbose = getCardinalVerbose(), \dots) 23 | 24 | \S4method{NMF}{SpectralImagingExperiment}(x, ncomp = 3, method = c("als", "mult"), \dots) 25 | 26 | \S4method{predict}{SpatialNMF}(object, newdata, \dots) 27 | 28 | \S4method{plot}{SpatialNMF,missing}(x, type = c("activation", "x"), \dots, xlab, ylab) 29 | 30 | \S4method{image}{SpatialNMF}(x, type = "x", \dots) 31 | } 32 | \arguments{ 33 | \item{x}{A dataset in P x N matrix format.} 34 | 35 | \item{ncomp}{The number of components to calculate.} 36 | 37 | \item{method}{The method to use. Alternating least squares ("als") tends to be faster and potentially more accurate, but can be numerically unstable for data with high correlated features. Multiplicative updates ("mult") can be slower, but is more numerically stable.} 38 | 39 | \item{verbose}{Should progress messages be printed?} 40 | 41 | \item{\dots}{Options passed to \code{\link[irlba]{irlba}}.} 42 | 43 | \item{object}{A \code{SpatialNMF} object.} 44 | 45 | \item{newdata}{A new \code{SpectralImagingExperiment} for which to calculate the scores.} 46 | 47 | \item{type}{The type of plot to display.} 48 | 49 | \item{xlab, ylab}{Plotting labels.} 50 | } 51 | 52 | \value{ 53 | An object of class \code{SpatialNMF} derived from \code{SpatialResults}, containing the fitted \code{\link[matter]{nnmf}} object and the spatial metadata. 54 | } 55 | 56 | \author{ 57 | Kylie A. Bemis 58 | } 59 | 60 | \seealso{ 61 | \code{\link[matter]{nnmf_als}}, 62 | \code{\link[matter]{nnmf_mult}}, 63 | \code{\link{PCA}}, 64 | \code{\link{spatialFastmap}} 65 | } 66 | 67 | \examples{ 68 | set.seed(1, kind="L'Ecuyer-CMRG") 69 | mse <- simulateImage(preset=2, npeaks=20, dim=c(10,10), 70 | centroided=TRUE) 71 | 72 | # project to principal components 73 | mf <- NMF(mse, ncomp=2) 74 | 75 | # visualize first 2 components 76 | image(mf, superpose=FALSE, scale=TRUE) 77 | } 78 | 79 | \keyword{multivariate} 80 | 81 | -------------------------------------------------------------------------------- /man/PositionDataFrame-class.Rd: -------------------------------------------------------------------------------- 1 | \name{PositionDataFrame-class} 2 | \docType{class} 3 | 4 | \alias{class:PositionDataFrame} 5 | \alias{PositionDataFrame} 6 | \alias{PositionDataFrame-class} 7 | 8 | \alias{coord} 9 | \alias{coord<-} 10 | \alias{coord,PositionDataFrame-method} 11 | \alias{coord<-,PositionDataFrame-method} 12 | \alias{coordNames} 13 | \alias{coordNames<-} 14 | \alias{coordNames,PositionDataFrame-method} 15 | \alias{coordNames<-,PositionDataFrame-method} 16 | \alias{run} 17 | \alias{run<-} 18 | \alias{run,PositionDataFrame-method} 19 | \alias{run<-,PositionDataFrame-method} 20 | \alias{runNames} 21 | \alias{runNames<-} 22 | \alias{runNames,PositionDataFrame-method} 23 | \alias{runNames<-,PositionDataFrame-method} 24 | \alias{nrun,PositionDataFrame-method} 25 | \alias{is3D,PositionDataFrame-method} 26 | \alias{[,PositionDataFrame,ANY,ANY,ANY-method} 27 | \alias{coerce,DFrame,PositionDataFrame-method} 28 | 29 | \title{PositionDataFrame: Extended data frame with key columns} 30 | 31 | \description{ 32 | A data frame for metadata with spatial coordinates and multiple experimental runs. 33 | } 34 | 35 | \usage{ 36 | PositionDataFrame(coord, run, \dots, row.names = FALSE) 37 | } 38 | 39 | \arguments{ 40 | \item{coord}{A data frame or matrix of coordinates.} 41 | 42 | \item{run}{A factor giving the experimental runs.} 43 | 44 | \item{\dots}{Arguments passed to the \code{DataFrame()}.} 45 | 46 | \item{row.names}{Either a vector of row names or a logical value indicating whether row names should be generated automatically (from the m/z values).} 47 | } 48 | 49 | \section{Methods}{ 50 | \describe{ 51 | \item{\code{coord(object)}, \code{coord(object) <- value}:}{Get or set the coordinate columns.} 52 | 53 | \item{\code{coordNames(object)}, \code{coordNames(object) <- value}:}{Get or set the names of the coordinate columns.} 54 | 55 | \item{\code{run(object)}, \code{run(object) <- value}:}{Get or set the experimental run column.} 56 | 57 | \item{\code{runNames(object)}, \code{runNames(object) <- value}:}{Get or set the experimental run levels.} 58 | 59 | \item{\code{nrun(object)}:}{Get the number of experimental runs.} 60 | 61 | \item{\code{is3D(object)}:}{Check if the number of spatial dimensions is greater than 2.} 62 | } 63 | } 64 | 65 | \author{Kylie A. Bemis} 66 | 67 | \seealso{ 68 | \code{\link{XDataFrame}}, 69 | \code{\link{MassDataFrame}} 70 | } 71 | 72 | \examples{ 73 | ## Create an PositionDataFrame object 74 | coord <- expand.grid(x=1:3, y=1:3) 75 | PositionDataFrame(coord=coord, label=LETTERS[1:9]) 76 | } 77 | 78 | \keyword{classes} 79 | -------------------------------------------------------------------------------- /R/spatialWeights.R: -------------------------------------------------------------------------------- 1 | 2 | #### Find spatial neighbors #### 3 | ## ----------------------------- 4 | 5 | setMethod("spatialWeights", "ANY", 6 | function(x, coord = x, r = 1, byrow = TRUE, 7 | neighbors = findNeighbors(coord, r=r), 8 | weights = c("gaussian", "adaptive"), 9 | sd = ((2 * r) + 1) / 4, matrix = FALSE, 10 | verbose = getCardinalVerbose(), chunkopts = list(), 11 | BPPARAM = getCardinalBPPARAM(), ...) 12 | { 13 | wts <- .spatialWeights(as.matrix(coord), byrow=byrow || !missing(coord), 14 | neighbors=neighbors, weights="gaussian", sd=sd, 15 | verbose=verbose, chunkopts=chunkopts, 16 | BPPARAM=BPPARAM) 17 | if ( match.arg(weights) == "adaptive" ) 18 | { 19 | awts <- .spatialWeights(x, byrow=byrow, 20 | neighbors=neighbors, weights="adaptive", sd=sd, 21 | verbose=verbose, chunkopts=chunkopts, 22 | BPPARAM=BPPARAM) 23 | wts <- Map("*", wts, awts) 24 | } 25 | if ( matrix ) { 26 | sparse_mat(index=neighbors, data=wts, 27 | nrow=length(neighbors), ncol=length(neighbors), 28 | offset=1L) 29 | } else { 30 | wts 31 | } 32 | }) 33 | 34 | setMethod("spatialWeights", "SpectralImagingExperiment", 35 | function(x, r = 1, 36 | neighbors = findNeighbors(x, r=r), 37 | weights = c("gaussian", "adaptive"), ...) 38 | { 39 | spatialWeights(spectra(x), 40 | coord=coord(x), r=r, byrow=FALSE, 41 | neighbors=neighbors, weights=weights, ...) 42 | }) 43 | 44 | setMethod("spatialWeights", "PositionDataFrame", 45 | function(x, r = 1, 46 | neighbors = findNeighbors(x, r=r), 47 | weights = c("gaussian", "adaptive"), ...) 48 | { 49 | spatialWeights(as.matrix(dropkeys(x)), 50 | coord=coord(x), r=r, byrow=TRUE, 51 | neighbors=neighbors, weights=weights, ...) 52 | }) 53 | 54 | .spatialWeights <- function(x, 55 | neighbors, weights, sd, byrow, 56 | verbose, chunkopts, BPPARAM) 57 | { 58 | if ( byrow ) { 59 | if ( is.matrix(x) || is.data.frame(x) ) { 60 | ds <- rowdist_at(x, ix=seq_len(nrow(x)), iy=neighbors) 61 | } else { 62 | ds <- rowDists(x, at=neighbors, 63 | verbose=verbose, chunkopts=chunkopts, 64 | BPPARAM=BPPARAM) 65 | } 66 | } else { 67 | if ( is.matrix(x) || is.data.frame(x) ) { 68 | ds <- coldist_at(x, ix=seq_len(ncol(x)), iy=neighbors) 69 | } else { 70 | ds <- colDists(x, at=neighbors, 71 | verbose=verbose, chunkopts=chunkopts, 72 | BPPARAM=BPPARAM) 73 | } 74 | } 75 | if ( weights == "gaussian" ) { 76 | sds <- rep_len(sd, nrow(x)) 77 | } else { 78 | sds <- vapply(ds, function(d) max(d) / 2, numeric(1L)) 79 | sds <- sds + sqrt(.Machine$double.eps) 80 | } 81 | Map(function(d, sd) exp(-d^2 / (2 * sd^2)), ds, sds) 82 | } 83 | 84 | -------------------------------------------------------------------------------- /man/colocalized.Rd: -------------------------------------------------------------------------------- 1 | \name{colocalized} 2 | 3 | \alias{colocalized} 4 | \alias{colocalized,MSImagingExperiment-method} 5 | \alias{colocalized,SpectralImagingExperiment-method} 6 | \alias{colocalized,SpatialDGMM-method} 7 | \alias{coregister} 8 | 9 | \title{Colocalized features} 10 | 11 | \description{ 12 | Find colocalized features in an imaging dataset. 13 | } 14 | 15 | \usage{ 16 | \S4method{colocalized}{MSImagingExperiment}(object, mz, \dots) 17 | 18 | \S4method{colocalized}{SpectralImagingExperiment}(object, i, ref, 19 | threshold = median, n = Inf, 20 | sort.by = c("cor", "MOC", "M1", "M2", "Dice", "none"), 21 | verbose = getCardinalVerbose(), chunkopts = list(), 22 | BPPARAM = getCardinalBPPARAM(), \dots) 23 | 24 | \S4method{colocalized}{SpatialDGMM}(object, ref, 25 | threshold = median, n = Inf, 26 | sort.by = c("MOC", "M1", "M2", "Dice", "none"), 27 | verbose = getCardinalVerbose(), chunkopts = list(), 28 | BPPARAM = getCardinalBPPARAM(), \dots) 29 | } 30 | 31 | \arguments{ 32 | \item{object}{An imaging experiment.} 33 | 34 | \item{mz}{An m/z value of a feature in \code{object} to use as a reference.} 35 | 36 | \item{i}{The index of a feature in \code{object} to use as a reference.} 37 | 38 | \item{ref}{Either a flattened image (i.e., a numeric vector) or a logical mask of a region-of-interest to use as a reference.} 39 | 40 | \item{threshold}{Either a function that returns the cutoff to use for creating logical masks of numeric references, or a numeric threshold to use.} 41 | 42 | \item{n}{The number of top-ranked colocalized features to return.} 43 | 44 | \item{sort.by}{The colocalization measure used to rank colocalized features. Possible options include Pearson's correlation ("cor"), Manders overlap coefficient ("MOC"), Manders colocalization coefficients ("M1" and "M2"), and Dice similarity coefficient ("Dice".} 45 | 46 | \item{verbose}{Should progress messages be printed?} 47 | 48 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 49 | 50 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 51 | 52 | \item{\dots}{Options passed to \code{\link{chunkApply}}.} 53 | } 54 | 55 | \value{ 56 | A data frame with the colocalized features, or a list of data frames if multiple references are given. 57 | } 58 | 59 | \author{Kylie A. Bemis} 60 | 61 | \examples{ 62 | set.seed(1, kind="L'Ecuyer-CMRG") 63 | x <- simulateImage(preset=1, dim=c(10,10), centroided=TRUE) 64 | 65 | # find features colocalized with first feature 66 | colocalized(x, i=1) 67 | } 68 | 69 | \keyword{methods} 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cardinal 2 | 3 | ## Mass spectrometry imaging tools 4 | 5 | *Cardinal* provides an interface for manipulating mass spectrometry (MS) imaging datasets, simplifying most of the basic programmatic tasks encountered during the statistical analysis of MS imaging data. These include image manipulation and processing of both images and mass spectra, and dynamic plotting of both. 6 | 7 | While pre-processing steps including normalization, baseline correction, and peak-picking are provided, the core functionality of the package is statistical analysis. The package includes classification and clustering methods based on nearest shrunken centroids, as well as traditional tools like PCA and PLS. 8 | 9 | ## User Installation 10 | 11 | ### Bioconductor Release 12 | 13 | *Cardinal* can be installed via the *BiocManager* package. 14 | 15 | This is the **recommended** installation method. 16 | 17 | ```{r install, eval=FALSE} 18 | if (!require("BiocManager", quietly = TRUE)) 19 | install.packages("BiocManager") 20 | 21 | BiocManager::install("Cardinal") 22 | ``` 23 | 24 | The same function can be used to update *Cardinal* and other Bioconductor packages. 25 | 26 | Once installed, *Cardinal* can be loaded with `library()`: 27 | 28 | ```{r library, eval=FALSE} 29 | library(Cardinal) 30 | ``` 31 | 32 | ### Github Release 33 | 34 | *Cardinal* can also be installed via the *remotes* package. 35 | 36 | ```{r install, eval=FALSE} 37 | if (!require("remotes", quietly = TRUE)) 38 | install.packages("remotes") 39 | 40 | remotes::install_github("kuwisdelu/Cardinal", ref=remotes::github_release()) 41 | ``` 42 | 43 | Previous releases can be installed by specifying the exact version. 44 | 45 | ```{r library, eval=FALSE} 46 | remotes::install_github("kuwisdelu/Cardinal@v3.6.2") 47 | ``` 48 | 49 | ## Developer Installation 50 | 51 | ### Bioconductor Devel 52 | 53 | The Bioconductor development version of *Cardinal* can also be installed via the *BiocManager* package. 54 | 55 | ```{r install, eval=FALSE} 56 | BiocManager::install("Cardinal", version="devel") 57 | ``` 58 | 59 | This version is **unstable** and should not be used for critical work. However, it is typically more stable than Github devel. 60 | 61 | This version should *typically* pass `R CMD check` without errors. 62 | 63 | ### Github Devel 64 | 65 | The most cutting edge version of *Cardinal* can be installed from Github via the *remotes* package. 66 | 67 | ```{r install, eval=FALSE} 68 | if (!require("remotes", quietly = TRUE)) 69 | install.packages("remotes") 70 | 71 | remotes::install_github("kuwisdelu/Cardinal") 72 | ``` 73 | 74 | This version is **unstable** and only recommended for developers. It should not be used for critical work. 75 | 76 | 77 | -------------------------------------------------------------------------------- /man/spectrapply.Rd: -------------------------------------------------------------------------------- 1 | \name{spectrapply} 2 | 3 | \alias{spectrapply} 4 | \alias{spectrapply,SpectralImagingExperiment-method} 5 | \alias{spectrapply,SpectralImagingArrays-method} 6 | 7 | \title{Apply functions over spectra} 8 | 9 | \description{ 10 | Apply a user-specified function over all spectra in a spectral imaging dataset. 11 | } 12 | 13 | \usage{ 14 | \S4method{spectrapply}{SpectralImagingExperiment}(object, FUN, \dots, 15 | spectra = "intensity", index = NULL, 16 | simplify = TRUE, outpath = NULL, 17 | verbose = getCardinalVerbose(), chunkopts = list(), 18 | BPPARAM = getCardinalBPPARAM()) 19 | 20 | \S4method{spectrapply}{SpectralImagingArrays}(object, FUN, \dots, 21 | spectra = "intensity", index = NULL, 22 | simplify = TRUE, outpath = NULL, 23 | verbose = getCardinalVerbose(), chunkopts = list(), 24 | BPPARAM = getCardinalBPPARAM()) 25 | } 26 | 27 | \arguments{ 28 | \item{object}{A spectral imaging dataset.} 29 | 30 | \item{FUN}{A function to be applied. The first argument will be the \code{spectra} elements. Additional arguments are passed for each \code{index} component.} 31 | 32 | \item{\dots}{Options passed to \code{\link[matter]{chunkMapply}} or \code{\link[matter]{chunkApply}}.} 33 | 34 | \item{spectra}{The name of the array in \code{spectraData()} to use for the spectral intensities.} 35 | 36 | \item{index}{The name of the array in \code{spectraData()} (for \code{SpectralImagingArrays}) or column in \code{featureData()} (for \code{SpectralImagingExperiment}) to use for the spectral locations.} 37 | 38 | \item{simplify}{Should the result be simplified to an array if possible?} 39 | 40 | \item{outpath}{Optional. The name of a file to write the resulting data.} 41 | 42 | \item{verbose}{Should progress messages be printed?} 43 | 44 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 45 | 46 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 47 | } 48 | 49 | \value{ 50 | A list if \code{simplify=FALSE}. Otherwise, a vector or matrix, or a higher-dimensional array if the attempted simplification is successful. 51 | } 52 | 53 | \author{ 54 | Kylie A. Bemis 55 | } 56 | 57 | \seealso{ 58 | \code{\link{summarizeFeatures}}, 59 | \code{\link{summarizePixels}} 60 | } 61 | 62 | \examples{ 63 | set.seed(1, kind="L'Ecuyer-CMRG") 64 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10)) 65 | 66 | # find m/z locations of peaks in each spectrum 67 | peaks <- spectrapply(mse, index="mz", 68 | function(x, mz) mz[matter::findpeaks(x)]) 69 | 70 | head(peaks[[1L]]) 71 | head(peaks[[2L]]) 72 | } 73 | 74 | \keyword{manip} 75 | 76 | -------------------------------------------------------------------------------- /man/SpatialPCA.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialPCA} 2 | 3 | \alias{SpatialPCA} 4 | \alias{class:SpatialPCA} 5 | \alias{SpatialPCA-class} 6 | 7 | \alias{PCA} 8 | \alias{PCA,ANY-method} 9 | \alias{PCA,SpectralImagingExperiment-method} 10 | \alias{predict,SpatialPCA-method} 11 | \alias{plot,SpatialPCA,missing-method} 12 | \alias{image,SpatialPCA-method} 13 | 14 | \title{Principal components analysis} 15 | 16 | \description{ 17 | Compute principal components efficiently using implicitly restarted Lanczos bi-diagonalization (IRLBA) algorithm for approximate singular value decomposition. 18 | } 19 | 20 | \usage{ 21 | \S4method{PCA}{ANY}(x, ncomp = 3, 22 | center = TRUE, scale = FALSE, 23 | verbose = getCardinalVerbose(), chunkopts = list(), 24 | BPPARAM = getCardinalBPPARAM(), \dots) 25 | 26 | \S4method{PCA}{SpectralImagingExperiment}(x, ncomp = 3, 27 | center = TRUE, scale = FALSE, \dots) 28 | 29 | \S4method{predict}{SpatialPCA}(object, newdata, 30 | BPPARAM = getCardinalBPPARAM(), \dots) 31 | 32 | \S4method{plot}{SpatialPCA,missing}(x, type = c("rotation", "scree", "x"), \dots, xlab, ylab) 33 | 34 | \S4method{image}{SpatialPCA}(x, type = "x", \dots) 35 | } 36 | \arguments{ 37 | \item{x}{A dataset in P x N matrix format.} 38 | 39 | \item{ncomp}{The number of principal components to calculate.} 40 | 41 | \item{center}{Should the data be centered?} 42 | 43 | \item{scale}{Shoud the data be scaled?} 44 | 45 | \item{verbose}{Should progress messages be printed?} 46 | 47 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 48 | 49 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 50 | 51 | \item{\dots}{Options passed to \code{\link[irlba]{irlba}}.} 52 | 53 | \item{object}{A \code{SpatialPCA} object.} 54 | 55 | \item{newdata}{A new \code{SpectralImagingExperiment} for which to calculate the scores.} 56 | 57 | \item{type}{The type of plot to display.} 58 | 59 | \item{xlab, ylab}{Plotting labels.} 60 | } 61 | 62 | \value{ 63 | An object of class \code{SpatialPCA} derived from \code{SpatialResults}, containing the fitted \code{\link[matter]{prcomp_lanczos}} object and the spatial metadata. 64 | } 65 | 66 | \author{ 67 | Kylie A. Bemis 68 | } 69 | 70 | \seealso{ 71 | \code{\link[matter]{prcomp_lanczos}}, 72 | \code{\link{NMF}}, 73 | \code{\link{spatialFastmap}}, 74 | \code{\link{irlba}}, 75 | \code{\link{svd}} 76 | } 77 | 78 | \examples{ 79 | set.seed(1, kind="L'Ecuyer-CMRG") 80 | mse <- simulateImage(preset=2, npeaks=20, dim=c(10,10), 81 | centroided=TRUE) 82 | 83 | # project to principal components 84 | pc <- PCA(mse, ncomp=2) 85 | 86 | # visualize first 2 components 87 | image(pc, superpose=FALSE, scale=TRUE) 88 | } 89 | 90 | \keyword{multivariate} 91 | 92 | -------------------------------------------------------------------------------- /R/selectROI.R: -------------------------------------------------------------------------------- 1 | 2 | #### Select ROIs #### 3 | ## ------------------- 4 | 5 | setMethod("selectROI", "SpectralImagingExperiment", 6 | function(object, ..., mode = c("region", "pixels")) 7 | { 8 | mode <- match.arg(mode) 9 | if ( ...length() > 0L ) { 10 | plot <- plot(image(object, ...)) 11 | } else { 12 | plot <- plot(.last$image) 13 | } 14 | .select_ROI(object, plot, mode) 15 | }) 16 | 17 | # combine logical ROIs into a factor 18 | makeFactor <- function(..., ordered = FALSE) 19 | { 20 | inds <- list(...) 21 | labs <- vapply(substitute(...()), deparse, character(1L)) 22 | if ( !is.null(names(inds)) ) { 23 | nz <- nzchar(names(inds)) 24 | labs[nz] <- names(inds)[nz] 25 | } 26 | names(labs) <- NULL 27 | inds <- do.call("cbind", inds) 28 | inds <- apply(inds, 1, function(i) which(i)[1L]) 29 | factor(labs[inds], levels=labs, ordered=ordered) 30 | } 31 | 32 | .select_ROI <- function(object, plot, mode) 33 | { 34 | if ( length(dev.list()) == 0L ) 35 | .Error("no plot available to use") 36 | if ( nrun(object) > 1L ) 37 | .Warn("multiple runs plotted; results may be unexpected") 38 | box(bty="o", col="red", lty="solid", lwd=2) 39 | .Message("select ", mode, ": press ESC or 2nd mouse button to stop") 40 | loc <- .select_locator(plot, mode == "region") 41 | roi <- logical(ncol(object)) 42 | sub <- .last$subset 43 | if ( is.null(sub) ) { 44 | sub <- rep.int(TRUE, ncol(object)) 45 | } else { 46 | sub <- rep_len(sub, ncol(object)) 47 | } 48 | pos <- coord(object)[sub,,drop=FALSE] 49 | if ( mode == "region" ) { 50 | selected <- inpoly(pos, cbind(loc$x, loc$y)) 51 | } else { 52 | selected <- logical(nrow(pos)) 53 | ind <- kdsearch(cbind(loc$x, loc$y), pos, tol=0.5) 54 | selected[unlist(ind)] <- TRUE 55 | } 56 | roi[sub] <- selected 57 | roi 58 | } 59 | 60 | .select_locator <- function(plot, region = TRUE) 61 | { 62 | xs <- numeric() 63 | ys <- numeric() 64 | shape <- if (region) 1L else 4L 65 | while ( TRUE ) { 66 | loc <- locator(1) 67 | if ( !is.null(loc) ) { 68 | xs <- c(xs, loc$x) 69 | ys <- c(ys, loc$y) 70 | if ( region ) { 71 | plot <- add_mark(plot, "lines", x=xs, y=ys, 72 | params=list(col="white"), 73 | trans=list(sort=FALSE)) 74 | } 75 | plot <- add_mark(plot, "points", x=xs, y=ys, 76 | params=list(col="white", pch=shape)) 77 | print(plot) 78 | box(bty="o", col="red", lty="solid", lwd=2) 79 | } else { 80 | break 81 | } 82 | } 83 | if ( region ) { 84 | xsp <- c(xs, xs[1L]) 85 | ysp <- c(ys, ys[1L]) 86 | plot <- add_mark(plot, "lines", x=xsp, y=ysp, 87 | params=list(col="white"), 88 | trans=list(sort=FALSE)) 89 | print(plot) 90 | } 91 | list(x=xs, y=ys) 92 | } 93 | 94 | .last <- list2env(list( 95 | plot = NULL, 96 | image = NULL, 97 | subset = TRUE 98 | )) 99 | 100 | -------------------------------------------------------------------------------- /man/estimateDomain.Rd: -------------------------------------------------------------------------------- 1 | \name{estimateDomain} 2 | 3 | \alias{estimateDomain} 4 | \alias{estimateReferenceMz} 5 | \alias{estimateReferencePeaks} 6 | 7 | \title{Estimate shared domain} 8 | 9 | \description{ 10 | For unaligned spectral data, it is often necessary to estimate a suitable shared domain in order to calculate statistical summaries like the mean spectrum. 11 | } 12 | 13 | \usage{ 14 | estimateDomain(xlist, 15 | width = c("median", "min", "max", "mean"), 16 | units = c("relative", "absolute"), 17 | verbose = getCardinalVerbose(), chunkopts = list(), 18 | BPPARAM = getCardinalBPPARAM(), \dots) 19 | 20 | estimateReferenceMz(object, 21 | width = c("median", "min", "max", "mean"), 22 | units = c("ppm", "mz"), 23 | verbose = getCardinalVerbose(), chunkopts = list(), 24 | BPPARAM = getCardinalBPPARAM(), \dots) 25 | 26 | estimateReferencePeaks(object, SNR = 2, 27 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 28 | verbose = getCardinalVerbose(), chunkopts = list(), 29 | BPPARAM = getCardinalBPPARAM(), \dots) 30 | } 31 | 32 | \arguments{ 33 | \item{xlist}{A list of the domain values (e.g., m/z values) for each spectrum.} 34 | 35 | \item{object}{A mass spectral imaging dataset.} 36 | 37 | \item{units}{Should the spacing between domain values use absolute or relative units?} 38 | 39 | \item{width}{How the domain spacing should be estimated from the distribution of resolutions across all spectra.} 40 | 41 | \item{method}{The peak picking method to use. See \code{\link[matter]{findpeaks}} for details.} 42 | 43 | \item{SNR}{The signal-to-noise threshold to use to determine a peak.} 44 | 45 | \item{verbose}{Should progress messages be printed?} 46 | 47 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 48 | 49 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 50 | 51 | \item{\dots}{Options passed to \code{\link{chunkLapply}}.} 52 | } 53 | 54 | \details{ 55 | For \code{estimateDomain}, the domain is estimated by first finding the resolution of each spectrum's individual domain values (e.g., the spacing between m/z values), and then creating a sequence of domain values using (by default) the median resolution of all spectra. 56 | 57 | The \code{estimateReferenceMz} function simply calls \code{estimateDomain} on the appropriate components of a mass spectral imaging dataset to estimate profile m/z bins. 58 | 59 | The \code{estimateReferencePeaks} function calculates the mean spectrum (or looks for a "mean" column in \code{featureData()}) and performs peak picking on the mean spectrum. It can be used to create a set of reference peaks if all relevant peaks appear in the mean spectrum. 60 | } 61 | 62 | \value{ 63 | A vector of domain values, m/z values, or peaks. 64 | } 65 | 66 | \author{ 67 | Kylie A. Bemis 68 | } 69 | 70 | \seealso{ 71 | \code{\link{summarizeFeatures}}, 72 | \code{\link{recalibrate}}, 73 | \code{\link{peakAlign}}, 74 | \code{\link{peakProcess}} 75 | } 76 | 77 | \keyword{utilities} 78 | \keyword{ts} 79 | -------------------------------------------------------------------------------- /R/estimateDomain.R: -------------------------------------------------------------------------------- 1 | 2 | #### Estimate shared domain #### 3 | ## ------------------------------ 4 | 5 | estimateDomain <- function(xlist, 6 | width = c("median", "min", "max", "mean"), 7 | units = c("relative", "absolute"), 8 | verbose = getCardinalVerbose(), chunkopts = list(), 9 | BPPARAM = getCardinalBPPARAM(), ...) 10 | { 11 | units <- match.arg(units) 12 | width <- match.arg(width) 13 | ref <- switch(units, relative="x", absolute="abs") 14 | FUN <- isofun(function(x, ref) { 15 | x <- x[!is.na(x)] 16 | res <- unname(estres(x, ref=ref)) 17 | if ( length(x) > 0 && is.finite(res) ) { 18 | c(min=min(x), max=max(x), res=res) 19 | } else { 20 | c(min=NA_real_, max=NA_real_, res=res) 21 | } 22 | }, CardinalEnv()) 23 | ans <- chunkLapply(xlist, FUN, ref=ref, 24 | verbose=verbose, chunkopts=chunkopts, 25 | BPPARAM=BPPARAM, ...) 26 | ans <- do.call(rbind, ans) 27 | colnames(ans) <- c("min", "max", "res") 28 | from <- floor(min(ans[,"min"], na.rm=TRUE)) 29 | to <- ceiling(max(ans[,"max"], na.rm=TRUE)) 30 | by <- match.fun(width)(ans[,"res"], na.rm=TRUE) 31 | minRelativeRes <- 5e-7 # == 0.5 ppm 32 | minAbsoluteRes <- 1e-4 # == 0.0001 33 | by <- switch(units, 34 | relative=max(minRelativeRes, round(2 * by, digits=6L) * 0.5), 35 | absolute=max(minAbsoluteRes, round(by, digits=4L))) 36 | ans <- switch(units, 37 | relative=seq_rel(from, to, by=by), 38 | absolute=seq.default(from, to, by=by)) 39 | structure(as.vector(ans), 40 | resolution = setNames(by, units)) 41 | } 42 | 43 | estimateReferenceMz <- function(object, 44 | width = c("median", "min", "max", "mean"), 45 | units = c("ppm", "mz"), 46 | verbose = getCardinalVerbose(), chunkopts = list(), 47 | BPPARAM = getCardinalBPPARAM(), ...) 48 | { 49 | if ( length(processingData(object)) > 0L ) 50 | .Warn("queued processing steps will be ignored") 51 | if ( is(object, "MSImagingExperiment") || is(object, "MassDataFrame") ) { 52 | mz(object) 53 | } else if ( is(object, "MSImagingArrays") ) { 54 | units <- match.arg(units) 55 | units <- switch(units, ppm="relative", mz="absolute") 56 | estimateDomain(mz(object), width=width, units=units, 57 | verbose=verbose, chunkopts=chunkopts, 58 | BPPARAM=BPPARAM, ...) 59 | } else { 60 | .Error("can't estimate m/z values for class ", sQuote(class(object))) 61 | } 62 | } 63 | 64 | estimateReferencePeaks <- function(object, SNR = 2, 65 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 66 | verbose = getCardinalVerbose(), chunkopts = list(), 67 | BPPARAM = getCardinalBPPARAM(), ...) 68 | { 69 | if ( length(processingData(object)) > 0L ) 70 | .Warn("queued processing steps will be ignored") 71 | method <- match.arg(method) 72 | if ( is(object, "MSImagingArrays") ) { 73 | object <- convertMSImagingArrays2Experiment(object, 74 | verbose=verbose, chunkopts=chunkopts, 75 | BPPARAM=BPPARAM, ...) 76 | } 77 | object <- summarizeFeatures(object, stat="mean", 78 | verbose=verbose, chunkopts=chunkopts, 79 | BPPARAM=BPPARAM) 80 | featureData <- featureData(object) 81 | peaks <- findpeaks(featureData[["mean"]], noise=method, snr=SNR, ...) 82 | featureData[peaks,,drop=FALSE] 83 | } 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /man/XDataFrame-class.Rd: -------------------------------------------------------------------------------- 1 | \name{XDataFrame-class} 2 | \docType{class} 3 | 4 | \alias{class:XDataFrame} 5 | \alias{XDataFrame} 6 | \alias{XDataFrame-class} 7 | 8 | \alias{class:XDFrame} 9 | \alias{XDFrame} 10 | \alias{XDFrame-class} 11 | 12 | \alias{classNameForDisplay,XDFrame-method} 13 | 14 | \alias{show,XDataFrame-method} 15 | \alias{keys} 16 | \alias{keys<-} 17 | \alias{keys,XDataFrame-method} 18 | \alias{keys<-,XDataFrame-method} 19 | \alias{dropkeys} 20 | \alias{dropkeys,XDataFrame-method} 21 | \alias{names<-,XDataFrame-method} 22 | \alias{cbind,XDataFrame-method} 23 | \alias{rbind,XDataFrame-method} 24 | \alias{coerce,DataFrame,XDataFrame-method} 25 | 26 | \alias{[,XDataFrame,ANY,ANY,ANY-method} 27 | \alias{[<-,XDataFrame,ANY,ANY,ANY-method} 28 | 29 | \alias{[[<-,XDataFrame-method} 30 | \alias{$<-,XDataFrame-method} 31 | 32 | \title{XDataFrame: Extended data frame with key columns} 33 | 34 | \description{ 35 | The \code{XDataFrame} extends the \code{\linkS4class{DataFrame}} class from the \code{S4Vectors} package with support for columns (or sets of columns) designated as keys. 36 | } 37 | 38 | \usage{ 39 | XDataFrame(\dots, keys = list()) 40 | } 41 | 42 | \arguments{ 43 | \item{\dots}{Arguments passed to the \code{DataFrame()}.} 44 | 45 | \item{keys}{A named list of character vectors giving the names of key columns. The names of the list become the names of the keys (which may be different from the columns). The character vectors specify the names of columns that compose that key.} 46 | } 47 | 48 | \details{ 49 | For the most part, \code{XDataFrame} behaves identically to \code{DataFrame}, and key columns can be get or set as usual. 50 | 51 | The \code{XDataFrame} class is primarily intended as a way to enforce additional requirements or constraints on specific sets of columns in a structured way. It provides an abstracted way of manipulating sets of columns that are expected to follow certain rules. The keys remain consistent and accessible even if the columns of the data frame are renamed. 52 | 53 | The base class currently has only minimal requirements for keys (i.e., that they are valid columns in the data frame). Additionally, keys are checked for compatibility when combining data frames. Uniqueness is \emph{not} checked. 54 | 55 | Subclasses can enforce additional constraints on key columns. For example, the \code{\linkS4class{PositionDataFrame}} and \code{\linkS4class{MassDataFrame}} classes. 56 | } 57 | 58 | \section{Methods}{ 59 | \describe{ 60 | \item{\code{keys(object, i = NULL, ..., drop = TRUE)}, \code{keys(object, i = NULL, ...) <- value}:}{Get or set the key columns. By default, this gets or sets the \code{keys} slot. Provide \code{i} to get or set specific keys.} 61 | 62 | \item{\code{dropkeys(object, ...)}:}{Return a \code{\linkS4class{DataFrame}} copy of the object without the key columns.} 63 | } 64 | } 65 | 66 | \author{Kylie A. Bemis} 67 | 68 | \seealso{ 69 | \code{\link{DataFrame}}, 70 | \code{\link{MassDataFrame}}, 71 | \code{\link{PositionDataFrame}} 72 | } 73 | 74 | \examples{ 75 | ## Create an XDataFrame object 76 | XDataFrame(id=1:10, letter=LETTERS[1:10], keys=list(index="id")) 77 | } 78 | 79 | \keyword{classes} 80 | -------------------------------------------------------------------------------- /man/SpectraArrays-class.Rd: -------------------------------------------------------------------------------- 1 | \name{SpectraArrays-class} 2 | \docType{class} 3 | 4 | \alias{class:SpectraArrays} 5 | \alias{SpectraArrays} 6 | \alias{SpectraArrays-class} 7 | 8 | \alias{show,SpectraArrays-method} 9 | \alias{vm_used,SpectraArrays-method} 10 | \alias{fetch,SpectraArrays-method} 11 | \alias{flash,SpectraArrays-method} 12 | \alias{[,SpectraArrays,ANY,ANY,ANY-method} 13 | \alias{[<-,SpectraArrays,ANY,ANY,ANY-method} 14 | \alias{$,SpectraArrays-method} 15 | \alias{$<-,SpectraArrays-method} 16 | \alias{[[,SpectraArrays-method} 17 | \alias{[[<-,SpectraArrays-method} 18 | \alias{names,SpectraArrays-method} 19 | \alias{names<-,SpectraArrays-method} 20 | \alias{length,SpectraArrays-method} 21 | \alias{dim,SpectraArrays-method} 22 | \alias{cbind,SpectraArrays-method} 23 | \alias{rbind,SpectraArrays-method} 24 | \alias{combine,SpectraArrays,ANY-method} 25 | \alias{c,SpectraArrays-method} 26 | \alias{coerce,SpectraArrays,list-method} 27 | \alias{coerce,list,SpectraArrays-method} 28 | \alias{coerce,SpectraArrays,SimpleList-method} 29 | \alias{coerce,SimpleList,SpectraArrays-method} 30 | 31 | \title{SpectraArrays: List of spectra arrays} 32 | 33 | \description{ 34 | The \code{SpectraArrays} class provides a list-like container for spectra arrays of conformable dimensions. 35 | } 36 | 37 | \usage{ 38 | ## Instance creation 39 | SpectraArrays(arrays = SimpleList()) 40 | 41 | ## Additional methods documented below 42 | } 43 | 44 | \arguments{ 45 | \item{arrays}{A list of arrays.} 46 | } 47 | 48 | \details{ 49 | The \code{SpectraArrays} class is intended to be flexible and the arrays do not need to be "array-like" (i.e., have non-NULL \code{dim()}.) One dimensional arrays and lists are allowd. Every array must have the same \code{NROW()} and \code{NCOL()}. 50 | 51 | It supports lossless coercion to and from \code{\linkS4class{SimpleList}}. 52 | } 53 | 54 | \section{Methods}{ 55 | \describe{ 56 | \item{\code{length(object)}:}{Get the number of spectra in the object.} 57 | 58 | \item{\code{names(object)}, \code{names(object) <- value}:}{Get or set the names of spectra arrays in the object.} 59 | 60 | \item{\code{object[[i]]}, \code{object[[i]] <- value}:}{Get or set an array in the object.} 61 | 62 | \item{\code{object[i, j, ..., drop]}:}{Subset as a list or array, depending on the number of dimensions of the stored spectra arrays. The result is the same class as the original object.} 63 | 64 | \item{\code{rbind(...)}, \code{cbind(...)}:}{Combine \code{SpectraArrays} objects by row or column.} 65 | 66 | \item{\code{c(...)}:}{Combine \code{SpectraArrays} objects as lists.} 67 | 68 | \item{\code{fetch(object, \dots)}:}{Pull data arrays into shared memory.} 69 | 70 | \item{\code{flash(object, \dots)}:}{Push data arrays to a temporary file.} 71 | } 72 | } 73 | 74 | \author{Kylie A. Bemis} 75 | 76 | \seealso{ 77 | \code{\linkS4class{SpectralImagingData}}, 78 | \code{\linkS4class{MSImagingArrays}} 79 | } 80 | 81 | \examples{ 82 | set.seed(1, kind="L'Ecuyer-CMRG") 83 | x <- matrix(rlnorm(128), nrow=16, ncol=8) 84 | y <- matrix(rlnorm(128), nrow=16, ncol=8) 85 | 86 | s <- SpectraArrays(list(x=x, y=y)) 87 | 88 | print(s) 89 | } 90 | 91 | \keyword{classes} 92 | -------------------------------------------------------------------------------- /man/writeMSIData.Rd: -------------------------------------------------------------------------------- 1 | \name{writeMSIData} 2 | 3 | \alias{writeMSIData} 4 | 5 | \alias{writeImzML} 6 | \alias{writeImzML,MSImagingExperiment_OR_Arrays-method} 7 | 8 | \alias{writeAnalyze} 9 | \alias{writeAnalyze,MSImagingExperiment-method} 10 | \alias{writeAnalyze,SpectralImagingExperiment-method} 11 | 12 | \title{Write mass spectrometry imaging data files} 13 | 14 | \description{ 15 | Write supported mass spectrometry imaging data files, including imzML and Analyze 7.5. 16 | } 17 | 18 | \usage{ 19 | writeMSIData(object, file, \dots) 20 | 21 | \S4method{writeImzML}{MSImagingExperiment_OR_Arrays}(object, file, bundle = TRUE, 22 | verbose = getCardinalVerbose(), chunkopts = list(), 23 | BPPARAM = getCardinalBPPARAM(), \dots) 24 | 25 | \S4method{writeAnalyze}{MSImagingExperiment}(object, file, 26 | verbose = getCardinalVerbose(), chunkopts = list(), 27 | BPPARAM = getCardinalBPPARAM(), \dots) 28 | 29 | \S4method{writeAnalyze}{SpectralImagingExperiment}(object, file, 30 | verbose = getCardinalVerbose(), chunkopts = list(), 31 | BPPARAM = getCardinalBPPARAM(), \dots) 32 | } 33 | 34 | \arguments{ 35 | \item{object}{A spectral imaging dataset.} 36 | 37 | \item{file}{The absolute or relative file path. The file extension must be included for \code{writeMSIData}.} 38 | 39 | \item{bundle}{Should the ".imzML" and ".ibd" files be bundled into a new directory of the same name?} 40 | 41 | \item{verbose}{Should progress messages be printed?} 42 | 43 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 44 | 45 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 46 | 47 | \item{\dots}{Additional arguments passed to \code{\link[CardinalIO]{writeImzML}} or \code{\link[CardinalIO]{writeAnalyze}}.} 48 | } 49 | \details{ 50 | The \code{writeImzML} function supports writing both the "continuous" and "processed" formats. 51 | 52 | Exporting the experimental metadata to \code{cvParam} tags is lossy, and not all metadata will be preserved. If exporting an object that was originally imported from an imzML file, only metadata that appears in \code{experimentData()} will be preserved when writing. 53 | 54 | Datasets with multiple experimental runs will be merged into a single file. The object's \code{pixelData()} and \code{featureData()} will also be written to tab-delimted files if appropriate. These will be read back in by \code{readImzML()}. 55 | 56 | The imzML files can be modified after writing (such as to add additional experimental metadata) using the Java-based imzMLValidator application: \url{https://gitlab.com/imzML/imzMLValidator/}. 57 | } 58 | 59 | \value{ 60 | \code{TRUE} if the file was written successfully, with the output file paths and data objects attached as attributes. 61 | } 62 | 63 | \author{ 64 | Kylie A. Bemis 65 | } 66 | 67 | \references{ 68 | Schramm T, Hester A, Klinkert I, Both J-P, Heeren RMA, Brunelle A, Laprevote O, Desbenoit N, Robbe M-F, Stoeckli M, Spengler B, Rompp A (2012) imzML - A common data format for the flexible exchange and processing of mass spectrometry imaging data. Journal of Proteomics 75 (16):5106-5110. doi:10.1016/j.jprot.2012.07.026 69 | } 70 | 71 | \seealso{ 72 | \code{\link{readMSIData}} 73 | } 74 | 75 | \keyword{IO} 76 | -------------------------------------------------------------------------------- /man/spatialWeights.Rd: -------------------------------------------------------------------------------- 1 | \name{spatialWeights} 2 | 3 | \alias{spatialWeights} 4 | \alias{spatialWeights,ANY-method} 5 | \alias{spatialWeights,SpectralImagingExperiment-method} 6 | \alias{spatialWeights,PositionDataFrame-method} 7 | 8 | \title{Calculate spatial weights} 9 | 10 | \description{ 11 | Calculate weights for neighboring observations based on either the spatial distance between the neighbors or the dissimilarity between the observations. 12 | } 13 | 14 | \usage{ 15 | \S4method{spatialWeights}{ANY}(x, coord = x, r = 1, byrow = TRUE, 16 | neighbors = findNeighbors(coord, r=r), 17 | weights = c("gaussian", "adaptive"), 18 | sd = ((2 * r) + 1) / 4, matrix = FALSE, 19 | verbose = getCardinalVerbose(), chunkopts = list(), 20 | BPPARAM = getCardinalBPPARAM(), \dots) 21 | 22 | \S4method{spatialWeights}{SpectralImagingExperiment}(x, r = 1, 23 | neighbors = findNeighbors(x, r=r), 24 | weights = c("gaussian", "adaptive"), \dots) 25 | 26 | \S4method{spatialWeights}{PositionDataFrame}(x, r = 1, 27 | neighbors = findNeighbors(x, r=r), 28 | weights = c("gaussian", "adaptive"), \dots) 29 | } 30 | 31 | \arguments{ 32 | \item{x}{Either a matrix or data frame of spatial coordinates, or a data matrix with rows or columns located at the coordinates given by \code{coord}.} 33 | 34 | \item{coord}{The spatial coordinates of the rows/columns of \code{x}. Ignored if \code{neighbors} is provided.} 35 | 36 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor. Ignored if \code{neighbors} is provided.} 37 | 38 | \item{byrow}{If \code{x} is a data matrix, then are the weights calculated based on the dissimilarity between the rows (TRUE) or the columns (FALSE).} 39 | 40 | \item{neighbors}{A list of numeric vectors giving the row or column indices of the spatial neighbors for the rows or columns of \code{x}.} 41 | 42 | \item{weights}{The type of weights to calculate. Either Gaussian weights with a constant standard deviation, or adaptive weights with a standard deviation based on the dissimilarity between the neighboring observations.} 43 | 44 | \item{sd}{The standard deviation for the Gaussian weights. Ignored with \code{weights="adaptive"}.} 45 | 46 | \item{matrix}{Should the weights be returned as a sparse adjacency matrix instead of a list?} 47 | 48 | \item{verbose}{Should progress messages be printed?} 49 | 50 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 51 | 52 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 53 | 54 | \item{\dots}{Additional arguments passed to the next method.} 55 | } 56 | 57 | \value{ 58 | Either a list of weights of neighbors or a sparse adjacency matrix (\code{\linkS4class{sparse_mat}}). 59 | } 60 | 61 | \author{ 62 | Kylie A. Bemis 63 | } 64 | 65 | \seealso{ 66 | \code{\link{findNeighbors}} 67 | } 68 | 69 | \examples{ 70 | set.seed(1, kind="L'Ecuyer-CMRG") 71 | mse <- simulateImage(preset=1, dim=c(10,10)) 72 | 73 | # calculate weights based on distance 74 | spatialWeights(pixelData(mse), r=1) 75 | 76 | # calculate weights based on spectral dissimilarity 77 | spatialWeights(mse, r=1) 78 | } 79 | 80 | \keyword{spatial} 81 | -------------------------------------------------------------------------------- /man/summarize.Rd: -------------------------------------------------------------------------------- 1 | \name{summarizeFeatures} 2 | 3 | \alias{summarizeFeatures} 4 | \alias{summarizePixels} 5 | \alias{rowStats,SpectralImagingExperiment-method} 6 | \alias{colStats,SpectralImagingExperiment-method} 7 | \alias{rowSums,SpectralImagingExperiment-method} 8 | \alias{colSums,SpectralImagingExperiment-method} 9 | \alias{rowMeans,SpectralImagingExperiment-method} 10 | \alias{colMeans,SpectralImagingExperiment-method} 11 | 12 | \title{Summarize a spectral imaging dataset} 13 | 14 | \description{ 15 | Summarizes over the rows or columns of the dataset. 16 | } 17 | 18 | \usage{ 19 | summarizeFeatures(x, stat = "mean", groups = NULL, 20 | verbose = getCardinalVerbose(), chunkopts = list(), 21 | BPPARAM = getCardinalBPPARAM(), \dots) 22 | 23 | summarizePixels(x, stat = c(tic="sum"), groups = NULL, 24 | verbose = getCardinalVerbose(), chunkopts = list(), 25 | BPPARAM = getCardinalBPPARAM(), \dots) 26 | 27 | \S4method{rowStats}{SpectralImagingExperiment}(x, stat, \dots, 28 | verbose = getCardinalVerbose(), chunkopts = list(), 29 | BPPARAM = getCardinalBPPARAM()) 30 | 31 | \S4method{colStats}{SpectralImagingExperiment}(x, stat, \dots, 32 | verbose = getCardinalVerbose(), chunkopts = list(), 33 | BPPARAM = getCardinalBPPARAM()) 34 | 35 | \S4method{rowSums}{SpectralImagingExperiment}(x, na.rm = FALSE, dims = 1, \dots) 36 | 37 | \S4method{colSums}{SpectralImagingExperiment}(x, na.rm = FALSE, dims = 1, \dots) 38 | 39 | \S4method{rowMeans}{SpectralImagingExperiment}(x, na.rm = FALSE, dims = 1, \dots) 40 | 41 | \S4method{colMeans}{SpectralImagingExperiment}(x, na.rm = FALSE, dims = 1, \dots) 42 | } 43 | 44 | \arguments{ 45 | \item{x}{A spectral imaging dataset.} 46 | 47 | \item{stat}{The name of summary statistics to compute over the rows or columns of a matrix. Allowable values include: "min", "max", "prod", "sum", "mean", "var", "sd", "any", "all", and "nnzero".} 48 | 49 | \item{groups}{A vector coercible to a factor giving groups to summarize.} 50 | 51 | \item{na.rm}{If \code{TRUE}, remove \code{NA} values before summarizing.} 52 | 53 | \item{dims}{Ignored.} 54 | 55 | \item{verbose}{Should progress messages be printed?} 56 | 57 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 58 | 59 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 60 | 61 | \item{\dots}{Additional arguments passed to \code{\link[matter]{rowStats}} or \code{\link[matter]{colStats}}, such as the number of chunks.} 62 | } 63 | 64 | \value{ 65 | For \code{summarizeFeatures} and \code{summarizePixels}, an object of the same class as \code{x} with the statistical summaries added as columns in the \code{featureData()} or \code{pixelData()}, respectively. 66 | 67 | For \code{rowStats}, \code{colStats}, etc., a vector, matrix, or array with the summary statistics. 68 | } 69 | 70 | \author{ 71 | Kylie A. Bemis 72 | } 73 | 74 | \examples{ 75 | set.seed(1, kind="L'Ecuyer-CMRG") 76 | mse <- simulateImage(preset=1, npeaks=10, dim=c(10,10)) 77 | 78 | # summarize mean spectrum 79 | mse <- summarizeFeatures(mse, stat="mean") 80 | plot(mse, "mean") 81 | 82 | # summarize total ion current 83 | mse <- summarizePixels(mse, stat=c(TIC="sum")) 84 | image(mse, "TIC") 85 | } 86 | 87 | \keyword{univar} 88 | -------------------------------------------------------------------------------- /tests/testthat/test-SpectralImagingArrays.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("SpectralImagingArrays") 5 | 6 | test_that("SpectralImagingArrays accessors", { 7 | 8 | sa <- SpectralImagingArrays() 9 | 10 | expect_true(validObject(sa)) 11 | 12 | sa <- SpectralImagingArrays(numeric(0)) 13 | 14 | expect_true(validObject(sa)) 15 | 16 | set.seed(1) 17 | n <- 10 18 | i <- rep(list(1:n), n) 19 | a <- replicate(n, rlnorm(n), simplify=FALSE) 20 | s <- SpectraArrays(list(index=i, intensity=a)) 21 | pdata <- PositionDataFrame( 22 | coord=expand.grid(x=1:5, y=1:2), 23 | diagnosis=rep(c("yes", "no"), each=5)) 24 | pdata2 <- PositionDataFrame( 25 | coord=expand.grid(x=1:5, y=3:4), 26 | diagnosis=rep(c("yes", "no"), each=5)) 27 | sa <- SpectralImagingArrays(s, pixelData=pdata) 28 | 29 | expect_true(validObject(sa)) 30 | expect_length(sa, n) 31 | expect_null(dim(sa)) 32 | 33 | expect_equal(spectraData(sa), s) 34 | expect_equal(pixelData(sa), pdata) 35 | 36 | expect_equal(spectra(sa, 1L), s[[1L]]) 37 | expect_equal(spectra(sa, 2L), s[[2L]]) 38 | expect_equal(pData(sa), pdata) 39 | 40 | expect_equal(coord(sa), coord(pdata)) 41 | expect_equal(run(sa), run(pdata)) 42 | expect_equal(pData(sa)$diagnosis, pdata$diagnosis) 43 | 44 | expect_setequal(pixels(sa, 1:10), 1:10) 45 | expect_setequal(pixels(sa, diagnosis == "yes"), 1:5) 46 | expect_setequal(pixels(sa, diagnosis == "no"), 6:10) 47 | expect_setequal(pixels(sa, coord=c(x=3, y=1)), 3) 48 | expect_setequal(pixels(sa, run="run0"), 1:10) 49 | 50 | j <- 1 51 | 52 | expect_setequal(pixels(sa, j), 1) 53 | expect_setequal(pixels(sa, x > 1, y > j), c(7, 8, 9, 10)) 54 | expect_setequal(pixels(sa, coord=c(x=3, y=j)), 3) 55 | 56 | expect_equal(subset(sa, j), sa[j]) 57 | expect_equal(subset(sa, x > 1 & y > j), sa[c(7, 8, 9, 10)]) 58 | expect_equal(subset(sa, x == 3 & y == j), sa[3]) 59 | 60 | pixelData(sa) <- pdata2 61 | 62 | expect_true(validObject(sa)) 63 | expect_equal(pixelData(sa), pdata2) 64 | 65 | coord(sa) <- coord(pdata) 66 | run(sa) <- run(pdata) 67 | 68 | expect_equal(coord(sa), coord(pdata)) 69 | expect_equal(run(sa), run(pdata)) 70 | 71 | sa2 <- sa[2:9] 72 | 73 | expect_true(validObject(sa2)) 74 | expect_equal(length(sa2), 8L) 75 | expect_equal(spectra(sa2, 1L), spectra(sa, 1L)[2:9]) 76 | expect_equal(spectra(sa2, 2L), spectra(sa, 2L)[2:9]) 77 | expect_equal(pixelData(sa2), pixelData(sa)[2:9,]) 78 | 79 | }) 80 | 81 | test_that("SpectralImagingArrays combine", { 82 | 83 | set.seed(1) 84 | n <- 10 85 | i <- rep(list(1:n), n) 86 | a <- replicate(n, rlnorm(n), simplify=FALSE) 87 | s <- SpectraArrays(list(index=i, intensity=a)) 88 | pdata <- PositionDataFrame( 89 | coord=expand.grid(x=1:5, y=1:2), 90 | diagnosis=rep(c("yes", "no"), each=5)) 91 | pdata2 <- PositionDataFrame( 92 | coord=expand.grid(x=1:5, y=3:4), 93 | diagnosis=rep(c("yes", "no"), each=5)) 94 | sa <- SpectralImagingArrays(s, pixelData=pdata) 95 | sa2 <- SpectralImagingArrays(s, pixelData=pdata2) 96 | 97 | sa3 <- c(sa, sa2) 98 | 99 | expect_equal(spectra(sa3, 1L), c(spectra(sa, 1L), spectra(sa2, 1L))) 100 | expect_equal(spectra(sa3, 2L), c(spectra(sa, 2L), spectra(sa2, 2L))) 101 | expect_equal(pData(sa3), rbind(pData(sa), pData(sa2))) 102 | 103 | }) 104 | -------------------------------------------------------------------------------- /R/AllClasses.R: -------------------------------------------------------------------------------- 1 | 2 | #### VIRTUAL class for a DataFrame with key columns #### 3 | ## ----------------------------------------------------- 4 | setClass("XDataFrame", 5 | contains = c("VIRTUAL", "DataFrame"), 6 | slots = c(keys = "list")) 7 | 8 | setClass("XDFrame", contains = c("XDataFrame", "DFrame")) 9 | 10 | #### DataFrame with position information #### 11 | ## ------------------------------------------ 12 | setClass("PositionDataFrame", contains = "XDFrame") 13 | 14 | #### DataFrame with mass-to-charge information #### 15 | ## ------------------------------------------------ 16 | setClass("MassDataFrame", contains = "XDFrame") 17 | 18 | #### List of spectra arrays with array-like subsetting #### 19 | ## --------------------------------------------------------- 20 | 21 | setClass("SpectraArrays", 22 | contains = "Vector", 23 | slots = c(data = "SimpleList")) 24 | 25 | #### VIRTUAL class for spectra-based imaging data #### 26 | ## --------------------------------------------------- 27 | setClass("SpectralImagingData", 28 | contains = c("VIRTUAL", "Vector"), 29 | slots = c( 30 | spectraData = "SpectraArrays", 31 | elementMetadata = "PositionDataFrame", 32 | processing = "list")) 33 | 34 | #### Class for spectra-based imaging arrays #### 35 | ## ---------------------------------------------- 36 | setClassUnion("ImzMeta_OR_NULL", c("ImzMeta", "NULL")) 37 | 38 | setClass("SpectralImagingArrays", 39 | contains = "SpectralImagingData") 40 | 41 | setClass("MSImagingArrays", 42 | contains = "SpectralImagingArrays", 43 | slots = c( 44 | experimentData = "ImzMeta_OR_NULL", 45 | centroided = "logical", 46 | continuous = "logical")) 47 | 48 | #### Class for spectra-based imaging experiments #### 49 | ## -------------------------------------------------- 50 | setClass("SpectralImagingExperiment", 51 | contains = c("RectangularData", "SpectralImagingData"), 52 | slots = c(featureData = "DataFrame")) 53 | 54 | setClass("MSImagingExperiment", 55 | contains = "SpectralImagingExperiment", 56 | slots = c( 57 | featureData = "MassDataFrame", 58 | experimentData = "ImzMeta_OR_NULL", 59 | centroided = "logical")) 60 | 61 | #### Class union for MS-based imaging experiments #### 62 | ## ---------------------------------------------------- 63 | setClassUnion("MSImagingExperiment_OR_Arrays", 64 | c("MSImagingExperiment", "MSImagingArrays")) 65 | 66 | #### Class for spatially-aware analysis results #### 67 | ## ------------------------------------------------- 68 | 69 | setClass("ResultsList", contains = "SimpleList") 70 | 71 | setClass("SpatialResults", 72 | contains = "Annotated", 73 | slots = c( 74 | model = "ANY", 75 | featureData = "DataFrame_OR_NULL", 76 | pixelData = "PositionDataFrame")) 77 | 78 | setClass("SpatialCV", contains="SpatialResults") 79 | setClass("SpatialNMF", contains="SpatialResults") 80 | setClass("SpatialPCA", contains="SpatialResults") 81 | setClass("SpatialPLS", contains="SpatialResults") 82 | setClass("SpatialOPLS", contains="SpatialResults") 83 | setClass("SpatialFastmap", contains="SpatialResults") 84 | setClass("SpatialKMeans", contains="SpatialResults") 85 | setClass("SpatialShrunkenCentroids", contains="SpatialResults") 86 | setClass("SpatialDGMM", contains="SpatialResults") 87 | setClass("MeansTest", contains="ResultsList") 88 | setClass("SegmentationTest", contains="ResultsList") 89 | setClass("ContrastTest", contains="ResultsList") 90 | -------------------------------------------------------------------------------- /man/spatialDists.Rd: -------------------------------------------------------------------------------- 1 | \name{spatialDists} 2 | 3 | \alias{spatialDists} 4 | \alias{spatialDists,ANY-method} 5 | \alias{spatialDists,SpectralImagingExperiment-method} 6 | \alias{spatialDists,PositionDataFrame-method} 7 | 8 | \title{Calculate spatially-smoothed distances} 9 | 10 | \description{ 11 | Calculate distances between observations with smoothing based on their spatial structure. 12 | } 13 | 14 | \usage{ 15 | \S4method{spatialDists}{ANY}(x, y, coord, r = 1, byrow = TRUE, 16 | metric = "euclidean", p = 2, weights = NULL, 17 | neighbors = findNeighbors(coord, r=r), 18 | neighbors.weights = spatialWeights(coord, r=r), 19 | verbose = getCardinalVerbose(), chunkopts = list(), 20 | BPPARAM = getCardinalBPPARAM(), \dots) 21 | 22 | \S4method{spatialDists}{SpectralImagingExperiment}(x, y, r = 1, 23 | neighbors = findNeighbors(x, r=r), 24 | neighbors.weights = spatialWeights(x, r=r), \dots) 25 | 26 | \S4method{spatialDists}{PositionDataFrame}(x, y, r = 1, 27 | neighbors = findNeighbors(x, r=r), 28 | neighbors.weights = spatialWeights(x, r=r), ...) 29 | } 30 | 31 | \arguments{ 32 | \item{x}{A data matrix with rows or columns located at the coordinates given by \code{coord}.} 33 | 34 | \item{y}{A data matrix from which to calculate distances with the observations in \code{x}.} 35 | 36 | \item{coord}{The spatial coordinates of the rows/columns of \code{x}. Ignored if \code{neighbors} is provided.} 37 | 38 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor. Ignored if \code{neighbors} is provided.} 39 | 40 | \item{byrow}{Are the distances calculated based on the dissimilarity between the rows (TRUE) or the columns (FALSE) of \code{x} and \code{y}.} 41 | 42 | \item{metric}{Distance metric to use when finding the nearest neighbors. Supported metrics include "euclidean", "maximum", "manhattan", and "minkowski".} 43 | 44 | \item{p}{The power for the Minkowski distance.} 45 | 46 | \item{weights}{A numeric vector of \emph{feature} weights for the distance components if calculating weighted distances. For example, the weighted Euclidean distance is \code{sqrt(sum(w * (x - y)^2))}.} 47 | 48 | \item{neighbors}{A list of numeric vectors giving the row or column indices of the spatial neighbors for the rows or columns of \code{x}.} 49 | 50 | \item{neighbors.weights}{A list of numeric vectors giving the spatial weights corresponding to \code{neighbors}.} 51 | 52 | \item{verbose}{Should progress messages be printed?} 53 | 54 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 55 | 56 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 57 | 58 | \item{\dots}{Additional arguments passed to the next method.} 59 | } 60 | 61 | \value{ 62 | A matrix of distances with rows equal to the number of observations in \code{x} and columns equal to the number of observations in \code{y}. 63 | } 64 | 65 | \author{ 66 | Kylie A. Bemis 67 | } 68 | 69 | \seealso{ 70 | \code{\link{findNeighbors}}, 71 | \code{\link{spatialWeights}} 72 | } 73 | 74 | \examples{ 75 | set.seed(1, kind="L'Ecuyer-CMRG") 76 | mse <- simulateImage(preset=1, dim=c(10,10)) 77 | 78 | # calculate spatially-aware distances from first 5 spectra 79 | spatialDists(mse, spectra(mse)[,1:5], r=1) 80 | } 81 | 82 | \keyword{spatial} 83 | -------------------------------------------------------------------------------- /man/bin.Rd: -------------------------------------------------------------------------------- 1 | \name{bin} 2 | 3 | \alias{bin} 4 | \alias{bin,MSImagingExperiment-method} 5 | \alias{bin,MSImagingArrays-method} 6 | \alias{bin,SpectralImagingExperiment-method} 7 | \alias{bin,SpectralImagingArrays-method} 8 | 9 | \title{Bin spectra} 10 | 11 | \description{ 12 | Apply on-the-fly binning to spectra. 13 | } 14 | 15 | \usage{ 16 | \S4method{bin}{MSImagingExperiment}(x, ref, 17 | spectra = "intensity", index = "mz", 18 | method = c("sum", "mean", "max", "min", 19 | "linear", "cubic", "gaussian", "lanczos"), 20 | resolution = NA, tolerance = NA, units = c("ppm", "mz"), 21 | mass.range = NULL, \dots) 22 | 23 | \S4method{bin}{MSImagingArrays}(x, ref, 24 | spectra = "intensity", index = "mz", 25 | method = c("sum", "mean", "max", "min", 26 | "linear", "cubic", "gaussian", "lanczos"), 27 | resolution = NA, tolerance = NA, units = c("ppm", "mz"), 28 | mass.range = NULL, \dots) 29 | 30 | \S4method{bin}{SpectralImagingExperiment}(x, ref, 31 | spectra = "intensity", index = NULL, 32 | method = c("sum", "mean", "max", "min", 33 | "linear", "cubic", "gaussian", "lanczos"), 34 | resolution = NA, tolerance = NA, units = c("relative", "absolute"), 35 | verbose = getCardinalVerbose(), \dots) 36 | 37 | \S4method{bin}{SpectralImagingArrays}(x, ref, 38 | spectra = "intensity", index = NULL, 39 | method = c("sum", "mean", "max", "min", 40 | "linear", "cubic", "gaussian", "lanczos"), 41 | resolution = NA, tolerance = NA, units = c("relative", "absolute"), 42 | verbose = getCardinalVerbose(), \dots) 43 | } 44 | 45 | \arguments{ 46 | \item{x}{A spectral imaging dataset.} 47 | 48 | \item{ref}{Optional. The bin centers, or their range if \code{resolution} is specified. Created from \code{resolution} if not provided.} 49 | 50 | \item{spectra}{The name of the array in \code{spectraData()} to bin.} 51 | 52 | \item{index}{The name of the array in \code{spectraData()} (for \code{SpectralImagingArrays}) or column in \code{featureData()} (for \code{SpectralImagingExperiment}) to use for the bins.} 53 | 54 | \item{method}{The peak picking method to use. See \code{\link[matter]{approx1}} for details.} 55 | 56 | \item{resolution}{The spacing between bin centers. If \code{tolerance} is not provided, then this is also used to calculate the bin width.} 57 | 58 | \item{tolerance}{The half-bin width.} 59 | 60 | \item{units}{The units for the above resolution.} 61 | 62 | \item{mass.range}{An alternative way of specifying the mass range (replaces the value of \code{ref}).} 63 | 64 | \item{verbose}{Should progress messages be printed?} 65 | 66 | \item{\dots}{Ignored.} 67 | } 68 | 69 | \details{ 70 | The binning is applied but not processed immediately. It is performed on-the-fly whenever the spectra are accessed. 71 | } 72 | 73 | \value{ 74 | A new object derived from \code{SpectralImagingExperiment} with the binned spectra. 75 | } 76 | 77 | \author{ 78 | Kylie A. Bemis 79 | } 80 | 81 | \seealso{ 82 | \code{\link[matter]{approx1}}, 83 | \code{\link{estimateDomain}}, 84 | \code{\link{estimateReferenceMz}} 85 | } 86 | 87 | \examples{ 88 | set.seed(1, kind="L'Ecuyer-CMRG") 89 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 90 | 91 | # bin to unit resolution 92 | mse2 <- bin(mse, resolution=1, units="mz") 93 | 94 | # bin to a specific range and resolution 95 | mse3 <- bin(mse, ref=c(800, 1000), resolution=1, units="mz") 96 | } 97 | 98 | \keyword{ts} 99 | -------------------------------------------------------------------------------- /man/SpectralImagingArrays-class.Rd: -------------------------------------------------------------------------------- 1 | \name{SpectralImagingArrays-class} 2 | \docType{class} 3 | 4 | \alias{class:SpectralImagingArrays} 5 | \alias{SpectralImagingArrays} 6 | \alias{SpectralImagingArrays-class} 7 | 8 | \alias{show,SpectralImagingArrays-method} 9 | \alias{names,SpectralImagingArrays-method} 10 | \alias{names<-,SpectralImagingArrays-method} 11 | \alias{length,SpectralImagingArrays-method} 12 | \alias{[,SpectralImagingArrays,ANY,ANY,ANY-method} 13 | \alias{[<-,SpectralImagingArrays,ANY,ANY,ANY-method} 14 | \alias{dim,SpectralImagingArrays-method} 15 | \alias{cbind,SpectralImagingArrays-method} 16 | \alias{rbind,SpectralImagingArrays-method} 17 | \alias{combine,SpectralImagingArrays,ANY-method} 18 | \alias{c,SpectralImagingArrays-method} 19 | 20 | \title{SpectralImagingArrays: Spectral imaging data with arbitrary domain} 21 | 22 | \description{ 23 | The \code{SpectralImagingArrays} class provides a list-like container for high-dimensional spectral imaging data where every spectrum may have its own domain values. It is designed to provide easy access to raw individual spectra, but images cannot be easily reconstructed. 24 | 25 | The \code{\linkS4class{MSImagingArrays}} class extends \code{SpectralImagingArrays} for mass spectrometry-based imaging experiments with unaligned mass features. 26 | } 27 | 28 | \usage{ 29 | ## Instance creation 30 | SpectralImagingArrays(spectraData = SimpleList(), 31 | pixelData = PositionDataFrame(), metadata = list()) 32 | 33 | ## Additional methods documented below 34 | } 35 | 36 | \arguments{ 37 | \item{spectraData}{Either a list-like object with lists of individual spectra and lists of their domain values, or a \code{\linkS4class{SpectraArrays}} instance.} 38 | 39 | \item{pixelData}{A \code{\linkS4class{PositionDataFrame}} with pixel metadata, with a row for each spectrum.} 40 | 41 | \item{metadata}{A \code{list} with experimental-level metadata.} 42 | } 43 | 44 | \section{Slots}{ 45 | \describe{ 46 | \item{\code{spectraData}:}{A \code{\linkS4class{SpectraArrays}} object storing one or more array-like data elements with conformable dimensions.} 47 | 48 | \item{\code{elementMetadata}:}{A \code{\linkS4class{PositionDataFrame}} containing spectrum-level metadata, including each spectrum's pixel coordinates and experimental run information.} 49 | 50 | \item{\code{processing}:}{A list containing unexecuted \code{\linkS4class{ProcessingStep}} objects.} 51 | } 52 | } 53 | 54 | \section{Methods}{ 55 | All methods for \code{\linkS4class{SpectralImagingData}} also work on \code{SpectralImagingArrays} objects. Additional methods are documented below: 56 | 57 | \describe{ 58 | \item{\code{length(object)}:}{Get the number of spectra in the object.} 59 | 60 | \item{\code{object[i, ..., drop]}:}{Subset as a list based on the spectra. The result is the same class as the original object.} 61 | 62 | \item{\code{rbind(...)}, \code{cbind(...)}:}{Combine \code{SpectralImagingArrays} objects by row or column.} 63 | } 64 | } 65 | 66 | \author{Kylie A. Bemis} 67 | 68 | \seealso{ 69 | \code{\linkS4class{SpectralImagingData}}, 70 | \code{\linkS4class{MSImagingArrays}} 71 | } 72 | 73 | \examples{ 74 | set.seed(1, kind="L'Ecuyer-CMRG") 75 | x <- replicate(9, rlnorm(10), simplify=FALSE) 76 | t <- replicate(9, sort(runif(10)), simplify=FALSE) 77 | coord <- expand.grid(x=1:3, y=1:3) 78 | 79 | sa <- SpectralImagingArrays( 80 | spectraData=list(intensity=x, wavelength=t), 81 | pixelData=PositionDataFrame(coord)) 82 | 83 | print(sa) 84 | } 85 | 86 | \keyword{classes} 87 | -------------------------------------------------------------------------------- /tests/testthat/test-spectrapply.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("spectrapply") 5 | 6 | test_that("spectrapply - SpectralImagingArrays", { 7 | 8 | set.seed(1, kind="default") 9 | x <- replicate(9, rlnorm(100), simplify=FALSE) 10 | t1 <- replicate(9, sort(runif(100)), simplify=FALSE) 11 | t2 <- replicate(9, sort(runif(100)), simplify=FALSE) 12 | t3 <- replicate(9, sort(runif(100)), simplify=FALSE) 13 | 14 | sa <- SpectralImagingArrays( 15 | spectraData=list(x=x, t1=t1, t2=t2, t3=t3), 16 | pixelData=PositionDataFrame(expand.grid(x=1:3, y=1:3))) 17 | 18 | xout <- spectrapply(sa, 19 | FUN=function(x, t1, ...) x, 20 | spectra="x", index=c("t1", "t2"), 21 | simplify=FALSE) 22 | 23 | t1out <- spectrapply(sa, 24 | FUN=function(x, t1, ...) t1, 25 | spectra="x", index="t1", 26 | simplify=FALSE) 27 | 28 | expect_equal(spectra(sa, "x"), xout) 29 | expect_equal(spectra(sa, "t1"), t1out) 30 | 31 | xout <- spectrapply(sa, 32 | FUN=function(x, t1, t2, ...) x, 33 | spectra="x", index=c("t1", "t2"), 34 | simplify=FALSE) 35 | 36 | t1out <- spectrapply(sa, 37 | FUN=function(x, t1, t2, ...) t1, 38 | spectra="x", index=c("t1", "t2"), 39 | simplify=FALSE) 40 | 41 | t2out <- spectrapply(sa, 42 | FUN=function(x, t1, t2, ...) t2, 43 | spectra="x", index=c("t1", "t2"), 44 | simplify=FALSE) 45 | 46 | expect_equal(spectra(sa, "x"), xout) 47 | expect_equal(spectra(sa, "t1"), t1out) 48 | expect_equal(spectra(sa, "t2"), t2out) 49 | 50 | xout <- spectrapply(sa, 51 | FUN=function(x, t1, t2, t3, ...) x, 52 | spectra="x", index=c("t1", "t2", "t3"), 53 | simplify=FALSE) 54 | 55 | t1out <- spectrapply(sa, 56 | FUN=function(x, t1, t2, t3, ...) t1, 57 | spectra="x", index=c("t1", "t2", "t3"), 58 | simplify=FALSE) 59 | 60 | t2out <- spectrapply(sa, 61 | FUN=function(x, t1, t2, t3, ...) t2, 62 | spectra="x", index=c("t1", "t2", "t3"), 63 | simplify=FALSE) 64 | 65 | t3out <- spectrapply(sa, 66 | FUN=function(x, t1, t2, t3, ...) t3, 67 | spectra="x", index=c("t1", "t2", "t3"), 68 | simplify=FALSE) 69 | 70 | expect_equal(spectra(sa, "x"), xout) 71 | expect_equal(spectra(sa, "t1"), t1out) 72 | expect_equal(spectra(sa, "t2"), t2out) 73 | expect_equal(spectra(sa, "t3"), t3out) 74 | 75 | }) 76 | 77 | test_that("spectrapply - SpectralImagingExperiment", { 78 | 79 | set.seed(1, kind="default") 80 | x <- replicate(9, rlnorm(100), simplify=TRUE) 81 | t <- sort(runif(100)) 82 | 83 | se <- SpectralImagingExperiment( 84 | spectraData=list(x=x), 85 | featureData=DataFrame(t=t), 86 | pixelData=PositionDataFrame(expand.grid(x=1:3, y=1:3))) 87 | 88 | xout <- spectrapply(se, 89 | FUN=function(x, t, ...) x, 90 | spectra="x", index="t", 91 | simplify=TRUE) 92 | 93 | tout <- spectrapply(se, 94 | FUN=function(x, t, ...) t, 95 | spectra="x", index="t", 96 | simplify=TRUE) 97 | 98 | expect_equal(spectra(se, "x"), xout) 99 | expect_equal(featureData(se)$t, tout[,1]) 100 | 101 | }) 102 | 103 | test_that("spectrapply - MSImagingArrays", { 104 | 105 | path <- CardinalIO::exampleImzMLFile("processed") 106 | msa <- readImzML(path, memory=TRUE) 107 | 108 | tic <- spectrapply(msa, sum) 109 | 110 | expect_equal(tic, sapply(intensity(msa), sum)) 111 | 112 | }) 113 | 114 | test_that("spectrapply - MSImagingExperiment", { 115 | 116 | path <- CardinalIO::exampleImzMLFile("continuous") 117 | mse <- readImzML(path, memory=TRUE) 118 | 119 | tic <- spectrapply(mse, sum) 120 | 121 | expect_equal(tic, apply(spectra(mse), 2L, sum)) 122 | 123 | }) 124 | -------------------------------------------------------------------------------- /tests/testthat/test-bin.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("binning") 5 | 6 | test_that("bin - SpectralImagingArrays", { 7 | 8 | path <- CardinalIO::exampleImzMLFile("processed") 9 | s <- as(readImzML(path), "SpectralImagingArrays") 10 | 11 | s2 <- bin(s, units="relative") 12 | s3 <- bin(s, units="absolute") 13 | 14 | expect_is(s2, "SpectralImagingExperiment") 15 | expect_is(s3, "SpectralImagingExperiment") 16 | expect_is(spectra(s2), "sparse_mat") 17 | expect_is(spectra(s3), "sparse_mat") 18 | expect_equal(fData(s3)$index, seq_len(8399)) 19 | 20 | s4 <- bin(s, ref=fData(s3)$index, units="absolute") 21 | s5 <- bin(s, ref=c(100, 500), resolution=1, units="absolute") 22 | 23 | expect_equal(s4, s3) 24 | expect_equal(range(fData(s5)$index), c(100, 500)) 25 | expect_equal(matter::estres(fData(s5)$index), c(absolute=1)) 26 | 27 | s6 <- bin(s, ref=c(100, 500), tolerance=1, units="absolute") 28 | 29 | expect_equal(fData(s6)$index, c(100, 500)) 30 | expect_equivalent(tolerance(spectra(s6)), 1) 31 | 32 | }) 33 | 34 | test_that("bin - SpectralImagingExperiment", { 35 | 36 | path <- CardinalIO::exampleImzMLFile("continuous") 37 | s <- as(readImzML(path), "SpectralImagingExperiment") 38 | 39 | s2 <- bin(s, units="relative") 40 | s3 <- bin(s, units="absolute") 41 | 42 | expect_is(s2, "SpectralImagingExperiment") 43 | expect_is(s3, "SpectralImagingExperiment") 44 | expect_is(spectra(s2), "sparse_mat") 45 | expect_is(spectra(s3), "sparse_mat") 46 | expect_equal(fData(s3)$index, seq_len(8399)) 47 | 48 | s4 <- bin(s, ref=fData(s3)$index, units="absolute") 49 | s5 <- bin(s, ref=c(100, 500), resolution=1, units="absolute") 50 | 51 | expect_equal(s4, s3) 52 | expect_equal(range(fData(s5)$index), c(100, 500)) 53 | expect_equal(matter::estres(fData(s5)$index), c(absolute=1)) 54 | 55 | s6 <- bin(s, ref=c(100, 500), tolerance=1, units="absolute") 56 | 57 | expect_equal(fData(s6)$index, c(100, 500)) 58 | expect_equivalent(tolerance(spectra(s6)), 1) 59 | 60 | }) 61 | 62 | test_that("bin - MSImagingArrays", { 63 | 64 | path <- CardinalIO::exampleImzMLFile("processed") 65 | ms <- readImzML(path) 66 | 67 | ms2 <- bin(ms, units="ppm") 68 | ms3 <- bin(ms, units="mz") 69 | ms4 <- bin(ms, resolution=1, units="mz") 70 | ms5 <- bin(ms, mass.range=c(200, 600), resolution=1, units="mz") 71 | ms6 <- bin(ms, ref=152.9, tolerance=50, units="ppm") 72 | 73 | expect_is(ms2, "MSImagingExperiment") 74 | expect_is(ms3, "MSImagingExperiment") 75 | expect_is(spectra(ms2), "sparse_mat") 76 | expect_is(spectra(ms3), "sparse_mat") 77 | expect_equal(mz(ms4), 100:800) 78 | expect_equal(mz(ms5), 200:600) 79 | expect_equal(mz(ms6), 152.9) 80 | expect_equivalent(tolerance(spectra(ms6)), 5e-5) 81 | 82 | expect_error(bin(ms, mass.range=c(200, 600))) 83 | 84 | }) 85 | 86 | test_that("bin - MSImagingExperiment", { 87 | 88 | path <- CardinalIO::exampleImzMLFile("continuous") 89 | ms <- readImzML(path) 90 | 91 | ms2 <- bin(ms, units="ppm") 92 | ms3 <- bin(ms, units="mz") 93 | ms4 <- bin(ms, resolution=1, units="mz") 94 | ms5 <- bin(ms, mass.range=c(200, 600), resolution=1, units="mz") 95 | ms6 <- bin(ms, ref=152.9, tolerance=50, units="ppm") 96 | 97 | expect_is(ms2, "MSImagingExperiment") 98 | expect_is(ms3, "MSImagingExperiment") 99 | expect_is(spectra(ms2), "sparse_mat") 100 | expect_is(spectra(ms3), "sparse_mat") 101 | expect_equal(mz(ms4), 100:800) 102 | expect_equal(mz(ms5), 200:600) 103 | expect_equal(mz(ms6), 152.9) 104 | expect_equivalent(tolerance(spectra(ms6)), 5e-5) 105 | 106 | expect_error(bin(ms, mass.range=c(200, 600))) 107 | 108 | }) 109 | -------------------------------------------------------------------------------- /R/spectrapply.R: -------------------------------------------------------------------------------- 1 | 2 | #### Row/column apply #### 3 | ## ------------------------ 4 | 5 | setMethod("spectrapply", "SpectralImagingExperiment", 6 | function(object, FUN, ..., 7 | spectra = "intensity", index = NULL, 8 | simplify = TRUE, outpath = NULL, 9 | verbose = getCardinalVerbose(), chunkopts = list(), 10 | BPPARAM = getCardinalBPPARAM()) 11 | { 12 | if ( length(processingData(object)) > 0L ) 13 | .Warn("queued processing steps will be ignored") 14 | if ( length(index) > 1L ) 15 | .Error("more than 1 'index' array not allowed ", 16 | "for class ", sQuote(class(object)[1L])) 17 | nindex <- max(0L, length(index)) 18 | snm <- spectra 19 | inm <- index 20 | spectra <- spectra(object, snm) 21 | if ( !is.null(index) ) { 22 | index <- featureData(object)[[inm[1L]]] 23 | if ( is.null(index) ) 24 | .Error("index ", sQuote(inm[1L]), " not found") 25 | } 26 | if ( ...length() > 0L && is.null(...names()) ) 27 | .Error("spectrapply() arguments passed via ... must be named") 28 | if ( nindex == 0L ) { 29 | chunkApply(spectra, 2L, FUN, ..., 30 | simplify=simplify, outpath=outpath, 31 | verbose=verbose, chunkopts=chunkopts, 32 | BPPARAM=BPPARAM) 33 | } else { 34 | chunkApply(spectra, 2L, FUN, index, ..., 35 | simplify=simplify, outpath=outpath, 36 | verbose=verbose, chunkopts=chunkopts, 37 | BPPARAM=BPPARAM) 38 | } 39 | }) 40 | 41 | setMethod("spectrapply", "SpectralImagingArrays", 42 | function(object, FUN, ..., 43 | spectra = "intensity", index = NULL, 44 | simplify = TRUE, outpath = NULL, 45 | verbose = getCardinalVerbose(), chunkopts = list(), 46 | BPPARAM = getCardinalBPPARAM()) 47 | { 48 | if ( length(processingData(object)) > 0L ) 49 | .Warn("queued processing steps will be ignored") 50 | if ( length(index) > 3L ) 51 | .Error("more than 3 'index' arrays not allowed ", 52 | "for class ", sQuote(class(object)[1L])) 53 | nindex <- max(0L, length(index)) 54 | snm <- spectra 55 | inm <- index 56 | spectra <- spectra(object, snm) 57 | if ( !is.null(index) ) { 58 | index <- spectra(object, inm[1L]) 59 | if ( is.null(index) ) 60 | .Error("index ", sQuote(inm[1L]), " not found") 61 | if ( nindex >= 2L ) { 62 | index2 <- spectra(object, inm[2L]) 63 | if ( is.null(index2) ) 64 | .Error("index ", sQuote(inm[2L]), " not found") 65 | } 66 | if ( nindex >= 3L ) { 67 | index3 <- spectra(object, inm[3L]) 68 | if ( is.null(index2) ) 69 | .Error("index ", sQuote(inm[3L]), " not found") 70 | } 71 | } 72 | if ( ...length() > 0L && is.null(...names()) ) 73 | .Error("spectrapply() arguments passed via ... must be named") 74 | if ( nindex == 0L ) { 75 | chunkLapply(spectra, FUN, ..., 76 | simplify=simplify, outpath=outpath, 77 | verbose=verbose, chunkopts=chunkopts, 78 | BPPARAM=BPPARAM) 79 | } else { 80 | args <- list(...) 81 | if ( nindex == 1L ) { 82 | chunkMapply(FUN, spectra, index, MoreArgs=args, 83 | simplify=simplify, outpath=outpath, 84 | verbose=verbose, chunkopts=chunkopts, 85 | BPPARAM=BPPARAM) 86 | } else if ( nindex == 2L ) { 87 | chunkMapply(FUN, spectra, index, index2, MoreArgs=args, 88 | simplify=simplify, outpath=outpath, 89 | verbose=verbose, chunkopts=chunkopts, 90 | BPPARAM=BPPARAM) 91 | } else if ( nindex == 3L ) { 92 | chunkMapply(FUN, spectra, index, index2, index3, MoreArgs=args, 93 | simplify=simplify, outpath=outpath, 94 | verbose=verbose, chunkopts=chunkopts, 95 | BPPARAM=BPPARAM) 96 | } else { 97 | .Error("too many 'index' arrays") 98 | } 99 | } 100 | }) 101 | 102 | -------------------------------------------------------------------------------- /man/deprecated.Rd: -------------------------------------------------------------------------------- 1 | \name{deprecated} 2 | \alias{deprecated} 3 | 4 | % legacy classes 5 | 6 | \alias{class:Hashmat} 7 | \alias{Hashmat} 8 | \alias{Hashmat-class} 9 | 10 | \alias{class:IAnnotatedDataFrame} 11 | \alias{IAnnotatedDataFrame} 12 | \alias{IAnnotatedDataFrame-class} 13 | 14 | \alias{class:ImageData} 15 | \alias{ImageData} 16 | \alias{ImageData-class} 17 | 18 | \alias{class:iSet} 19 | \alias{iSet} 20 | \alias{iSet-class} 21 | 22 | \alias{class:MIAPE-Imaging} 23 | \alias{MIAPE-Imaging} 24 | \alias{MIAPE-Imaging-class} 25 | 26 | \alias{class:MSImageData} 27 | \alias{MSImageData} 28 | \alias{MSImageData-class} 29 | 30 | \alias{class:MSImageProcess} 31 | \alias{MSImageProcess} 32 | \alias{MSImageProcess-class} 33 | 34 | \alias{class:MSImageSet} 35 | \alias{MSImageSet} 36 | \alias{MSImageSet-class} 37 | 38 | \alias{class:ResultSet} 39 | \alias{ResultSet} 40 | \alias{ResultSet-class} 41 | 42 | \alias{class:SImageData} 43 | \alias{SImageData} 44 | \alias{SImageData-class} 45 | 46 | \alias{class:SImageSet} 47 | \alias{SImageSet} 48 | \alias{SImageSet-class} 49 | 50 | % deprecated and defunct 51 | 52 | \alias{alpha.colors} 53 | \alias{bw.colors} 54 | \alias{col.map} 55 | \alias{color.map} 56 | \alias{darkmode} 57 | \alias{discrete.colors} 58 | \alias{divergent.colors} 59 | \alias{gradient.colors} 60 | \alias{intensity.colors} 61 | \alias{jet.colors} 62 | \alias{lightmode} 63 | \alias{risk.colors} 64 | 65 | \alias{baselineReduction} 66 | \alias{baselineReduction<-} 67 | \alias{cvApply} 68 | \alias{gridded} 69 | \alias{gridded<-} 70 | \alias{height} 71 | \alias{height<-} 72 | \alias{instrumentVendor} 73 | \alias{intensityData} 74 | \alias{intensityData<-} 75 | \alias{ionizationType} 76 | \alias{is3D} 77 | \alias{lineScanDirection} 78 | \alias{massAnalyzerType} 79 | \alias{matrixApplication} 80 | \alias{msiInfo} 81 | \alias{mzData} 82 | \alias{mzData<-} 83 | \alias{normalization} 84 | \alias{normalization<-} 85 | \alias{peakBin} 86 | \alias{peakData} 87 | \alias{peakData<-} 88 | \alias{peakPicking} 89 | \alias{peakPicking<-} 90 | \alias{pixelSize} 91 | \alias{resolution} 92 | \alias{resolution<-} 93 | \alias{resultData} 94 | \alias{resultData<-} 95 | \alias{resultNames} 96 | \alias{resultNames<-} 97 | \alias{scanDirection} 98 | \alias{scanPattern} 99 | \alias{scanPolarity} 100 | \alias{scanType} 101 | \alias{smoothing} 102 | \alias{smoothing<-} 103 | \alias{spectrumRepresentation} 104 | \alias{spectrumRepresentation<-} 105 | 106 | \alias{simulateSpectrum} 107 | 108 | \alias{aggregate,SpectralImagingExperiment-method} 109 | \alias{featureApply} 110 | \alias{featureApply,SpectralImagingExperiment-method} 111 | \alias{iData} 112 | \alias{iData<-} 113 | \alias{iData,ANY-method} 114 | \alias{iData<-,ANY-method} 115 | \alias{mzAlign} 116 | \alias{mzAlign,MSImagingExperiment,missing-method} 117 | \alias{mzAlign,MSImagingExperiment,numeric-method} 118 | \alias{mzBin} 119 | \alias{mzBin,MSImagingExperiment,missing-method} 120 | \alias{mzBin,MSImagingExperiment,numeric-method} 121 | \alias{mzFilter} 122 | \alias{mzFilter,MSImagingExperiment-method} 123 | \alias{peakFilter} 124 | \alias{peakFilter,MSImagingExperiment-method} 125 | \alias{pixelApply} 126 | \alias{pixelApply,SpectralImagingExperiment-method} 127 | \alias{smoothSignal} 128 | \alias{smoothSignal,SpectralImagingExperiment-method} 129 | \alias{spatialApply} 130 | \alias{spatialApply,SpectralImagingExperiment-method} 131 | 132 | \alias{slice} 133 | 134 | \alias{setCardinalNumBlocks} 135 | \alias{getCardinalNumBlocks} 136 | 137 | \title{Deprecated and defunct objects in Cardinal} 138 | 139 | \description{ 140 | These functions are provided for compatibility with older versions of Cardinal, and will be removed in the future. 141 | } 142 | -------------------------------------------------------------------------------- /R/stats-spatialFastmap.R: -------------------------------------------------------------------------------- 1 | 2 | #### Spatially-aware FastMap #### 3 | ## ------------------------------ 4 | 5 | setMethod("spatialFastmap", "ANY", 6 | function(x, coord, r = 1, ncomp = 3, 7 | weights = c("gaussian", "adaptive"), 8 | neighbors = findNeighbors(coord, r=r), 9 | transpose = TRUE, niter = 10L, 10 | verbose = getCardinalVerbose(), chunkopts = list(), 11 | BPPARAM = getCardinalBPPARAM(), ...) 12 | { 13 | if ( "method" %in% ...names() ) { 14 | .Deprecated(old="method", new="weights") 15 | weights <- list(...)$method 16 | } 17 | if ( is.character(weights) ) { 18 | weights <- match.arg(weights) 19 | .Log("computing ", weights, " weights", 20 | message=verbose) 21 | nbwts <- spatialWeights(x=x, 22 | coord=coord, r=r, byrow=!transpose, 23 | weights=weights, neighbors=neighbors, 24 | verbose=verbose, chunkopts=chunkopts, 25 | BPPARAM=BPPARAM) 26 | } else { 27 | .Log("using custom weights", 28 | message=verbose) 29 | nbwts <- rep_len(weights, length(neighbors)) 30 | weights <- "custom" 31 | } 32 | if ( transpose ) { 33 | distfun <- .spatialColDists 34 | } else { 35 | distfun <- .spatialRowDists 36 | } 37 | ncomp <- min(ncomp, dim(x)) 38 | ans <- fastmap(x, k=ncomp, distfun=distfun, 39 | neighbors=neighbors, neighbors.weights=nbwts, 40 | transpose=transpose, niter=niter, 41 | verbose=verbose, chunkopts=chunkopts, 42 | BPPARAM=BPPARAM, ...) 43 | ans$weights <- weights 44 | ans$r <- r 45 | .Log("returning FastMap projection", 46 | message=verbose) 47 | ans 48 | }) 49 | 50 | setMethod("spatialFastmap", "SpectralImagingExperiment", 51 | function(x, r = 1, ncomp = 3, 52 | weights = c("gaussian", "adaptive"), 53 | neighbors = findNeighbors(x, r=r), ...) 54 | { 55 | if ( length(processingData(x)) > 0L ) 56 | .Warn("queued processing steps will be ignored") 57 | ans <- spatialFastmap(spectra(x), 58 | coord=coord(x), r=r, ncomp=ncomp, 59 | neighbors=neighbors, weights=weights, 60 | transpose=TRUE, ...) 61 | as(SpatialResults(ans, x), "SpatialFastmap") 62 | }) 63 | 64 | setMethod("predict", "SpatialFastmap", 65 | function(object, newdata, 66 | weights = object$weights, r = object$r, 67 | neighbors = findNeighbors(newdata, r=r), 68 | BPPARAM = getCardinalBPPARAM(), ...) 69 | { 70 | if ( !is(newdata, "SpectralImagingExperiment") ) 71 | .Error("'newdata' must inherit from 'SpectralImagingExperiment'") 72 | if ( nrow(newdata) != nrow(object$pivot.array) ) 73 | .Error("'newdata' does not have the correct number of dimensions") 74 | if ( length(processingData(newdata)) > 0L ) 75 | .Warn("queued processing steps will be ignored") 76 | if ( is.character(weights) ) { 77 | nbwts <- spatialWeights(newdata, r=r, 78 | neighbors=neighbors, weights=weights, 79 | BPPARAM=BPPARAM, ...) 80 | } else { 81 | nbwts <- rep_len(weights, length(neighbors)) 82 | } 83 | predict(object@model, newdata=spectra(newdata), 84 | neighbors=neighbors, neighbors.weights=nbwts, 85 | verbose=FALSE, BPPARAM=BPPARAM, ...) 86 | }) 87 | 88 | setMethod("plot", c(x = "SpatialFastmap", y = "missing"), 89 | function(x, type = c("scree", "x"), ..., xlab, ylab) 90 | { 91 | type <- match.arg(type) 92 | if ( type == "x" ) { 93 | callNextMethod(x, y=x$x, xlab=xlab, ylab=ylab, 94 | reducedDims=TRUE, ...) 95 | } else { 96 | if ( missing(xlab) ) 97 | xlab <- NULL 98 | if ( missing(ylab) ) 99 | ylab <- "Variances" 100 | panel_grid(c(1L,1L)) 101 | screeplot(x@model, main="", ...) 102 | title(xlab=xlab, ylab=ylab, outer=TRUE) 103 | } 104 | }) 105 | 106 | setMethod("image", c(x = "SpatialFastmap"), 107 | function(x, type = "x", ...) 108 | { 109 | type <- match.arg(type) 110 | callNextMethod(x, y=x$x, ...) 111 | }) 112 | 113 | -------------------------------------------------------------------------------- /tests/testthat/test-MSImagingArrays.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("MSImagingArrays") 5 | 6 | test_that("MSImagingArrays accessors", { 7 | 8 | msa <- MSImagingArrays() 9 | 10 | expect_true(validObject(msa)) 11 | 12 | set.seed(1) 13 | n <- 10 14 | i <- rep(list(501:510), n) 15 | a <- replicate(n, rlnorm(n), simplify=FALSE) 16 | s <- SpectraArrays(list(mz=i, intensity=a)) 17 | pdata <- PositionDataFrame( 18 | coord=expand.grid(x=1:5, y=1:2), 19 | diagnosis=rep(c("yes", "no"), each=5)) 20 | pdata2 <- PositionDataFrame( 21 | coord=expand.grid(x=1:5, y=3:4), 22 | diagnosis=rep(c("yes", "no"), each=5)) 23 | expdata <- CardinalIO::ImzMeta(spectrumType="MS1 spectrum", 24 | spectrumRepresentation="profile", 25 | contactName="Kylie Ariel Bemis") 26 | msa <- MSImagingArrays(s, pixelData=pdata, 27 | experimentData=NULL, centroided=FALSE) 28 | 29 | expect_true(validObject(msa)) 30 | expect_length(msa, n) 31 | expect_null(dim(msa)) 32 | 33 | expect_equal(spectraData(msa), s) 34 | expect_equal(pixelData(msa), pdata) 35 | expect_equal(experimentData(msa), NULL) 36 | expect_false(centroided(msa)) 37 | 38 | expect_equal(spectra(msa, 1L), s[[1L]]) 39 | expect_equal(spectra(msa, 2L), s[[2L]]) 40 | expect_equal(pData(msa), pdata) 41 | 42 | expect_equal(mz(msa), s[["mz"]]) 43 | expect_equal(mz(msa, 1L), s[["mz"]][[1L]]) 44 | expect_equal(mz(msa, 10L), s[["mz"]][[10L]]) 45 | expect_equal(intensity(msa), s[["intensity"]]) 46 | expect_equal(intensity(msa, 1L), s[["intensity"]][[1L]]) 47 | expect_equal(intensity(msa, 10L), s[["intensity"]][[10L]]) 48 | expect_equal(coord(msa), coord(pdata)) 49 | expect_equal(run(msa), run(pdata)) 50 | expect_equal(nrun(msa), nrun(pdata)) 51 | expect_equal(msa$diagnosis, pdata$diagnosis) 52 | 53 | experimentData(msa) <- expdata 54 | 55 | expect_true(validObject(msa)) 56 | expect_equal(experimentData(msa), expdata) 57 | 58 | centroided(msa) <- NA 59 | 60 | expect_equal(centroided(msa), NA) 61 | expect_false(isCentroided(msa)) 62 | 63 | msa2 <- msa[2:9] 64 | 65 | expect_true(validObject(msa2)) 66 | expect_equal(length(msa2), 8L) 67 | expect_equal(mz(msa2), mz(msa)[2:9]) 68 | expect_equal(intensity(msa2), intensity(msa)[2:9]) 69 | expect_equal(pixelData(msa2), pixelData(msa)[2:9,]) 70 | 71 | }) 72 | 73 | test_that("MSImagingArrays combine", { 74 | 75 | set.seed(1) 76 | n <- 10 77 | i <- rep(list(501:510), n) 78 | a <- replicate(n, rlnorm(n), simplify=FALSE) 79 | s <- SpectraArrays(list(mz=i, intensity=a)) 80 | pdata <- PositionDataFrame( 81 | coord=expand.grid(x=1:5, y=1:2), 82 | diagnosis=rep(c("yes", "no"), each=5)) 83 | pdata2 <- PositionDataFrame( 84 | coord=expand.grid(x=1:5, y=3:4), 85 | diagnosis=rep(c("yes", "no"), each=5)) 86 | expdata <- CardinalIO::ImzMeta(spectrumType="MS1 spectrum", 87 | spectrumRepresentation="profile", 88 | contactName="Kylie Ariel Bemis") 89 | msa <- MSImagingArrays(s, pixelData=pdata, 90 | experimentData=NULL, centroided=FALSE) 91 | msa2 <- MSImagingArrays(s, pixelData=pdata2) 92 | 93 | msa3 <- c(msa, msa2) 94 | 95 | expect_equal(mz(msa3), c(mz(msa), mz(msa2))) 96 | expect_equal(intensity(msa3), c(intensity(msa), intensity(msa2))) 97 | expect_equal(pData(msa3), rbind(pData(msa), pData(msa2))) 98 | 99 | }) 100 | 101 | test_that("MSImagingArrays/MSImagingExperiment conversion", { 102 | 103 | path <- CardinalIO::exampleImzMLFile("processed") 104 | msa <- readImzML(path) 105 | msa2 <- msa 106 | centroided(msa2) <- TRUE 107 | 108 | mse <- convertMSImagingArrays2Experiment(msa) 109 | mse2 <- convertMSImagingArrays2Experiment(msa2) 110 | mse3 <- convertMSImagingArrays2Experiment(msa, mz=mz(mse)) 111 | msa3 <- convertMSImagingExperiment2Arrays(mse) 112 | 113 | expect_is(mse, "MSImagingExperiment") 114 | expect_is(mse2, "MSImagingExperiment") 115 | expect_is(msa3, "MSImagingArrays") 116 | 117 | }) 118 | 119 | -------------------------------------------------------------------------------- /man/plot-image.Rd: -------------------------------------------------------------------------------- 1 | \name{plot-image} 2 | \alias{plot-image} 3 | 4 | \alias{image} 5 | \alias{image,MSImagingExperiment-method} 6 | \alias{image,SpectralImagingExperiment-method} 7 | \alias{image,PositionDataFrame-method} 8 | 9 | \alias{image3D} 10 | \alias{image3D,MSImagingExperiment-method} 11 | 12 | \title{Plot images from a spectral imaging dataset} 13 | 14 | \description{ 15 | Create and display sliced images from the spectra or pixel data of a spectral imaging dataset using a formula interface. 16 | } 17 | 18 | \usage{ 19 | \S4method{image}{MSImagingExperiment}(x, 20 | formula = intensity ~ x * y, 21 | i = features(x, mz=mz), 22 | mz = NULL, 23 | tolerance = NA, 24 | units = c("ppm", "mz"), 25 | \dots, 26 | xlab, ylab) 27 | 28 | \S4method{image}{SpectralImagingExperiment}(x, 29 | formula, 30 | i = 1L, 31 | run = NULL, 32 | groups = NULL, 33 | superpose = FALSE, 34 | key = TRUE, 35 | \dots, 36 | enhance = NULL, 37 | smooth = NULL, 38 | scale = NULL, 39 | subset = TRUE) 40 | 41 | \S4method{image}{PositionDataFrame}(x, 42 | formula, 43 | run = NULL, 44 | superpose = FALSE, 45 | key = TRUE, 46 | \dots, 47 | enhance = NULL, 48 | smooth = NULL, 49 | scale = NULL, 50 | subset = TRUE) 51 | } 52 | 53 | \arguments{ 54 | \item{x}{A spectral imaging dataset.} 55 | 56 | \item{formula}{A formula of the form \code{vals ~ x * y} giving the image values and the pixel coordinates. The LHS is taken to be the name of an array in \code{spectraData()} and the RHS is taken to be columns of \code{pixelData()}. Alternatively, if \code{formula} is a string or if \code{i} is NULL, then the LHS is interpreted as the name of a column of \code{pixelData()} as well.} 57 | 58 | \item{i}{The index of the feature(s) to plot for the image(s).} 59 | 60 | \item{mz}{The m/z value(s) to plot for the image(s).} 61 | 62 | \item{tolerance}{If specified, the tolerance to consider a feature as being equal to the given \code{mz} value.} 63 | 64 | \item{units}{The units for the above tolerance.} 65 | 66 | \item{\dots}{Additional arguments passed to \code{\link[matter]{plot_image}}.} 67 | 68 | \item{xlab, ylab}{Plotting labels.} 69 | 70 | \item{run}{The names of experimental runs to include, or the index of the levels of the runs to include.} 71 | 72 | \item{groups}{A vector coercible to a factor indicating which of the specified features should be plotted with the same color.} 73 | 74 | \item{superpose}{If multiple images are plotted, should they be superposed on top of each other, or plotted seperately?} 75 | 76 | \item{key}{Should a legend or colorkey be plotted?} 77 | 78 | \item{enhance}{The name of a contrast enhancement method, such as \code{"hist"} or \code{"adapt"} for \code{enhance_hist()} and \code{enhance_adapt()}, etc. See \code{\link{enhance}} for details.} 79 | 80 | \item{smooth}{The name of a smoothing method, such as \code{"gauss"} or \code{"bi"} for \code{filt2_gauss()} and \code{filt2_bi()}, etc. See \code{\link{filt2}} for details.} 81 | 82 | \item{scale}{If multiple images are plotted, should they be scaled to the same intensity scale?} 83 | 84 | \item{subset}{A logical vector indicating which pixels to include in the image.} 85 | } 86 | 87 | \author{ 88 | Kylie A. Bemis 89 | } 90 | 91 | \seealso{ 92 | \code{\link{image}}, 93 | \code{\link{plot_image}}, 94 | \code{\link{selectROI}} 95 | } 96 | 97 | \examples{ 98 | set.seed(1, kind="L'Ecuyer-CMRG") 99 | x <- simulateImage(preset=2, npeaks=10, dim=c(16,16)) 100 | peaks <- mz(metadata(x)$design$featureData) 101 | 102 | image(x, mz=peaks[1L], tolerance=0.5, units="mz") 103 | image(x, mz=peaks[1L], smooth="gaussian") 104 | image(x, mz=peaks[1:9], smooth="adaptive") 105 | 106 | x <- summarizePixels(x, stat=c(TIC="mean")) 107 | image(x, "TIC") 108 | } 109 | 110 | \keyword{hplot} 111 | 112 | -------------------------------------------------------------------------------- /man/SpatialCV.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialCV} 2 | 3 | \alias{SpatialCV} 4 | \alias{class:SpatialCV} 5 | \alias{SpatialCV-class} 6 | 7 | \alias{crossValidate} 8 | \alias{fitted,SpatialCV-method} 9 | \alias{image,SpatialCV-method} 10 | 11 | \title{Cross-validation for spectral imaging data} 12 | 13 | \description{ 14 | Apply cross-validation with an existing or a user-specified modeling function over folds of a spectral imaging dataset. 15 | } 16 | 17 | \usage{ 18 | crossValidate(fit., x, y, folds = run(x), \dots, 19 | predict. = predict, keep.models = FALSE, 20 | trainProcess = peakProcess, trainArgs = list(), 21 | testProcess = peakProcess, testArgs = list(), 22 | verbose = getCardinalVerbose(), chunkopts = list(), 23 | BPPARAM = getCardinalBPPARAM()) 24 | 25 | \S4method{fitted}{SpatialCV}(object, type = c("response", "class"), \dots) 26 | 27 | \S4method{image}{SpatialCV}(x, i = 1L, type = c("response", "class"), 28 | layout = NULL, free = "", \dots) 29 | } 30 | 31 | \arguments{ 32 | \item{fit.}{The function used to fit the model.} 33 | 34 | \item{x, y}{The data and response variable, where \code{x} is assumed to be an P x N dataset such as a \code{SpectralImagingExperiment}} 35 | 36 | \item{folds}{A vector coercible to a factor giving the fold for each row or column of \code{x}.} 37 | 38 | \item{\dots}{Additional arguments passed to \code{fit.} and \code{predict.}.} 39 | 40 | \item{predict.}{The function used to predict on new data from the fitted model. The fitted model is passed as the 1st argument and the test data is passed as the 2nd argument.} 41 | 42 | \item{keep.models}{Should the models be kept and returned?} 43 | 44 | \item{trainProcess, trainArgs}{A function and arguments used for processing the training sets. The training set is passed as the 1st argument to \code{trainProcess}.} 45 | 46 | \item{testProcess, testArgs}{A function and arguments used for processing the test sets. The test set is passed as the 1st argument to \code{trainProcess}, and the processed training set is passed as the 2nd argument.} 47 | 48 | \item{verbose}{Should progress be printed for each iteration?} 49 | 50 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 51 | 52 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}. \emph{Passed} to \code{fit.}, \code{predict.}, \code{trainProcess} and \code{testProcess}.} 53 | 54 | \item{object}{An object inheriting from \code{SpatialCV}.} 55 | 56 | \item{type}{The type of prediction, where \code{"response"} means the fitted response matrix and \code{"class"} will be the vector of class predictions (only for classification).} 57 | 58 | \item{i}{If predictions are made for multiple sets of parameters, which set of parameters (i.e., which element of the \code{fitted.values} list) should be plotted?} 59 | 60 | \item{layout}{A vector of the form \code{c(nrow, ncol)} specifying the number of rows and columns in the facet grid.} 61 | 62 | \item{free}{A string specifying the free spatial dimensions during faceting. E.g., \code{""}, \code{"x"}, \code{"y"}, \code{"xy"}, \code{"yx"}.} 63 | } 64 | 65 | \details{ 66 | This method is designed to be used with the provided classification methods, but can also be used with user-provided functions and methods as long as they conform to certain expectations. Internally, \code{\link{cv_do}} from the \code{matter} package is used to perform the cross-validation. See \code{?cv_do} for details. 67 | } 68 | 69 | \value{ 70 | An object of class \code{SpatialCV} derived from \code{SpatialResults} and containing accuracies for each fold, the predictions for each fold, and (optionally) the fitted models. 71 | } 72 | 73 | \author{ 74 | Kylie A. Bemis 75 | } 76 | 77 | \seealso{ 78 | \code{\link{cv_do}}, 79 | \code{\link{spatialShrunkenCentroids}}, 80 | \code{\link{PLS}}, 81 | \code{\link{OPLS}} 82 | } 83 | 84 | \keyword{utilities} 85 | \keyword{classif} 86 | \keyword{regression} 87 | -------------------------------------------------------------------------------- /man/peakPick.Rd: -------------------------------------------------------------------------------- 1 | \name{peakPick} 2 | 3 | \alias{peakPick} 4 | \alias{peakPick,MSImagingExperiment-method} 5 | \alias{peakPick,MSImagingArrays-method} 6 | \alias{peakPick,SpectralImagingData-method} 7 | 8 | \title{Peak pick spectra} 9 | 10 | \description{ 11 | Apply deferred peak picking to spectra. 12 | } 13 | 14 | \usage{ 15 | \S4method{peakPick}{MSImagingExperiment}(object, ref, 16 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 17 | SNR = 2, type = c("height", "area"), 18 | tolerance = NA, units = c("ppm", "mz"), \dots) 19 | 20 | \S4method{peakPick}{MSImagingArrays}(object, ref, 21 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 22 | SNR = 2, type = c("height", "area"), 23 | tolerance = NA, units = c("ppm", "mz"), \dots) 24 | 25 | \S4method{peakPick}{SpectralImagingData}(object, ref, 26 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 27 | SNR = 2, type = c("height", "area"), 28 | tolerance = NA, units = c("relative", "absolute"), \dots) 29 | } 30 | 31 | \arguments{ 32 | \item{object}{A spectral imaging dataset.} 33 | 34 | \item{ref}{Optional vector giving locations of reference peaks to extract from the dataset.} 35 | 36 | \item{method}{The peak picking method to use. See \code{\link[matter]{findpeaks}} for details.} 37 | 38 | \item{SNR}{The signal-to-noise threshold to use to determine a peak.} 39 | 40 | \item{type}{The type of value to use to summarize the peak.} 41 | 42 | \item{tolerance}{If \code{ref} is specified, the tolerance to use when deciding if a local peak in a spectrum matches a reference peak. If \code{NA}, then the tolerance is automatically determined as half the minimum distance between peaks in the reference.} 43 | 44 | \item{units}{The units for the above tolerance.} 45 | 46 | \item{\dots}{Additional arguments passed to the peak picking function.} 47 | } 48 | 49 | \details{ 50 | Unless otherwise specified, peaks are detected as local maxima which are then compared to the estimated noise level to determine a signal-to-noise ratio for each peak. Most of the peak detection methods below are differentiated by how they estimate the noise in the specturm. 51 | 52 | The supported peak picking methods are: 53 | 54 | \itemize{ 55 | 56 | \item{"diff": Estimate noise based on the derivative of the signal using \code{\link{estnoise_diff}}.} 57 | 58 | \item{"sd": Estimate noise from standard deviation using \code{\link{estnoise_sd}}.} 59 | 60 | \item{"mad": Estimate noise from mean absolute deviation using \code{\link{estnoise_mad}}.} 61 | 62 | \item{"quantile": Estimate noise from a rolling quantile of the difference between the raw signal and a smoothed signal using \code{\link{estnoise_quant}}.} 63 | 64 | \item{"filter": Estimate noise using dynamic filtering of the local peaks using \code{\link{estnoise_filt}}.} 65 | 66 | \item{"cwt": Detect peaks based on continuous wavelet transform (CWT) using \code{\link{findpeaks_cwt}}.} 67 | } 68 | 69 | If \code{ref} is provided, then the signal-to-noise ratio is not determined, and any detected local maxima are summarized as long as they match to a reference peak. 70 | } 71 | 72 | \note{ 73 | The peak picking is deferred until \code{process()} is called. 74 | } 75 | 76 | \value{ 77 | An object of the same class with the processing step queued. 78 | } 79 | 80 | \author{ 81 | Kylie A. Bemis 82 | } 83 | 84 | \seealso{ 85 | \code{\link{process}}, 86 | \code{\link{peakAlign}}, 87 | \code{\link{peakProcess}}, 88 | \code{\link{estimateReferencePeaks}} 89 | } 90 | 91 | \examples{ 92 | set.seed(1, kind="L'Ecuyer-CMRG") 93 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 94 | 95 | # queue peak picking 96 | mse2 <- peakPick(mse, method="diff", SNR=6) 97 | plot(mse2, i=4) 98 | 99 | # apply peak picking 100 | mse2 <- process(mse2) 101 | } 102 | 103 | \keyword{ts} 104 | -------------------------------------------------------------------------------- /man/SpatialFastmap.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialFastmap} 2 | 3 | \alias{SpatialFastmap} 4 | \alias{class:SpatialFastmap} 5 | \alias{SpatialFastmap-class} 6 | 7 | \alias{spatialFastmap} 8 | \alias{spatialFastmap,ANY-method} 9 | \alias{spatialFastmap,SpectralImagingExperiment-method} 10 | \alias{predict,SpatialFastmap-method} 11 | \alias{plot,SpatialFastmap,missing-method} 12 | \alias{image,SpatialFastmap-method} 13 | 14 | \title{Spatially-aware FastMap projection} 15 | 16 | \description{ 17 | Compute spatially-aware FastMap projection. 18 | } 19 | 20 | \usage{ 21 | \S4method{spatialFastmap}{ANY}(x, coord, r = 1, ncomp = 3, 22 | weights = c("gaussian", "adaptive"), 23 | neighbors = findNeighbors(coord, r=r), 24 | transpose = TRUE, niter = 10L, 25 | verbose = getCardinalVerbose(), chunkopts = list(), 26 | BPPARAM = getCardinalBPPARAM(), \dots) 27 | 28 | \S4method{spatialFastmap}{SpectralImagingExperiment}(x, r = 1, ncomp = 3, 29 | weights = c("gaussian", "adaptive"), 30 | neighbors = findNeighbors(x, r=r), \dots) 31 | 32 | \S4method{predict}{SpatialFastmap}(object, newdata, 33 | weights = object$weights, r = object$r, 34 | neighbors = findNeighbors(newdata, r=r), 35 | BPPARAM = getCardinalBPPARAM(), \dots) 36 | 37 | \S4method{plot}{SpatialFastmap,missing}(x, type = c("scree", "x"), \dots, xlab, ylab) 38 | 39 | \S4method{image}{SpatialFastmap}(x, type = "x", \dots) 40 | } 41 | \arguments{ 42 | \item{x}{A spatial dataset in P x N matrix format.} 43 | 44 | \item{coord}{The spatial coordinates of the rows/columns of \code{x}. Ignored if \code{neighbors} is provided.} 45 | 46 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor. Ignored if \code{neighbors} is provided.} 47 | 48 | \item{ncomp}{The number of FastMap components.} 49 | 50 | \item{weights}{The type of spatial weights to use for the smoothing. Gaussian weights are weighted only by distance, while adaptive weights also consider the dissimilarity between neighboring observations.} 51 | 52 | \item{neighbors}{A \code{factor} giving which observations should be treated as spatially-independent. Observations in the same group are assumed to have a spatial relationship.} 53 | 54 | \item{transpose}{Should \code{x} be considered P x N?} 55 | 56 | \item{niter}{The number of iterations used to calculate the pivots for each FastMap component.} 57 | 58 | \item{verbose}{Should progress messages be printed?} 59 | 60 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 61 | 62 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 63 | 64 | \item{\dots}{Additional arguments passed to the next method.} 65 | 66 | \item{object}{A \code{SpatialFastmap} object.} 67 | 68 | \item{newdata}{A new \code{SpectralImagingExperiment} for which to calculate the scores.} 69 | 70 | \item{type}{The type of plot to display.} 71 | 72 | \item{xlab, ylab}{Plotting labels.} 73 | } 74 | 75 | \value{ 76 | An object of class \code{SpatialFastmap} derived from \code{SpatialResults}, containing the fitted \code{\link[matter]{fastmap}} object and the spatial metadata. 77 | } 78 | 79 | \author{ 80 | Kylie A. Bemis 81 | } 82 | 83 | \references{ 84 | Alexandrov, T., & Kobarg, J. H. (2011). Efficient spatial segmentation of large imaging mass spectrometry datasets with spatially aware clustering. Bioinformatics, 27(13), i230-i238. doi:10.1093/bioinformatics/btr246 85 | 86 | Faloutsos, C., & Lin, D. (1995). FastMap: A Fast Algorithm for Indexing, Data-Mining and Visualization of Traditional and Multimedia Datasets. Presented at the Proceedings of the 1995 ACM SIGMOD international conference on Management of data. 87 | } 88 | 89 | \seealso{ 90 | \code{\link{PCA}}, 91 | \code{\link{NMF}}, 92 | \code{\link{spatialKMeans}} 93 | } 94 | 95 | \examples{ 96 | set.seed(1, kind="L'Ecuyer-CMRG") 97 | mse <- simulateImage(preset=2, npeaks=20, dim=c(10,10), 98 | centroided=TRUE) 99 | 100 | # project to FastMap components 101 | fm <- spatialFastmap(mse, r=1, ncomp=2, weights="adaptive") 102 | 103 | # visualize first 2 components 104 | image(fm) 105 | } 106 | 107 | \keyword{multivariate} 108 | \keyword{spatial} 109 | 110 | -------------------------------------------------------------------------------- /man/MSImagingArrays-class.Rd: -------------------------------------------------------------------------------- 1 | \name{MSImagingArrays-class} 2 | \docType{class} 3 | 4 | \alias{class:MSImagingArrays} 5 | \alias{MSImagingArrays} 6 | \alias{MSImagingArrays-class} 7 | 8 | \alias{show,MSImagingArrays-method} 9 | \alias{mz,MSImagingArrays-method} 10 | \alias{mz<-,MSImagingArrays-method} 11 | \alias{intensity,MSImagingArrays-method} 12 | \alias{intensity<-,MSImagingArrays-method} 13 | \alias{c,MSImagingArrays-method} 14 | 15 | \title{MSImagingArrays: MS imaging data with arbitrary m/z values} 16 | 17 | \description{ 18 | The \code{MSImagingArrays} class provides a list-like container for high-throughput mass spectrometry imaging data where every mass spectrum may have its own m/z values. It is designed for easy access to raw mass spectra for the purposes of pre-processing. 19 | 20 | It can be converted to a \code{\linkS4class{MSImagingExperiment}} object for easier image slicing and for applying statistical models and machine learning methods. 21 | } 22 | 23 | \usage{ 24 | ## Instance creation 25 | MSImagingArrays(spectraData = SimpleList(), 26 | pixelData = PositionDataFrame(), experimentData = NULL, 27 | centroided = NA, continuous = NA, metadata = list()) 28 | 29 | ## Additional methods documented below 30 | } 31 | 32 | \arguments{ 33 | \item{spectraData}{Either a list-like object with lists of individual spectra and lists of their domain values, or a \code{\linkS4class{SpectraArrays}} instance.} 34 | 35 | \item{pixelData}{A \code{\linkS4class{PositionDataFrame}} with pixel metadata, with a row for each spectrum.} 36 | 37 | \item{experimentData}{Either NULL or a \code{\linkS4class{ImzMeta}} object with MS-specific experiment-level metadata.} 38 | 39 | \item{centroided}{A logical value indicated whether the spectra have been centroided.} 40 | 41 | \item{continuous}{A logical value indicated whether the spectra all have the same m/z values.} 42 | 43 | \item{metadata}{A list of arbitrary metadata.} 44 | } 45 | 46 | \section{Slots}{ 47 | \describe{ 48 | \item{\code{spectraData}:}{A \code{\linkS4class{SpectraArrays}} object storing one or more array-like data elements with conformable dimensions.} 49 | 50 | \item{\code{elementMetadata}:}{A \code{\linkS4class{PositionDataFrame}} containing spectrum-level metadata, including each spectrum's pixel coordinates and experimental run information.} 51 | 52 | \item{\code{processing}:}{A list containing unexecuted \code{\linkS4class{ProcessingStep}} objects.} 53 | 54 | \item{\code{experimentData}:}{Either NULL or an \code{\linkS4class{ImzMeta}} object containing experiment-level metadata (necessary for writing the data to imzML).} 55 | 56 | \item{\code{centroided}:}{A logical value indicated whether the spectra have been centroided (if known).} 57 | 58 | \item{\code{continuous}:}{A logical value indicated whether the spectra all have the same m/z values (if known).} 59 | } 60 | } 61 | 62 | \section{Methods}{ 63 | All methods for \code{\linkS4class{SpectralImagingData}} and \code{\linkS4class{SpectralImagingArrays}} also work on \code{MSImagingArrays} objects. Additional methods are documented below: 64 | 65 | \describe{ 66 | \item{\code{mz(object, i = NULL, ...)}, \code{mz(object, i = NULL, ...) <- value}:}{Get or set the m/z arrays in the \code{spectraData} slot.} 67 | 68 | \item{\code{intensity(object, i = NULL, ...)}, \code{intensity(object, i = NULL, ...) <- value}:}{Get or set the intensity arrays in the \code{spectraData} slot.} 69 | 70 | \item{\code{centroided(object, ...)}, \code{centroided(object, ...) <- value}:}{Get or set the \code{centroided} slot.} 71 | 72 | \item{\code{isCentroided(object, ...)}:}{Equivalent to \code{isTRUE(centroided(object))}.} 73 | 74 | \item{\code{experimentData(object)}, \code{experimentData(object) <- value}:}{Get or set the \code{experimentData} slot.} 75 | } 76 | } 77 | 78 | \author{Kylie A. Bemis} 79 | 80 | \seealso{ 81 | \code{\linkS4class{SpectralImagingArrays}}, 82 | \code{\linkS4class{MSImagingExperiment}} 83 | } 84 | 85 | \examples{ 86 | set.seed(1, kind="L'Ecuyer-CMRG") 87 | x <- replicate(9, rlnorm(10), simplify=FALSE) 88 | mz <- replicate(9, 500 * sort(runif(10)), simplify=FALSE) 89 | coord <- expand.grid(x=1:3, y=1:3) 90 | 91 | msa <- MSImagingArrays( 92 | spectraData=list(intensity=x, mz=mz), 93 | pixelData=PositionDataFrame(coord)) 94 | 95 | print(msa) 96 | } 97 | 98 | \keyword{classes} 99 | -------------------------------------------------------------------------------- /man/Cardinal-package.Rd: -------------------------------------------------------------------------------- 1 | \name{Cardinal-package} 2 | \alias{Cardinal-package} 3 | \docType{package} 4 | 5 | \alias{Cardinal} 6 | 7 | \alias{getCardinalParallel} 8 | \alias{setCardinalParallel} 9 | \alias{getCardinalBPPARAM} 10 | \alias{setCardinalBPPARAM} 11 | \alias{getCardinalVerbose} 12 | \alias{setCardinalVerbose} 13 | 14 | \alias{getCardinalNChunks} 15 | \alias{setCardinalNChunks} 16 | \alias{getCardinalChunksize} 17 | \alias{setCardinalChunksize} 18 | \alias{getCardinalSerialize} 19 | \alias{setCardinalSerialize} 20 | 21 | \alias{getCardinalLogger} 22 | \alias{setCardinalLogger} 23 | \alias{saveCardinalLog} 24 | 25 | \alias{vizi_style} 26 | \alias{vizi_engine} 27 | \alias{vizi_par} 28 | 29 | \title{Mass spectrometry imaging tools} 30 | 31 | \description{ 32 | Implements statistical & computational tools for analyzing mass spectrometry imaging datasets, including methods for efficient pre-processing, spatial segmentation, and classification. 33 | } 34 | 35 | \details{ 36 | Cardinal provides an abstracted interface to manipulating mass spectrometry imaging datasets, simplifying most of the basic programmatic tasks encountered during the statistical analysis of imaging data. These include image manipulation and processing of both images and mass spectra, and dynamic plotting of both. 37 | 38 | While pre-processing steps including normalization, baseline correction, and peak-picking are provided, the core functionality of the package is statistical analysis. The package includes classification and clustering methods based on nearest shrunken centroids, as well as traditional tools like PCA and PLS. 39 | 40 | Type \code{browseVignettes("Cardinal")} to view a user's guide and vignettes of common workflows. 41 | } 42 | 43 | 44 | \section{Options}{ 45 | 46 | The following Cardinal-specific options are available: 47 | 48 | \itemize{ 49 | \item{\code{getCardinalParallel(), setCardinalParallel(workers=snowWorkers())}: Set up a default parallelization backend (if passed \code{TRUE}, a number of workers, or a vector of node names, or turn off parallelization (if \code{FALSE} or \code{NULL}.} 50 | 51 | \item{\code{getCardinalBPPARAM(), setCardinalBPPARAM(BPPARAM=NULL)}: The default backend to use for parallel processing. By default, this is initially set to \code{NULL} (no parallelization). Otherwise, it must be a \code{BiocParallelParam} instance. See documentation for \code{\link{bplapply}}.} 52 | 53 | \item{\code{getCardinalVerbose(), setCardinalVerbose(verbose=interactive())}: Should progress messages be printed?} 54 | } 55 | 56 | The following Cardinal-controlled \code{matter} chunk options are available: 57 | 58 | \itemize{ 59 | \item{\code{getCardinalNChunks(), setCardinalNChunks(nchunks=20L)}: The default number of data chunks used when iterating over large datasets. Used by many methods internally.} 60 | 61 | \item{\code{getCardinalChunksize(), setCardinalChunksize(chunksize=NA, units=names(chunksize))}: The approximate size of data chunks used when iterating over large datasets. Can be used as an alternative to setting the number of chunks. The default (\code{NA}) means to ignore this parameter and use the \code{getCardinalNChunks()}.} 62 | 63 | \item{\code{getCardinalSerialize(), setCardinalSerialize(serialize=NA)}: Whether data chunks should be loaded on the manager and serialized to the workers (\code{TRUE}), or loaded on the workers (\code{FALSE}). The default (\code{NA}) means to choose automatically based on the type of data and the type of cluster.} 64 | } 65 | 66 | The following Cardinal-controlled \code{matter} logging options are available: 67 | 68 | \itemize{ 69 | \item{\code{getCardinalLogger(), setCardinalLogger(logger=matter_logger())}: The logger used by Cardinal for messages, warnings, and errors. The logger must be of class \code{\link{simple_logger}}.} 70 | 71 | \item{\code{saveCardinalLog(file="Cardinal.log"))}: Save the log to a file. Note that Cardinal will continue to log to the specified file until the end of the R session or until saved to a new location.} 72 | } 73 | 74 | Additionally, visualization parameters are available: 75 | 76 | \itemize{ 77 | \item{\code{vizi_style()}: Set the default plotting style and color palettes.} 78 | 79 | \item{\code{vizi_engine()}: Set the default plotting engine.} 80 | 81 | \item{\code{vizi_par()}: Set default graphical parameters.} 82 | } 83 | } 84 | 85 | \author{ 86 | Kylie A. Bemis 87 | 88 | Maintainer: Kylie A. Bemis 89 | } 90 | 91 | \keyword{package} 92 | -------------------------------------------------------------------------------- /R/options.R: -------------------------------------------------------------------------------- 1 | 2 | #### Setup options and resources #### 3 | ## ---------------------------------- 4 | 5 | CardinalResources <- list2env(list(logger=simple_logger())) 6 | 7 | CardinalNamespace <- environment(NULL) 8 | 9 | CardinalEnv <- function() CardinalNamespace 10 | 11 | # set up Cardinal defaults 12 | .onLoad <- function(libname, pkgname) { 13 | setCardinalBPPARAM() 14 | setCardinalVerbose() 15 | setCardinalLogger() 16 | } 17 | 18 | #### Cardinal-specific options #### 19 | ## -------------------------------- 20 | 21 | # parallel defaults 22 | getCardinalParallel <- function() { 23 | BPPARAM <- getOption("CardinalBPPARAM") 24 | if ( is.null(BPPARAM) ) { 25 | FALSE 26 | } else { 27 | bpworkers() 28 | } 29 | } 30 | setCardinalParallel <- function(workers = snowWorkers()) { 31 | maxcores <- snowWorkers() 32 | if ( isTRUE(workers) ) 33 | workers <- maxcores 34 | if ( isFALSE(workers) || is.null(workers) ) { 35 | workers <- 1L 36 | } else { 37 | if ( !"L'Ecuyer-CMRG" %in% RNGkind() ) { 38 | .Log("making RNG parallel-safe with \"L'Ecuyer-CMRG\"", 39 | message=getCardinalVerbose()) 40 | RNGkind("L'Ecuyer-CMRG") 41 | } 42 | } 43 | if ( is.numeric(workers) ) { 44 | nworkers <- min(workers, maxcores) 45 | } else if ( is.character(workers) ) { 46 | nworkers <- length(workers) 47 | } else { 48 | .Error("'workers' must be nodenames or the number of workers") 49 | } 50 | if ( nworkers > 1L ) { 51 | nchunks <- 4L * max(nworkers, 1L) 52 | .Log("making Snowfast cluster with ", nworkers, " workers ", 53 | "and ", nchunks, " chunks", 54 | message=getCardinalVerbose()) 55 | setCardinalNChunks(nchunks) 56 | setCardinalBPPARAM(SnowfastParam(workers)) 57 | } else { 58 | setCardinalNChunks() 59 | setCardinalBPPARAM(NULL) 60 | } 61 | } 62 | 63 | # parallel backend 64 | getCardinalBPPARAM <- function() { 65 | getOption("CardinalBPPARAM") 66 | } 67 | setCardinalBPPARAM <- function(BPPARAM = NULL) { 68 | if ( !is.null(BPPARAM) && !is(BPPARAM, "BiocParallelParam") ) 69 | stop("BPPARAM must be a BiocParallelParam instance or NULL") 70 | options(CardinalBPPARAM=BPPARAM) 71 | } 72 | 73 | # should progress messages be printed? 74 | getCardinalVerbose <- function() { 75 | getOption("CardinalVerbose") 76 | } 77 | setCardinalVerbose <- function(verbose = interactive()) { 78 | verbose <- as.logical(verbose) 79 | if ( !isTRUE(verbose) && !isFALSE(verbose) ) 80 | stop("verbose must be TRUE or FALSE") 81 | options(CardinalVerbose=verbose) 82 | } 83 | 84 | # default logger 85 | getCardinalLogger <- function() { 86 | CardinalResources[["logger"]] 87 | } 88 | setCardinalLogger <- function(logger = matter_logger()) { 89 | if ( !inherits(logger, "simple_logger") ) 90 | stop("logger must inherit from class 'simple_logger'") 91 | CardinalResources[["logger"]] <- logger 92 | } 93 | 94 | # save log file 95 | saveCardinalLog <- function(file = "Cardinal.log") { 96 | getCardinalLogger()$append_trace() 97 | getCardinalLogger()$move(file) 98 | if ( getCardinalVerbose() ) { 99 | .Log("saved log file to: ", 100 | sQuote(getCardinalLogger()$logfile), message=TRUE) 101 | } 102 | invisible(getCardinalLogger()) 103 | } 104 | 105 | # logging functions 106 | .Log <- function(..., message = FALSE) { 107 | getCardinalLogger()$log(..., signal=message) 108 | } 109 | .Message <- function(...) { 110 | getCardinalLogger()$message(...) 111 | } 112 | .Warn <- function(...) { 113 | call <- sys.call(-1L) 114 | getCardinalLogger()$warning(..., call=call) 115 | } 116 | .Error <- function(...) { 117 | call <- sys.call(-1L) 118 | getCardinalLogger()$stop(..., call=call) 119 | } 120 | 121 | #### Cardinal-controlled matter options #### 122 | ## ----------------------------------------- 123 | 124 | # number of chunks to use for processing 125 | getCardinalNChunks <- function() { 126 | matter_defaults()[["nchunks"]] 127 | } 128 | setCardinalNChunks <- function(nchunks = 20L) { 129 | matter_defaults(nchunks=nchunks) 130 | } 131 | 132 | # size of chunks to use for processing 133 | getCardinalChunksize <- function() { 134 | matter_defaults()[["chunksize"]] 135 | } 136 | setCardinalChunksize <- function(chunksize = NA, units = names(chunksize)) { 137 | matter_defaults(chunksize=setNames(chunksize, units)) 138 | } 139 | 140 | # whether to serialize external data 141 | getCardinalSerialize <- function() { 142 | matter_defaults()[["serialize"]] 143 | } 144 | setCardinalSerialize <- function(serialize = NA) { 145 | matter_defaults(serialize=serialize) 146 | } 147 | 148 | -------------------------------------------------------------------------------- /R/summarize.R: -------------------------------------------------------------------------------- 1 | 2 | #### Summarize features #### 3 | ## -------------------------- 4 | 5 | summarizeFeatures <- function(x, stat = "mean", groups = NULL, 6 | verbose = getCardinalVerbose(), chunkopts = list(), 7 | BPPARAM = getCardinalBPPARAM(), ...) 8 | { 9 | if ( "FUN" %in% ...names() ) { 10 | .Deprecated(old="FUN", new="stat") 11 | stat <- list(...)$FUN 12 | } 13 | if ( !is(x, "SpectralImagingExperiment") ) 14 | .Error("object must inherit from SpectralImagingExperiment") 15 | if ( is.null(names(stat)) ) { 16 | labels <- stat 17 | } else { 18 | labels <- ifelse(nchar(names(stat)), names(stat), stat) 19 | } 20 | ans <- rowStats(x, stat=stat, group=groups, simplify=FALSE, 21 | verbose=verbose, chunkopts=chunkopts, 22 | BPPARAM=BPPARAM, ...) 23 | for ( i in seq_along(ans) ) { 24 | y <- as.vector(ans[[i]]) 25 | if ( is.null(dim(ans[[i]])) ) { 26 | names(y) <- names(ans[[i]]) 27 | } else { 28 | dim(y) <- dim(ans[[i]]) 29 | dimnames(y) <- dimnames(ans[[i]]) 30 | } 31 | if ( is.array(y) ) { 32 | nm <- paste0(colnames(y), ".", labels[i]) 33 | featureData(x)[nm] <- y 34 | } else { 35 | featureData(x)[[labels[i]]] <- y 36 | } 37 | } 38 | x 39 | } 40 | 41 | 42 | #### Summarize pixels #### 43 | ## ------------------------ 44 | 45 | summarizePixels <- function(x, stat = c(tic="sum"), groups = NULL, 46 | verbose = getCardinalVerbose(), chunkopts = list(), 47 | BPPARAM = getCardinalBPPARAM(), ...) 48 | { 49 | if ( "FUN" %in% ...names() ) { 50 | .Deprecated(old="FUN", new="stat") 51 | stat <- list(...)$FUN 52 | } 53 | if ( !is(x, "SpectralImagingData") ) 54 | .Error("object must inherit from SpectralImagingData") 55 | if ( is.null(names(stat)) ) { 56 | labels <- stat 57 | } else { 58 | labels <- ifelse(nchar(names(stat)), names(stat), stat) 59 | } 60 | if ( is(x, "SpectralImagingExperiment") ) { 61 | ans <- colStats(x, stat=stat, group=groups, simplify=FALSE, 62 | verbose=verbose, chunkopts=chunkopts, 63 | BPPARAM=BPPARAM, ...) 64 | } else { 65 | if ( !is.null(groups) ) 66 | .Error("'groups' not supported for class ", sQuote(class(x)[1L])) 67 | FUN <- isofun(function(xi, stat, labels, ...) { 68 | yi <- vector("list", length=length(stat)) 69 | yi <- setNames(yi, labels) 70 | for ( i in seq_along(yi) ) 71 | yi[[i]] <- vapply(xi, match.fun(stat[i]), numeric(1L), ...) 72 | list(yi) 73 | }, CardinalEnv()) 74 | ans <- chunk_lapply(spectra(x), FUN, stat=stat, labels=labels, 75 | verbose=verbose, chunkopts=chunkopts, 76 | BPPARAM=BPPARAM, ...) 77 | ans <- Reduce(function(e1, e2) Map(c, e1, e2), ans) 78 | } 79 | for ( i in seq_along(ans) ) { 80 | y <- as.vector(ans[[i]]) 81 | if ( is.null(dim(ans[[i]])) ) { 82 | names(y) <- names(ans[[i]]) 83 | } else { 84 | dim(y) <- dim(ans[[i]]) 85 | dimnames(y) <- dimnames(ans[[i]]) 86 | } 87 | if ( is.array(y) ) { 88 | nm <- paste0(colnames(y), ".", labels[i]) 89 | pixelData(x)[nm] <- y 90 | } else { 91 | pixelData(x)[[labels[i]]] <- y 92 | } 93 | } 94 | x 95 | } 96 | 97 | 98 | #### Row/column statistics #### 99 | ## ---------------------------- 100 | 101 | setMethod("rowStats", "SpectralImagingExperiment", 102 | function(x, stat, ..., 103 | verbose = getCardinalVerbose(), chunkopts = list(), 104 | BPPARAM = getCardinalBPPARAM()) 105 | { 106 | rowStats(spectra(x), stat=stat, 107 | verbose=verbose, chunkopts=chunkopts, 108 | BPPARAM=BPPARAM, ...) 109 | }) 110 | 111 | setMethod("colStats", "SpectralImagingExperiment", 112 | function(x, stat, ..., 113 | verbose = getCardinalVerbose(), chunkopts = list(), 114 | BPPARAM = getCardinalBPPARAM()) 115 | { 116 | colStats(spectra(x), stat=stat, 117 | verbose=verbose, chunkopts=chunkopts, 118 | BPPARAM=BPPARAM, ...) 119 | }) 120 | 121 | setMethod("rowSums", "SpectralImagingExperiment", 122 | function(x, na.rm = FALSE, dims = 1, ...) 123 | { 124 | rowStats(x, stat="sum", ..., na.rm=na.rm) 125 | }) 126 | 127 | setMethod("colSums", "SpectralImagingExperiment", 128 | function(x, na.rm = FALSE, dims = 1, ...) 129 | { 130 | colStats(x, stat="sum", ..., na.rm=na.rm) 131 | }) 132 | 133 | setMethod("rowMeans", "SpectralImagingExperiment", 134 | function(x, na.rm = FALSE, dims = 1, ...) 135 | { 136 | rowStats(x, stat="mean", ..., na.rm=na.rm) 137 | }) 138 | 139 | setMethod("colMeans", "SpectralImagingExperiment", 140 | function(x, na.rm = FALSE, dims = 1, ...) 141 | { 142 | colStats(x, stat="mean", ..., na.rm=na.rm) 143 | }) 144 | 145 | 146 | -------------------------------------------------------------------------------- /R/colocalized.R: -------------------------------------------------------------------------------- 1 | 2 | #### Find features colocalized with a reference #### 3 | ## ------------------------------------------------ 4 | 5 | setMethod("colocalized", "MSImagingExperiment", 6 | function(object, mz, ...) 7 | { 8 | if ( missing(mz) || is.null(mz) ) { 9 | callNextMethod() 10 | } else { 11 | i <- features(object, mz=mz) 12 | if ( length(i) < length(mz) ) 13 | .Error("no matching features for some m/z-values") 14 | callNextMethod(object, i=i, ...) 15 | } 16 | }) 17 | 18 | setMethod("colocalized", "SpectralImagingExperiment", 19 | function(object, i, ref, 20 | threshold = median, n = Inf, 21 | sort.by = c("cor", "MOC", "M1", "M2", "Dice", "none"), 22 | verbose = getCardinalVerbose(), chunkopts = list(), 23 | BPPARAM = getCardinalBPPARAM(), ...) 24 | { 25 | sort.by <- match.arg(sort.by) 26 | if ( !missing(i) && !is.null(i) ) { 27 | ref <- as.matrix(spectra(object)[i,,drop=FALSE]) 28 | ref <- apply(ref, 1L, identity, simplify=FALSE) 29 | } 30 | if ( is.factor(ref) || is.character(ref) ) { 31 | ref <- as.factor(ref) 32 | lvl <- setNames(levels(ref), levels(ref)) 33 | ref <- lapply(lvl, function(ci) ref %in% ci) 34 | } 35 | if ( !is.list(ref) && !is(ref, "List") ) 36 | ref <- list(ref) 37 | if ( any(lengths(ref) != ncol(object)) ) 38 | .Error("length of reference [", length(ref[[1L]]), "] ", 39 | "does not match length of object [", length(object), "]") 40 | label <- if (length(ref) != 1L) "images" else "image" 41 | .Log("calculating colocalization with ", length(ref), " ", label, 42 | message=verbose) 43 | FUN <- .coscore_fun(ref, threshold, FALSE) 44 | scores <- chunkApply(spectra(object), 1L, FUN, 45 | verbose=verbose, chunkopts=chunkopts, 46 | BPPARAM=BPPARAM, ...) 47 | scores <- simplify2array(lapply(scores, t)) 48 | ans <- apply(scores, 1L, function(sc) 49 | { 50 | sc <- as.data.frame(t(sc)) 51 | data <- .rank_featureData(object, sc, sort.by) 52 | head(data, n=n) 53 | }) 54 | if ( length(ans) > 1L ) { 55 | ans 56 | } else { 57 | ans[[1L]] 58 | } 59 | }) 60 | 61 | setMethod("colocalized", "SpatialDGMM", 62 | function(object, ref, 63 | threshold = median, n = Inf, 64 | sort.by = c("MOC", "M1", "M2", "Dice", "none"), 65 | verbose = getCardinalVerbose(), chunkopts = list(), 66 | BPPARAM = getCardinalBPPARAM(), ...) 67 | { 68 | sort.by <- match.arg(sort.by) 69 | if ( is.factor(ref) || is.character(ref) ) { 70 | ref <- as.factor(ref) 71 | lvl <- setNames(levels(ref), levels(ref)) 72 | ref <- lapply(lvl, function(ci) ref %in% ci) 73 | } 74 | if ( !is.list(ref) && !is(ref, "List") ) 75 | ref <- list(ref) 76 | if ( any(lengths(ref) != nrow(pixelData(object))) ) 77 | .Error("length of reference [", length(ref[[1L]]), "] ", 78 | "does not match length of object [", nrow(pixelData(object)), "]") 79 | label <- if (length(ref) != 1L) "images" else "image" 80 | .Log("calculating colocalization with ", length(ref), " ", label, 81 | message=verbose) 82 | FUN <- .coscore_fun(ref, threshold, TRUE) 83 | scores <- chunkLapply(object$class, FUN, 84 | verbose=verbose, chunkopts=chunkopts, 85 | BPPARAM=BPPARAM, ...) 86 | scores <- simplify2array(lapply(scores, t)) 87 | ans <- apply(scores, 1L, function(sc) 88 | { 89 | sc <- as.data.frame(t(sc)) 90 | data <- .rank_featureData(object, sc, sort.by) 91 | head(data, n=n) 92 | }) 93 | if ( length(ans) > 1L ) { 94 | ans 95 | } else { 96 | ans[[1L]] 97 | } 98 | }) 99 | 100 | .coscore_fun <- function(ref, threshold, categorical) 101 | { 102 | if ( categorical ) { 103 | isoclos(function(x) 104 | { 105 | vapply(ref, function(y) { 106 | sc <- lapply(levels(x), 107 | function(lvl) coscore(as.factor(x) == lvl, y)) 108 | sc[[which.max(vapply(sc, max, numeric(1L), na.rm=TRUE))]] 109 | }, numeric(4L)) 110 | }, CardinalEnv()) 111 | } else { 112 | isoclos(function(x) 113 | { 114 | vapply(ref, function(y) { 115 | cor <- cor(x, y, use="pairwise.complete.obs") 116 | c(cor=cor, coscore(x, y, threshold=threshold)) 117 | }, numeric(5L)) 118 | }, CardinalEnv()) 119 | } 120 | } 121 | 122 | .rank_featureData <- function(object, importance, sort.by) 123 | { 124 | data <- featureData(object) 125 | data$i <- seq_len(nrow(data)) 126 | if ( is(data, "XDataFrame") ) { 127 | keep <- c("i", unlist(keys(data))) 128 | } else { 129 | keep <- "i" 130 | } 131 | data <- data[keep] 132 | data <- cbind(data, importance) 133 | if ( sort.by != "none" ) { 134 | data <- as(data, "DFrame", strict=TRUE) 135 | i <- order(data[[sort.by]], decreasing=TRUE) 136 | data <- data[i,,drop=FALSE] 137 | } 138 | data 139 | } 140 | 141 | -------------------------------------------------------------------------------- /man/SpatialKMeans.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialKMeans} 2 | 3 | \alias{SpatialKMeans} 4 | \alias{class:SpatialKMeans} 5 | \alias{SpatialKMeans-class} 6 | 7 | \alias{spatialKMeans} 8 | \alias{spatialKMeans,ANY-method} 9 | \alias{spatialKMeans,SpectralImagingExperiment-method} 10 | \alias{topFeatures,SpatialKMeans-method} 11 | \alias{plot,SpatialKMeans,missing-method} 12 | \alias{image,SpatialKMeans-method} 13 | 14 | \title{Spatially-aware K-means clustering} 15 | 16 | \description{ 17 | Perform spatially-aware k-means clustering. First the data is projected to a reduced dimension space using \code{\link{spatialFastmap}}. Then ordinary k-means clustering is applied to the projected data. 18 | } 19 | 20 | \usage{ 21 | \S4method{spatialKMeans}{ANY}(x, coord, r = 1, k = 2, ncomp = max(k), 22 | weights = c("gaussian", "adaptive"), 23 | neighbors = findNeighbors(coord, r=r), 24 | transpose = TRUE, niter = 10L, 25 | centers = TRUE, correlation = TRUE, 26 | verbose = getCardinalVerbose(), chunkopts = list(), 27 | BPPARAM = getCardinalBPPARAM(), \dots) 28 | 29 | \S4method{spatialKMeans}{SpectralImagingExperiment}(x, r = 1, k = 2, ncomp = max(k), 30 | weights = c("gaussian", "adaptive"), 31 | neighbors = findNeighbors(x, r=r), \dots) 32 | 33 | \S4method{topFeatures}{SpatialKMeans}(object, n = Inf, sort.by = "correlation", \dots) 34 | 35 | \S4method{plot}{SpatialKMeans,missing}(x, type = c("correlation", "centers"), \dots, xlab, ylab) 36 | 37 | \S4method{image}{SpatialKMeans}(x, type = "cluster", \dots) 38 | } 39 | \arguments{ 40 | \item{x}{A spatial dataset in P x N matrix format.} 41 | 42 | \item{coord}{The spatial coordinates of the rows/columns of \code{x}. Ignored if \code{neighbors} is provided.} 43 | 44 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor. Ignored if \code{neighbors} is provided.} 45 | 46 | \item{k}{The number of clusters.} 47 | 48 | \item{ncomp}{The number of FastMap components.} 49 | 50 | \item{weights}{The type of spatial weights to use for the smoothing. Gaussian weights are weighted only by distance, while adaptive weights also consider the dissimilarity between neighboring observations.} 51 | 52 | \item{neighbors}{A \code{factor} giving which observations should be treated as spatially-independent. Observations in the same group are assumed to have a spatial relationship.} 53 | 54 | \item{transpose}{Should \code{x} be considered P x N?} 55 | 56 | \item{niter}{The number of iterations used to calculate the pivots for each FastMap component.} 57 | 58 | \item{centers}{Should the cluster centers be re-calculated on the original data?} 59 | 60 | \item{correlation}{Should the correlations between features and the clusters be calculated?} 61 | 62 | \item{verbose}{Should progress messages be printed?} 63 | 64 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 65 | 66 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 67 | 68 | \item{\dots}{Additional arguments passed to the next method.} 69 | 70 | \item{object}{A \code{SpatialKMeans} object.} 71 | 72 | \item{n, sort.by}{For \code{topFeatures}, the number of top features to return and how to sort them.} 73 | 74 | \item{type}{The type of plot to display.} 75 | 76 | \item{xlab, ylab}{Plotting labels.} 77 | } 78 | 79 | \value{ 80 | An object of class \code{SpatialKMeans} derived from \code{SpatialResults}, containing the fitted \code{\link[stats]{kmeans}} object and the spatial metadata. 81 | } 82 | 83 | \author{ 84 | Kylie A. Bemis 85 | } 86 | 87 | \references{ 88 | Alexandrov, T., & Kobarg, J. H. (2011). Efficient spatial segmentation of large imaging mass spectrometry datasets with spatially aware clustering. Bioinformatics, 27(13), i230-i238. doi:10.1093/bioinformatics/btr246 89 | 90 | Faloutsos, C., & Lin, D. (1995). FastMap: A Fast Algorithm for Indexing, Data-Mining and Visualization of Traditional and Multimedia Datasets. Presented at the Proceedings of the 1995 ACM SIGMOD international conference on Management of data. 91 | } 92 | 93 | \seealso{ 94 | \code{\link{spatialKMeans}} 95 | \code{\link{spatialShrunkenCentroids}} 96 | } 97 | 98 | \examples{ 99 | set.seed(1, kind="L'Ecuyer-CMRG") 100 | mse <- simulateImage(preset=3, dim=c(10,10), npeaks=20, 101 | peakheight=c(3,6,9), centroided=TRUE) 102 | 103 | # fit spatial k-means 104 | skm <- spatialKMeans(mse, r=1, k=4, weights="adaptive") 105 | 106 | # visualize clusters 107 | image(skm) 108 | } 109 | 110 | \keyword{spatial} 111 | \keyword{clustering} 112 | -------------------------------------------------------------------------------- /man/peakAlign.Rd: -------------------------------------------------------------------------------- 1 | \name{peakAlign} 2 | 3 | \alias{peakAlign} 4 | \alias{peakAlign,MSImagingExperiment-method} 5 | \alias{peakAlign,MSImagingArrays-method} 6 | \alias{peakAlign,SpectralImagingExperiment-method} 7 | \alias{peakAlign,SpectralImagingArrays-method} 8 | 9 | \title{Align peaks across spectra} 10 | 11 | \description{ 12 | Align peaks across spectra in a spectral imaging dataset. 13 | } 14 | 15 | \usage{ 16 | \S4method{peakAlign}{MSImagingExperiment}(object, ref, 17 | spectra = "intensity", index = "mz", 18 | binfun = "min", binratio = 2, 19 | tolerance = NA, units = c("ppm", "mz"), \dots) 20 | 21 | \S4method{peakAlign}{MSImagingArrays}(object, ref, 22 | spectra = "intensity", index = "mz", 23 | binfun = "min", binratio = 2, 24 | tolerance = NA, units = c("ppm", "mz"), \dots) 25 | 26 | \S4method{peakAlign}{SpectralImagingExperiment}(object, ref, 27 | spectra = "intensity", index = NULL, 28 | binfun = "min", binratio = 2, 29 | tolerance = NA, units = c("relative", "absolute"), 30 | verbose = getCardinalVerbose(), chunkopts = list(), 31 | BPPARAM = getCardinalBPPARAM(), \dots) 32 | 33 | \S4method{peakAlign}{SpectralImagingArrays}(object, ref, 34 | spectra = "intensity", index = NULL, 35 | binfun = "min", binratio = 2, 36 | tolerance = NA, units = c("relative", "absolute"), 37 | verbose = getCardinalVerbose(), chunkopts = list(), 38 | BPPARAM = getCardinalBPPARAM(), \dots) 39 | } 40 | 41 | \arguments{ 42 | \item{object}{A spectral imaging dataset.} 43 | 44 | \item{ref}{The locations of reference peaks to use for the alignment.} 45 | 46 | \item{spectra}{The name of the array in \code{spectraData()} to use for the peak intensities.} 47 | 48 | \item{index}{The name of the array in \code{spectraData()} (for \code{SpectralImagingArrays}) or column in \code{featureData()} (for \code{SpectralImagingExperiment}) to use for the peak locations.} 49 | 50 | \item{binfun}{The function used to summarize the minimum distance between same-spectrum peaks across all spectra. This is passed to \code{estimateDomain} as \code{width} (see "Details").} 51 | 52 | \item{binratio}{The ratio between the alignment tolerance and the peak bin widths. If \code{tolerance} is \code{NA}, then this is also used to estimate the tolerance from the shared domain (see "Details").} 53 | 54 | \item{tolerance}{The alignment tolerance for matching a detected peak to a reference. If \code{NA}, then the tolerance is automatically determined from \code{binratio} times the minimum distance between same-spectrum peaks (see "Details").} 55 | 56 | \item{units}{The units for the above tolerance.} 57 | 58 | \item{verbose}{Should progress messages be printed?} 59 | 60 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 61 | 62 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 63 | 64 | \item{\dots}{Options passed to \code{process()}.} 65 | } 66 | 67 | \details{ 68 | Before peak alignment, \code{process()} is called to apply any queued pre-processing steps. It is assumed that \code{peakPick()} has either been queued or already applied to the data. 69 | 70 | If \code{ref} is provided, then the aligned peaks are returned immediately without additional processing. (Peaks are binned on-the-fly to the reference peak locations.) 71 | 72 | If \code{ref} is not provided, then the shared peaks must be determined automatically. This starts with creation of a shared domain giving a list of possible peak locations. The shared domain is estimated by \code{estimateDomain()}. 73 | 74 | Next, \code{\link[matter]{binpeaks}} is used to bin the observed peaks to the shared domain. Then, \code{\link[matter]{mergepeaks}} is used to merge peaks that are separated by a distance less than the given \code{tolerance}. 75 | 76 | The averaged locations of the merged peaks in each bin are used as the shared peaks for the full dataset, and the aligned peaks are returned. (Peaks are binned on-the-fly to the shared peak locations.) 77 | } 78 | 79 | \value{ 80 | A new object derived from \code{SpectralImagingExperiment} with the aligned peaks. 81 | } 82 | 83 | \author{ 84 | Kylie A. Bemis 85 | } 86 | 87 | \seealso{ 88 | \code{\link{process}} 89 | \code{\link{peakPick}}, 90 | \code{\link{peakProcess}} 91 | } 92 | 93 | \examples{ 94 | set.seed(1, kind="L'Ecuyer-CMRG") 95 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 96 | 97 | # queue peak picking 98 | mse2 <- peakPick(mse, method="diff", SNR=6) 99 | 100 | # align peaks 101 | mse2 <- peakAlign(mse2) 102 | plot(mse2, i=4) 103 | } 104 | 105 | \keyword{ts} 106 | -------------------------------------------------------------------------------- /tests/testthat/test-MSImagingExperiment.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("MSImagingExperiment") 5 | 6 | test_that("MSImagingExperiment accessors", { 7 | 8 | mse <- MSImagingExperiment() 9 | 10 | expect_true(validObject(mse)) 11 | 12 | mse <- MSImagingExperiment(matrix(nrow=0, ncol=0)) 13 | 14 | expect_true(validObject(mse)) 15 | 16 | set.seed(1) 17 | nr <- 20 18 | nc <- 10 19 | a <- matrix(rlnorm(nr * nc), nrow=nr, ncol=nc) 20 | s <- SpectraArrays(a) 21 | fdata <- MassDataFrame(mz=seq(500, 550, length.out=nr), 22 | label=rep.int("light", 10)) 23 | fdata2 <- MassDataFrame(mz=seq(551, 600, length.out=nr), 24 | label=rep.int("heavy", 10)) 25 | pdata <- PositionDataFrame( 26 | coord=expand.grid(x=1:5, y=1:2), 27 | diagnosis=rep(c("yes", "no"), each=5)) 28 | pdata2 <- PositionDataFrame( 29 | coord=expand.grid(x=1:5, y=3:4), 30 | diagnosis=rep(c("yes", "no"), each=5)) 31 | expdata <- CardinalIO::ImzMeta(spectrumType="MS1 spectrum", 32 | spectrumRepresentation="profile", 33 | contactName="Kylie Ariel Bemis") 34 | mse <- MSImagingExperiment(s, featureData=fdata, pixelData=pdata, 35 | experimentData=NULL, centroided=FALSE) 36 | 37 | expect_true(validObject(mse)) 38 | expect_length(mse, nc) 39 | expect_equal(dim(mse), c(nr, nc)) 40 | 41 | expect_equal(spectraData(mse), s) 42 | expect_equal(pixelData(mse), pdata) 43 | expect_equal(featureData(mse), fdata) 44 | expect_equal(experimentData(mse), NULL) 45 | expect_false(centroided(mse)) 46 | 47 | expect_equal(spectra(mse), s[[1L]]) 48 | expect_equal(pData(mse), pdata) 49 | expect_equal(fData(mse), fdata) 50 | 51 | expect_equal(mz(mse), mz(fdata)) 52 | expect_equal(coord(mse), coord(pdata)) 53 | expect_equal(run(mse), run(pdata)) 54 | expect_equal(mse$diagnosis, pdata$diagnosis) 55 | 56 | m1 <- 505.3 57 | m2 <- 544.7 58 | 59 | expect_setequal(features(mse, label=="light"), 1:20) 60 | expect_setequal(features(mse, mz=505), 3) 61 | expect_setequal(features(mse, mz=545), 18) 62 | expect_setequal(features(mse, mz=m1), 3) 63 | expect_setequal(features(mse, mz=m2), 18) 64 | expect_setequal(features(mse, mz=c(m1, m2)), c(3,18)) 65 | 66 | mz(mse) <- mz(fdata2) 67 | experimentData(mse) <- expdata 68 | 69 | expect_true(validObject(mse)) 70 | expect_equal(mz(mse), mz(fdata2)) 71 | expect_equal(experimentData(mse), expdata) 72 | 73 | centroided(mse) <- NA 74 | 75 | expect_equal(centroided(mse), NA) 76 | expect_false(isCentroided(mse)) 77 | 78 | mse2 <- mse[1:10,1:5] 79 | mse3 <- mse[1:10,] 80 | mse4 <- mse[,1:5] 81 | 82 | expect_true(validObject(mse2)) 83 | expect_equal(dim(mse2), c(10,5)) 84 | expect_equal(spectra(mse2), spectra(mse)[1:10,1:5]) 85 | expect_equal(pixelData(mse2), pixelData(mse)[1:5,]) 86 | expect_equal(featureData(mse2), featureData(mse)[1:10,]) 87 | 88 | expect_true(validObject(mse3)) 89 | expect_equal(dim(mse3), c(10,10)) 90 | expect_equal(spectra(mse3), spectra(mse)[1:10,]) 91 | expect_equal(featureData(mse2), featureData(mse)[1:10,]) 92 | 93 | expect_true(validObject(mse4)) 94 | expect_equal(dim(mse4), c(20,5)) 95 | expect_equal(spectra(mse4), spectra(mse)[,1:5]) 96 | expect_equal(pixelData(mse2), pixelData(mse)[1:5,]) 97 | 98 | }) 99 | 100 | test_that("MSImagingExperiment rbind/cbind", { 101 | 102 | set.seed(1) 103 | nr <- 20 104 | nc <- 10 105 | a <- matrix(rlnorm(nr * nc), nrow=nr, ncol=nc) 106 | s <- SpectraArrays(a) 107 | fdata <- MassDataFrame(mz=seq(500, 550, length.out=nr), 108 | label=rep.int("light", 10)) 109 | fdata2 <- MassDataFrame(mz=seq(551, 600, length.out=nr), 110 | label=rep.int("heavy", 10)) 111 | pdata <- PositionDataFrame( 112 | coord=expand.grid(x=1:5, y=1:2), 113 | diagnosis=rep(c("yes", "no"), each=5)) 114 | pdata2 <- PositionDataFrame( 115 | coord=expand.grid(x=1:5, y=3:4), 116 | diagnosis=rep(c("yes", "no"), each=5)) 117 | expdata <- CardinalIO::ImzMeta(spectrumType="MS1 spectrum", 118 | spectrumRepresentation="profile", 119 | contactName="Kylie Ariel Bemis") 120 | mse <- MSImagingExperiment(s, featureData=fdata, pixelData=pdata, 121 | experimentData=NULL, centroided=FALSE) 122 | mse02 <- MSImagingExperiment(s, featureData=fdata, pixelData=pdata2) 123 | mse20 <- MSImagingExperiment(s, featureData=fdata2, pixelData=pdata) 124 | 125 | r20 <- rbind(mse, mse20) 126 | 127 | expect_equal(spectra(r20), rbind(spectra(mse), spectra(mse20))) 128 | expect_equal(fData(r20), rbind(fData(mse), fData(mse20))) 129 | expect_equal(pData(r20), cbind(pData(mse), pData(mse20))) 130 | 131 | c02 <- cbind(mse, mse02) 132 | 133 | expect_equal(spectra(c02), cbind(spectra(mse), spectra(mse02))) 134 | expect_equal(fData(c02), cbind(fData(mse), fData(mse02))) 135 | expect_equal(pData(c02), rbind(pData(mse), pData(mse02))) 136 | 137 | }) 138 | -------------------------------------------------------------------------------- /man/SpatialDGMM.Rd: -------------------------------------------------------------------------------- 1 | \name{SpatialDGMM} 2 | 3 | \alias{SpatialDGMM} 4 | \alias{class:SpatialDGMM} 5 | \alias{SpatialDGMM-class} 6 | 7 | \alias{spatialDGMM} 8 | \alias{spatialDGMM,ANY-method} 9 | \alias{spatialDGMM,SpectralImagingExperiment-method} 10 | \alias{logLik,SpatialDGMM-method} 11 | \alias{plot,SpatialDGMM,missing-method} 12 | \alias{image,SpatialDGMM-method} 13 | 14 | \title{Spatially-aware Dirichlet Gaussian mixture model} 15 | 16 | \description{ 17 | Fit a spatially-aware Gaussian mixture models to each feature. The model uses Dirichlet prior is used to achieve spatial smoothing. The means and standard deviations of the Gaussian components are estimated using gradient descent. Simulated annealing is used to avoid local optimia and achieve better parameter estimates. 18 | } 19 | 20 | \usage{ 21 | \S4method{spatialDGMM}{ANY}(x, coord, i, r = 1, k = 2, groups = NULL, 22 | weights = c("gaussian", "adaptive"), 23 | neighbors = findNeighbors(coord, r=r, groups=groups), 24 | annealing = TRUE, compress = TRUE, byrow = FALSE, 25 | verbose = getCardinalVerbose(), chunkopts = list(), 26 | BPPARAM = getCardinalBPPARAM(), \dots) 27 | 28 | \S4method{spatialDGMM}{SpectralImagingExperiment}(x, i, r = 1, k = 2, groups = run(x), 29 | weights = c("gaussian", "adaptive"), 30 | neighbors = findNeighbors(coord(x), r=r, groups=groups), \dots) 31 | 32 | \S4method{logLik}{SpatialDGMM}(object, \dots) 33 | 34 | \S4method{plot}{SpatialDGMM,missing}(x, i = 1L, type = "density", 35 | layout = NULL, free = "", \dots) 36 | 37 | \S4method{image}{SpatialDGMM}(x, i = 1L, type = "class", 38 | layout = NULL, free = "", \dots) 39 | } 40 | \arguments{ 41 | \item{x}{A spatial dataset in P x N matrix format.} 42 | 43 | \item{i}{The rows/columns of \code{x} to segment (if not all of them).} 44 | 45 | \item{coord}{The spatial coordinates of the rows/columns of \code{x}. Ignored if \code{neighbors} is provided.} 46 | 47 | \item{r}{The spatial maximum distance for an observation to be considered a neighbor. Ignored if \code{neighbors} is provided.} 48 | 49 | \item{k}{The number of Gaussian components.} 50 | 51 | \item{groups}{Observations belonging to the different groups will be segmented independently. This should be set to the samples if statistic testing (via \code{\link{meansTest}} is to be performed.)} 52 | 53 | \item{weights}{The type of spatial weights to use for the smoothing. Gaussian weights are weighted only by distance, while adaptive weights also consider the dissimilarity between neighboring observations.} 54 | 55 | \item{neighbors}{A \code{factor} giving which observations should be treated as spatially-independent. Observations in the same group are assumed to have a spatial relationship.} 56 | 57 | \item{annealing}{Should simulated annealing be used?} 58 | 59 | \item{compress}{Should the results be compressed? The results can be larger than the original dataset, so compressing them is useful. If this option is used, then the class probabilities are not returned, and the class assignments are compressed using \code{\link[matter]{drle}}.} 60 | 61 | \item{byrow}{Should the rows or columns of \code{x} be segmented?} 62 | 63 | \item{verbose}{Should progress messages be printed?} 64 | 65 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 66 | 67 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 68 | 69 | \item{\dots}{Additional arguments passed to the next method.} 70 | 71 | \item{object}{A \code{SpatialDGMM} object.} 72 | 73 | \item{type}{The type of plot to display.} 74 | 75 | \item{layout}{A vector of the form \code{c(nrow, ncol)} specifying the number of rows and columns in the facet grid.} 76 | 77 | \item{free}{A string specifying the free spatial dimensions during faceting. E.g., \code{""}, \code{"x"}, \code{"y"}, \code{"xy"}, \code{"yx"}.} 78 | } 79 | 80 | \value{ 81 | An object of class \code{SpatialDGMM} derived from \code{SpatialResults}, containing the fitted \code{\link[matter]{sgmixn}} object and the spatial metadata. 82 | } 83 | 84 | \author{ 85 | Dan Guo and Kylie A. Bemis 86 | } 87 | 88 | \references{ 89 | Guo, D., Bemis, K., Rawlins, C., Agar, J., and Vitek, O. (2019.) Unsupervised segmentation of mass spectrometric ion images characterizes morphology of tissues. Proceedings of ISMB/ECCB, Basel, Switzerland, 2019. 90 | } 91 | 92 | \examples{ 93 | set.seed(1, kind="L'Ecuyer-CMRG") 94 | mse <- simulateImage(preset=3, dim=c(10,10), npeaks=9, 95 | peakheight=c(3,6,9), centroided=TRUE) 96 | 97 | gmm <- spatialDGMM(mse, r=1, k=4, weights="adaptive") 98 | 99 | image(gmm, i=1:9) 100 | } 101 | 102 | \keyword{spatial} 103 | \keyword{clustering} 104 | -------------------------------------------------------------------------------- /man/peakProcess.Rd: -------------------------------------------------------------------------------- 1 | \name{peakProcess} 2 | 3 | \alias{peakProcess} 4 | \alias{peakProcess,MSImagingExperiment_OR_Arrays-method} 5 | 6 | \title{Process peaks in mass spectra} 7 | 8 | \description{ 9 | Apply peak picking and alignment to a mass spectrometry imaging dataset. 10 | } 11 | 12 | \usage{ 13 | \S4method{peakProcess}{MSImagingExperiment_OR_Arrays}(object, ref, 14 | spectra = "intensity", index = "mz", 15 | method = c("diff", "sd", "mad", "quantile", "filter", "cwt"), 16 | SNR = 2, type = c("height", "area"), 17 | tolerance = NA, units = c("ppm", "mz"), 18 | sampleSize = NA, filterFreq = TRUE, outfile = NULL, 19 | verbose = getCardinalVerbose(), chunkopts = list(), 20 | BPPARAM = getCardinalBPPARAM(), \dots) 21 | } 22 | 23 | \arguments{ 24 | \item{object}{A spectral imaging dataset.} 25 | 26 | \item{ref}{The locations of reference peaks to use for the alignment.} 27 | 28 | \item{spectra}{The name of the array in \code{spectraData()} to use for the peak intensities.} 29 | 30 | \item{index}{The name of the array in \code{spectraData()} (for \code{MSImagingArrays}) or column in \code{featureData()} (for \code{MSImagingExperiment}) to use for the peak locations.} 31 | 32 | \item{method}{The peak picking method to use. See \code{\link[matter]{findpeaks}} for details.} 33 | 34 | \item{SNR}{The signal-to-noise threshold to use to determine a peak.} 35 | 36 | \item{type}{The type of value to use to summarize the peak.} 37 | 38 | \item{tolerance}{The tolerance for matching a detected peak to the reference peaks or the shared m/z values. Passed to \code{\link{peakPick}} and \code{\link{peakAlign}}.} 39 | 40 | \item{units}{The units for the above tolerance.} 41 | 42 | \item{sampleSize}{The count or proportion giving a subset of spectra to use to determine reference peaks.} 43 | 44 | \item{filterFreq}{Either a logical value indicating whether singleton peaks should be removed, or a count or frequency used as a threshold to filter the peaks.} 45 | 46 | \item{outfile}{Optional. The name of a file to write the resulting dataset as imzML.} 47 | 48 | \item{verbose}{Should progress messages be printed?} 49 | 50 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 51 | 52 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 53 | 54 | \item{\dots}{Options passed to \code{process()}.} 55 | } 56 | 57 | \details{ 58 | This method provides a combined interface for \code{\link{peakPick}} and \code{\link{peakAlign}} for the most common approaches to peak processing. 59 | 60 | If \code{peakPick()} has been queued already, then it will be applied. Otherwise, it will be called internally with the provided arguments. 61 | 62 | There are two main paths depending on whether (1) peaks should be extracted based on a reference or (2) peak picking should be performed on the full dataset and then aligned. 63 | 64 | If either \code{ref} is provided or \code{sampleSize} is finite, then (1) is chosen and peaks are extracted based on the reference. If the reference is not provided, then peak picking and alignment performed on a subset of spectra (according to \code{sampleSize}) to create the reference peaks. The reference peaks are then used to extract peaks from the full dataset. 65 | 66 | Otherwise, (2) is chosen and peaks are picked and aligned across all spectra. 67 | 68 | The advantage of (1) is that all reference peaks will be summarized even they would not have a high enough signal-to-noise ratio to be detected in some spectra. The disadvantage is that rare peaks that do not appear in the sampled subset of spectra will not be included in the process peaks. 69 | 70 | The advantage of (2) is that rare peaks will be included because peak detection is performed on all spectra. The disadvantage is that some peaks may be missing from some spectra despite having nonzero intensities, because they did not have a high enough signal-to-noise ratio to be detected as peaks. 71 | 72 | Setting \code{sampleSize} to 1 will balance these advantages and disadvantages because the reference will be based on all spectra. However, this means the full dataset must be processed at least twice (possibly more if intermediate calculations are necessary), so it will be more time-consuming. 73 | } 74 | 75 | \value{ 76 | A new object derived from \code{MSImagingExperiment} with the processed peaks. 77 | } 78 | 79 | \author{ 80 | Kylie A. Bemis 81 | } 82 | 83 | \seealso{ 84 | \code{\link{process}} 85 | \code{\link{peakPick}}, 86 | \code{\link{peakAlign}} 87 | } 88 | 89 | \examples{ 90 | set.seed(1, kind="L'Ecuyer-CMRG") 91 | mse <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 92 | 93 | # process peaks 94 | mse2 <- peakProcess(mse, method="diff", SNR=3) 95 | plot(mse2, i=4) 96 | } 97 | 98 | \keyword{ts} 99 | -------------------------------------------------------------------------------- /man/process.Rd: -------------------------------------------------------------------------------- 1 | \name{process} 2 | 3 | \alias{process} 4 | \alias{process,MSImagingExperiment-method} 5 | \alias{process,MSImagingArrays-method} 6 | \alias{process,SpectralImagingExperiment-method} 7 | \alias{process,SpectralImagingArrays-method} 8 | \alias{addProcessing,SpectralImagingData-method} 9 | \alias{reset} 10 | 11 | \title{Apply queued processing to spectra} 12 | 13 | \description{ 14 | Queue pre-processing steps on an imaging dataset and apply them, possibly writing out the processed data to a file. 15 | } 16 | 17 | \usage{ 18 | \S4method{process}{MSImagingExperiment}(object, spectra = "intensity", index = "mz", 19 | domain = NULL, outfile = NULL, \dots) 20 | 21 | \S4method{process}{MSImagingArrays}(object, spectra = "intensity", index = "mz", 22 | domain = NULL, outfile = NULL, \dots) 23 | 24 | \S4method{process}{SpectralImagingExperiment}(object, spectra = "intensity", index = NULL, 25 | domain = NULL, outfile = NULL, 26 | verbose = getCardinalVerbose(), chunkopts = list(), 27 | BPPARAM = getCardinalBPPARAM(), \dots) 28 | 29 | \S4method{process}{SpectralImagingArrays}(object, spectra = "intensity", index = NULL, 30 | domain = NULL, outfile = NULL, 31 | verbose = getCardinalVerbose(), chunkopts = list(), 32 | BPPARAM = getCardinalBPPARAM(), \dots) 33 | 34 | \S4method{addProcessing}{SpectralImagingData}(object, FUN, label, metadata = list(), 35 | verbose = getCardinalVerbose(), \dots) 36 | 37 | reset(object, \dots) 38 | } 39 | 40 | \arguments{ 41 | \item{object}{A spectral imaging dataset.} 42 | 43 | \item{spectra}{The name of the array in \code{spectraData()} to use for the peak intensities.} 44 | 45 | \item{index}{The name of the array in \code{spectraData()} (for \code{MSImagingArrays}) or column in \code{featureData()} (for \code{MSImagingExperiment}) to use for the peak locations.} 46 | 47 | \item{domain}{Optional. The name of the array in \code{spectraData()} (for \code{MSImagingArrays}) or column in \code{featureData()} (for \code{MSImagingExperiment}) to use for output domain (if known).} 48 | 49 | \item{outfile}{Optional. The name of a file to write the resulting dataset. Creates an imzML file for \code{MSImagingExperiment} or \code{MSImagingArrays}. The "continuous" format will be written if \code{domain} is specified; otherwise the "processed" format will be used in most cases.} 50 | 51 | \item{verbose}{Should progress messages be printed?} 52 | 53 | \item{chunkopts}{Chunk processing options. See \code{\link{chunkApply}} for details.} 54 | 55 | \item{BPPARAM}{An optional instance of \code{BiocParallelParam}. See documentation for \code{\link{bplapply}}.} 56 | 57 | \item{\dots}{For \code{process}, options passed to \code{\link[matter]{chunk_mapply}} or \code{\link[matter]{chunk_colapply}}. For \code{addProcessing}, arguments to \code{FUN}.} 58 | 59 | \item{FUN}{A user-specified processing function.} 60 | 61 | \item{label}{The name of the processing step.} 62 | 63 | \item{metadata}{A list of processing metadata to be added to the object's metadata after processing has been applied. Concatenated with any arguments passed to \code{FUN} via \code{dots}.} 64 | } 65 | 66 | \details{ 67 | This method allows queueing of delayed processing to an imaging dataset. All of the queued processing steps will be applied in sequence whenever \code{process()} is called next. Use \code{reset()} to remove all queued processing steps. 68 | 69 | Typically, processing steps are queued using methods like \code{normalize}, \code{smooth}, \code{peakPick}, etc. 70 | 71 | However, a processing step can be queued manually with \code{addProcessing}. 72 | 73 | In this case, the user-specified function \emph{must} accept (1) a first argument giving the spectral intensities as a numeric vector and (2) a second argument giving the intensity locations (e.g., m/z values) as a numeric vector. 74 | 75 | The value returned by a user-specified function \code{must} return either (1) a numeric vector of the same length as the input intensities or (2) a 2-column matrix where the first column is the new locations (e.g., m/z values of peaks) and the second column is the new intensities. 76 | } 77 | 78 | \value{ 79 | An object of the same class as the original object, with all processing steps applied. 80 | } 81 | 82 | \author{ 83 | Kylie A. Bemis 84 | } 85 | 86 | \seealso{ 87 | \code{\link{normalize}}, 88 | \code{\link{smooth}}, 89 | \code{\link{recalibrate}}, 90 | \code{\link{reduceBaseline}}, 91 | \code{\link{peakPick}} 92 | } 93 | 94 | \examples{ 95 | set.seed(1, kind="L'Ecuyer-CMRG") 96 | mse <- simulateImage(preset=1, dim=c(3,3), baseline=1) 97 | 98 | mse2 <- smooth(mse, width=11) 99 | mse2 <- reduceBaseline(mse2) 100 | plot(mse2, i=4) 101 | 102 | mse2 <- process(mse2) 103 | } 104 | 105 | \keyword{manip} 106 | \keyword{ts} 107 | -------------------------------------------------------------------------------- /man/plot-spectra.Rd: -------------------------------------------------------------------------------- 1 | \name{plot-spectra} 2 | \alias{plot-spectra} 3 | 4 | \alias{plot} 5 | \alias{plot,MSImagingExperiment,numeric-method} 6 | \alias{plot,MSImagingExperiment,character-method} 7 | \alias{plot,MSImagingExperiment,formula-method} 8 | \alias{plot,MSImagingExperiment,missing-method} 9 | 10 | \alias{plot,MSImagingArrays,numeric-method} 11 | \alias{plot,MSImagingArrays,formula-method} 12 | \alias{plot,MSImagingArrays,missing-method} 13 | 14 | \alias{plot,SpectralImagingExperiment,numeric-method} 15 | \alias{plot,SpectralImagingExperiment,character-method} 16 | \alias{plot,SpectralImagingExperiment,formula-method} 17 | \alias{plot,SpectralImagingExperiment,missing-method} 18 | 19 | \alias{plot,SpectralImagingArrays,numeric-method} 20 | \alias{plot,SpectralImagingArrays,formula-method} 21 | \alias{plot,SpectralImagingArrays,missing-method} 22 | 23 | \alias{plot,XDataFrame,character-method} 24 | \alias{plot,XDataFrame,formula-method} 25 | \alias{plot,XDataFrame,missing-method} 26 | 27 | \title{Plot spectra from a spectral imaging dataset} 28 | 29 | \description{ 30 | Create and display plots from the spectra or feature data of a spectral imaging dataset using a formula interface. 31 | } 32 | 33 | \usage{ 34 | \S4method{plot}{MSImagingExperiment,missing}(x, 35 | formula = intensity ~ mz, 36 | i = pixels(x, coord=coord, run=run), 37 | coord = NULL, 38 | run = NULL, 39 | \dots, 40 | xlab, ylab, 41 | isPeaks = isCentroided(x)) 42 | 43 | \S4method{plot}{MSImagingArrays,missing}(x, 44 | formula = intensity ~ mz, 45 | i = pixels(x, coord=coord, run=run), 46 | coord = NULL, 47 | run = NULL, 48 | \dots, 49 | xlab, ylab, 50 | isPeaks = isCentroided(x)) 51 | 52 | \S4method{plot}{SpectralImagingExperiment,missing}(x, 53 | formula, 54 | i = 1L, 55 | groups = NULL, 56 | superpose = FALSE, 57 | key = TRUE, 58 | \dots, 59 | n = Inf, 60 | downsampler = "lttb", 61 | isPeaks = FALSE, 62 | annPeaks = 0) 63 | 64 | \S4method{plot}{SpectralImagingArrays,missing}(x, 65 | formula, 66 | i = 1L, 67 | groups = NULL, 68 | superpose = FALSE, 69 | key = TRUE, 70 | \dots, 71 | n = Inf, 72 | downsampler = "lttb", 73 | isPeaks = FALSE, 74 | annPeaks = 0) 75 | 76 | \S4method{plot}{XDataFrame,missing}(x, 77 | formula, 78 | superpose = FALSE, 79 | key = TRUE, 80 | \dots, 81 | n = Inf, 82 | downsampler = "lttb", 83 | isPeaks = FALSE, 84 | annPeaks = 0) 85 | } 86 | 87 | \arguments{ 88 | \item{x}{A spectral imaging dataset.} 89 | 90 | \item{formula}{A formula of the form \code{vals ~ t} giving the spectra values and their domain locations. The LHS is taken to be the name of an array in \code{spectraData()} and the RHS is either an array in \code{spectraData()} for \code{SpectralImagingArrays}-derived classes or a column of \code{featureData()} for \code{SpectralImagingExperiment}-derived classes. Alternatively, if \code{formula} is a string or if \code{i} is NULL, then the LHS is interpreted as the name of a column of \code{featureData()} for \code{SpectralImagingExperiment} as well.} 91 | 92 | \item{i}{The index of the spectrum to plot.} 93 | 94 | \item{coord}{The coordinates of the spectrum to plot.} 95 | 96 | \item{run}{The run of the spectrum to plot.} 97 | 98 | \item{\dots}{Additional arguments passed to \code{\link[matter]{plot_signal}}.} 99 | 100 | \item{xlab, ylab}{Plotting labels.} 101 | 102 | \item{isPeaks}{Should the spectrum be plotted as peaks or as a continuous signal?} 103 | 104 | \item{annPeaks}{If \code{isPeaks} is \code{TRUE}, either an integer giving the number of peaks to annotate (i.e., label with their location), or a plotting symbol (e.g., "circle", "cross", etc.) to indicate the peak locations.} 105 | 106 | \item{groups}{A vector coercible to a factor indicating which of the specified spectra should be plotted with the same color.} 107 | 108 | \item{superpose}{If multiple spectra are plotted, should they be superposed on top of each other, or plotted seperately?} 109 | 110 | \item{key}{Should a legend or colorkey be plotted?} 111 | 112 | \item{n, downsampler}{A spectrum can contain far more data points than are needed to visualize it, potentially making the plotting unnecessarily slow. Downsampling can be performed to improve plotting speed while maintaining the visual integrity of the spectrum. See \code{\link{downsample}} for details.} 113 | } 114 | 115 | \author{ 116 | Kylie A. Bemis 117 | } 118 | 119 | \seealso{ 120 | \code{\link{plot}}, 121 | \code{\link{plot_signal}} 122 | } 123 | 124 | \examples{ 125 | set.seed(1, kind="L'Ecuyer-CMRG") 126 | x <- simulateImage(preset=1, npeaks=10, dim=c(3,3)) 127 | 128 | plot(x, i=4) 129 | plot(x, coord=c(x=1, y=2)) 130 | plot(x, log2(intensity + 1) ~ mz, i=4, 131 | xlab=expression(italic("m/z")), 132 | ylab=expression(italic("Log Intensity"))) 133 | } 134 | 135 | \keyword{hplot} 136 | 137 | -------------------------------------------------------------------------------- /man/MSImagingExperiment-class.Rd: -------------------------------------------------------------------------------- 1 | \name{MSImagingExperiment-class} 2 | \docType{class} 3 | 4 | \alias{class:MSImagingExperiment} 5 | \alias{MSImagingExperiment} 6 | \alias{MSImagingExperiment-class} 7 | 8 | \alias{show,MSImagingExperiment-method} 9 | \alias{mz,missing-method} 10 | \alias{mz,MSImagingExperiment-method} 11 | \alias{mz<-,MSImagingExperiment-method} 12 | \alias{intensity,MSImagingExperiment-method} 13 | \alias{intensity<-,MSImagingExperiment-method} 14 | \alias{centroided,MSImagingExperiment_OR_Arrays-method} 15 | \alias{centroided<-,MSImagingExperiment_OR_Arrays-method} 16 | \alias{isCentroided,MSImagingExperiment_OR_Arrays-method} 17 | \alias{experimentData,MSImagingExperiment_OR_Arrays-method} 18 | \alias{experimentData<-,MSImagingExperiment_OR_Arrays,ANY-method} 19 | \alias{cbind,MSImagingExperiment-method} 20 | \alias{rbind,MSImagingExperiment-method} 21 | \alias{coerce,MSImageSet,MSImagingExperiment-method} 22 | 23 | \title{MSImagingExperiment: MS imaging data with shared m/z values} 24 | 25 | \description{ 26 | The \code{MSImagingExperiment} class provides a matrix-like container for high-throughput mass spectrometry imaging data where every mass spectrum shares the same m/z values. It is designed to provide easy access to both the spectra (as columns) and sliced images (as rows). 27 | 28 | It can be converted from a \code{\linkS4class{MSImagingArrays}} object which is designed for representing raw mass spectra. 29 | } 30 | 31 | \usage{ 32 | ## Instance creation 33 | MSImagingExperiment(spectraData = SimpleList(), 34 | featureData = MassDataFrame(), pixelData = PositionDataFrame(), 35 | experimentData = NULL, centroided = NA, metadata = list()) 36 | 37 | ## Additional methods documented below 38 | } 39 | 40 | \arguments{ 41 | \item{spectraData}{Either a matrix-like object with number of rows equal to the number of features and number of columns equal to the number of pixels, a list of such objects, or a \code{\linkS4class{SpectraArrays}} instance.} 42 | 43 | \item{featureData}{A \code{\linkS4class{MassDataFrame}} with feature metadata, with a row for each feature.} 44 | 45 | \item{pixelData}{A \code{\linkS4class{PositionDataFrame}} with pixel metadata, with a row for each spectrum.} 46 | 47 | \item{experimentData}{Either NULL or a \code{\linkS4class{ImzMeta}} object with MS-specific experiment-level metadata.} 48 | 49 | \item{centroided}{A logical value indicated whether the spectra have been centroided.} 50 | 51 | \item{metadata}{A list of arbitrary metadata.} 52 | } 53 | 54 | \section{Slots}{ 55 | \describe{ 56 | \item{\code{spectraData}:}{A \code{\linkS4class{SpectraArrays}} object storing one or more array-like data elements with conformable dimensions.} 57 | 58 | \item{\code{featureData}:}{A \code{\linkS4class{MassDataFrame}} containing feature-level metadata.} 59 | 60 | \item{\code{elementMetadata}:}{A \code{\linkS4class{PositionDataFrame}} containing spectrum-level metadata, including each spectrum's pixel coordinates and experimental run information.} 61 | 62 | \item{\code{processing}:}{A list containing unexecuted \code{\linkS4class{ProcessingStep}} objects.} 63 | 64 | \item{\code{experimentData}:}{Either NULL or an \code{\linkS4class{ImzMeta}} object containing experiment-level metadata (necessary for writing the data to imzML).} 65 | 66 | \item{\code{centroided}:}{A logical value indicated whether the spectra have been centroided (if known).} 67 | } 68 | } 69 | 70 | \section{Methods}{ 71 | All methods for \code{\linkS4class{SpectralImagingData}} and \code{\linkS4class{SpectralImagingExperiment}} also work on \code{MSImagingExperiment} objects. Additional methods are documented below: 72 | 73 | \describe{ 74 | \item{\code{mz(object, ...)}, \code{mz(object, ...) <- value}:}{Get or set the m/z column in the \code{featureData} slot.} 75 | 76 | \item{\code{intensity(object, ...)}, \code{intensity(object, ...) <- value}:}{Get or set the intensity matrix in the \code{spectraData} slot.} 77 | 78 | \item{\code{centroided(object, ...)}, \code{centroided(object, ...) <- value}:}{Get or set the \code{centroided} slot.} 79 | 80 | \item{\code{isCentroided(object, ...)}:}{Equivalent to \code{isTRUE(centroided(object))}.} 81 | 82 | \item{\code{experimentData(object)}, \code{experimentData(object) <- value}:}{Get or set the \code{experimentData} slot.} 83 | } 84 | } 85 | 86 | \author{Kylie A. Bemis} 87 | 88 | \seealso{ 89 | \code{\linkS4class{SpectralImagingExperiment}}, 90 | \code{\linkS4class{MSImagingArrays}} 91 | } 92 | 93 | \examples{ 94 | set.seed(1, kind="L'Ecuyer-CMRG") 95 | x <- matrix(rlnorm(81), nrow=9, ncol=9) 96 | mz <- sort(runif(9)) 97 | coord <- expand.grid(x=1:3, y=1:3) 98 | 99 | mse <- MSImagingExperiment( 100 | spectraData=x, 101 | featureData=MassDataFrame(mz=mz), 102 | pixelData=PositionDataFrame(coord)) 103 | 104 | print(mse) 105 | } 106 | 107 | \keyword{classes} 108 | -------------------------------------------------------------------------------- /man/SpectralImagingExperiment-class.Rd: -------------------------------------------------------------------------------- 1 | \name{SpectralImagingExperiment-class} 2 | \docType{class} 3 | 4 | \alias{class:SpectralImagingExperiment} 5 | \alias{SpectralImagingExperiment} 6 | \alias{SpectralImagingExperiment-class} 7 | 8 | \alias{show,SpectralImagingExperiment-method} 9 | \alias{fData,SpectralImagingExperiment-method} 10 | \alias{fData<-,SpectralImagingExperiment,ANY-method} 11 | \alias{featureData,SpectralImagingExperiment-method} 12 | \alias{featureData<-,SpectralImagingExperiment,ANY-method} 13 | \alias{featureNames,SpectralImagingExperiment-method} 14 | \alias{featureNames<-,SpectralImagingExperiment-method} 15 | \alias{colnames,SpectralImagingExperiment-method} 16 | \alias{colnames<-,SpectralImagingExperiment-method} 17 | \alias{rownames,SpectralImagingExperiment-method} 18 | \alias{rownames<-,SpectralImagingExperiment-method} 19 | \alias{names,SpectralImagingExperiment-method} 20 | \alias{names<-,SpectralImagingExperiment-method} 21 | \alias{length,SpectralImagingExperiment-method} 22 | \alias{[,SpectralImagingExperiment,ANY,ANY,ANY-method} 23 | \alias{[<-,SpectralImagingExperiment,ANY,ANY,ANY-method} 24 | \alias{dim,SpectralImagingExperiment-method} 25 | \alias{cbind,SpectralImagingExperiment-method} 26 | \alias{rbind,SpectralImagingExperiment-method} 27 | \alias{combine,SpectralImagingExperiment,ANY-method} 28 | 29 | \title{SpectralImagingExperiment: Spectral imaging data with shared domain} 30 | 31 | \description{ 32 | The \code{SpectralImagingExperiment} class provides a matrix-like container for high-dimensional spectral imaging data where every spectrum shares the same domain values. It is designed to provide easy access to both the spectra (as columns) and sliced images (as rows). 33 | 34 | The \code{\linkS4class{MSImagingExperiment}} class extends \code{SpectralImagingExperiment} for mass spectrometry-based imaging experiments with aligned mass features. 35 | } 36 | 37 | \usage{ 38 | ## Instance creation 39 | SpectralImagingExperiment(spectraData = SimpleList(), 40 | featureData = DataFrame(), pixelData = PositionDataFrame(), 41 | metadata = list()) 42 | 43 | ## Additional methods documented below 44 | } 45 | 46 | \arguments{ 47 | \item{spectraData}{Either a matrix-like object with number of rows equal to the number of features and number of columns equal to the number of pixels, a list of such objects, or a \code{\linkS4class{SpectraArrays}} instance.} 48 | 49 | \item{featureData}{A \code{\linkS4class{DataFrame}} with feature metadata, with a row for each feature.} 50 | 51 | \item{pixelData}{A \code{\linkS4class{PositionDataFrame}} with pixel metadata, with a row for each spectrum.} 52 | 53 | \item{metadata}{A \code{list} with experimental-level metadata.} 54 | } 55 | 56 | \section{Slots}{ 57 | \describe{ 58 | \item{\code{spectraData}:}{A \code{\linkS4class{SpectraArrays}} object storing one or more array-like data elements with conformable dimensions.} 59 | 60 | \item{\code{featureData}:}{A \code{\linkS4class{DataFrame}} containing feature-level metadata (e.g., a color channel, a molecular analyte, or a mass-to-charge ratio).} 61 | 62 | \item{\code{elementMetadata}:}{A \code{\linkS4class{PositionDataFrame}} containing spectrum-level metadata, including each spectrum's pixel coordinates and experimental run information.} 63 | 64 | \item{\code{processing}:}{A list containing unexecuted \code{\linkS4class{ProcessingStep}} objects.} 65 | } 66 | } 67 | 68 | \section{Methods}{ 69 | All methods for \code{\linkS4class{SpectralImagingData}} also work on \code{SpectralImagingExperiment} objects. Additional methods are documented below: 70 | 71 | \describe{ 72 | \item{\code{featureData(object)}, \code{featureData(object) <- value}:}{Get or set the \code{featureData} slot.} 73 | 74 | \item{\code{fData(object)}, \code{fData(object) <- value}:}{Get or set the \code{featureData} slot.} 75 | 76 | \item{\code{featureNames(object)}, \code{featureNames(object) <- value}:}{Get or set the feature names (i.e., the row names of the \code{featureData} slot).} 77 | 78 | \item{\code{length(object)}:}{Get the number of spectra in the object.} 79 | 80 | \item{\code{nrow(object)}, \code{ncol(object)}:}{Get the number of rows (features) or the number of columns (pixels) in the object.} 81 | 82 | \item{\code{object[i, j, ..., drop]}:}{Subset based on the rows (\code{featureData}) and the columns (\code{pixelData}). The result is the same class as the original object.} 83 | 84 | \item{\code{rbind(...)}, \code{cbind(...)}:}{Combine \code{SpectralImagingExperiment} objects by row or column.} 85 | } 86 | } 87 | 88 | \author{Kylie A. Bemis} 89 | 90 | \seealso{ 91 | \code{\linkS4class{SpectralImagingData}}, 92 | \code{\linkS4class{MSImagingExperiment}} 93 | } 94 | 95 | \examples{ 96 | set.seed(1, kind="L'Ecuyer-CMRG") 97 | x <- matrix(rlnorm(81), nrow=9, ncol=9) 98 | index <- 1:9 99 | coord <- expand.grid(x=1:3, y=1:3) 100 | 101 | se <- SpectralImagingExperiment( 102 | spectraData=x, 103 | featureData=DataFrame(index=1:9), 104 | pixelData=PositionDataFrame(coord)) 105 | 106 | print(se) 107 | } 108 | 109 | \keyword{classes} 110 | -------------------------------------------------------------------------------- /tests/testthat/test-SpectralImagingExperiment.R: -------------------------------------------------------------------------------- 1 | require(testthat) 2 | require(Cardinal) 3 | 4 | context("SpectralImagingExperiment") 5 | 6 | test_that("SpectralImagingExperiment accessors", { 7 | 8 | se <- SpectralImagingExperiment() 9 | 10 | expect_true(validObject(se)) 11 | 12 | se <- SpectralImagingExperiment(matrix(nrow=0, ncol=0)) 13 | 14 | expect_true(validObject(se)) 15 | 16 | set.seed(1) 17 | nr <- 20 18 | nc <- 10 19 | a <- matrix(rlnorm(nr * nc), nrow=nr, ncol=nc) 20 | s <- SpectraArrays(a) 21 | fdata <- XDataFrame(index=seq_len(nr), 22 | wavelength=seq(900, 1000, length.out=nr), keys=list(index="index")) 23 | fdata2 <- XDataFrame(index=nr+seq_len(nr), 24 | wavelength=seq(1001, 1100, length.out=nr), keys=list(index="index")) 25 | pdata <- PositionDataFrame( 26 | coord=expand.grid(x=1:5, y=1:2), 27 | diagnosis=rep(c("yes", "no"), each=5)) 28 | pdata2 <- PositionDataFrame( 29 | coord=expand.grid(x=1:5, y=3:4), 30 | diagnosis=rep(c("yes", "no"), each=5)) 31 | se <- SpectralImagingExperiment(s, featureData=fdata, pixelData=pdata) 32 | 33 | expect_true(validObject(se)) 34 | expect_length(se, nc) 35 | expect_equal(dim(se), c(nr, nc)) 36 | 37 | expect_equal(spectraData(se), s) 38 | expect_equal(pixelData(se), pdata) 39 | expect_equal(featureData(se), fdata) 40 | 41 | expect_equal(spectra(se), s[[1L]]) 42 | expect_equal(pData(se), pdata) 43 | expect_equal(fData(se), fdata) 44 | 45 | expect_equal(coord(se), coord(pdata)) 46 | expect_equal(run(se), run(pdata)) 47 | expect_equal(nrun(se), nrun(pdata)) 48 | expect_equal(se$diagnosis, pdata$diagnosis) 49 | 50 | expect_setequal(features(se, 1:10), 1:10) 51 | expect_setequal(features(se, wavelength > 920), 5:20) 52 | expect_setequal(features(se, wavelength < 975), 1:15) 53 | expect_setequal(features(se, 1:10, wavelength > 920), 5:10) 54 | expect_setequal(features(se, 1:10, wavelength < 975), 1:10) 55 | 56 | w1 <- 920 57 | w2 <- 975 58 | 59 | expect_setequal(features(se, wavelength > w1), 5:20) 60 | expect_setequal(features(se, wavelength < w2), 1:15) 61 | expect_setequal(features(se, 1:10, wavelength > w1), 5:10) 62 | expect_setequal(features(se, 1:10, wavelength < w2), 1:10) 63 | 64 | expect_equal(subsetFeatures(se, wavelength > w1), se[5:20,]) 65 | expect_equal(subsetFeatures(se, wavelength < w2), se[1:15,]) 66 | expect_equal(subset(se, wavelength > w1, 1:5), se[5:20,1:5]) 67 | expect_equal(subset(se, wavelength < w2, 1:5), se[1:15,1:5]) 68 | 69 | expect_equal(subsetPixels(se, 1:5), se[,1:5]) 70 | expect_equal(subsetPixels(se, diagnosis == "yes"), se[,se$diagnosis == "yes"]) 71 | expect_equal(subsetFeatures(se, 1:10), se[1:10,]) 72 | 73 | pixelData(se) <- pdata2 74 | featureData(se) <- fdata2 75 | 76 | expect_true(validObject(se)) 77 | expect_equal(pixelData(se), pdata2) 78 | expect_equal(featureData(se), fdata2) 79 | 80 | coord(se) <- coord(pdata) 81 | run(se) <- run(pdata) 82 | 83 | expect_equal(coord(se), coord(pdata)) 84 | expect_equal(run(se), run(pdata)) 85 | 86 | se2 <- se[1:10,1:5] 87 | se3 <- se[1:10,] 88 | se4 <- se[,1:5] 89 | 90 | expect_true(validObject(se2)) 91 | expect_equal(dim(se2), c(10,5)) 92 | expect_equal(spectra(se2), spectra(se)[1:10,1:5]) 93 | expect_equal(pixelData(se2), pixelData(se)[1:5,]) 94 | expect_equal(featureData(se2), featureData(se)[1:10,]) 95 | 96 | expect_true(validObject(se3)) 97 | expect_equal(dim(se3), c(10,10)) 98 | expect_equal(spectra(se3), spectra(se)[1:10,]) 99 | expect_equal(featureData(se2), featureData(se)[1:10,]) 100 | 101 | expect_true(validObject(se4)) 102 | expect_equal(dim(se4), c(20,5)) 103 | expect_equal(spectra(se4), spectra(se)[,1:5]) 104 | expect_equal(pixelData(se2), pixelData(se)[1:5,]) 105 | 106 | }) 107 | 108 | test_that("SpectralImagingExperiment rbind/cbind", { 109 | 110 | set.seed(1) 111 | nr <- 20 112 | nc <- 10 113 | a <- matrix(rlnorm(nr * nc), nrow=nr, ncol=nc) 114 | s <- SpectraArrays(a) 115 | fdata <- XDataFrame(index=seq_len(nr), 116 | wavelength=seq(900, 1000, length.out=nr), keys=list(index="index")) 117 | fdata2 <- XDataFrame(index=nr+seq_len(nr), 118 | wavelength=seq(1001, 1100, length.out=nr), keys=list(index="index")) 119 | pdata <- PositionDataFrame( 120 | coord=expand.grid(x=1:5, y=1:2), 121 | diagnosis=rep(c("yes", "no"), each=5)) 122 | pdata2 <- PositionDataFrame( 123 | coord=expand.grid(x=1:5, y=3:4), 124 | diagnosis=rep(c("yes", "no"), each=5)) 125 | se <- SpectralImagingExperiment(s, featureData=fdata, pixelData=pdata) 126 | se02 <- SpectralImagingExperiment(s, featureData=fdata, pixelData=pdata2) 127 | se20 <- SpectralImagingExperiment(s, featureData=fdata2, pixelData=pdata) 128 | 129 | r00 <- rbind(se, se) 130 | expect_error(r02 <- rbind(se, se02)) 131 | r20 <- rbind(se, se20) 132 | 133 | expect_equal(spectra(r00), rbind(spectra(se), spectra(se))) 134 | expect_equal(fData(r00), rbind(fData(se), fData(se))) 135 | expect_equal(pData(r00), cbind(pData(se), pData(se))) 136 | expect_equal(spectra(r20), rbind(spectra(se), spectra(se20))) 137 | expect_equal(fData(r20), rbind(fData(se), fData(se20))) 138 | expect_equal(pData(r20), cbind(pData(se), pData(se20))) 139 | 140 | c00 <- cbind(se, se) 141 | c02 <- cbind(se, se02) 142 | expect_error(c20 <- cbind(se, se20)) 143 | 144 | expect_equal(spectra(c00), cbind(spectra(se), spectra(se))) 145 | expect_equal(fData(c00), cbind(fData(se), fData(se))) 146 | expect_equal(pData(c00), rbind(pData(se), pData(se))) 147 | expect_equal(spectra(c02), cbind(spectra(se), spectra(se02))) 148 | expect_equal(fData(c02), cbind(fData(se), fData(se02))) 149 | expect_equal(pData(c02), rbind(pData(se), pData(se02))) 150 | 151 | }) 152 | -------------------------------------------------------------------------------- /R/stats-spatialKMeans.R: -------------------------------------------------------------------------------- 1 | 2 | #### Spatially-aware k-means #### 3 | ## ------------------------------ 4 | 5 | setMethod("spatialKMeans", "ANY", 6 | function(x, coord, r = 1, k = 2, ncomp = max(k), 7 | weights = c("gaussian", "adaptive"), 8 | neighbors = findNeighbors(coord, r=r), 9 | transpose = TRUE, niter = 10L, 10 | centers = TRUE, correlation = TRUE, 11 | verbose = getCardinalVerbose(), chunkopts = list(), 12 | BPPARAM = getCardinalBPPARAM(), ...) 13 | { 14 | if ( "method" %in% ...names() ) { 15 | .Deprecated(old="method", new="weights") 16 | weights <- list(...)$method 17 | } 18 | if ( is.character(weights) ) { 19 | weights <- match.arg(weights) 20 | .Log("computing ", weights, " weights", 21 | message=verbose) 22 | nbwts <- spatialWeights(x=x, 23 | coord=coord, r=r, byrow=!transpose, 24 | weights=weights, neighbors=neighbors, 25 | verbose=verbose, chunkopts=chunkopts, 26 | BPPARAM=BPPARAM) 27 | } else { 28 | .Log("using custom weights", 29 | message=verbose) 30 | nbwts <- rep_len(weights, length(neighbors)) 31 | weights <- "custom" 32 | } 33 | if ( transpose ) { 34 | k <- pmin(k, nrow(x)) 35 | } else { 36 | k <- pmin(k, ncol(x)) 37 | } 38 | proj <- spatialFastmap(x, r=r, ncomp=ncomp, 39 | neighbors=neighbors, weights=nbwts, 40 | transpose=transpose, niter=niter, 41 | verbose=verbose, chunkopts=chunkopts, 42 | BPPARAM=BPPARAM, ...) 43 | k <- rev(sort(k)) 44 | ans <- vector("list", length=length(k)) 45 | truecenters <- vector("list", length=length(k)) 46 | for ( i in seq_along(k) ) 47 | { 48 | if ( i > 1L ) { 49 | icenters <- ans[[i - 1L]]$centers[seq_len(k[i]),,drop=FALSE] 50 | } else { 51 | icenters <- k[i] 52 | } 53 | .Log("fitting k-means for k = ", k[i], 54 | message=verbose) 55 | ans[[i]] <- kmeans(proj$x, centers=icenters, ...) 56 | if ( centers ) 57 | { 58 | .Log("calculating cluster centers", 59 | message=verbose) 60 | if ( transpose ) { 61 | truecenters[[i]] <- rowStats(x, "mean", 62 | group=as.factor(ans[[i]]$cluster), 63 | verbose=verbose, chunkopts=chunkopts, 64 | BPPARAM=BPPARAM) 65 | } else { 66 | truecenters[[i]] <- colStats(x, "mean", 67 | group=as.factor(ans[[i]]$cluster), 68 | verbose=verbose, chunkopts=chunkopts, 69 | BPPARAM=BPPARAM) 70 | } 71 | } 72 | if ( correlation ) 73 | { 74 | .Log("calculating spatial correlations with clusters", 75 | message=verbose) 76 | cls <- as.factor(ans[[i]]$cluster) 77 | lvl <- setNames(levels(cls), levels(cls)) 78 | mask <- lapply(lvl, function(ci) cls %in% ci) 79 | margin <- if (transpose) 1L else 2L 80 | FUN <- isofun(function(xi, mask) { 81 | vapply(mask, stats::cor, numeric(1L), y=xi) 82 | }, CardinalEnv()) 83 | corr <- chunkApply(x, margin, FUN, mask=mask, 84 | verbose=verbose, chunkopts=chunkopts, 85 | BPPARAM=BPPARAM) 86 | corr <- do.call(rbind, corr) 87 | rownames(corr) <- dimnames(x)[[margin]] 88 | ans[[i]]$correlation <- corr 89 | } 90 | ans[[i]]$weights <- weights 91 | ans[[i]]$ncomp <- ncomp 92 | ans[[i]]$r <- r 93 | ans[[i]]$k <- k[i] 94 | } 95 | for ( i in seq_along(k) ) 96 | { 97 | if ( centers ) { 98 | ans[[i]]$centers <- truecenters[[i]] 99 | } else { 100 | ans[[i]]$centers <- NULL 101 | } 102 | } 103 | names(ans) <- paste0("k=", k) 104 | .Log("returning spatial k-means", 105 | message=verbose) 106 | if ( length(ans) > 1L ) { 107 | ResultsList(ans, 108 | mcols=DataFrame(r=r, k=k, weights=weights, ncomp=ncomp)) 109 | } else { 110 | ans[[1L]] 111 | } 112 | }) 113 | 114 | setMethod("spatialKMeans", "SpectralImagingExperiment", 115 | function(x, r = 1, k = 2, ncomp = max(k), 116 | weights = c("gaussian", "adaptive"), 117 | neighbors = findNeighbors(x, r=r), ...) 118 | { 119 | if ( length(processingData(x)) > 0L ) 120 | .Warn("queued processing steps will be ignored") 121 | ans <- spatialKMeans(spectra(x), 122 | coord=coord(x), r=r, k=k, ncomp=ncomp, 123 | neighbors=neighbors, weights=weights, 124 | transpose=TRUE, ...) 125 | f <- function(a) as(SpatialResults(a, x), "SpatialKMeans") 126 | if ( is(ans, "ResultsList") ) { 127 | ResultsList(lapply(ans, f), mcols=mcols(ans)) 128 | } else { 129 | f(ans) 130 | } 131 | }) 132 | 133 | setMethod("topFeatures", "SpatialKMeans", 134 | function(object, n = Inf, sort.by = "correlation", ...) 135 | { 136 | sort.by <- match.arg(sort.by) 137 | corr <- object$correlation 138 | if ( is.null(corr) ) 139 | .Error("missing component: 'correlation'") 140 | cluster <- rep(colnames(corr), each=nrow(corr)) 141 | topf <- DataFrame(cluster=cluster, correlation=as.vector(corr)) 142 | topf <- .rank_featureData(object, topf, sort.by) 143 | head(topf, n=n) 144 | }) 145 | 146 | setMethod("plot", c(x = "SpatialKMeans", y = "missing"), 147 | function(x, type = c("correlation", "centers"), ..., xlab, ylab) 148 | { 149 | type <- match.arg(type) 150 | if ( missing(xlab) ) 151 | xlab <- NULL 152 | if ( type == "correlation" ) { 153 | if ( is.null(x$correlation) ) 154 | .Error("missing component: 'correlation'") 155 | if ( missing(ylab) ) 156 | ylab <- "Correlation" 157 | callNextMethod(x, y=x$correlation, xlab=xlab, ylab=ylab, ...) 158 | } else { 159 | if ( is.null(x$centers) ) 160 | .Error("missing component: 'centers'") 161 | if ( missing(ylab) ) 162 | ylab <- "Centers" 163 | callNextMethod(x, y=x$centers, xlab=xlab, ylab=ylab, ...) 164 | } 165 | }) 166 | 167 | setMethod("image", c(x = "SpatialKMeans"), 168 | function(x, type = "cluster", ...) 169 | { 170 | type <- match.arg(type) 171 | callNextMethod(x, y=as.factor(x$cluster), ...) 172 | }) 173 | 174 | 175 | --------------------------------------------------------------------------------