From 24bdf519e993279014d928ad2ec57b9006c80dbf Mon Sep 17 00:00:00 2001 From: jorainer Date: Thu, 16 May 2024 07:44:53 +0200 Subject: [PATCH 1/6] feat: add dataStorageBasePath method --- NAMESPACE | 3 +++ R/AllGenerics.R | 4 ++++ R/MsBackend.R | 31 ++++++++++++++++++++++++++++++ R/MsBackendMzR.R | 16 +++++++++++++++ R/Spectra.R | 9 +++++++++ man/MsBackend.Rd | 12 ++++++++++++ tests/testthat/test_MsBackend.R | 6 ++++++ tests/testthat/test_MsBackendMzR.R | 14 ++++++++++++++ 8 files changed, 95 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 668b6c50..2d56f253 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,6 +49,7 @@ exportMethods("centroided<-") exportMethods("collisionEnergy<-") exportMethods("dataOrigin<-") exportMethods("dataStorage<-") +exportMethods("dataStorageBasePath<-") exportMethods("intensity<-") exportMethods("isolationWindowLowerMz<-") exportMethods("isolationWindowTargetMz<-") @@ -77,6 +78,7 @@ exportMethods(containsMz) exportMethods(containsNeutralLoss) exportMethods(dataOrigin) exportMethods(dataStorage) +exportMethods(dataStorageBasePath) exportMethods(dropNaSpectraVariables) exportMethods(entropy) exportMethods(export) @@ -156,6 +158,7 @@ importFrom(MsCoreUtils,coefMA) importFrom(MsCoreUtils,coefSG) importFrom(MsCoreUtils,coefWMA) importFrom(MsCoreUtils,common) +importFrom(MsCoreUtils,common_path) importFrom(MsCoreUtils,entropy) importFrom(MsCoreUtils,group) importFrom(MsCoreUtils,i2index) diff --git a/R/AllGenerics.R b/R/AllGenerics.R index f68500ad..0b69bdaf 100644 --- a/R/AllGenerics.R +++ b/R/AllGenerics.R @@ -11,6 +11,10 @@ setGeneric("containsMz", function(object, ...) #' @rdname hidden_aliases setGeneric("containsNeutralLoss", function(object, ...) standardGeneric("containsNeutralLoss")) +setGeneric("dataStorageBasePath", function(object, ...) + standardGeneric("dataStorageBasePath")) +setGeneric("dataStorageBasePath<-", function(object, ..., value) + standardGeneric("dataStorageBasePath<-")) #' @rdname hidden_aliases setGeneric("dropNaSpectraVariables", function(object, ...) standardGeneric("dropNaSpectraVariables")) diff --git a/R/MsBackend.R b/R/MsBackend.R index 9528c628..dc73ee5f 100644 --- a/R/MsBackend.R +++ b/R/MsBackend.R @@ -11,6 +11,10 @@ #' @aliases backendInitialize #' @aliases backendParallelFactor,MsBackendMzR-method #' @aliases backendParallelFactor,MsBackendHdf5Peaks-method +#' @aliases dataStorageBasePath +#' @aliases dataStorageBasePath,MsBackendMzR-method +#' @aliases dataStorageBasePath<- +#' @aliases dataStorageBasePath<-,MsBackendMzR-method #' #' @description #' @@ -280,6 +284,16 @@ #' spectra in `object` with the data storage of each spectrum. Note that #' missing values (`NA_character_`) are not supported for `dataStorage`. #' +#' - `dataStorageBasePath()`, `dataStorageBasePath<-: gets or sets the common +#' *base* path of the directory containing all data files. If supported, +#' the function is expected to return (or accept) a `character` of length 1. +#' Most backends (such as for example the `MsBackendMemory` will not support +#' this function and `dataStorageBasePath()` will return `NA_character_`. +#' For `MsBackendMzR`, this function allows to get or change the path to the +#' directory containing the original data files, which is required if e.g. +#' a serialized `MsBackendMzR` instance gets copied to another computer or +#' file system. +#' #' - `dropNaSpectraVariables()`: removes spectra variables (i.e. columns in the #' object's `spectraData` that contain only missing values (`NA`). Note that #' while columns with only `NA`s are removed, a `spectraData()` call after @@ -1711,3 +1725,20 @@ setReplaceMethod("[[", "MsBackend", function(x, i, j, ..., value) { setMethod("uniqueMsLevels", "MsBackend", function(object, ...) { unique(msLevel(object)) }) + +#' @exportMethod dataStorageBasePath +#' +#' @rdname MsBackend +setMethod("dataStorageBasePath", "MsBackend", function(object) { + NA_character_ +}) + +#' @exportMethod dataStorageBasePath<- +#' +#' @rdname MsBackend +setReplaceMethod( + "dataStorageBasePath", "MsBackend", function(object, value) { + warning(class(object)[1L], " does not support changing", + " 'dataStorageBasePath'.") + object + }) diff --git a/R/MsBackendMzR.R b/R/MsBackendMzR.R index 74b00308..2e8cafd1 100644 --- a/R/MsBackendMzR.R +++ b/R/MsBackendMzR.R @@ -214,3 +214,19 @@ setMethod("export", "MsBackendMzR", function(object, x, file = tempfile(), setMethod("backendParallelFactor", "MsBackendMzR", function(object) { factor(dataStorage(object), levels = unique(dataStorage(object))) }) + +#' @importFrom MsCoreUtils common_path +setMethod("dataStorageBasePath", "MsBackendMzR", function(object) { + common_path(dataStorage(object)) +}) + +setReplaceMethod( + "dataStorageBasePath", "MsBackendMzR", function(object, value) { + ds <- dataStorage(object) + cp <- common_path(ds) + ds <- sub(cp, value, ds, fixed = TRUE) + if (!all(file.exists(unique(ds)))) + stop("Provided path does not contain all data files.") + dataStorage(object) <- ds + object + }) diff --git a/R/Spectra.R b/R/Spectra.R index 78a74464..9b6dfb5f 100644 --- a/R/Spectra.R +++ b/R/Spectra.R @@ -136,6 +136,15 @@ NULL #' - `...`: additional parameters specific for the `MsBackend` passed with #' parameter `backend`. #' +#' The `dataStorageBasePath()` and `dataStoragePath<-` functions allow, for +#' backend classes that support this operation, to get or change the *base* +#' path to the directory where the backend stores the data. In-memory backends +#' such as [MsBackendMemory] or [MsBackendDataFrame] keeping all MS data in +#' memory don't support, and need, this function, but for [MsBackendMzR] this +#' function can be used to update/adapt the path to the directory containing +#' the original data files. Thus, for `Spectra` objects (using this backend) +#' that were moved to another file system or computer, these functions allow to +#' adjust/adapt the base file path. #' #' @section Accessing spectra data: #' diff --git a/man/MsBackend.Rd b/man/MsBackend.Rd index 1ee1d331..2e9292e9 100644 --- a/man/MsBackend.Rd +++ b/man/MsBackend.Rd @@ -17,6 +17,10 @@ \alias{backendInitialize} \alias{backendParallelFactor,MsBackendMzR-method} \alias{backendParallelFactor,MsBackendHdf5Peaks-method} +\alias{dataStorageBasePath} +\alias{dataStorageBasePath,MsBackendMzR-method} +\alias{dataStorageBasePath<-} +\alias{dataStorageBasePath<-,MsBackendMzR-method} \alias{backendBpparam,MsBackend-method} \alias{backendInitialize,MsBackend-method} \alias{backendMerge,list-method} @@ -93,6 +97,8 @@ \alias{$<-,MsBackend-method} \alias{[[,MsBackend-method} \alias{[[<-,MsBackend-method} +\alias{dataStorageBasePath,MsBackend-method} +\alias{dataStorageBasePath<-,MsBackend-method} \alias{MsBackendDataFrame} \alias{backendInitialize,MsBackendDataFrame-method} \alias{MsBackendHdf5Peaks} @@ -269,6 +275,10 @@ \S4method{uniqueMsLevels}{MsBackend}(object, ...) +\S4method{dataStorageBasePath}{MsBackend}(object) + +\S4method{dataStorageBasePath}{MsBackend}(object) <- value + MsBackendDataFrame() \S4method{backendInitialize}{MsBackendDataFrame}(object, data, peaksVariables = c("mz", "intensity"), ...) @@ -559,6 +569,8 @@ e.g. be the mzML file from which the data was read. \item \code{dataStorage()}: gets a \code{character} of length equal to the number of spectra in \code{object} with the data storage of each spectrum. Note that missing values (\code{NA_character_}) are not supported for \code{dataStorage}. +\item \code{dataStorageBasePath()}, \verb{dataStorageBasePath<-: gets or sets the common *base* path of the directory containing all data files. If supported, the function is expected to return (or accept) a }character\verb{of length 1. Most backends (such as for example the}MsBackendMemory\verb{will not support this function and}dataStorageBasePath()\verb{will return}NA_character_\verb{. For }MsBackendMzR\verb{, this function allows to get or change the path to the directory containing the original data files, which is required if e.g. a serialized }MsBackendMzR` instance gets copied to another computer or +file system. \item \code{dropNaSpectraVariables()}: removes spectra variables (i.e. columns in the object's \code{spectraData} that contain only missing values (\code{NA}). Note that while columns with only \code{NA}s are removed, a \code{spectraData()} call after diff --git a/tests/testthat/test_MsBackend.R b/tests/testthat/test_MsBackend.R index 3d3f7e28..d80bd757 100644 --- a/tests/testthat/test_MsBackend.R +++ b/tests/testthat/test_MsBackend.R @@ -75,3 +75,9 @@ test_that("backendBpparam,MsBackend works", { test_that("backendParallelFactor,MsBackend works", { expect_equal(backendParallelFactor(MsBackendMemory()), factor()) }) + +test_that("dataStorageBasePath,MsExperiment works", { + expect_identical(dataStorageBasePath(MsBackendMemory()), NA_character_) + tmp <- MsBackendMemory() + expect_warning(dataStorageBasePath(tmp) <- "/", "not support") +}) diff --git a/tests/testthat/test_MsBackendMzR.R b/tests/testthat/test_MsBackendMzR.R index ff891738..318a73ca 100644 --- a/tests/testthat/test_MsBackendMzR.R +++ b/tests/testthat/test_MsBackendMzR.R @@ -570,3 +570,17 @@ test_that("backendParallelFactor,MsBackendMzR", { factor(dataStorage(sciex_mzr), levels = unique(dataStorage(sciex_mzr)))) }) + +test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { + tmpd <- tempdir() + file.copy(sciex_file, tmpd) + + expect_equal(dataStorageBasePath(sciex_mzr), + MsCoreUtils::common_path(sciex_file)) + tmp <- sciex_mzr + dataStorageBasePath(tmp) <- tmpd + expect_equal(dataStorageBasePath(tmp), tmpd) + + #' errors + expect_error(dataStorageBasePath(tmp) <- "some path", "Provided path") +}) From 4c7d03acab6ed77391ba13de9997f5809fcc0972 Mon Sep 17 00:00:00 2001 From: jorainer Date: Thu, 16 May 2024 11:42:05 +0200 Subject: [PATCH 2/6] docs: bump version --- DESCRIPTION | 2 +- NEWS.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 26055771..40e8d371 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: Spectra Title: Spectra Infrastructure for Mass Spectrometry Data -Version: 1.15.0 +Version: 1.15.1 Description: The Spectra package defines an efficient infrastructure for storing and handling mass spectrometry spectra and functionality to subset, process, visualize and compare spectra data. It provides different diff --git a/NEWS.md b/NEWS.md index 0f67f490..b4a949e4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# Spectra 1.15 + +## Changes in 1.15.2 + + + # Spectra 1.13 ## Changes in 1.13.8 From 8527d64d754a1dc4e5974d5795761dd05cd68f31 Mon Sep 17 00:00:00 2001 From: jorainer Date: Fri, 17 May 2024 08:15:49 +0200 Subject: [PATCH 3/6] fix: paths for Windows --- R/MsBackendMzR.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/MsBackendMzR.R b/R/MsBackendMzR.R index 2e8cafd1..7cadc0d5 100644 --- a/R/MsBackendMzR.R +++ b/R/MsBackendMzR.R @@ -223,10 +223,12 @@ setMethod("dataStorageBasePath", "MsBackendMzR", function(object) { setReplaceMethod( "dataStorageBasePath", "MsBackendMzR", function(object, value) { ds <- dataStorage(object) + ds <- gsub("\\", "/", ds, fixed = TRUE) + value <- gsub("\\", "/", value, fixed = TRUE) cp <- common_path(ds) ds <- sub(cp, value, ds, fixed = TRUE) if (!all(file.exists(unique(ds)))) stop("Provided path does not contain all data files.") - dataStorage(object) <- ds + dataStorage(object) <- normalizePath(ds) object }) From 44050a0c31bd1048e0db0dff894f097e4db0ddb0 Mon Sep 17 00:00:00 2001 From: jorainer Date: Fri, 17 May 2024 11:05:59 +0200 Subject: [PATCH 4/6] fix: adapt unit test to Windows OS --- tests/testthat/test_MsBackendMzR.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test_MsBackendMzR.R b/tests/testthat/test_MsBackendMzR.R index 318a73ca..0a4e7954 100644 --- a/tests/testthat/test_MsBackendMzR.R +++ b/tests/testthat/test_MsBackendMzR.R @@ -579,7 +579,7 @@ test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { MsCoreUtils::common_path(sciex_file)) tmp <- sciex_mzr dataStorageBasePath(tmp) <- tmpd - expect_equal(dataStorageBasePath(tmp), tmpd) + expect_equal(dataStorageBasePath(tmp), gsub("\\", "/", tmpd, fixed = TRUE)) #' errors expect_error(dataStorageBasePath(tmp) <- "some path", "Provided path") From 05f5e8b48cb307564fdfd1c54c62b42b14ded351 Mon Sep 17 00:00:00 2001 From: jorainer Date: Fri, 17 May 2024 11:56:54 +0200 Subject: [PATCH 5/6] fix: use normalzePath for path comparisons --- tests/testthat/test_MsBackendMzR.R | 4 +++- tests/testthat/test_Spectra.R | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test_MsBackendMzR.R b/tests/testthat/test_MsBackendMzR.R index 0a4e7954..dcbf5ec0 100644 --- a/tests/testthat/test_MsBackendMzR.R +++ b/tests/testthat/test_MsBackendMzR.R @@ -579,7 +579,9 @@ test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { MsCoreUtils::common_path(sciex_file)) tmp <- sciex_mzr dataStorageBasePath(tmp) <- tmpd - expect_equal(dataStorageBasePath(tmp), gsub("\\", "/", tmpd, fixed = TRUE)) + expect_true(validObject(tmp)) + bp <- normalizePath(dataStorageBasePath(tmp)) + expect_equal(bp, tmpd) #' errors expect_error(dataStorageBasePath(tmp) <- "some path", "Provided path") diff --git a/tests/testthat/test_Spectra.R b/tests/testthat/test_Spectra.R index 9bdf7bfc..d3db066b 100644 --- a/tests/testthat/test_Spectra.R +++ b/tests/testthat/test_Spectra.R @@ -1901,7 +1901,9 @@ test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { tmp <- sciex_mzr tmp <- Spectra(tmp) dataStorageBasePath(tmp) <- tmpd - expect_equal(dataStorageBasePath(tmp), tmpd) + expect_true(validObject(tmp@backend)) + bp <- normalizePath(dataStorageBasePath(tmp)) + expect_equal(bp, tmpd) #' errors expect_error(dataStorageBasePath(tmp) <- "some path", "Provided path") From 6bafa7d097438f621a18470ac2a78657788019f3 Mon Sep 17 00:00:00 2001 From: jorainer Date: Fri, 17 May 2024 12:31:12 +0200 Subject: [PATCH 6/6] fix: use normalizePath also for tempdir() --- tests/testthat/test_MsBackendMzR.R | 2 +- tests/testthat/test_Spectra.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test_MsBackendMzR.R b/tests/testthat/test_MsBackendMzR.R index dcbf5ec0..dee66253 100644 --- a/tests/testthat/test_MsBackendMzR.R +++ b/tests/testthat/test_MsBackendMzR.R @@ -572,7 +572,7 @@ test_that("backendParallelFactor,MsBackendMzR", { }) test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { - tmpd <- tempdir() + tmpd <- normalizePath(tempdir()) file.copy(sciex_file, tmpd) expect_equal(dataStorageBasePath(sciex_mzr), diff --git a/tests/testthat/test_Spectra.R b/tests/testthat/test_Spectra.R index d3db066b..b0cda2ca 100644 --- a/tests/testthat/test_Spectra.R +++ b/tests/testthat/test_Spectra.R @@ -1892,7 +1892,7 @@ test_that("entropy,Spectra works", { }) test_that("dataStorageBasePath,dataStorageBasePath<-,MsBackendMzR works", { - tmpd <- tempdir() + tmpd <- normalizePath(tempdir()) file.copy(sciex_file, tmpd) tmp <- Spectra(sciex_mzr)