Skip to content

Commit 30d1676

Browse files
committed
Merge Nils Hoffmann's PR #302
2 parents fbfd6c9 + 385f5f7 commit 30d1676

File tree

6 files changed

+75
-18
lines changed

6 files changed

+75
-18
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: mzR
22
Type: Package
33
Title: parser for netCDF, mzXML and mzML and mzIdentML files
44
(mass spectrometry data)
5-
Version: 2.41.2
5+
Version: 2.41.3
66
Author: Bernd Fischer, Steffen Neumann, Laurent Gatto, Qiang Kou, Johannes Rainer
77
Authors@R: c(
88
person("Steffen", "Neumann", email="[email protected]", role=c("aut","cre")),

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
CHANGES IN VERSION 2.41.3
2+
-------------------------
3+
o Fixed off-by-one indexing issue with index access for chromatogramHeader vs chromatogram. Fixes #302. Thanks Nils Hoffmann !
4+
15
CHANGES IN VERSION 2.41.2
26
-------------------------
37
o Report also electron beam energy (MS:1003410) for EAD data.

R/methods-mzRpwiz.R

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ setMethod("tic", "mzRpwiz",
150150
function(object, ...) {
151151
if (nChrom(object) < 1)
152152
stop("No chromatogram data available.")
153-
object@backend$getChromatogramsInfo(0L)
153+
object@backend$getChromatogramsInfo(1L)
154154
})
155155

156156
setMethod("chromatograms", "mzRpwiz",
@@ -173,8 +173,7 @@ setMethod("chromatogram", "mzRpwiz",
173173
chrom <- as.integer(chrom)
174174
if (min(chrom) < 1 | max(chrom) > n)
175175
stop("Index out of bound [", 1, ":", n, "].")
176-
## Update index to match original indices at the C-level
177-
chrom <- chrom - 1L
176+
# chromatogram index is adjusted in the backend function
178177
if (length(chrom) == 1 & !all) {
179178
ans <- object@backend$getChromatogramsInfo(chrom)
180179
} else {
@@ -192,10 +191,11 @@ setMethod("chromatogramHeader", "mzRpwiz",
192191
} else {
193192
stopifnot(is.numeric(chrom))
194193
n <- nChrom(object)
195-
if (min(chrom) < 1 || max(chrom) > n)
196-
stop("Index out of bound [", 1, ":", n, "]")
197-
chrom <- chrom -1L
198-
res <- object@backend$getChromatogramHeaderInfo(chrom)
194+
195+
if (min(chrom) < 1 | max(chrom) > n)
196+
stop("Index out of bound [", 1, ":", n, "]")
197+
# chromatogram index is adjusted in the backend function
198+
res <- object@backend$getChromatogramHeaderInfo(as.integer(chrom))
199199
}
200200
res$chromatogramId <- as.character(res$chromatogramId)
201201
res

inst/unitTests/test_chromatograms.R

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,69 @@ test_chromatograms1 <- function() {
1111
checkIdentical(nrow(chromatogram(x, 136L)), 527L)
1212
checkIdentical(nrow(chromatogram(x, 137L)), 567L)
1313
checkIdentical(nrow(chromatogram(x, 138L)), 567L)
14+
close(x)
1415
}
1516

1617
test_chromatograms2 <- function() {
1718
f <- proteomics(full.names = TRUE,
1819
pattern = "TMT_Erwinia_1uLSike_Top10HCD_isol2_45stepped_60min_01.mzML.gz")
1920
x <- openMSfile(f, backend = "pwiz")
20-
checkIdentical(nChrom(x), 1L)
21+
checkIdentical(nChrom(x), 1L)
2122
checkIdentical(tic(x), chromatogram(x, 1L))
2223
checkIdentical(nrow(tic(x)), 7534L)
24+
close(x)
25+
}
26+
27+
test_chromatogramHeader_indexing <- function() {
28+
f <- proteomics(full.names = TRUE, pattern = "MRM")
29+
x <- openMSfile(f, backend = "pwiz")
30+
tic <- chromatogramHeader(x, 1)
31+
tic1 <- chromatogramHeader(x, 1:1)
32+
# next chromatogram after TIC (if we assume TIC is always at index 1)
33+
ch2 <- chromatogramHeader(x, 2)
34+
checkEquals(colnames(ch2), c("chromatogramId", "chromatogramIndex", "polarity",
35+
"precursorIsolationWindowTargetMZ",
36+
"precursorIsolationWindowLowerOffset",
37+
"precursorIsolationWindowUpperOffset",
38+
"precursorCollisionEnergy",
39+
"productIsolationWindowTargetMZ",
40+
"productIsolationWindowLowerOffset",
41+
"productIsolationWindowUpperOffset"))
42+
checkEquals(tic$chromatogramId, "TIC")
43+
checkEquals(tic1$chromatogramId, "TIC")
44+
checkTrue(!is.na(ch2$precursorIsolationWindowTargetMZ))
45+
checkTrue(!is.na(ch2$productIsolationWindowTargetMZ))
46+
checkEquals(nrow(ch2), 1)
47+
# test index below lower bound should raise error
48+
tryCatch({
49+
chromatogramHeader(x, 0)
50+
checkTrue(FALSE)
51+
}, error = function(e) {
52+
checkTrue(grepl("Index out of bound", e$message))
53+
})
54+
# check last chromatogram in bounds
55+
ch138 <- chromatogramHeader(x, 138)
56+
checkTrue(startsWith(ch138$chromatogramId, "- SRM SIC Q1=808.1 Q3=407.996"))
57+
# test index above upper bound should raise error
58+
tryCatch({
59+
chromatogramHeader(x, 139)
60+
checkTrue(FALSE)
61+
}, error = function(e) {
62+
checkTrue(grepl("Index out of bound", e$message))
63+
})
64+
65+
chrom2 <- chromatogram(x, 2)
66+
ch2SafeChromId <- make.names(ch2$chromatogramId)
67+
checkEquals(ch2SafeChromId, colnames(chrom2)[2])
68+
69+
close(x)
2370
}
2471

2572
test_chromatogramHeader <- function() {
2673
library(mzR)
2774
library(RUnit)
2875
library(msdata)
29-
76+
3077
f <- proteomics(full.names = TRUE, pattern = "MRM")
3178
x <- openMSfile(f)
3279

@@ -42,7 +89,7 @@ test_chromatogramHeader <- function() {
4289
"productIsolationWindowUpperOffset"))
4390
checkEquals(ch$chromatogramId[1], "TIC")
4491
checkEquals(sum(is.na(ch$precursorIsolationWindowTargetMZ)), 1)
45-
checkEquals(sum(is.na(ch$productIsolationWindowTargetMZ)), 1)
92+
checkEquals(sum(is.na(ch$productIsolationWindowTargetMZ)), 1)
4693
checkEquals(length(chrs), nrow(ch))
4794
close(x)
4895

src/RcppPwiz.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,9 @@ void RcppPwiz::addSpectrumList(MSData& msd,
845845
spct.defaultArrayLength = spct_mz->data.size();
846846
}
847847
}
848-
848+
// get the chromatogram data arrays.
849+
// whichChrom - 1-based index of chromatogram to extract.
850+
//
849851
Rcpp::DataFrame RcppPwiz::getChromatogramsInfo( int whichChrom )
850852
{
851853
if (msd != NULL) {
@@ -856,13 +858,14 @@ Rcpp::DataFrame RcppPwiz::getChromatogramsInfo( int whichChrom )
856858
} else if (clp->size() == 0) {
857859
Rf_warningcall(R_NilValue, "No available chromatogram info.");
858860
return Rcpp::DataFrame::create();
859-
} else if ( (whichChrom < 0) || (whichChrom > clp->size()) ) {
860-
Rprintf("Index whichChrom out of bounds [0 ... %d].\n", (clp->size())-1);
861+
} else if ( (whichChrom < 1) || (whichChrom > clp->size()) ) {
862+
Rprintf("Index whichChrom out of bounds [1 ... %d].\n", (clp->size()));
861863
return Rcpp::DataFrame::create( );
862864
} else {
863865
std::vector<double> time;
864866
std::vector<double> intensity;
865-
ChromatogramPtr c = clp->chromatogram(whichChrom, true);
867+
// correct index from 1-based (R) to 0-based indexing (C++)
868+
ChromatogramPtr c = clp->chromatogram(whichChrom - 1, true);
866869
vector<TimeIntensityPair> pairs;
867870
c->getTimeIntensityPairs (pairs);
868871

@@ -915,12 +918,13 @@ Rcpp::DataFrame RcppPwiz::getChromatogramHeaderInfo (Rcpp::IntegerVector whichCh
915918

916919
for (int i = 0; i < N_chrom; i++) {
917920
int current_chrom = whichChrom[i];
918-
if (current_chrom < 0 || current_chrom > N) {
921+
if (current_chrom < 1 || current_chrom > N) {
919922
Rf_warningcall(R_NilValue, "Provided index out of bounds.");
920923
Rcpp::Rcerr << "Provided index out of bounds" << std::endl;
921924
}
922925
ChromatogramPtr ch = clp->chromatogram(current_chrom - 1, false);
923926
chromatogramId[i] = ch->id;
927+
// retain 1-based index for the chromatogram to return to R
924928
chromatogramIndex[i] = current_chrom;
925929
CVParam param = ch->cvParamChild(MS_scan_polarity);
926930
polarity[i] = (param.cvid==MS_negative_scan ? 0 : (param.cvid==MS_positive_scan ? +1 : -1 ) );

vignettes/mzR.Rmd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ matrices or a single matrix if one spectrum is queried.
8080

8181
Access to the chromatogram(s) is done using the `chromatogram` (or
8282
`chromatograms`) function, that return one (or a list of)
83-
data.frames. See `?chromatogram` for details. This functionality is
84-
only available with the `pwiz` backend.
83+
data.frames. See `?chromatogram` for details. Chromatogram header information
84+
is available via the `chromatogramHeader` function that returns one (or
85+
a list of) data.frames. See `?chromatogramHeader` for details. This
86+
functionality is only available with the `pwiz` backend.
8587

8688
## Identification result access
8789

0 commit comments

Comments
 (0)