Skip to content

Commit

Permalink
Merge pull request #699 from sneumann/phili
Browse files Browse the repository at this point in the history
Addition of PlainTextParam to the storeResults generic function
  • Loading branch information
sneumann authored Nov 21, 2023
2 parents 120ab3f + 6c7e980 commit f1cbe52
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 27 deletions.
6 changes: 4 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: xcms
Version: 4.1.1
Version: 4.1.2
Title: LC-MS and GC-MS Data Analysis
Description: Framework for processing and visualization of chromatographically
separated and single-spectra mass spectral data. Imports from AIA/ANDI NetCDF,
Expand Down Expand Up @@ -61,7 +61,8 @@ Imports:
MsExperiment (>= 1.1.2),
Spectra (>= 1.11.10),
progress,
multtest
multtest,
jsonlite
Suggests:
BiocStyle,
caTools,
Expand Down Expand Up @@ -96,6 +97,7 @@ Collate:
'MPI.R'
'MsExperiment-functions.R'
'MsExperiment.R'
'PlainTextParam.R'
'RDataParam.R'
'XcmsExperiment-functions.R'
'XcmsExperiment-plotting.R'
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ exportMethods("uniqueMsLevels")
exportMethods("filterMzRange")

## saving xcms objects things
importFrom("jsonlite", "serializeJSON", "write_json", "unserializeJSON",
"read_json")
export("RDataParam")
export("PlainTextParam")
exportMethods("storeResults")

40 changes: 24 additions & 16 deletions R/AllGenerics.R
Original file line number Diff line number Diff line change
Expand Up @@ -1953,40 +1953,48 @@ setGeneric("stitch.netCDF.new", function(object, lockMass) standardGeneric("stit
#' and exporting are available and can be defined by the `param` argument.
#'
#' Supported `param` objects are:
#'
#'
#' - [`RDataParam`]: Save in an .RData format file. The name of the file can be
#' specified in the `fileName` argument.
#'
#' - `PlainTextParam`: Save in a plain text format (to be defined).
#'
#' specified in the `fileName` argument.
#'
#' - [`PlainTextParam`]: Store `MsExperiment` and `XcmsExperiment` objects as a
#' folder of plain text files, folder path defined in the `path` argument.
#'
#' - `MzTabMParam`: Save in MzTab format (to be defined).
#'
#'
#' For specific examples, see the help pages of the individual parameter classes
#' listed above.
#'
#' @param object The data object that needs to be saved.
#' @param object `MsExperiment` or `XcmsExperiment` The data object that needs
#' to be saved.
#'
#' @param param The parameter object selecting and configuring the format for
#' saving. It can be one of the following classes: `RDataParam`,
#' `PlainTextParam`, or `MzTabMParam`.
#' saving. It can be one of the following classes: [`RDataParam`],
#' [`PlainTextParam`], or `MzTabMParam`.
#'
#' @param ... Optional parameters.
#'
#' @name storeResults
#'
#'
#' @author Philippine Louail
#'
#'
#' @examples
#'
#'
#' ## Load a test data set with detected peaks
#' faahko_sub <- loadXcmsData("faahko_sub2")
#'
#' ## Set up parameter to save as .RData file
#'
#' ## Set up parameter to save as .RData file
#' param <- RDataParam(fileName = "example_xcms_results")
#'
#'
#' ## save as .RData
#' storeResults(object = faahko_sub, param = param)
#'
#'
#' ## Set up parameter to save as a collection of plain text file
#' param <- PlainTextParam(path = "test/path/")
#'
#' ## Save as a collection of plain text files
#' storeResults(object = faahko_sub, param = param)
#'
#' @md
setGeneric("storeResults", function(object, param, ...) standardGeneric("storeResults"))
setGeneric("subset<-", function(object, value) standardGeneric("subset<-"))
Expand Down
224 changes: 224 additions & 0 deletions R/PlainTextParam.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
#' @title Store contents of `MsExperiment` and `XcmsExperiment` objects as
#' plain text files
#'
#' @name PlainTextParam
#'
#' @export
#'
#' @family xcms result export formats.
#'
#' @description
#' The `PlainTextParam` class and method enable users to save `MsExperiment` or
#' `XcmsExperiment` objects as collections of plain text files in a specified
#' folder. Note that, while for all xcms results within the `XcmsExperiment` can
#' and will be exported, the full raw MS data (of the object's `Spectra` object)
#' will currently not be exported in plain text format. For `Spectra` using the
#' [MsBackendMzR()] backend, the names of the raw data files will however be
#' exported (which enables to *restore* the full `Spectra` respectively
#' `MsExperiment` objects).
#'
#' For an `MsExperiment` object, the exported files include:
#'
#' - The [sampleData()] stored as a text file named *sample_data.txt*.
#'
#' - The [fileNames()] of the *Spectra* object stored in a tabular format in a
#' text file named *spectra_files.txt*.The file names will only be exported if
#' the `Spectra` object uses a [MsBackendMzR()] backend. For other backends no
#' information on raw spectra data is currently exported with `PlainTextParam`.
#'
#' - Processing queue of the `Spectra` object, ensuring that any spectra data
#' modifications are retained. It is stored in a `json` file named
#' *spectra_processing_queue.json*.
#'
#' For an `XcmsExperiment` object, the exported files are the same as those
#' for an `MsExperiment` object, with the addition of the following:
#'
#' - The [processHistory()] information of the object, stored in a `json` file
#' named *process_history.json*.
#'
#' - The chromatographic peak information obtained with [chromPeaks()] and
#' [chromPeaksData()], stored in tabular format in the text files
#' *chrom_peaks.txt* and *chrom_peak_data.txt* respectively.
#'
#' - The retention time information obtained with [adjustedRtime()] stored
#' in the text file named *rtime_adjusted.txt*.
#'
#' - The [featureDefinitions()] stored in a text file named
#' *feature_definitions.txt*. Additionally, a second file named
#' *feature_peak_index.txt* is generated to connect the features' definitions
#' with their names.
#'
#' This `param` class and method are part of the possible dispatch of the
#' generic function `storeResults`. The folder will be created by calling
#' `storeResults`. If the folder already exists, previous exports in that
#' folder might get overwritten.
#'
#' @param path for `PlainTextParam` `character(1)`, defining where the files are
#' going to be stored. The default will be `tempdir()`.
#'
#' @inheritParams storeResults
#'
#' @return for `PlainTextParam`: a `PlainTextParam` class. `storeResults` does
#' not return anything but saves the object to collections of different plain
#' text files to a folder.
#'
#' @author Philippine Louail, Johannes Rainer.
#'
#' @importFrom jsonlite serializeJSON write_json unserializeJSON read_json
#'
#' @examples
#' ## Load test data set of class `MsExperiment`
#' library(MsExperiment)
#' fls <- dir(system.file("sciex", package = "msdata"), full.names = TRUE)
#' pd <- data.frame(file = basename(fls),
#' sample = c("POOL_1", "POOL_2"),
#' injection_index = c(1, 19),
#' group = "POOL")
#' rownames(pd) <- c("1", "2")
#' mse <- readMsExperiment(fls, sampleData = pd)
#'
#' ## Define param
#' pth = file.path(tempdir(), "test")
#' param <- PlainTextParam(path = pth)
#'
#' ## Save as a collection of plain text files
#' storeResults(object = mse, param = param)
#'
#' ## Load a test data set with detected peaks, of class `XcmsExperiment`
#' faahko_sub <- loadXcmsData("faahko_sub2")
#'
#' ## Define param
#' pth = file.path(tempdir(), "test")
#' param <- PlainTextParam(path = pth)
#'
#' ## Save as a collection of plain text files
#' storeResults(object = faahko_sub, param = param)
#'
NULL

#' @noRd
setClass("PlainTextParam",
slots = c(path = "character"),
contains = "Param",
prototype = prototype(
path = character()),
validity = function(object) {
msg <- NULL
if (length(object@path) != 1)
msg <- c("'path' has to be a character string of length 1")
msg
})

#' @rdname PlainTextParam
#'
#' @export
PlainTextParam <- function(path = tempdir()) {
new("PlainTextParam", path = path)
}


#' @rdname PlainTextParam
setMethod("storeResults",
signature(object = "MsExperiment",
param = "PlainTextParam"),
function(object, param){
dir.create(path = param@path, recursive = TRUE, showWarnings = TRUE)
.store_msexperiment(x = object, path = param@path)
}
)


#' @noRd
.store_msexperiment <- function(x, path = tempdir()) {
.export_sample_data(as.data.frame(sampleData(x)),
file.path(path, "sample_data.txt"))
.export_spectra_files(x, path = path)
.export_spectra_processing_queue(spectra(x), path = path)
}

#' Sample data
#' @noRd
.export_sample_data <- function(x, file = tempfile()) {
write.table(x, file = file)
}

#' Spectra file
#' @noRd
.export_spectra_files <- function(x, path = character()) {
s <- spectra(x)
if (!inherits(s@backend, "MsBackendMzR"))
warning("Spectra data will not be exported, backend need to be of ",
"class 'MsBackendMzR'")
else {
fls <- fileNames(x)
write.table(fls, file = file.path(path, "spectra_files.txt"),
row.names = FALSE, col.names = FALSE)
}
}

#' Processing queue
#' @param x `Spectra`
#'
#' @noRd
.export_spectra_processing_queue <- function(x, path = character()) {
pq <- x@processingQueue
if (length(pq))
write_json(serializeJSON(pq),
file.path(path, "spectra_processing_queue.json"))
}


#' @rdname PlainTextParam
setMethod("storeResults",
signature(object = "XcmsExperiment",
param = "PlainTextParam"),
function(object, param){
callNextMethod()
.store_xcmsexperiment(x = object, path = param@path)
}
)

#' @noRd
.store_xcmsexperiment <- function(x, path = tempdir()) {
.export_process_history(x, path = path)
if (hasChromPeaks(x))
.export_chrom_peaks(x, path)
if (hasAdjustedRtime(x))
.export_adjusted_rtime(x, path)
if (hasFeatures(x))
.export_features(x, path)
}

#' Processing history
#' @noRd
.export_process_history <- function(x, path = character()) {
ph <- processHistory(x)
write_json(serializeJSON(ph), file.path(path, "process_history.json"))
}

#' Chromatographic peaks
#' @noRd
.export_chrom_peaks <- function(x, path = character()) {
write.table(chromPeaks(x), file = file.path(path, "chrom_peaks.txt"))
write.table(as.data.frame(chromPeakData(x)),
file = file.path(path, "chrom_peak_data.txt"))
}

#' Retention times
#' @noRd
.export_adjusted_rtime <- function(x, path = character()) {
write.table(adjustedRtime(x), file = file.path(path, "rtime_adjusted.txt"),
row.names = FALSE, col.names = FALSE)
}

#' Features
#' @noRd
.export_features <- function(x, path = character()) {
fts <- featureDefinitions(x)
pkidx <- data.frame(
feature_index = rep(seq_len(nrow(fts)), lengths(fts$peakidx)),
peak_index = unlist(fts$peakidx, use.names = FALSE))
fts$peakidx <- NA
write.table(fts, file = file.path(path, "feature_definitions.txt"))
write.table(pkidx, file = file.path(path, "feature_peak_index.txt"))
}
7 changes: 7 additions & 0 deletions inst/NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Changes in version 4.1.2
----------------------

- Add a `param =` to generic function `storeResults`: `PlainTextParam` to save
an `XcmsExperiment` or `MsExperiment` object as colleciton of plain text
files.

Changes in version 4.1.1
----------------------

Expand Down
Loading

0 comments on commit f1cbe52

Please sign in to comment.