From 15a2619d2ff01fa1f184946e3c105351a53f380a Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Sun, 3 Mar 2019 22:47:14 +0100 Subject: [PATCH 01/11] First draft implementation of OnDiskVector --- DESCRIPTION | 86 +++++++++++++- R/OnDiskVector-class.R | 141 +++++++++++++++++++++++ R/hidden_aliases.R | 9 ++ man/hidden_aliases.Rd | 23 ++++ man/match.closest.Rd | 1 - tests/testthat/test_OnDiskVector-class.R | 67 +++++++++++ 6 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 R/OnDiskVector-class.R create mode 100644 R/hidden_aliases.R create mode 100644 man/hidden_aliases.Rd create mode 100644 tests/testthat/test_OnDiskVector-class.R diff --git a/DESCRIPTION b/DESCRIPTION index 9452a26..16ececf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: MALDIquant -Version: 1.19.1 -Date: 2019-03-03 +Version: 1.99.1 +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/R/OnDiskVector-class.R b/R/OnDiskVector-class.R new file mode 100644 index 0000000..2ff747d --- /dev/null +++ b/R/OnDiskVector-class.R @@ -0,0 +1,141 @@ +#' @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 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", + n="numeric", + offset="numeric", + size="integer" + ), + prototype=list( + path=character(), 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") + } + new("OnDiskVector", path=path, 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.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 +} + +setValidity("OnDiskVector", function(object) { + msg <- c( + .valid.OnDiskVector.path(object@path), + .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.") + + 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) + 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) { + 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'.") + } + writeBin(as.double(value), x@path, size=x@size, endian="little") + x +}) + +.readBin <- function(x, n, size) { + readBin(x, double(), n=n, size=size, signed=TRUE, endian="little") +} 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/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/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R new file mode 100644 index 0000000..ca72da8 --- /dev/null +++ b/tests/testthat/test_OnDiskVector-class.R @@ -0,0 +1,67 @@ +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.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("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:3], 11:13) +}) From c5f70bd4740b7d25e714759cbd0cce0d4ca50a58 Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Wed, 6 Mar 2019 14:11:19 +0100 Subject: [PATCH 02/11] Fix [ for length(i) > 2 --- R/OnDiskVector-class.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/OnDiskVector-class.R b/R/OnDiskVector-class.R index 2ff747d..de6bf9e 100644 --- a/R/OnDiskVector-class.R +++ b/R/OnDiskVector-class.R @@ -101,7 +101,7 @@ setMethod(f="[", 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) + 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") From 274cc6555d40c89087390b99b4ffd60c1756d900 Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Wed, 6 Mar 2019 22:47:45 +0100 Subject: [PATCH 03/11] Add modification counter slot --- R/OnDiskVector-class.R | 34 ++++++++++++++++++++++-- tests/testthat/test_OnDiskVector-class.R | 10 +++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/R/OnDiskVector-class.R b/R/OnDiskVector-class.R index de6bf9e..d566fa6 100644 --- a/R/OnDiskVector-class.R +++ b/R/OnDiskVector-class.R @@ -13,6 +13,8 @@ NULL #' 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 @@ -23,12 +25,19 @@ NULL setClass("OnDiskVector", slots=list( path="character", + mpath="character", + modification="integer", n="numeric", offset="numeric", size="integer" ), prototype=list( - path=character(), n=numeric(), offset=numeric(), size=integer() + path=character(), + mpath=character(), + modification=0L, + n=numeric(), + offset=numeric(), + size=integer() ) ) @@ -40,7 +49,9 @@ OnDiskVector <- function(x, path, n=length(x), offset=0L, size=8L) { path <- tempfile() writeBin(as.double(x), con=path, size=size, endian="little") } - new("OnDiskVector", path=path, n=n, offset=offset, size=size) + 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) { @@ -51,6 +62,12 @@ OnDiskVector <- function(x, path, n=length(x), offset=0L, size=8L) { 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.") @@ -73,9 +90,18 @@ OnDiskVector <- function(x, path, n=length(x), offset=0L, size=8L) { 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) @@ -93,6 +119,7 @@ setMethod(f="[", 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)) @@ -118,6 +145,7 @@ setMethod(f="[", 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) @@ -133,6 +161,8 @@ setReplaceMethod(f="[", stop("Length of 'value' doesn't match length of 'x'.") } writeBin(as.double(value), x@path, size=x@size, endian="little") + x@modification <- x@modification + 1L + writeBin(x@modification, x@mpath, size=NA_integer_, endian="little") x }) diff --git a/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R index ca72da8..d59965a 100644 --- a/tests/testthat/test_OnDiskVector-class.R +++ b/tests/testthat/test_OnDiskVector-class.R @@ -37,6 +37,16 @@ test_that("validity", { 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") }) From 8353118eede03c4dad1e3ea2fc91282476fa8895 Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Wed, 6 Mar 2019 23:01:25 +0100 Subject: [PATCH 04/11] Add offset support for [<- --- R/OnDiskVector-class.R | 8 +++++++- tests/testthat/test_OnDiskVector-class.R | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/R/OnDiskVector-class.R b/R/OnDiskVector-class.R index d566fa6..552f084 100644 --- a/R/OnDiskVector-class.R +++ b/R/OnDiskVector-class.R @@ -160,7 +160,13 @@ setReplaceMethod(f="[", if (length(value) != x@n) { stop("Length of 'value' doesn't match length of 'x'.") } - writeBin(as.double(value), x@path, size=x@size, endian="little") + f <- file(x@path, "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") + x@modification <- x@modification + 1L writeBin(x@modification, x@mpath, size=NA_integer_, endian="little") x diff --git a/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R index d59965a..3bbaf23 100644 --- a/tests/testthat/test_OnDiskVector-class.R +++ b/tests/testthat/test_OnDiskVector-class.R @@ -9,6 +9,11 @@ test_that(".valid.OnDiskVector.path", { expect_match(.valid.OnDiskVector.path(tempfile()), "exists") }) +test_that(".valid.OnDiskVector.modification", { + expect_null(.valid.OnDiskVector.n(1)) + expect_match(.valid.OnDiskVector.n(1:2), "length 1") +}) + test_that(".valid.OnDiskVector.n", { expect_null(.valid.OnDiskVector.n(1)) expect_match(.valid.OnDiskVector.n(1:2), "length 1") @@ -73,5 +78,9 @@ test_that("[", { 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) }) From 6590b66e82099d3eed3a53cecffb25447dd55103 Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Wed, 6 Mar 2019 23:04:12 +0100 Subject: [PATCH 05/11] Add unit test for error when trying to write longer replacements --- tests/testthat/test_OnDiskVector-class.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R index 3bbaf23..fbb8f59 100644 --- a/tests/testthat/test_OnDiskVector-class.R +++ b/tests/testthat/test_OnDiskVector-class.R @@ -83,4 +83,6 @@ test_that("[", { 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") }) From 9f10c7471498de009172dcefc9064feb80f500dd Mon Sep 17 00:00:00 2001 From: Sebastian Gibb Date: Wed, 6 Mar 2019 23:06:31 +0100 Subject: [PATCH 06/11] Fix .valid.OnDiskVector.modification unit test --- tests/testthat/test_OnDiskVector-class.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test_OnDiskVector-class.R b/tests/testthat/test_OnDiskVector-class.R index fbb8f59..1da34a2 100644 --- a/tests/testthat/test_OnDiskVector-class.R +++ b/tests/testthat/test_OnDiskVector-class.R @@ -10,8 +10,8 @@ test_that(".valid.OnDiskVector.path", { }) test_that(".valid.OnDiskVector.modification", { - expect_null(.valid.OnDiskVector.n(1)) - expect_match(.valid.OnDiskVector.n(1:2), "length 1") + expect_null(.valid.OnDiskVector.modification(1)) + expect_match(.valid.OnDiskVector.modification(1:2), "length 1") }) test_that(".valid.OnDiskVector.n", { From 4670e3000b59efe4569b50dbe40d7058bb8be165 Mon Sep 17 00:00:00 2001 From: dsammour Date: Mon, 15 Apr 2019 16:45:46 +0200 Subject: [PATCH 07/11] Added support for OnDiskVector --- .Rbuildignore | 2 + .gitignore | 1 + DESCRIPTION | 2 +- NAMESPACE | 5 +- R/AllClasses.R | 52 +++++++++++++- R/AllGenerics.R | 4 +- R/OnDiskVector-class.R | 6 ++ R/alignSpectra-functions.R | 4 +- R/approxfun-methods.R | 4 +- R/as.matrix-functions.R | 4 +- R/as.matrix-methods.R | 2 +- R/averageMassSpectra-functions.R | 2 +- R/calibrateIntensity-functions.R | 4 +- R/calibrateIntensity-methods.R | 2 +- R/constructor-functions.R | 33 +++++++++ R/detectPeaks-methods.R | 17 +++-- R/estimateBaseline-methods.R | 6 +- R/estimateNoise-methods.R | 6 +- R/findLocalMaxima-methods.R | 10 +-- R/intensity-methods.R | 4 +- R/isEmpty-methods.R | 2 +- R/isMassObject-functions.R | 2 +- R/isMassObjectList-functions.R | 2 +- R/isRegular-methods.R | 4 +- R/lines-methods.R | 2 +- R/mass-methods.R | 4 +- R/memoryUsage-functions.R | 14 +++- R/plot-methods.R | 2 +- R/points-methods.R | 2 +- R/range-functions.R | 4 +- R/removeBaseline-methods.R | 9 ++- R/reorder-functions.R | 10 +-- R/replaceNegativeIntensityValues-functions.R | 7 +- R/show-methods.R | 71 ++++++++++++++++++++ R/smoothIntensity-methods.R | 2 +- R/subset-methods.R | 46 ++++++++++++- R/totalIonCurrent-methods.R | 10 +-- R/transformIntensity-methods.R | 16 +++-- R/trim-methods.R | 38 +++++++++++ R/valid-methods.R | 22 +++--- R/warp-functions.R | 6 +- 41 files changed, 359 insertions(+), 86 deletions(-) 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 16ececf..6dc9f00 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: MALDIquant -Version: 1.99.1 +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"), diff --git a/NAMESPACE b/NAMESPACE index af0c7c0..41fa281 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,13 +49,16 @@ importFrom("utils", exportClasses("MassPeaks", - "MassSpectrum") + "MassSpectrum" + "MassSpectrumOnDisk", + "OnDiskVector") export("alignSpectra", "averageMassSpectra", "binPeaks", "createMassPeaks", "createMassSpectrum", + "createMassSpectrumOnDisk", "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 index 552f084..6b550d7 100644 --- a/R/OnDiskVector-class.R +++ b/R/OnDiskVector-class.R @@ -172,6 +172,12 @@ setReplaceMethod(f="[", x }) +#' @rdname hidden_aliases +setMethod("min", "OnDiskVector", function(x)min(x[])) + +#' @rdname hidden_aliases +setMethod("max", "OnDiskVector", function(x)max(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.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/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..9f668de 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(y), 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..2e85461 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,45 @@ setMethod(f=".prepareShow", list(groups=l$groups, values=l$values) }) + +## OnDiskVector +setMethod(f="show", + signature=signature(object="OnDiskVector"), + definition=function(object) { + + #l <- .prepareShow(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(min(object), digits=4L, + scientific=TRUE), " - ", + format(max(object), digits=4L, + scientific=TRUE)), + 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 } From 98e654333cbfa001c659bddcc994a2e5a12b71e5 Mon Sep 17 00:00:00 2001 From: dsammour Date: Mon, 15 Apr 2019 17:34:42 +0200 Subject: [PATCH 08/11] additional fixes --- NAMESPACE | 2 +- man/AbstractMassObject-class.Rd | 8 +-- man/AbstractMassSpectrum-class.Rd | 104 +++++++++++++++++++++++++++ man/MassSpectrum-class.Rd | 2 +- man/MassSpectrumOnDisk-class.Rd | 112 ++++++++++++++++++++++++++++++ man/OnDiskVector-class.Rd | 51 ++++++++++++++ src/MALDIquant.dll | Bin 0 -> 21504 bytes 7 files changed, 273 insertions(+), 6 deletions(-) create mode 100644 man/AbstractMassSpectrum-class.Rd create mode 100644 man/MassSpectrumOnDisk-class.Rd create mode 100644 man/OnDiskVector-class.Rd create mode 100644 src/MALDIquant.dll diff --git a/NAMESPACE b/NAMESPACE index 41fa281..7b893a0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,7 +49,7 @@ importFrom("utils", exportClasses("MassPeaks", - "MassSpectrum" + "MassSpectrum", "MassSpectrumOnDisk", "OnDiskVector") 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/src/MALDIquant.dll b/src/MALDIquant.dll new file mode 100644 index 0000000000000000000000000000000000000000..23f46ba1c3151d9b0b76c8a2e4d59eab7a97a567 GIT binary patch literal 21504 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 literal 0 HcmV?d00001 From b2ba93cd47909c76069125b1ae5496e0b9083925 Mon Sep 17 00:00:00 2001 From: dsammour Date: Tue, 16 Apr 2019 17:36:47 +0200 Subject: [PATCH 09/11] additional fixes --- NAMESPACE | 1 + R/OnDiskVector-class.R | 26 ++++++++++++++++---------- R/show-methods.R | 9 +++------ src/MALDIquant.dll | Bin 21504 -> 21504 bytes 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 7b893a0..f1b8801 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -59,6 +59,7 @@ export("alignSpectra", "createMassPeaks", "createMassSpectrum", "createMassSpectrumOnDisk", + "OnDiskVector", "determineWarpingFunctions", "filterPeaks", "findEmptyMassObjects", diff --git a/R/OnDiskVector-class.R b/R/OnDiskVector-class.R index 6b550d7..cb0322f 100644 --- a/R/OnDiskVector-class.R +++ b/R/OnDiskVector-class.R @@ -22,6 +22,7 @@ NULL #' @author Sebastian Gibb #' #' @noRd + setClass("OnDiskVector", slots=list( path="character", @@ -90,12 +91,12 @@ OnDiskVector <- function(x, path, n=length(x), offset=0L, size=8L) { 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 -} +# .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( @@ -119,7 +120,7 @@ setMethod(f="[", if (any(i < 1) || any (i > x@n)) stop("Index out of boundaries.") - .isModified.OnDiskVector(x) + #.isModified.OnDiskVector(x) f <- file(x@path, "rb") on.exit(close(f)) @@ -145,7 +146,7 @@ setMethod(f="[", setMethod(f="[", signature=signature(x="OnDiskVector", i="missing", j="missing"), definition=function(x, i, j, ..., drop=FALSE) { - .isModified.OnDiskVector(x) + #.isModified.OnDiskVector(x) f <- file(x@path, "rb") on.exit(close(f)) if (x@offset) @@ -160,15 +161,17 @@ setReplaceMethod(f="[", if (length(value) != x@n) { stop("Length of 'value' doesn't match length of 'x'.") } - f <- file(x@path, "wb") + 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") + 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 }) @@ -178,6 +181,9 @@ 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/show-methods.R b/R/show-methods.R index 2e85461..41aa8a9 100644 --- a/R/show-methods.R +++ b/R/show-methods.R @@ -105,8 +105,7 @@ setMethod(f="show", signature=signature(object="OnDiskVector"), definition=function(object) { - #l <- .prepareShow(object) - + groups <- c("S4 class type", "Vector length", "Vector range", @@ -119,10 +118,8 @@ setMethod(f="show", values <- c(class(object)[1L], length(object), - paste0(format(min(object), digits=4L, - scientific=TRUE), " - ", - format(max(object), digits=4L, - scientific=TRUE)), + paste0(format(range(object), digits=4L, + scientific=TRUE), collapse = " - "), object@path, object@mpath, .memoryUsageStr(object@path, FALSE), diff --git a/src/MALDIquant.dll b/src/MALDIquant.dll index 23f46ba1c3151d9b0b76c8a2e4d59eab7a97a567..62fedab2ab26a0655e664c039338c2bfbc01cf2c 100644 GIT binary patch delta 32 mcmZoz!Pu~ZaY6_4rZ-zBcKb5-onY8_ThkH5-OTRvQxE|22@cf& delta 32 mcmZoz!Pu~ZaY6^P-;ym8yM37tn=@{_t?3BjZf1A-DF^`Bi47nC From b526feac07803cff7757022f5aa1c1f8c134249f Mon Sep 17 00:00:00 2001 From: dsammour Date: Wed, 17 Apr 2019 16:01:59 +0200 Subject: [PATCH 10/11] minor fix --- R/lines-methods.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/lines-methods.R b/R/lines-methods.R index 9f668de..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=mass(x), y=intensity(y), type, ...) + lines(x=mass(x), y=intensity(x), type, ...) }) From 8fb7242b52a788f4b3d197126010dc0854079b33 Mon Sep 17 00:00:00 2001 From: dsammour Date: Tue, 23 Apr 2019 11:29:58 +0200 Subject: [PATCH 11/11] added as method for converting MassSpectrumOnDisk to MassSpectrum --- R/as-methods.R | 11 +++++++++++ src/MALDIquant.dll | Bin 21504 -> 21504 bytes 2 files changed, 11 insertions(+) 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/src/MALDIquant.dll b/src/MALDIquant.dll index 62fedab2ab26a0655e664c039338c2bfbc01cf2c..182c3184bdebe6cb063f05d0b0a25d24d0079aec 100644 GIT binary patch delta 31 lcmZoz!Pu~ZaY6_4ty}vhcKb4YShDe!mLrI_nceB9AOP{*4^RLA delta 31 lcmZoz!Pu~ZaY6_4rZ-zBcKb5*o!EFw%Mrxe%