Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: SpectriPy
Title: Enhancing Cross-Language Mass Spectrometry Data Analysis with R and Python
Version: 1.1.4
Version: 1.1.5
Description: The SpectriPy package allows integration of Python-based MS
analysis code with the Spectra package. Spectra objects can be converted
into Python MS data structures. In addition, SpectriPy integrates
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# SpectriPy 1.1

## Changes in 1.1.5

- Fix `$<-`, `spectraData()<-` and related replacement methods for
`Spectra`/`MsBackendPy` of length 1.

## Changes in 1.1.4

- Implement a `setBackend()` method for `MsBackendPy` with a parameter
Expand Down
18 changes: 16 additions & 2 deletions R/MsBackendPython.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@
#' between R and Python. See the description for `backendInitialize()` and the
#' package vignette for details and examples.
#'
#' @section Python metadata names *vs* spectra variables:
#'
#' The *matchms* library in Python supports arbitrary metadata assigned to
#' a spectrum, similar to *Spectra*'s spectra variables concept. However,
#' *matchms* and *Spectra* use different names for the same metadata/variables.
#' To support this, *MsBackendPy* implements `spectraVariableMapping` which
#' allows to link spectra variable names to *matchms* metadata names. This
#' mapping can be provided with the `spectraVariableMapping` to the
#' `backendInitialize()` function. Also, be aware that *matchms* automatically
#' **renames** certain metadata fields: a metadata `"NAME"` will be
#' automatically renamed to `"compound_name"`. Also, *matchms* generally
#' supports only lower-case metadata names.
#' See also [setSpectraVariableMapping()] for more information.
#'
#' @details
#'
#' The `MsBackendPy` keeps only a reference to the MS data in Python (i.e. the
Expand Down Expand Up @@ -633,7 +647,7 @@ setMethod("$", "MsBackendPy", function(x, name) {
#' @importMethodsFrom Spectra peaksVariables
setReplaceMethod("$", "MsBackendPy", function(x, name, value) {
spd <- spectraData(
x, union(names(spectraVariableMapping(x)), peaksVariables(x)))
x, union(spectraVariables(x), peaksVariables(x)))
spd[[name]] <- value
spectraData(x) <- spd
x
Expand Down Expand Up @@ -678,7 +692,7 @@ setMethod("intensity", "MsBackendPy", function(object) {
#' @rdname MsBackendPy
setReplaceMethod("intensity", "MsBackendPy", function(object, value) {
.check_mz_intensity(value, length(object), lengths(object))
spd <- spectraData(object, union(names(spectraVariableMapping(object)),
spd <- spectraData(object, union(spectraVariables(object),
peaksVariables(object)))
spd[["intensity"]] <- value
spectraData(object) <- spd
Expand Down
9 changes: 6 additions & 3 deletions R/conversion.R
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ NULL
collisionEnergy = "collision_energy",
isolationWindowTargetMz = "isolation_window_target_mz",
## polarity = "ionmode", # Disabling since matchms does not support int.
msLevel = "ms_level"
msLevel = "ms_level",
dataStorage = "data_storage"
)

.SPECTRA_2_SPECTRUM_UTILS <- c(
Expand Down Expand Up @@ -408,7 +409,8 @@ rspec_to_pyspec <- function(x, mapping = spectraVariableMapping(),
.rspec_to_matchms_pyspec <- function(x, mapping = spectraVariableMapping()) {
if (is(x, "Spectra"))
pks <- peaksData(x, c("mz", "intensity"), return.type = "list")
else pks <- mapply(mz = x$mz, intensity = x$intensity, FUN = cbind)
else pks <- mapply(mz = x$mz, intensity = x$intensity, FUN = cbind,
SIMPLIFY = FALSE, USE.NAMES = FALSE)
sv <- mapping[!mapping %in% c("mz", "intensity")]
if (length(sv)) {
if (is(x, "Spectra"))
Expand Down Expand Up @@ -447,7 +449,8 @@ rspec_to_pyspec <- function(x, mapping = spectraVariableMapping(),
function(x, mapping = spectraVariableMapping()) {
if (is(x, "Spectra"))
pks <- peaksData(x, c("mz", "intensity"))
else pks <- mapply(mz = x$mz, intensity = x$intensity, FUN = cbind)
else pks <- mapply(mz = x$mz, intensity = x$intensity, FUN = cbind,
SIMPLIFY = FALSE, USE.NAMES = FALSE)
l <- length(pks)
sv <- mapping[!mapping %in% c("mz", "intensity")]
svm <- sv[sv %in% .SPECTRA_2_SPECTRUM_UTILS]
Expand Down
16 changes: 16 additions & 0 deletions man/MsBackendPy.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions tests/testthat.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ test_check("SpectriPy")

## TODO: add tests from the Spectra unit test suite!

## ## Run the MsBackend spectra variable test suite
## test_suite <- system.file("test_backends", "test_MsBackend",
## package = "Spectra")
## Run the MsBackend spectra variable test suite
test_suite <- system.file("test_backends", "test_MsBackend",
package = "Spectra")

## ## Run single test file.
## Run single test file.
## res <- test_dir(test_suite, stop_on_failure = TRUE)
43 changes: 42 additions & 1 deletion tests/testthat/test_MsBackendPython.R
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ test_that("backendInitialize,MsBackendPy works with providing data", {
expect_true(all(is.na(res$precursorMz)))
## Only non-NA variables have a mapping
expect_equal(res@spectraVariableMapping,
c(precursorCharge = "charge", msLevel = "ms_level"))
c(precursorCharge = "charge", msLevel = "ms_level",
dataStorage = "data_storage"))

## Repeat with spectrum_utils
py_del_attr(py, "ttt")
Expand Down Expand Up @@ -788,6 +789,46 @@ test_that("setBackend,Spectra,MsBackendPy works", {
expect_equal(smod_1$compound_name, smod$NAME)
})

test_that("$<- does not change any other spectra variables", {
map <- c(spectraVariableMapping(), INCHI = "inchi", NAME = "NAME",
SMILES = "smiles", spectrum_index = "spectrum_index")
a <- setBackend(s, MsBackendPy(), pythonVariableName = "tmp",
spectraVariableMapping = map)@backend
sd <- spectraData(a)
a$other_variable <- "a"
res <- spectraData(a)
expect_true(all(colnames(sd) %in% colnames(res)))
expect_equal(sd[, intersect(colnames(sd), colnames(res))],
res[, intersect(colnames(sd), colnames(res))])
expect_true(all(res$other_col == "a"))
})

test_that("MsBackendPy of length 1 works", {
map <- c(spectraVariableMapping(), INCHI = "inchi", NAME = "NAME",
SMILES = "smiles")
a <- setBackend(s, MsBackendPy(), pythonVariableName = "tmp",
spectraVariableMapping = map)@backend
## Subset
a_3 <- a[c(3L, 1L, 5L)]
sd <- spectraData(a_3)
expect_equal(sd$SMILES, a$SMILES[c(3L, 1L, 5L)])
a_3$other_var <- "a"
res <- spectraData(a_3)
expect_true(all(colnames(sd) %in% colnames(res)))
expect_equal(sd[, intersect(colnames(sd), colnames(res))],
res[, intersect(colnames(sd), colnames(res))])
expect_true(all(res$other_var == "a"))

a_1 <- a[3L]
sd <- spectraData(a_1)
a_1$other_var_2 <- "a"
res <- spectraData(a_1)
expect_true(all(colnames(sd) %in% colnames(res)))
expect_equal(sd[, intersect(colnames(sd), colnames(res))],
res[, intersect(colnames(sd), colnames(res))])
expect_equal(res$other_var_2, "a")
})

## Comments, thoughts TODO
## DONE spectraData()<-: replaces the full data and allows adding/removing
## spectra variables. number of spectra has to match.
Expand Down
Loading