diff --git a/.Rbuildignore b/.Rbuildignore index 2da0e4f..f3c1d09 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,5 @@ ^hooks$ ^playground$ ^revdep$ +^.*\.Rproj$ +^\.Rproj\.user$ diff --git a/.gitignore b/.gitignore index 46a42de..da0db21 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.so *.o *.rds +.Rproj.user diff --git a/DESCRIPTION b/DESCRIPTION index 9452a26..6dc9f00 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MALDIquant -Version: 1.19.1 -Date: 2019-03-03 +Version: 1.19.15 +Date: 2019-03-05 Title: Quantitative Analysis of Mass Spectrometry Data Authors@R: c(person("Sebastian", "Gibb", role=c("aut", "cre"), email="mail@sebastiangibb.de", @@ -25,4 +25,84 @@ URL: http://strimmerlab.org/software/maldiquant/ BugReports: https://github.com/sgibb/MALDIquant/issues/ LazyLoad: yes VignetteBuilder: knitr -RoxygenNote: 5.0.1 +RoxygenNote: 6.1.1 +Collate: + 'AllClasses.R' + 'AllGenerics.R' + 'Deprecated.R' + 'hidden_aliases.R' + 'OnDiskVector-class.R' + 'alignSpectra-functions.R' + 'approxfun-methods.R' + 'as-methods.R' + 'as.matrix-functions.R' + 'as.matrix-methods.R' + 'averageMassSpectra-functions.R' + 'binPeaks-functions.R' + 'calculateLabelPositions-functions.R' + 'calibrateIntensity-functions.R' + 'calibrateIntensity-methods.R' + 'colMedians-functions.R' + 'constructor-functions.R' + 'coordinates-methods.R' + 'deprecated-functions.R' + 'detectPeaks-methods.R' + 'determineWarpingFunctions-functions.R' + 'doByLabels-functions.R' + 'estimateBaseline-functions.R' + 'estimateBaseline-methods.R' + 'estimateNoise-functions.R' + 'estimateNoise-methods.R' + 'filterPeaks-functions.R' + 'findEmptyMassObjects-functions.R' + 'findLocalMaxima-methods.R' + 'grouper-functions.R' + 'intensity-methods.R' + 'intensityMatrix-functions.R' + 'irregular-functions.R' + 'isEmpty-methods.R' + 'isFunctionList-functions.R' + 'isMassObject-functions.R' + 'isMassObjectList-functions.R' + 'isRegular-methods.R' + 'isValidHalfWindowSize-functions.R' + 'labelPeaks-methods.R' + 'lapply-functions.R' + 'length-methods.R' + 'lines-methods.R' + 'localMaxima-functions.R' + 'mapply-functions.R' + 'mass-methods.R' + 'match.closest-functions.R' + 'memoryUsage-functions.R' + 'merge-functions.R' + 'metaData-methods.R' + 'monoisotopic-functions.R' + 'monoisotopicPeaks-methods.R' + 'morphologicalFilter-functions.R' + 'msiSlices-functions.R' + 'mz-methods.R' + 'onAttach.R' + 'plot-methods.R' + 'plotMsiSlice-functions.R' + 'plotMsiSlice-methods.R' + 'points-methods.R' + 'range-functions.R' + 'referencePeaks-functions.R' + 'removeBaseline-methods.R' + 'removeEmptyMassObjects-functions.R' + 'reorder-functions.R' + 'replaceNegativeIntensityValues-functions.R' + 'show-functions.R' + 'show-methods.R' + 'smoothIntensity-methods.R' + 'smoothingFilters-functions.R' + 'snr-methods.R' + 'subset-methods.R' + 'totalIonCurrent-methods.R' + 'transformIntensity-methods.R' + 'trim-methods.R' + 'unlist-functions.R' + 'valid-methods.R' + 'warp-functions.R' + 'warpingFunction-functions.R' diff --git a/NAMESPACE b/NAMESPACE index af0c7c0..f1b8801 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,13 +49,17 @@ importFrom("utils", exportClasses("MassPeaks", - "MassSpectrum") + "MassSpectrum", + "MassSpectrumOnDisk", + "OnDiskVector") export("alignSpectra", "averageMassSpectra", "binPeaks", "createMassPeaks", "createMassSpectrum", + "createMassSpectrumOnDisk", + "OnDiskVector", "determineWarpingFunctions", "filterPeaks", "findEmptyMassObjects", diff --git a/R/AllClasses.R b/R/AllClasses.R index 5045c55..849cf1b 100644 --- a/R/AllClasses.R +++ b/R/AllClasses.R @@ -1,17 +1,63 @@ ## basic class for all spectra based information + +# AbstractMassObject (VIRTUAL, mass/intensity = "numeric"/"matter_vec", metaData="list/matter") +# ├── AbstractMassSpectrum (VIRTUAL, just for method implementation) +# │ ├── MassSpectrum (mass/intensity = "numeric"/"double", metaData="list") +# │ ├── MassSpectrumOnDisk (mass/intensity = "OnDiskVector", metaData="list") +# └── MassPeaks (mass/intensity = "numeric"/"double", metaData="list") + + +setClass("OnDiskVector", + slots=list( + path="character", + mpath="character", + modification="integer", + n="numeric", + offset="numeric", + size="integer" + ), + prototype=list( + path=character(), + mpath=character(), + modification=0L, + n=numeric(), + offset=numeric(), + size=integer() + ) +) + + +## Set a class union to extend slots +# type to matter Objects +setClassUnion("NumericOrOnDisk", c("numeric", "OnDiskVector")) + setClass("AbstractMassObject", - slots=list(mass="numeric", intensity="numeric", + slots=list(mass="NumericOrOnDisk", + intensity="NumericOrOnDisk", metaData="list"), - prototype=list(mass=numeric(), intensity=numeric(), + prototype=list(mass=numeric(), + intensity=numeric(), metaData=list()), contains="VIRTUAL") +## represnt abstract spectrum +setClass("AbstractMassSpectrum", + contains="AbstractMassObject") + ## represent a spectrum setClass("MassSpectrum", - contains="AbstractMassObject") + contains="AbstractMassSpectrum") + +## represent an On-disk spectrum +setClass("MassSpectrumOnDisk", + contains="AbstractMassSpectrum") ## represent a peak list from a single spectrum setClass("MassPeaks", slots=list(snr="numeric"), prototype=list(snr=numeric()), contains="AbstractMassObject") + + + + diff --git a/R/AllGenerics.R b/R/AllGenerics.R index b0733e5..2dc618c 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -77,7 +77,7 @@ if (is.null(getGeneric("coordinates<-"))) { ## end of AbstractMassObject -## MassSpectrum +## MassSpectrum/MassSpectrumOnDisk i.e. AbstractMassSpectrum if (is.null(getGeneric("approxfun"))) { setGeneric("approxfun", function(x, y=NULL, method="linear", yleft, yright, rule=1, f=0, @@ -128,7 +128,7 @@ if (is.null(getGeneric("totalIonCurrent"))) { setGeneric("totalIonCurrent", function(object) standardGeneric("totalIonCurrent")) } -## end of MassSpectrum +## end of MassSpectrum/MassSpectrumOnDisk ## MassPeaks if (is.null(getGeneric("labelPeaks"))) { diff --git a/R/OnDiskVector-class.R b/R/OnDiskVector-class.R new file mode 100644 index 0000000..cb0322f --- /dev/null +++ b/R/OnDiskVector-class.R @@ -0,0 +1,189 @@ +#' @include hidden_aliases.R +NULL + +#' @title OnDiskVector class +#' +#' @name OnDiskVector +#' +#' @aliases OnDiskVector-class +#' +#' @description +#' +#' [OnDiskVector-class] objects support the storage of numeric data on-disk. The +#' data are just loaded into memory when they have to be processed. +#' +#' @slot path file path +#' @slot mpath file path to the modification counter file +#' @slot modification counter, to detect modification after `odv2 <- odv` +#' @slot n length of the vector +#' @slot offset offset of the data in the file +#' @slot size size of one vector element in the file +#' +#' @author Sebastian Gibb +#' +#' @noRd + +setClass("OnDiskVector", + slots=list( + path="character", + mpath="character", + modification="integer", + n="numeric", + offset="numeric", + size="integer" + ), + prototype=list( + path=character(), + mpath=character(), + modification=0L, + n=numeric(), + offset=numeric(), + size=integer() + ) +) + +OnDiskVector <- function(x, path, n=length(x), offset=0L, size=8L) { + if (missing(x) && missing(path)) + stop("'x' or 'path' are necessary.") + if (!missing(x)) { + if (missing(path)) + path <- tempfile() + writeBin(as.double(x), con=path, size=size, endian="little") + } + mpath <- paste(path, "mod", sep=".") + writeBin(0L, mpath, size=NA_integer_, endian="little") + new("OnDiskVector", path=path, mpath=mpath, n=n, offset=offset, size=size) +} + +.valid.OnDiskVector.path <- function(x) { + if (length(x) != 1L) + return("'path' has to be a 'character' of length 1.") + if (!file.exists(x)) + return(paste0("File '", x, "' doesn't exists!")) + NULL +} + +.valid.OnDiskVector.modification <- function(x) { + if (length(x) != 1L) + return("'modification' has to be a 'numeric' of length 1.") + NULL +} + +.valid.OnDiskVector.n <- function(x) { + if (length(x) != 1L) + return("'n' has to be a 'numeric' of length 1.") + NULL +} + +.valid.OnDiskVector.offset <- function(x) { + if (length(x) != 1L) + return("'offset' has to be a 'numeric' of length 1.") + if (x < 0) + return("'offset' has to be >= 0.") + NULL +} + +.valid.OnDiskVector.size <- function(x) { + if (length(x) != 1L) + return("'size' has to be a 'integer' of length 1.") + if (log2(x) %% 1) + return("'size' has to be 2^x.") + NULL +} + +# .isModified.OnDiskVector <- function(x) { +# m <- readBin(x@mpath, integer(), n=1L, size=NA_integer_, endian="little") +# if (m != x@modification) +# stop(x@path, " was modified by a different object.") +# FALSE +# } + +setValidity("OnDiskVector", function(object) { + msg <- c( + .valid.OnDiskVector.path(object@path), + .valid.OnDiskVector.path(object@mpath), + .valid.OnDiskVector.modification(object@n), + .valid.OnDiskVector.n(object@n), + .valid.OnDiskVector.offset(object@offset), + .valid.OnDiskVector.size(object@size) + ) + if (is.null(msg)) { TRUE } else { msg } +}) + +#' @rdname hidden_aliases +setMethod("length", "OnDiskVector", function(x)x@n) + +#' @rdname hidden_aliases +setMethod(f="[", + signature=signature(x="OnDiskVector", i="numeric", j="missing"), + definition=function(x, i, j, ..., drop=FALSE) { + if (any(i < 1) || any (i > x@n)) + stop("Index out of boundaries.") + + #.isModified.OnDiskVector(x) + f <- file(x@path, "rb") + on.exit(close(f)) + + if (length(i) == 1L) { + if (x@offset || i > 1L) + seek(f, where=x@offset + (i - 1L) * x@size, rw="read") + .readBin(f, n=1L, size=x@size) + } else if (length(i) == 2) { + if (x@offset || i[1L] > 1L) + seek(f, where=x@offset + (i[1L] - 1L) * x@size, rw="read") + y <- .readBin(f, n=1L, size=x@size) + seek(f, where=x@offset + (i[2L] - 1L) * x@size, rw="read") + c(y, .readBin(f, n=1L, size=x@size)) + } else { + if (x@offset) + seek(f, where=x@offset, rw="read") + # that's stupid but not used often + .readBin(f, n=x@n, size=x@size)[i] + } +}) + +#' @rdname hidden_aliases +setMethod(f="[", + signature=signature(x="OnDiskVector", i="missing", j="missing"), + definition=function(x, i, j, ..., drop=FALSE) { + #.isModified.OnDiskVector(x) + f <- file(x@path, "rb") + on.exit(close(f)) + if (x@offset) + seek(f, where=x@offset, rw="read") + .readBin(f, n=x@n, size=x@size) +}) + +#' @rdname hidden_aliases +setReplaceMethod(f="[", + signature=signature(x="OnDiskVector", i="missing", j="missing"), + definition=function(x, i, j, ..., value) { + if (length(value) != x@n) { + stop("Length of 'value' doesn't match length of 'x'.") + } + f <- file(x@path, "r+b") # unpredictable behaviour with "wb" + on.exit(close(f)) + + if (x@offset) + seek(f, where=x@offset, rw="write") + writeBin(as.double(value), f, size=x@size, endian="little", useBytes = TRUE) + + x@modification <- x@modification + 1L + writeBin(x@modification, x@mpath, size=NA_integer_, endian="little") + # warning("The OnDiskVector has been modified by the following call:\n", + # deparse(match.call(definition = sys.function(sys.parent(n=5)))), "\n") + x +}) + +#' @rdname hidden_aliases +setMethod("min", "OnDiskVector", function(x)min(x[])) + +#' @rdname hidden_aliases +setMethod("max", "OnDiskVector", function(x)max(x[])) + +#' @rdname hidden_aliases +setMethod("range", "OnDiskVector", function(x)range(x[])) + +.readBin <- function(x, n, size) { + readBin(x, double(), n=n, size=size, signed=TRUE, endian="little") +} diff --git a/R/alignSpectra-functions.R b/R/alignSpectra-functions.R index d584492..f79589b 100644 --- a/R/alignSpectra-functions.R +++ b/R/alignSpectra-functions.R @@ -2,7 +2,7 @@ ## wrapper around detectPeaks, determineWarpingFunctions and warpMassSpectra ## ## params: -## spectra: list, list of MassSpectrum objects +## spectra: list, list of AbstractMassSpectrum objects ## halfWindowSize: numeric, half window size. ## noiseMethod: character, noise estimation method ## SNR: double, signal-to-noise ratio @@ -16,7 +16,7 @@ ## emptyNoMatches: logical, if TRUE mismatches (warping function NA) ## ## returns: -## a list of aligned MassSpectrum objects +## a list of aligned AbstractMassSpectrum objects ## alignSpectra <- function(spectra, ## peak detection diff --git a/R/approxfun-methods.R b/R/approxfun-methods.R index 5bfe6b6..1a88323 100644 --- a/R/approxfun-methods.R +++ b/R/approxfun-methods.R @@ -1,12 +1,12 @@ ## MassSpectrum setMethod(f="approxfun", - signature=signature(x="MassSpectrum"), + signature=signature(x="AbstractMassSpectrum"), definition=function(x, y=NULL, method="linear", yleft, yright, rule=1L, f=0L, ties=mean) { if (isEmpty(x)) { function(x)rep.int(NA, length(x)) } else { - approxfun(x=x@mass, y=x@intensity, method=method, + approxfun(x=mass(x), y=intensity(x), method=method, yleft=yleft, yright=yright, rule=rule, f=f, ties=ties) } }) diff --git a/R/as-methods.R b/R/as-methods.R index b74e504..62fd69a 100644 --- a/R/as-methods.R +++ b/R/as-methods.R @@ -7,3 +7,14 @@ setAs(from="MassPeaks", to="MassSpectrum", function (from)createMassSpectrum(mass=from@mass, intensity=from@intensity, metaData=from@metaData)) + + +## convert MassSpectrumOnDisk into MassSpectrum objects - from disk to memory +## +## returns: +## a MassSpectrum object + +setAs(from="MassSpectrumOnDisk", to="MassSpectrum", + function (from)createMassSpectrum(mass=mass(from), + intensity=intensity(from), + metaData=from@metaData)) diff --git a/R/as.matrix-functions.R b/R/as.matrix-functions.R index e9472de..188586b 100644 --- a/R/as.matrix-functions.R +++ b/R/as.matrix-functions.R @@ -10,8 +10,8 @@ .as.matrix.MassObjectList <- function(l) { .stopIfNotIsMassObjectList(l) - mass <- .unlist(lapply(l, function(x)x@mass)) - intensity <- .unlist(lapply(l, function(x)x@intensity)) + mass <- .unlist(lapply(l, function(x)mass(x))) + intensity <- .unlist(lapply(l, function(x)intensity(x))) uniqueMass <- sort.int(unique(mass)) n <- lengths(l) r <- rep.int(seq_along(l), n) diff --git a/R/as.matrix-methods.R b/R/as.matrix-methods.R index 03ff2a9..325ffab 100644 --- a/R/as.matrix-methods.R +++ b/R/as.matrix-methods.R @@ -3,6 +3,6 @@ setMethod(f="as.matrix", signature=signature(x="AbstractMassObject"), definition=function(x, index) { - matrix(c(x@mass[index], x@intensity[index]), ncol=2L, byrow=FALSE, + matrix(c(mass(x)[index], intensity(x)[index]), ncol=2L, byrow=FALSE, dimnames=list(NULL, c("mass", "intensity"))) }) diff --git a/R/averageMassSpectra-functions.R b/R/averageMassSpectra-functions.R index 94c39ef..c580c25 100644 --- a/R/averageMassSpectra-functions.R +++ b/R/averageMassSpectra-functions.R @@ -57,7 +57,7 @@ averageMassSpectra <- function(l, labels, method=c("mean", "median", "sum"), ## use the first non empty spectrum as reference i <- which(!vapply(l, isEmpty, logical(1L)))[1L] if (!is.na(i)) { - mass <- l[[i]]@mass + mass <- mass(l[[i]]) } else { mass <- NA_real_ } diff --git a/R/calibrateIntensity-functions.R b/R/calibrateIntensity-functions.R index 35a24e9..399ff2d 100644 --- a/R/calibrateIntensity-functions.R +++ b/R/calibrateIntensity-functions.R @@ -22,7 +22,7 @@ totalIonCurrent(object) }, "median" = { - median(object@intensity) + median(intensity(object)) } ) } @@ -85,7 +85,7 @@ lapply(l, function(x) { ## 3. quotient calculation - q <- approxfun(x)(reference@mass) / reference@intensity + q <- approxfun(x)(mass(reference)) / intensity(reference) ## 4. median m <- median(q, na.rm=TRUE) ## 5. divide by median diff --git a/R/calibrateIntensity-methods.R b/R/calibrateIntensity-methods.R index 89c3b49..fa22ad1 100644 --- a/R/calibrateIntensity-methods.R +++ b/R/calibrateIntensity-methods.R @@ -1,6 +1,6 @@ ## MassSpectrum setMethod(f="calibrateIntensity", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, method=c("TIC", "PQN", "median"), range, ...) { diff --git a/R/constructor-functions.R b/R/constructor-functions.R index 341d6ad..ca84537 100644 --- a/R/constructor-functions.R +++ b/R/constructor-functions.R @@ -18,6 +18,39 @@ createMassSpectrum <- function(mass, intensity, metaData=list()) { ## end of MassSpectrum + +## MassSpectrumOnDisk + +## createMassSpectrumOnDisk +## default constructor: MassSpectrumOnDisk class +## +## params: +## mass: matter_vec, spectrum mass +## intensity: matter_vec, spectrum intensities +## metaData: list, metadata +## +## returns: +## a MassSpectrumOnDisk object +## +createMassSpectrumOnDisk <- function(mass, intensity, metaData=list()) { + + onDiskMass <- OnDiskVector(x=mass, path=paste(tempfile("spectrum"), "mass", sep=".")) + onDiskIntensity <- OnDiskVector(x=intensity, path=paste(tempfile("spectrum"), "intensity", sep=".")) + + object <- new(Class="MassSpectrumOnDisk", + mass=onDiskMass, + intensity=onDiskIntensity, + metaData=metaData) + + + .reorder(object) + +} + + +## end of MassSpectrumOnDisk + + ## MassPeaks ## createMassPeaks diff --git a/R/detectPeaks-methods.R b/R/detectPeaks-methods.R index 7638c9a..29b7f82 100644 --- a/R/detectPeaks-methods.R +++ b/R/detectPeaks-methods.R @@ -1,30 +1,33 @@ ## MassSpectrum setMethod(f="detectPeaks", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, halfWindowSize=20L, method=c("MAD", "SuperSmoother"), SNR=2L, ...) { + tmpMass <- mass(object) + tmpIntensity <- intensity(object) + ## empty spectrum? if (.isEmptyWarning(object)) { - return(createMassPeaks(mass=object@mass, intensity=object@intensity, + return(createMassPeaks(mass=tmpMass, intensity=tmpIntensity, metaData=object@metaData)) } ## estimate noise - noise <- .estimateNoise(x=object@mass, y=object@intensity, method=method, ...) + noise <- .estimateNoise(x=tmpMass, y=tmpIntensity, method=method, ...) ## find local maxima isLocalMaxima <- .findLocalMaximaLogical(object, halfWindowSize=halfWindowSize) ## include only local maxima which are above the noise - isAboveNoise <- object@intensity > (SNR * noise) + isAboveNoise <- tmpIntensity > (SNR * noise) peakIdx <- which(isAboveNoise & isLocalMaxima) - createMassPeaks(mass=object@mass[peakIdx], - intensity=object@intensity[peakIdx], - snr=object@intensity[peakIdx] / noise[peakIdx], + createMassPeaks(mass=tmpMass[peakIdx], + intensity=tmpIntensity[peakIdx], + snr=tmpIntensity[peakIdx] / noise[peakIdx], metaData=object@metaData) }) diff --git a/R/estimateBaseline-methods.R b/R/estimateBaseline-methods.R index 6dc211f..d664b55 100644 --- a/R/estimateBaseline-methods.R +++ b/R/estimateBaseline-methods.R @@ -1,6 +1,6 @@ ## MassSpectrum setMethod(f="estimateBaseline", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, method=c("SNIP", "TopHat", "ConvexHull", "median"), ...) { @@ -8,7 +8,7 @@ setMethod(f="estimateBaseline", return(NA) } - cbind(mass=object@mass, - intensity=.estimateBaseline(x=object@mass, y=object@intensity, + cbind(mass=mass(object), + intensity=.estimateBaseline(x=mass(object), y=intensity(object), method=method, ...)) }) diff --git a/R/estimateNoise-methods.R b/R/estimateNoise-methods.R index ee37bf6..07e9bea 100644 --- a/R/estimateNoise-methods.R +++ b/R/estimateNoise-methods.R @@ -1,13 +1,13 @@ ## MassSpectrum setMethod(f="estimateNoise", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, method=c("MAD", "SuperSmoother"), ...) { if (.isEmptyWarning(object)) { return(0L) } - cbind(mass=object@mass, - intensity=.estimateNoise(x=object@mass, y=object@intensity, + cbind(mass=mass(object), + intensity=.estimateNoise(x=mass(object), y=intensity(object), method=method, ...)) }) diff --git a/R/findLocalMaxima-methods.R b/R/findLocalMaxima-methods.R index 138acb3..6683d53 100644 --- a/R/findLocalMaxima-methods.R +++ b/R/findLocalMaxima-methods.R @@ -1,6 +1,6 @@ -## MassSpectrum +## AbstractMassSpectrum setMethod(f=".findLocalMaxima", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, halfWindowSize=20L) { if (.isEmptyWarning(object)) { @@ -9,11 +9,11 @@ setMethod(f=".findLocalMaxima", localMaxima <- .findLocalMaximaLogical(object, halfWindowSize=halfWindowSize) - cbind(mass=object@mass, intensity=object@intensity)[localMaxima,] + cbind(mass=mass(object), intensity=intensity(object))[localMaxima,] }) setMethod(f=".findLocalMaximaLogical", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, halfWindowSize=20L) { if (.isEmptyWarning(object)) { @@ -23,5 +23,5 @@ setMethod(f=".findLocalMaximaLogical", .stopIfNotIsValidHalfWindowSize(halfWindowSize=halfWindowSize, n=length(object)) - .localMaxima(object@intensity, halfWindowSize=halfWindowSize) + .localMaxima(intensity(object), halfWindowSize=halfWindowSize) }) diff --git a/R/hidden_aliases.R b/R/hidden_aliases.R new file mode 100644 index 0000000..f6843c7 --- /dev/null +++ b/R/hidden_aliases.R @@ -0,0 +1,9 @@ +#' Internal page for hidden aliases +#' +#' For S4 methods that require a documentation entry but only clutter the index. +#' +#' @usage NULL +#' @format NULL +#' @keywords internal +#' @docType methods +hidden_aliases <- NULL diff --git a/R/intensity-methods.R b/R/intensity-methods.R index 00a3443..c88c5a5 100644 --- a/R/intensity-methods.R +++ b/R/intensity-methods.R @@ -3,7 +3,7 @@ setMethod(f="intensity", signature=signature(object="AbstractMassObject"), definition=function(object, ...) { - object@intensity + object@intensity[] # square brackets to account for the onDiskVector type of MassSpectromOnDisk class }) ## AbstractMassObject @@ -13,7 +13,7 @@ setReplaceMethod(f="intensity", definition=function(object, value) { if (length(object@intensity) == length(value)) { - object@intensity <- as.double(value) + object@intensity[] <- as.double(value) } else { stop("Lengths of intensity(", length(object@intensity), ") and value (", length(value), ") have to be equal.") diff --git a/R/isEmpty-methods.R b/R/isEmpty-methods.R index 2e9b8ea..ea552c1 100644 --- a/R/isEmpty-methods.R +++ b/R/isEmpty-methods.R @@ -3,7 +3,7 @@ setMethod(f="isEmpty", signature=signature(x="AbstractMassObject"), definition=function(x) { - !sum(as.double(x@intensity), na.rm=TRUE) + !sum(as.double(intensity(x)), na.rm=TRUE) }) setMethod(f=".isEmptyWarning", diff --git a/R/isMassObject-functions.R b/R/isMassObject-functions.R index 6905081..2a9dd98 100644 --- a/R/isMassObject-functions.R +++ b/R/isMassObject-functions.R @@ -3,7 +3,7 @@ } isMassSpectrum <- function(x) { - is(object=x, class2="MassSpectrum") + is(object=x, class2="AbstractMassSpectrum") } isMassPeaks <- function(x) { diff --git a/R/isMassObjectList-functions.R b/R/isMassObjectList-functions.R index 2e62f2f..248c580 100644 --- a/R/isMassObjectList-functions.R +++ b/R/isMassObjectList-functions.R @@ -27,7 +27,7 @@ isMassSpectrumList <- function(x) { if (!isMassSpectrumList(x)) { parentCall <- deparse(sys.call(-1L)) stop(parentCall, " : ", sQuote(deparse(substitute(x))), - " is no list of MALDIquant::MassSpectrum objects!", call.=FALSE) + " is no list of MALDIquant::MassSpectrum/MassSpectrumOnDisk objects!", call.=FALSE) } TRUE } diff --git a/R/isRegular-methods.R b/R/isRegular-methods.R index 26ad726..151752a 100644 --- a/R/isRegular-methods.R +++ b/R/isRegular-methods.R @@ -1,8 +1,8 @@ ## MassSpectrum setMethod(f="isRegular", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, threshold=1e-3) { - s <- .irregularScore(object@mass) <= threshold + s <- .irregularScore(mass(object)) <= threshold !is.na(s) & s }) diff --git a/R/lines-methods.R b/R/lines-methods.R index c3d7e66..de35e6b 100644 --- a/R/lines-methods.R +++ b/R/lines-methods.R @@ -5,5 +5,5 @@ setMethod(f="lines", type=ifelse(isMassPeaks(x), "h", "l"), ...) { - lines(x=x@mass, y=x@intensity, type, ...) + lines(x=mass(x), y=intensity(x), type, ...) }) diff --git a/R/mass-methods.R b/R/mass-methods.R index 1ca6b33..b58c66a 100644 --- a/R/mass-methods.R +++ b/R/mass-methods.R @@ -3,7 +3,7 @@ setMethod(f="mass", signature=signature(object="AbstractMassObject"), definition=function(object, ...) { - object@mass + object@mass[] # square brackets to account for the onDiskVector type of MassSpectromOnDisk class }) ## AbstractMassObject @@ -12,7 +12,7 @@ setReplaceMethod(f="mass", definition=function(object, value) { if (length(object@mass) == length(value)) { - object@mass <- as.double(value) + object@mass[] <- as.double(value) } else { stop("Lengths of mass (", length(object@mass), ") and value (", length(value), ") have to be equal.") diff --git a/R/memoryUsage-functions.R b/R/memoryUsage-functions.R index 7bda285..0cd3856 100644 --- a/R/memoryUsage-functions.R +++ b/R/memoryUsage-functions.R @@ -2,13 +2,21 @@ ## pretty string of memory usage ## ## params: -## x: object_size +## x: an R object for inMemory = TRUE and a file path otherwise. +## inMemory: logical, TRUE for in memory objects and FALSE for stored files on-disk. ## ## returns: ## character ## -.memoryUsageStr <- function(x) { - os <- object.size(x) +.memoryUsageStr <- function(x, inMemory=TRUE) { + + if(inMemory){ + os <- object.size(x) + } else { + if(!file.exists(x)) stop("Error in .memoryUsageStr; specified file deos not exist.") + os <- file.info(x)$size + } + iec <- c("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") l <- trunc(log(os) / log(1024L)) i <- pmin(l + 1L, 9L) diff --git a/R/plot-methods.R b/R/plot-methods.R index 56a1689..3705f19 100644 --- a/R/plot-methods.R +++ b/R/plot-methods.R @@ -22,7 +22,7 @@ setMethod(f="plot", " objects") } - plot(x=x@mass, y=x@intensity, col=col, type=type, xlab=xlab, ylab=ylab, + plot(x=mass(x), y=intensity(x), col=col, type=type, xlab=xlab, ylab=ylab, xlim=xlim, ylim=ylim, main=main, sub=sub, cex.sub=cex.sub, col.sub=col.sub, ...) }) diff --git a/R/points-methods.R b/R/points-methods.R index e8f4d9f..6c6cb1c 100644 --- a/R/points-methods.R +++ b/R/points-methods.R @@ -3,5 +3,5 @@ setMethod(f="points", signature=signature(x="AbstractMassObject"), definition=function(x, ...) { - points(x=x@mass, y=x@intensity, ...) + points(x=mass(x), y=intensity(x), ...) }) diff --git a/R/range-functions.R b/R/range-functions.R index 6d5332b..b771408 100644 --- a/R/range-functions.R +++ b/R/range-functions.R @@ -13,8 +13,8 @@ .stopIfNotIsMassObjectList(l) ## mass values are already sorted - leftMass <- .unlist(lapply(l, function(x)x@mass[1L])) - rightMass <- .unlist(lapply(l, function(x)x@mass[length(x@mass)])) + leftMass <- .unlist(lapply(l, function(x)mass(x)[1L])) + rightMass <- .unlist(lapply(l, function(x)mass(x)[length(x@mass)])) if (length(rightMass)) { r <- c(max(leftMass, na.rm=TRUE), min(rightMass, na.rm=TRUE)) diff --git a/R/removeBaseline-methods.R b/R/removeBaseline-methods.R index 6ded904..a4aa55f 100644 --- a/R/removeBaseline-methods.R +++ b/R/removeBaseline-methods.R @@ -1,6 +1,6 @@ ## MassSpectrum setMethod(f="removeBaseline", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, method=c("SNIP", "TopHat", "ConvexHull", "median"), @@ -10,12 +10,15 @@ setMethod(f="removeBaseline", return(object) } + tmpMass <- mass(object) + tmpIntensity <- intensity(object) + ## estimate baseline - baseline <- .estimateBaseline(x=object@mass, y=object@intensity, + baseline <- .estimateBaseline(x=tmpMass, y=tmpIntensity, method=method, ...) ## substract baseline - object@intensity <- object@intensity - baseline + intensity(object) <- tmpIntensity - baseline object }) diff --git a/R/reorder-functions.R b/R/reorder-functions.R index a34d91c..f70c0da 100644 --- a/R/reorder-functions.R +++ b/R/reorder-functions.R @@ -9,13 +9,15 @@ ## an AbstractMass object ## .reorder <- function(object, warn=TRUE) { - if (is.unsorted(object@mass)) { + + tmpMass <- mass(object) + if (is.unsorted(tmpMass)) { if (warn) { warning("Mass and intensity values are reordered.") } - i <- sort.int(object@mass, index.return=TRUE) - object@mass <- i$x - object@intensity <- object@intensity[i$ix] + i <- sort.int(tmpMass, index.return=TRUE) + mass(object) <- i$x + intensity(object) <- intensity(object)[i$ix] } object } diff --git a/R/replaceNegativeIntensityValues-functions.R b/R/replaceNegativeIntensityValues-functions.R index 280d21c..32b5a12 100644 --- a/R/replaceNegativeIntensityValues-functions.R +++ b/R/replaceNegativeIntensityValues-functions.R @@ -9,11 +9,14 @@ ## an AbstractMass object ## .replaceNegativeIntensityValues <- function(object, warn=TRUE) { - if (any(object@intensity < 0L, na.rm=TRUE) && !isEmpty(object)) { + + tmpIntensity <- intensity(object) + + if (any(tmpIntensity < 0L, na.rm=TRUE) && !isEmpty(object)) { if (warn) { warning("Negative intensity values are replaced by zeros.") } - object@intensity[which(object@intensity < 0L)] <- 0L + intensity(object)[which(tmpIntensity < 0L)] <- 0L } object } diff --git a/R/show-methods.R b/R/show-methods.R index 07600cc..41aa8a9 100644 --- a/R/show-methods.R +++ b/R/show-methods.R @@ -50,6 +50,35 @@ setMethod(f=".prepareShow", list(groups=groups, values=values) }) + +setMethod(f=".prepareShow", + signature=signature(object="MassSpectrumOnDisk"), + definition=function(object) { + + l <- callNextMethod(object) + + + + if (isEmpty(object)) { + values <- NA + } else { + values <- c(object@mass@path, + object@intensity@path) + } + + + groups <- c("Path to on-disk mass values", + "Path to on-disk intensities") + + + ## append path info + l$groups <- append(l$groups, groups) + l$values <- append(l$values, values) + + list(groups=l$groups, values=l$values) + }) + + setMethod(f=".prepareShow", signature=signature(object="MassPeaks"), definition=function(object) { @@ -70,3 +99,42 @@ setMethod(f=".prepareShow", list(groups=l$groups, values=l$values) }) + +## OnDiskVector +setMethod(f="show", + signature=signature(object="OnDiskVector"), + definition=function(object) { + + + groups <- c("S4 class type", + "Vector length", + "Vector range", + "Vector file path", + "Modification counter path", + "Memory usage on-disk", + "Memory usage in-memory") + + + + values <- c(class(object)[1L], + length(object), + paste0(format(range(object), digits=4L, + scientific=TRUE), collapse = " - "), + object@path, + object@mpath, + .memoryUsageStr(object@path, FALSE), + .memoryUsageStr(object, TRUE)) + + l <- list(groups=groups, values=values) + + isFilename <- grepl(pattern="^File.*|^path.*", x=l$groups) + + ## to avoid newlines in other values don't format filenames + ## (they could be very long) + l$values[!isFilename] <- format(l$values[!isFilename], justify="left") + + l$groups <- format(l$groups, justify="left") + + cat(paste0(l$groups, ": ", l$values, collapse="\n"), sep="\n") + }) + diff --git a/R/smoothIntensity-methods.R b/R/smoothIntensity-methods.R index 2721ecc..e687be9 100644 --- a/R/smoothIntensity-methods.R +++ b/R/smoothIntensity-methods.R @@ -1,6 +1,6 @@ ## AbstractMassObject setMethod(f="smoothIntensity", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object, method=c("SavitzkyGolay", "MovingAverage"), halfWindowSize, ...) { diff --git a/R/subset-methods.R b/R/subset-methods.R index f0b6a80..ba81300 100644 --- a/R/subset-methods.R +++ b/R/subset-methods.R @@ -22,6 +22,50 @@ setMethod(f="[", x }) + +## MassSpectrumOnDisk + +## In the case of MassSpectrumOnDisk objects , I opted for a conservative subsetting where +## the OnDiskVector pointers stay intact and a new subsetted MassSpectrum object is returned. Another +## scenario is to edit the OnDiskVector objects (pointing to mass and intensity axes) to accommodate +## the required subsetting. This can be revisited in the future if needed. + +setMethod(f="[", + signature=signature(x="MassSpectrumOnDisk", i="numeric", j="missing"), + definition=function(x, i, j, ..., drop=TRUE) { + + warning("For the supplied MassSpectrumOnDisk object, subsetting the original on-disk data ", + "is not supported. In this situation a new subsetted MassSpectrum object is returned.\n") + + + + createMassSpectrum(mass=mass(x)[i], + intensity=intensity(x)[i], + metaData=x@metaData) + + + }) + +## MassSpectrumOnDisk +setMethod(f="[", + signature=signature(x="MassSpectrumOnDisk", i="logical", j="missing"), + definition=function(x, i, j, ..., drop=TRUE) { + + warning("For the supplied MassSpectrumOnDisk object, subsetting the original on-disk data ", + "is not supported. In this situation a new subsetted MassSpectrum object is returned.\n") + + ## seems to be faster than evaluating the logical expression twice + i <- which(i) + + createMassSpectrum(mass=mass(x)[i], + intensity=intensity(x)[i], + metaData=x@metaData) + + + }) + + +## MassPeaks setMethod(f="[", signature=signature(x="MassPeaks", i="numeric", j="missing"), definition=function(x, i, j, ..., drop=TRUE) { @@ -33,7 +77,7 @@ setMethod(f="[", x }) -## AbstractMassObject +## MassPeaks setMethod(f="[", signature=signature(x="MassPeaks", i="logical", j="missing"), definition=function(x, i, j, ..., drop=TRUE) { diff --git a/R/totalIonCurrent-methods.R b/R/totalIonCurrent-methods.R index 8774c82..a82ef4a 100644 --- a/R/totalIonCurrent-methods.R +++ b/R/totalIonCurrent-methods.R @@ -1,10 +1,12 @@ ## MassSpectrum setMethod(f="totalIonCurrent", - signature=signature(object="MassSpectrum"), + signature=signature(object="AbstractMassSpectrum"), definition=function(object) { - left <- as.double(head(object@intensity, -1L)) - right <- as.double(tail(object@intensity, -1L)) + tmpIntensity <- intensity(object) + + left <- as.double(head(tmpIntensity, -1L)) + right <- as.double(tail(tmpIntensity, -1L)) - as.double(sum((left + right) / 2L * diff(object@mass), na.rm=TRUE)) + as.double(sum((left + right) / 2L * diff(mass(object)), na.rm=TRUE)) }) diff --git a/R/transformIntensity-methods.R b/R/transformIntensity-methods.R index 2220666..f081ed9 100644 --- a/R/transformIntensity-methods.R +++ b/R/transformIntensity-methods.R @@ -36,15 +36,17 @@ setMethod(f=".transformIntensity", if (!isEmpty(object)) { fun <- match.fun(fun) - - object@intensity <- fun(object@intensity, ...) - - if (na.rm) { - naIdx <- which(!is.na(object@intensity)) - object@intensity <- object@intensity[naIdx] - object@mass <- object@mass[naIdx] + + + tmpIntensity <- fun(intensity(object), ...) + + if (na.rm) { # Attention! + naIdx <- which(!is.na(tmpIntensity)) + tmpIntensity <- tmpIntensity[naIdx] + mass(object) <- mass(object)[naIdx] } + intensity(object) <- tmpIntensity object <- .replaceNegativeIntensityValues(object) } diff --git a/R/trim-methods.R b/R/trim-methods.R index 6a494ad..6fbeee7 100644 --- a/R/trim-methods.R +++ b/R/trim-methods.R @@ -18,6 +18,44 @@ setMethod("trim", object[sel] }) + +## MassSpectrumOnDisk + +## In the case of MassSpectrumOnDisk objects , I opted for a conservative subsetting/trimming where +## the OnDiskVector pointers stay intact and a new subsetted MassSpectrum object is returned. Another +## scenario is to edit the OnDiskVector objects (pointing to mass and intensity axes) to accommodate +## the required subsetting. This can be revisited in the future if needed. + +setMethod("trim", + signature=signature(object="MassSpectrumOnDisk", range="numeric"), + definition=function(object, range) { + if (length(range) != 2L) { + stop(sQuote("range"), " has to be a vector of length 2.") + } + + range <- .reorderRange(range) + + sel <- which(findInterval(mass(object), range, rightmost.closed=TRUE) == 1L) + + if (!length(sel)) { + warning("The mass range (", paste0(range, collapse=":"), + ") is outside of the stored mass values. No data points left.") + } + + warning("For the supplied MassSpectrumOnDisk object, trimming the original on-disk data ", + "is not supported. In this situation a new trimmed MassSpectrum object is returned.\n") + + + + createMassSpectrum(mass=mass(object)[sel], + intensity=intensity(object)[sel], + metaData=object@metaData) + + + }) + + + ## list setMethod("trim", signature=signature(object="list", range="numeric"), diff --git a/R/valid-methods.R b/R/valid-methods.R index 70efc6f..e99a312 100644 --- a/R/valid-methods.R +++ b/R/valid-methods.R @@ -1,21 +1,25 @@ ## AbstractMassObject .validAbstractMassObject <- function(object) { - if (length(object@mass) != length(object@intensity)) { - return(paste0("Lengths of mass (", length(object@mass), - ") and intensity (", length(object@intensity), + + tmpMass <- mass(object) + tmpIntensity <- intensity(object) + + if (length(tmpMass) != length(tmpIntensity)) { + return(paste0("Lengths of mass (", length(tmpMass), + ") and intensity (", length(tmpIntensity), ") have to be equal.")) } - if (is.numeric(object@mass) && - length(object@mass) && - any(object@mass < 0L)) { + if (is.numeric(tmpMass) && + length(tmpMass) && + any(tmpMass < 0L)) { warning("Negative mass values found.") } - if (is.numeric(object@intensity) && + if (is.numeric(tmpIntensity) && !isEmpty(object) && - any(object@intensity < 0L)) { + any(tmpIntensity < 0L)) { warning("Negative intensity values found.") } - if (is.unsorted(object@mass)) { + if (is.unsorted(tmpMass)) { warning("Unsorted mass values found.") } TRUE diff --git a/R/warp-functions.R b/R/warp-functions.R index a8b66d7..28998c8 100644 --- a/R/warp-functions.R +++ b/R/warp-functions.R @@ -54,11 +54,13 @@ warpMassPeaks <- function(l, w, emptyNoMatches=FALSE) { } l[notNa] <- .mapply(function(m, wf) { - m@mass <- m@mass + wf(m@mass) + tmpM <- mass(m) + tmpM <- tmpM + wf(tmpM) + mass(m) <- tmpM m }, m=ml, wf=wl) if (emptyNoMatches) { - l[!notNa] <- lapply(l[!notNa], function(m) { m@intensity[] <- 0; m }) + l[!notNa] <- lapply(l[!notNa], function(m) { intensity(m)[] <- 0; m }) } l } diff --git a/man/AbstractMassObject-class.Rd b/man/AbstractMassObject-class.Rd index ec0c973..59d0f6e 100644 --- a/man/AbstractMassObject-class.Rd +++ b/man/AbstractMassObject-class.Rd @@ -39,18 +39,18 @@ \title{Class "AbstractMassObject"} \description{ \code{\linkS4class{AbstractMassObject}} is an abstract (means pure virtual) -class. It is the parent class of \code{\linkS4class{MassSpectrum}} and +class. It is the parent class of \code{\linkS4class{AbstractMassSpectrum}} and \code{\linkS4class{MassPeaks}}. It shouldn't create or handle by the user because it is for internal use only. } \section{Derived classes}{ \code{\linkS4class{MassPeaks}}, -\code{\linkS4class{MassSpectrum}} +\code{\linkS4class{AbstractMassSpectrum}} } \section{Slots}{ \describe{ - \item{\code{mass}:}{\code{numeric}, mass or mass-to-charge ratio} - \item{\code{intensity}:}{\code{numeric}, intensities for measured + \item{\code{mass}:}{\code{numeric/OnDiskVector}, mass or mass-to-charge ratio} + \item{\code{intensity}:}{\code{numeric/OnDiskVector}, intensities for measured mass-to-charge ratios} \item{\code{metaData}:}{\code{list}, some metadata to describe the spectrum} diff --git a/man/AbstractMassSpectrum-class.Rd b/man/AbstractMassSpectrum-class.Rd new file mode 100644 index 0000000..742d26e --- /dev/null +++ b/man/AbstractMassSpectrum-class.Rd @@ -0,0 +1,104 @@ +\name{AbstractMassSpectrum-class} +\Rdversion{1.1} +\docType{class} +\alias{AbstractMassSpectrum} +\alias{MassSpectrum-class} + + +\title{Class "AbstractMassSpectrum"} +\description{ +\code{\linkS4class{AbstractMassSpectrum}} is an abstract (means pure virtual) +class representing a single spectrum of a MALDI-TOF +mass spectrometry measurement. It is the parent class of \code{\linkS4class{MassSpectrum}} and +\code{\linkS4class{MassSpectrumOnDisk}}. It shouldn't be created or handled by the user because it is for internal use only.. \cr +} + +\section{Extends}{ +Class \code{\linkS4class{AbstractMassObject}}, directly. +} + +\section{Derived classes}{ +\code{\linkS4class{MassSpectrum}}, +\code{\linkS4class{MassSpectrumOnDisk}} +} +\section{Methods}{ +\describe{ + \item{calibrateIntensity}{\code{signature(x = "MassSpectrum")}: + Calibrates the intensity of a + \code{\linkS4class{MassSpectrum}} object. + See \code{\link[MALDIquant]{calibrateIntensity,MassSpectrum-method}} for + details.} + \item{detectPeaks}{\code{signature(x = "MassSpectrum")}: + Look for local maxima and estimate noise to extract peaks out of a + \code{\linkS4class{MassSpectrum}} object. + See \code{\link[MALDIquant]{detectPeaks,MassSpectrum-method}} for + details.} + \item{estimateBaseline}{\code{signature(x = "MassSpectrum")}: + Estimates the baseline of a + \code{\linkS4class{MassSpectrum}} object. + See \code{\link[MALDIquant]{estimateBaseline,MassSpectrum-method}} for + details.} + \item{estimateNoise}{\code{signature(x = "MassSpectrum")}: + Estimates the noise of a + \code{\linkS4class{MassSpectrum}} object. + See \code{\link[MALDIquant]{estimateNoise,MassSpectrum-method}} for + details.} + \item{isRegular}{\code{signature(object = "MassSpectrum")}: + Returns \code{FALSE} if the frequency of mass values with irregular + intervals is greater than \code{threshold} (because \code{object} + was measured in \emph{centroid} mode or some \code{intensity} + values were filtered).} + \item{removeBaseline}{\code{signature(x = "MassSpectrum")}: + Estimates and removes the baseline of a + \code{\linkS4class{MassSpectrum}} object. + See \code{\link[MALDIquant]{removeBaseline,MassSpectrum-method}} for + details.} + \item{smoothIntensity}{\code{signature(object = "MassSpectrum")}: + Smoothes the intensities of an \code{MassSpectrum} object. + See \code{\link[MALDIquant]{smoothIntensity,MassSpectrum-method}} for + details.} + \item{totalIonCurrent}{\code{signature(object = "MassSpectrum")}: + Accessor function for Total Ion Current (TIC, area under the curve).} +} +} +\author{ +Sebastian Gibb \email{mail@sebastiangibb.de} +} +\seealso{ +\code{\link[MALDIquant]{createMassSpectrum}}, +\code{\link[MALDIquant]{calibrateIntensity,MassSpectrum-method}}, +\code{\link[MALDIquant]{detectPeaks,MassSpectrum-method}}, +\code{\link[MALDIquant]{estimateBaseline,MassSpectrum-method}}, +\code{\link[MALDIquant]{estimateNoise,MassSpectrum-method}}, +\code{\link[MALDIquant]{removeBaseline,MassSpectrum-method}}, +\code{\link[MALDIquant]{smoothIntensity,MassSpectrum-method}}, +\code{\linkS4class{AbstractMassObject}} + +Website: \url{http://strimmerlab.org/software/maldiquant/} +} +\examples{ +## load package +library("MALDIquant") + +## create a MassSpectrum object by default constructor +s <- createMassSpectrum(mass=1:100, intensity=rnorm(100)^2, + metaData=list(name="example")) + +## show some details +s + +## plot spectrum +plot(s) + +## get TIC +totalIonCurrent(s) + +## modify intensity and metaData +intensity(s)[1:50] <- 0 +metaData(s) <- list(name="modified example") + +## plot again +plot(s) +} +\keyword{classes} + diff --git a/man/MassSpectrum-class.Rd b/man/MassSpectrum-class.Rd index 29e15eb..9140846 100644 --- a/man/MassSpectrum-class.Rd +++ b/man/MassSpectrum-class.Rd @@ -20,7 +20,7 @@ much more. \cr \code{\linkS4class{MassSpectrum}} object. } \section{Extends}{ -Class \code{\linkS4class{AbstractMassObject}}, directly. +Class \code{\linkS4class{AbstractMassSpectrum}}, directly. } \section{Methods}{ \describe{ diff --git a/man/MassSpectrumOnDisk-class.Rd b/man/MassSpectrumOnDisk-class.Rd new file mode 100644 index 0000000..035c7d4 --- /dev/null +++ b/man/MassSpectrumOnDisk-class.Rd @@ -0,0 +1,112 @@ +\name{MassSpectrumOnDisk-class} +\Rdversion{1.1} +\docType{class} +\alias{MassSpectrumOnDisk} +\alias{MassSpectrumOnDisk-class} +\alias{isRegular} +\alias{isRegular,MassSpectrumOnDisk-method} +\alias{totalIonCurrent} +\alias{totalIonCurrent,MassSpectrumOnDisk-method} + +\title{Class "MassSpectrumOnDisk"} +\description{ +\code{\linkS4class{MassSpectrumOnDisk}} represents a single spectrum of a MALDI-TOF +mass spectrometry measurement. It provides an easy framework for doing +some preprocessing steps like peak detection, baseline correction and +much more. This class is identical to the \code{\linkS4class{MassSpectrum}} object except that it uses +the \code{OnDiskVector} class internally to interface directly with mass spectra on disk +without loading them into memory. This is handy when dealing with mass spectrometry +imaging (MSI) data which usually has high memory-footprint. The \code{mass} and \code{intensity} slots +are \code{OnDiskVector} objects with only the \code{metaData} list loaded into memory. +When used with \code{\href{https://ms-imaging.org/wp/imzml/}{imzML}} MSI files, the spectra can be +directly attached to the binary \code{ibd} file via \code{MALDIquantForeign::importImzMl; attachOnly = TRUE} without the need to load them into memory. \cr +} +\section{Objects from the Class}{ +\code{\link[MALDIquant]{createMassSpectrumOnDisk}}: Creates a +\code{\linkS4class{MassSpectrumOnDisk}} object. +} +\section{Extends}{ +Class \code{\linkS4class{AbstractMassSpectrum}}, directly. +} +\section{Methods}{ +\describe{ + \item{calibrateIntensity}{\code{signature(x = "MassSpectrumOnDisk")}: + Calibrates the intensity of a + \code{\linkS4class{MassSpectrumOnDisk}} object. + See \code{\link[MALDIquant]{calibrateIntensity,MassSpectrumOnDisk-method}} for + details.} + \item{detectPeaks}{\code{signature(x = "MassSpectrumOnDisk")}: + Look for local maxima and estimate noise to extract peaks out of a + \code{\linkS4class{MassSpectrumOnDisk}} object. + See \code{\link[MALDIquant]{detectPeaks,MassSpectrumOnDisk-method}} for + details.} + \item{estimateBaseline}{\code{signature(x = "MassSpectrumOnDisk")}: + Estimates the baseline of a + \code{\linkS4class{MassSpectrumOnDisk}} object. + See \code{\link[MALDIquant]{estimateBaseline,MassSpectrumOnDisk-method}} for + details.} + \item{estimateNoise}{\code{signature(x = "MassSpectrumOnDisk")}: + Estimates the noise of a + \code{\linkS4class{MassSpectrumOnDisk}} object. + See \code{\link[MALDIquant]{estimateNoise,MassSpectrumOnDisk-method}} for + details.} + \item{isRegular}{\code{signature(object = "MassSpectrumOnDisk")}: + Returns \code{FALSE} if the frequency of mass values with irregular + intervals is greater than \code{threshold} (because \code{object} + was measured in \emph{centroid} mode or some \code{intensity} + values were filtered).} + \item{removeBaseline}{\code{signature(x = "MassSpectrumOnDisk")}: + Estimates and removes the baseline of a + \code{\linkS4class{MassSpectrumOnDisk}} object. + See \code{\link[MALDIquant]{removeBaseline,MassSpectrumOnDisk-method}} for + details.} + \item{smoothIntensity}{\code{signature(object = "MassSpectrumOnDisk")}: + Smoothes the intensities of an \code{MassSpectrumOnDisk} object. + See \code{\link[MALDIquant]{smoothIntensity,MassSpectrumOnDisk-method}} for + details.} + \item{totalIonCurrent}{\code{signature(object = "MassSpectrumOnDisk")}: + Accessor function for Total Ion Current (TIC, area under the curve).} +} +} +\author{ +Sebastian Gibb \email{mail@sebastiangibb.de} \cr +Denis Abu Sammour \email{d.abu-sammour@hs-mannheim.de} +} + + + +\seealso{ +\code{\linkS4class{MassPeaks}}, +\code{\linkS4class{MassSpectrum}}, +\code{\linkS4class{AbstractMassObject}} + +Website: \url{http://strimmerlab.org/software/maldiquant/} +} +\examples{ +## load package +library("MALDIquant") + +## create a MassSpectrumOnDisk object by default constructor +## This creates two matter::matter_vec objects in the temp +## directory representing mass and intensity values, respectfully. +s <- createMassSpectrumOnDisk(mass=1:100, intensity=rnorm(100)^2, + metaData=list(name="example")) + +## show some details +s + +## plot spectrum +plot(s) + +## get TIC +totalIonCurrent(s) + +## modify intensity and metaData +intensity(s)[1:50] <- 0 +metaData(s) <- list(name="modified example") + +## plot again +plot(s) +} +\keyword{classes} + diff --git a/man/OnDiskVector-class.Rd b/man/OnDiskVector-class.Rd new file mode 100644 index 0000000..e4ee79b --- /dev/null +++ b/man/OnDiskVector-class.Rd @@ -0,0 +1,51 @@ +\name{OnDiskVector-class} +\Rdversion{1.1} +\docType{class} +\alias{OnDiskVector} + + +\title{Class "OnDiskVector"} +\description{ +\code{\linkS4class{AbstractMassObject}} is an internal class for creating and attaching to on-disk vectors. It is used within the \code{mass} and \code{intensity} slots of \code{\linkS4class{MassSpectrumOnDisk}} objects. +It shouldn't create or handle by the user because it is for internal use only. +} + +\section{Slots}{ +\describe{ + \item{\code{path}:}{\code{character}, path to the on-disk vector} + \item{\code{mpath}:}{\code{character}, path to the modification counter file} + \item{\code{modification}:}{\code{integer}, file modification counter} + \item{\code{n}:}{\code{integer}, length of the vector} + \item{\code{offset}:}{\code{integer}, offset of the data in the file} + \item{\code{size}:}{\code{integer}, size of one vector element in the file} +} +} + + + + +\author{ +Sebastian Gibb \email{mail@sebastiangibb.de} +} + +\seealso{ +\code{\linkS4class{MassSpectrumOnDisk}}} + + +\examples{ +## load package +library("MALDIquant") + +## create example vector +odv <- OnDiskVector(1:10) + +## query path +odv@path +# [1] "/tmp/Rtmpaz3SQG/file13ce3a31c136" + +## get stored values +odv[1:5] +# [1] 1 2 3 4 5 +} +\keyword{classes} + diff --git a/man/hidden_aliases.Rd b/man/hidden_aliases.Rd new file mode 100644 index 0000000..f04266a --- /dev/null +++ b/man/hidden_aliases.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/hidden_aliases.R, R/OnDiskVector-class.R +\docType{methods} +\name{hidden_aliases} +\alias{hidden_aliases} +\alias{length,OnDiskVector-method} +\alias{[,OnDiskVector,numeric,missing-method} +\alias{[,OnDiskVector,missing,missing-method} +\alias{[<-,OnDiskVector,missing,missing-method} +\title{Internal page for hidden aliases} +\usage{ +\S4method{length}{OnDiskVector}(x) + +\S4method{[}{OnDiskVector,numeric,missing}(x, i, j, ..., drop = FALSE) + +\S4method{[}{OnDiskVector,missing,missing}(x, i, j, ..., drop = FALSE) + +\S4method{[}{OnDiskVector,missing,missing}(x, i, j, ...) <- value +} +\description{ +For S4 methods that require a documentation entry but only clutter the index. +} +\keyword{internal} diff --git a/man/match.closest.Rd b/man/match.closest.Rd index aad0b27..75a174b 100644 --- a/man/match.closest.Rd +++ b/man/match.closest.Rd @@ -65,4 +65,3 @@ im[, match.closest(ref, attr(im, "mass"), tolerance=0.25, nomatch=0)] \seealso{ \code{\link{match}} } - diff --git a/src/MALDIquant.dll b/src/MALDIquant.dll new file mode 100644 index 0000000..182c318 Binary files /dev/null and b/src/MALDIquant.dll differ diff --git a/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R new file mode 100644 index 0000000..1da34a2 --- /dev/null +++ b/tests/testthat/test_OnDiskVector-class.R @@ -0,0 +1,88 @@ +context("OnDiskVector") + +test_that(".valid.OnDiskVector.path", { + f <- tempfile() + on.exit(unlink(f)) + file.create(f) + expect_null(.valid.OnDiskVector.path(f)) + expect_match(.valid.OnDiskVector.path(1:2), "length 1") + expect_match(.valid.OnDiskVector.path(tempfile()), "exists") +}) + +test_that(".valid.OnDiskVector.modification", { + expect_null(.valid.OnDiskVector.modification(1)) + expect_match(.valid.OnDiskVector.modification(1:2), "length 1") +}) + +test_that(".valid.OnDiskVector.n", { + expect_null(.valid.OnDiskVector.n(1)) + expect_match(.valid.OnDiskVector.n(1:2), "length 1") +}) + +test_that(".valid.OnDiskVector.size", { + expect_null(.valid.OnDiskVector.size(1)) + expect_null(.valid.OnDiskVector.size(8)) + expect_match(.valid.OnDiskVector.size(1:2), "length 1") + expect_match(.valid.OnDiskVector.size(3), "has to be 2\\^x") +}) + +test_that(".valid.OnDiskVector.n", { + expect_null(.valid.OnDiskVector.offset(1)) + expect_match(.valid.OnDiskVector.offset(1:2), "length 1") + expect_match(.valid.OnDiskVector.offset(-1), ">= 0") +}) + +test_that("validity", { + odv <- OnDiskVector(1:3) + f <- odv@path + odv@path <- "foobar" + expect_error(validObject(odv), "exists") + odv@path <- f + odv@offset <- -1 + expect_error(validObject(odv), ">= 0") +}) + +test_that(".isModified.OnDiskVector", { + odv1 <- OnDiskVector(1:3) + odv2 <- odv1 + odv2[] <- 4:6 + expect_error(odv1[1], "was modified") + expect_error(odv1[], "was modified") + expect_equal(odv2[1], 4) + expect_equal(odv2[], 4:6) +}) + +test_that("constructor", { + expect_error(OnDiskVector(), "necessary") +}) + +test_that("length", { + odv <- OnDiskVector(1:10) + expect_length(odv, 10) +}) + +test_that("[", { + odv <- OnDiskVector(1:10) + expect_error(odv[0], "out of boundaries") + expect_error(odv[11], "out of boundaries") + expect_equal(odv[3], 3) + expect_equal(odv[c(1, 10)], c(1, 10)) + expect_equal(odv[c(1, 2, 10)], c(1, 2, 10)) + expect_equal(odv[], 1:10) + expect_equal((odv[] <- 11:20)[1:10], 11:20) + + fn <- tempfile() + f <- file(fn, "wb") + writeBin(as.double(1:20), f, size=4L, endian="little") + close(f) + on.exit(unlink(fn)) + + odv2 <- OnDiskVector(path=fn, offset=4L * 10L, n=10L, size=4L) + expect_equal(odv2[1], 11) + expect_equal(odv2[c(1, 10)], c(11, 20)) + expect_equal(odv2[1:3], 11:13) + expect_equal(odv2[], 11:20) + expect_equal((odv2[] <- 21:30)[1:10], 21:30) + + expect_error(odv2[] <- 1:30, "Length") +})