## ----style, echo = FALSE, results = 'asis', message=FALSE--------------------- BiocStyle::markdown() ## ----echo = FALSE, message = FALSE-------------------------------------------- library(Chromatograms) library(BiocStyle) ## ----message = FALSE---------------------------------------------------------- library(Chromatograms) #' Definition of the backend class extending ChromBackend setClass("ChromBackendTest", contains = "ChromBackend", slots = c( chromData = "data.frame", peaksData = "list" ), prototype = prototype( chromData = data.frame(), peaksData = list() ) ) #' Simple constructor function ChromBackendTest <- function() { new("ChromBackendTest") } ## ----message = FALSE---------------------------------------------------------- #' Basic validation function setValidity("ChromBackendTest", function(object) { if (length(object@peaksData) != nrow(object@chromData)) { return( "length of 'peaksData' has to match the number of rows of ", "'chromData'" ) } NULL }) ## ----------------------------------------------------------------------------- #' Create an empty instance of ChromBackendTest be <- ChromBackendTest() be ## ----------------------------------------------------------------------------- #' implementation of show for ChromBackendTest setMethod("show", "ChromBackendTest", function(object) { cd <- object@chromData cat(class(object), "with", nrow(cd), "chromatograms\n") }) be ## ----------------------------------------------------------------------------- #' dataStorage method to provide information *where* data is stored setMethod("dataStorage", "ChromBackendTest", function(object) { as.character(object@chromData$dataStorage) }) ## ----------------------------------------------------------------------------- dataStorage(be) ## ----------------------------------------------------------------------------- #' length to provide information on the number of chromatograms setMethod("length", "ChromBackendTest", function(x) { nrow(x@chromData) }) length(be) ## ----------------------------------------------------------------------------- #' backendInitialize method to fill the backend with data. setMethod( "backendInitialize", "ChromBackendTest", function(object, chromData, peaksData) { if (!is.data.frame(chromData)) { stop( "'chromData' needs to be a 'data.frame' with the general", "chromatogram variables" ) } ## Defining dataStorage and dataOrigin, if not available if (is.null(chromData$dataOrigin)) { chromData$dataOrigin <- NA_character_ } ## Validate the provided data validChromData(chromData) validPeaksData(peaksData) ## Fill the object with data object@chromData <- chromData object@peaksData <- peaksData object } ) ## ----------------------------------------------------------------------------- # A data.frame with chromatogram variables. cdata <- data.frame( msLevel = c(1L, 1L), mz = c(112.2, 123.3) ) # Retention time and intensity values for each chromatogram. pdata <- list( data.frame( rtime = c(12.4, 12.8, 13.2, 14.6), intensity = c(123.3, 153.6, 2354.3, 243.4) ), data.frame( rtime = c(45.1, 46.2), intensity = c(100, 80.1) ) ) #' Create and initialize the backend be <- backendInitialize(ChromBackendTest(), chromData = cdata, peaksData = pdata ) be ## ----------------------------------------------------------------------------- #' List core chromatogram variables along with data types. coreChromVariables() ## ----------------------------------------------------------------------------- #' Accessor for available chromatogram variables setMethod("chromVariables", "ChromBackendTest", function(object) { union(names(object@chromData), names(coreChromVariables())) }) chromVariables(be) ## ----------------------------------------------------------------------------- #' Get the data.frame with the available chrom variables be@chromData #' Complete this data.frame with missing core variables fillCoreChromVariables(be@chromData) ## ----------------------------------------------------------------------------- #' function to extract the full chromData setMethod( "chromData", "ChromBackendTest", function(object, columns = chromVariables(object), drop = FALSE) { if (!any(chromVariables(object) %in% columns)) { stop( "Some of the requested Chromatogram variables are not ", "available" ) } res <- fillCoreChromVariables(object@chromData) res <- res[, columns, drop = drop] res } ) ## ----------------------------------------------------------------------------- #' Extract the full data chromData(be) #' Selected variables chromData(be, c("mz", "msLevel")) #' Only missing core chromatograms variables chromData(be, c("collisionEnergy", "mzMin")) ## ----------------------------------------------------------------------------- setMethod("peaksVariables", "ChromBackendTest", function(object) { union(names(corePeaksVariables()), names(object@peaksData[[1]])) }) ## ----------------------------------------------------------------------------- peaksVariables(be) ## ----------------------------------------------------------------------------- corePeaksVariables() ## ----------------------------------------------------------------------------- #' method to extract the full chromatographic data as list of arrays setMethod( "peaksData", "ChromBackendTest", function(object, columns = peaksVariables(object), drop = FALSE) { if (!all(columns %in% peaksVariables(object))) { stop("Some of the requested peaks variables are not available") } res <- lapply(object@peaksData, function(x) x[, columns, drop = drop]) res } ) ## ----------------------------------------------------------------------------- #' Extract the *peaks* data (i.e. intensity and retention times) peaksData(be) ## ----------------------------------------------------------------------------- #' Main subset method. setMethod("[", "ChromBackendTest", function(x, i, j, ..., drop = FALSE) { i <- MsCoreUtils::i2index(i, length = length(x)) x@chromData <- x@chromData[i, ] x@peaksData <- x@peaksData[i] x }) ## ----------------------------------------------------------------------------- a <- be[1] chromData(a) ## ----------------------------------------------------------------------------- a <- be[c(1, 1, 1)] chromData(a) ## ----------------------------------------------------------------------------- #' Access a single chromatogram variable setMethod("$", "ChromBackendTest", function(x, name) { if (name %in% union(chromVariables(x), names(coreChromVariables()))) { res <- chromData(x, columns = name, drop = TRUE) } else if (name %in% peaksVariables(x)) { res <- peaksData(x, columns = name, drop = TRUE) } else { stop("The requested variable '", name, "' is not available") } res }) ## ----------------------------------------------------------------------------- be$msLevel ## ----------------------------------------------------------------------------- be$precursorMz ## ----------------------------------------------------------------------------- be$intensity ## ----------------------------------------------------------------------------- #' Method allowing to join (concatenate) backends setMethod("backendMerge", "ChromBackendTest", function(object, ...) { res <- object object <- unname(c(list(object), list(...))) res@peaksData <- do.call(c, lapply(object, function(z) z@peaksData)) res@chromData <- do.call( MsCoreUtils::rbindFill, lapply(object, function(z) z@chromData) ) validObject(res) res }) ## ----------------------------------------------------------------------------- a <- backendMerge(be, be[2], be) a ## ----------------------------------------------------------------------------- #' Default for backends: isReadOnly(be) ## ----------------------------------------------------------------------------- #' Implementation of isReadOnly for ChromBackendTest setMethod("isReadOnly", "ChromBackendTest", function(object) FALSE) isReadOnly(be) ## ----------------------------------------------------------------------------- #' Replacement method for the full chromatogram data setReplaceMethod("chromData", "ChromBackendTest", function(object, value) { if (is(value, "DataFrame")) { value <- as(value, "data.frame") } if (!inherits(value, "data.frame")) { stop("'value' is expected to be a 'data.frame'") } if (length(object) && length(object) != nrow(value)) { stop("'value' has to be a 'data.frame' with ", length(object), " rows") } validChromData(value) object@chromData <- value object }) ## ----------------------------------------------------------------------------- d <- chromData(be) d$new_col <- c("a", "b") chromData(be) <- d ## ----------------------------------------------------------------------------- be$new_col ## ----------------------------------------------------------------------------- #' Replace or add a single chromatogram variable. setReplaceMethod("$", "ChromBackendTest", function(x, name, value) { if (length(x) && length(value) != length(x)) { stop( "length of 'value' needs to match the number of chromatograms ", "in object." ) } if (name %in% peaksVariables(x)) { if (!is.list(value)) { stop("The value for peaksData should be a list") } for (i in seq_along(value)) { x@peaksData[[i]][[name]] <- value[[i]] validPeaksData(x@peaksData) } } else { x@chromData[, name] <- value validChromData(x@chromData) } x }) ## ----------------------------------------------------------------------------- #' Values before replacement be$msLevel #' Replace MS levels be$msLevel <- c(3L, 2L) #' Values after replacement be$msLevel ## ----------------------------------------------------------------------------- #' Add a new chromatogram variable be$name <- c("A", "B") be$name ## ----------------------------------------------------------------------------- #' Replace intensity values be$msLevel3 <- be$msLevel + 3 be$msLevel3 ## ----------------------------------------------------------------------------- #' replacement method for peaks data setReplaceMethod("peaksData", "ChromBackendTest", function(object, value) { if (!is.list(value)) { stop("'value' is expected to be a list") } if (length(object) && length(object) != length(value)) { stop("'value' has to be a list with ", length(object), " elements") } validPeaksData(value) object@peaksData <- value object }) ## ----------------------------------------------------------------------------- #' Create a list with peaks matrices; our backend has 3 chromatograms #' thus our `list` has to be of length 3 tmp <- list( data.frame( rtime = c(12.3, 14.4, 15.4, 16.4), intensity = c(200, 312, 354.1, 232) ), data.frame( rtime = c(14.4), intensity = c(13.4) ) ) be_2 <- be #' Assign this peaks data to one of our test backends peaksData(be_2) <- tmp #' Evaluate that we properly added the peaks data peaksData(be_2) ## ----eval = FALSE------------------------------------------------------------- # #' Is there a specific way how the object could be best split for # #' parallel processing? # setMethod("backendParallelFactor", "ChromBackend", function(object, ...) { # factor() # }) ## ----------------------------------------------------------------------------- backendParallelFactor(be) ## ----eval = FALSE------------------------------------------------------------- # #' get the values for the chromIndex chromatogram variable # setMethod( # "chromIndex", "ChromBackend", # function(object, columns = chromVariables(object)) { # chromData(object, columns = "chromIndex", drop = TRUE) # } # ) ## ----------------------------------------------------------------------------- chromIndex(be) ## ----eval = FALSE------------------------------------------------------------- # #' get the values for the collisionEnergy chromatogram variable # setMethod("collisionEnergy", "ChromBackend", function(object) { # chromData(object, columns = "collisionEnergy", drop = TRUE) # }) ## ----------------------------------------------------------------------------- collisionEnergy(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default replacement method for collisionEnergy # setReplaceMethod( # "collisionEnergy", "ChromBackend", function(object, value) { # object$collisionEnergy <- value # object # } # ) ## ----------------------------------------------------------------------------- #' Replace the collision energy collisionEnergy(be) <- c(20, 30) collisionEnergy(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation to access dataOrigin # setMethod("dataOrigin", "ChromBackend", function(object) { # chromData(object, columns = "dataOrigin", drop = TRUE) # }) ## ----------------------------------------------------------------------------- #' Access the dataOrigin values dataOrigin(be) ## ----------------------------------------------------------------------------- #' Default implementation of the `dataOrigin<-` replacement method setReplaceMethod("dataOrigin", "ChromBackend", function(object, value) { object$dataOrigin <- value object }) ## ----------------------------------------------------------------------------- #' Replace the backend's dataOrigin values dataOrigin(be) <- rep("from somewhere", 2) dataOrigin(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default method to extract intensity values # setMethod("intensity", "ChromBackend", function(object) { # if (length(object)) { # peaksData(object, column = "intensity", drop = TRUE) # } else { # list() # } # }) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation of the replacement method for intensity values # setReplaceMethod("intensity", "ChromBackend", function(object, value) { # pd <- peaksData(object) # if (!is.list(value) || length(pd) != length(value)) { # stop("'value' should be a list of the same length as 'object'") # } # for (i in seq_along(pd)) { # if (length(value[[i]]) != nrow(pd[[i]])) { # stop(paste0( # "Length of 'value[[", i, "]]' does not match ", # "the number of rows in the intensity of chromatogram: ", # i, "'" # )) # } # } # peaksData(object) <- lapply(seq_along(pd), function(i) { # pd[[i]]$intensity <- value[[i]] # return(pd[[i]]) # }) # object # }) ## ----------------------------------------------------------------------------- #' Replace intensity values intensity(be)[[1]] <- intensity(be)[[1]] + 10 intensity(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation for `isEmpty()` # setMethod("isEmpty", "ChromBackend", function(x) { # lengths(x) == 0L # }) ## ----------------------------------------------------------------------------- isEmpty(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation of `isReadOnly()` # setMethod("isReadOnly", "ChromBackend", function(object) { # TRUE # }) ## ----------------------------------------------------------------------------- isReadOnly(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation for `length()` # setMethod("length", "ChromBackend", function(x) { # nrow(chromData(x, columns = "dataStorage")) # }) ## ----------------------------------------------------------------------------- length(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementation for `lengths()` # setMethod("lengths", "ChromBackend", function(x) { # lengths(intensity(x)) # }) ## ----------------------------------------------------------------------------- lengths(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default methods to get or set MS levels # setMethod("msLevel", "ChromBackend", function(object) { # chromData(object, columns = "msLevel", drop = TRUE) # }) # setReplaceMethod("msLevel", "ChromBackend", function(object, value) { # object$msLevel <- value # object # }) ## ----------------------------------------------------------------------------- msLevel(be) <- c(1L, 2L) msLevel(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations to get or set m/z value(s) # setMethod("mz", "ChromBackend", function(object) { # chromData(object, columns = "mz", drop = TRUE) # }) # setReplaceMethod("mz", "ChromBackend", function(object, value) { # object$mz <- value # object # }) ## ----------------------------------------------------------------------------- mz(be) <- c(314.3, 312.5) mz(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations to get or set upper m/z limits # setMethod("mzMax", "ChromBackend", function(object) { # chromData(object, columns = "mzMax", drop = TRUE) # }) # setReplaceMethod("mzMax", "ChromBackend", function(object, value) { # object$mzMax <- value # object # }) ## ----------------------------------------------------------------------------- mzMax(be) <- mz(be) + 0.01 mzMax(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default methods to get or set the lower m/z boundary # setMethod("mzMin", "ChromBackend", function(object) { # chromData(object, columns = "mzMin", drop = TRUE) # }) # # setReplaceMethod("mzMin", "ChromBackend", function(object, value) { # object$mzMin <- value # object # }) ## ----------------------------------------------------------------------------- mzMin(be) <- mz(be) - 0.01 mzMin(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations to get or set the precursorMz chrom variable # setMethod("precursorMz", "ChromBackend", function(object) { # chromData(object, columns = "precursorMz", drop = TRUE) # }) # setReplaceMethod("precursorMz", "ChromBackend", function(object, value) { # object$precursorMz <- value # object # }) ## ----------------------------------------------------------------------------- precursorMz(be) <- c(NA_real_, 123.3) precursorMz(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations for `precursorMzMax` # setMethod("precursorMzMax", "ChromBackend", function(object) { # chromData(object, columns = "precursorMzMax", drop = FALSE) # }) # setReplaceMethod("precursorMzMax", "ChromBackend", function(object, value) { # object$precursorMzMax <- value # object # }) ## ----------------------------------------------------------------------------- precursorMzMax(be) <- precursorMz(be) + 0.1 precursorMzMax(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations for `precursorMzMin` # setMethod("precursorMzMin", "ChromBackend", function(object) { # chromData(object, columns = "precursorMzMin", drop = FALSE) # }) # setReplaceMethod("precursorMzMin", "ChromBackend", function(object, value) { # object$precursorMzMin <- value # object # }) ## ----------------------------------------------------------------------------- precursorMzMin(be) <- precursorMz(be) - 0.1 precursorMzMin(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations for `productMz` # setMethod("productMz", "ChromBackend", function(object) { # chromData(object, columns = "productMz", drop = TRUE) # }) # setReplaceMethod("productMz", "ChromBackend", function(object, value) { # object$productMz <- value # object # }) ## ----------------------------------------------------------------------------- productMz(be) <- c(123.2, NA_real_) productMz(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations for `productMzMax` # setMethod("productMzMax", "ChromBackend", function(object) { # chromData(object, columns = "productMzMax", drop = FALSE) # }) # setReplaceMethod("productMzMax", "ChromBackend", function(object, value) { # object$productMzMax <- value # object # }) ## ----------------------------------------------------------------------------- productMzMax(be) <- productMz(be) + 0.02 productMzMax(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default implementations for `productMzMin` # setMethod("productMzMin", "ChromBackend", function(object) { # chromData(object, columns = "productMzMin", drop = FALSE) # }) # setReplaceMethod("productMzMin", "ChromBackend", function(object, value) { # object$productMzMin <- value # object # }) ## ----------------------------------------------------------------------------- productMzMin(be) <- productMz(be) - 0.2 productMzMin(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default methods for `rtime()` and `rtime<-` # setMethod("rtime", "ChromBackend", function(object) { # if (length(object)) { # peaksData(object, column = "rtime", drop = TRUE) # } else { # list() # } # }) # # setReplaceMethod("rtime", "ChromBackend", function(object, value) { # pd <- peaksData(object) # if (!is.list(value) || length(pd) != length(value)) { # stop("'value' should be a list of the same length as 'object'") # } # for (i in seq_along(pd)) { # if (length(value[[i]]) != nrow(pd[[i]])) { # stop(paste0( # "Length of 'value[[", i, "]]' does not match ", # "the number of rows in 'the rtime of chromatogram: ", i, "'" # )) # } # } # peaksData(object) <- lapply(seq_along(pd), function(i) { # pd[[i]]$rtime <- value[[i]] # return(pd[[i]]) # }) # object # }) ## ----------------------------------------------------------------------------- rtime(be)[[1]] <- rtime(be)[[1]] + 2 rtime(be) ## ----eval = FALSE------------------------------------------------------------- # #' Default method to split a backend # setMethod("split", "ChromBackend", function(x, f, drop = FALSE, ...) { # split.default(x, f, drop = drop, ...) # }) ## ----------------------------------------------------------------------------- split(be, f = c(1, 2, 1)) ## ----si----------------------------------------------------------------------- sessionInfo()