Skip to content

Commit 4687a57

Browse files
committed
feat: add filterPrecursorMzValues (issue #230)
- Add the `filterPrecursorMzValues` method to enable filtering based on multiple target precursor m/z values.
1 parent 94aa191 commit 4687a57

11 files changed

+121
-9
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: Spectra
22
Title: Spectra Infrastructure for Mass Spectrometry Data
3-
Version: 1.5.2
3+
Version: 1.5.3
44
Description: The Spectra package defines an efficient infrastructure
55
for storing and handling mass spectrometry spectra and functionality to
66
subset, process, visualize and compare spectra data. It provides different

NAMESPACE

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ exportMethods(filterMzValues)
7171
exportMethods(filterPolarity)
7272
exportMethods(filterPrecursorCharge)
7373
exportMethods(filterPrecursorMz)
74+
exportMethods(filterPrecursorMzValues)
7475
exportMethods(filterPrecursorScan)
7576
exportMethods(filterRt)
7677
exportMethods(intensity)

NEWS.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Spectra 1.5
22

3+
## Changes in 1.5.3
4+
5+
- Add `filterPrecursorMzValues` method to filter `Spectra` keeping all spectra
6+
with matching precursor m/z (supports multiple target precursor m/z values).
7+
38
## Changes in 1.5.2
49

510
- Small documentation update (related to `MsCoreUtils` issue

R/AllGenerics.R

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ setGeneric("filterMzRange", function(object, ...)
3535
setGeneric("filterMzValues", function(object, ...)
3636
standardGeneric("filterMzValues"))
3737
#' @rdname hidden_aliases
38+
setGeneric("filterPrecursorMzValues", function(object, ...)
39+
standardGeneric("filterPrecursorMzValues"))
40+
#' @rdname hidden_aliases
3841
setGeneric("isReadOnly", function(object, ...)
3942
standardGeneric("isReadOnly"))
4043
#' @rdname hidden_aliases

R/MsBackend.R

+26-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,12 @@
9090
#'
9191
#' @param mz For `filterIsolationWindow`: `numeric(1)` with the m/z value to
9292
#' filter the object. For `filterPrecursorMz`: `numeric(2)` with the lower
93-
#' and upper m/z boundary.
93+
#' and upper m/z boundary. For `filterPrecursorMzValues`: `numeric` with the
94+
#' m/z value(s) to filter the object.
95+
#'
96+
#' @param ppm For `filterPrecursorMzValues`: `numeric(1)` with the m/z-relative
97+
#' maximal acceptable difference for a m/z to be considered matching. See
98+
#' [closest()] for details.
9499
#'
95100
#' @param z For `filterPrecursorCharge`: `integer()` with the precursor charges
96101
#' to be used as filter.
@@ -112,6 +117,10 @@
112117
#' @param spectraVariables For `selectSpectraVariables`: `character` with the
113118
#' names of the spectra variables to which the backend should be subsetted.
114119
#'
120+
#' @param tolerance For `filterPrecursorMzValues`: `numeric(1)` with the
121+
#' maximal absolute acceptable difference for an m/z value to be considered
122+
#' matching. See [closest()] for details.
123+
#'
115124
#' @param use.names For `lengths`: whether spectrum names should be used.
116125
#'
117126
#' @param value replacement value for `<-` methods. See individual
@@ -253,6 +262,11 @@
253262
#' Implementation of this method is optional since a default implementation
254263
#' for `MsBackend` is available.
255264
#'
265+
#' - `filterPrecursorMzValues`: retains spectra with a precursor m/z matching
266+
#' any of the provided m/z values (given `ppm` and `tolerance`).
267+
#' Implementation of this method is optional since a default implementation
268+
#' for `MsBackend` is available.
269+
#'
256270
#' - `filterPrecursorCharge`: retains spectra with the defined precursor
257271
#' charge(s).
258272
#' Implementation of this method is optional since a default implementation
@@ -844,6 +858,17 @@ setMethod("filterPrecursorMz", "MsBackend",
844858
} else object
845859
})
846860

861+
#' @exportMethod filterPrecursorMzValues
862+
#'
863+
#' @rdname MsBackend
864+
setMethod("filterPrecursorMzValues", "MsBackend",
865+
function(object, mz = numeric(), ppm = 20, tolerance = 0) {
866+
if (length(mz)) {
867+
object[.values_match_mz(precursorMz(object), mz = mz,
868+
ppm = ppm, tolerance = tolerance)]
869+
} else object
870+
})
871+
847872
#' @exportMethod filterPrecursorCharge
848873
#'
849874
#' @importMethodsFrom ProtGenerics filterPrecursorCharge
@@ -857,8 +882,6 @@ setMethod("filterPrecursorCharge", "MsBackend",
857882
} else object
858883
})
859884

860-
861-
862885
#' @exportMethod filterPrecursorScan
863886
#'
864887
#' @importMethodsFrom ProtGenerics filterPrecursorScan

R/Spectra.R

+18-2
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ NULL
353353
#' provided m/z range. See examples for details on selecting spectra with
354354
#' a precursor m/z for a target m/z accepting a small difference in *ppm*.
355355
#'
356+
#' - `filterPrecursorMzValues`: retains spectra with precursor m/z matching any
357+
#' of the provided m/z values (given `ppm` and `tolerance`). Spectra with
358+
#' missing precursor m/z value (e.g. MS1 spectra) are dropped.
359+
#'
356360
#' - `filterPrecursorCharge`: retains spectra with the defined precursor
357361
#' charge(s).
358362
#'
@@ -702,8 +706,8 @@ NULL
702706
#' @param mz For `filterIsolationWindow`: `numeric(1)` with the m/z value to
703707
#' filter the object. For `filterPrecursorMz` and `filterMzRange`:
704708
#' `numeric(2)` defining the lower and upper m/z boundary.
705-
#' For `filterMzValues`: `numeric` with the m/z values to match peaks
706-
#' against.
709+
#' For `filterMzValues` and `filterPrecursorMzValues`: `numeric` with the
710+
#' m/z values to match peaks or precursor m/z against.
707711
#'
708712
#' @param z For `filterPrecursorCharge`: `integer()` with the precursor charges
709713
#' to be used as filter.
@@ -1943,6 +1947,18 @@ setMethod("filterPrecursorMz", "Spectra",
19431947
object
19441948
})
19451949

1950+
#' @rdname Spectra
1951+
setMethod("filterPrecursorMzValues", "Spectra",
1952+
function(object, mz = numeric(), ppm = 20, tolerance = 0) {
1953+
object@backend <- filterPrecursorMzValues(
1954+
object@backend, mz, ppm = ppm, tolerance = tolerance)
1955+
object@processing <- .logging(
1956+
object@processing,
1957+
"Filter: select spectra with precursor m/z matching ",
1958+
paste0(mz, collapse = ", "), "")
1959+
object
1960+
})
1961+
19461962
#' @rdname Spectra
19471963
setMethod("filterPrecursorCharge", "Spectra",
19481964
function(object, z = integer()) {

R/functions-util.R

+19
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,22 @@ setAs("logical", "factor", function(from, to) factor(from))
7070
sanitize_file_name <- function(x) {
7171
file.path(normalizePath(dirname(x)), path_sanitize(basename(x)))
7272
}
73+
74+
#' Helper function that matches `x` against `mz` (using the `closest` function)
75+
#' and returns the indices of `x` that match any of the values in `mz`. The
76+
#' function takes care of sorting `x` and `mz` and deals also with missing
77+
#' values.
78+
#'
79+
#' @return `integer` with the indices of values in `x` that are not `NA` and
80+
#' are matching any of the values in `mz` given `ppm` and `tolerance`.
81+
#'
82+
#' @noRd
83+
#'
84+
#' @author Johannes Rainer
85+
.values_match_mz <- function(x, mz, ppm = 20, tolerance = 0) {
86+
keep <- which(!is.na(x))
87+
idx <- order(x[keep])
88+
mtch <- closest(x[keep][idx], sort(mz), tolerance = tolerance, ppm = ppm,
89+
duplicates = "keep", .check = FALSE)
90+
keep[!is.na(mtch[order(idx)])]
91+
}

man/MsBackend.Rd

+17-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/Spectra.Rd

+8-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/hidden_aliases.Rd

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test_functions-util.R

+20
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,23 @@ test_that("sanitize_file_name works", {
2727
expect_equal(basename(res)[1], "memory")
2828
expect_equal(basename(res)[2], "path")
2929
})
30+
31+
test_that(".values_match_mz works", {
32+
pmz <- c(12.4, 15, 3, 12.4, 3, 1234, 23, 5, 12.4, NA, 3)
33+
mz <- c(200, 12.4, 3)
34+
35+
res <- .values_match_mz(pmz, mz)
36+
expect_true(all(pmz[res] %in% mz))
37+
expect_false(any(pmz[-res] %in% mz))
38+
39+
pmz <- rev(pmz)
40+
res <- .values_match_mz(pmz, mz)
41+
expect_true(all(pmz[res] %in% mz))
42+
expect_false(any(pmz[-res] %in% mz))
43+
44+
res <- .values_match_mz(c(NA, NA), mz)
45+
expect_identical(res, integer())
46+
47+
res <- .values_match_mz(pmz, c(NA, 3))
48+
expect_true(all(pmz[res] == 3))
49+
})

0 commit comments

Comments
 (0)