Conversation
…rash .insertColumn() mishandled two boundary cases used when re-inserting zero columns for empty spectra in profMat(): - pos == ncol(x) took an "append at end" branch, placing the new column one position too far right -> silent misalignment of profile-matrix columns with retention times. - a trailing empty spectrum yields pos == ncol(x) + 1, and the interior branch evaluated x[, pos:ncol(x)] out of bounds -> "subscript out of bounds" error. The second case is a hard crash in the public profMat() method (and thus adjustRtime(ObiwarpParam())) on ordinary data with empty trailing/adjacent spectra, e.g. after filterMz() (reported in sneumann#366, worked around with filterEmptySpectra()). Rewrite the branches: pos == 1 prepend, pos > ncol(x) append, otherwise insert *at* pos (with drop = FALSE for single-row robustness). Extend the unit tests with the boundary cases. Fixes sneumann#366 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NfgjUvLj79rbf3J4xX2wr9
Contributor
Author
|
An example with adjustRtime instead of directly profMat: library(xcms)
library(MsExperiment)
library(Spectra)
library(faahKO)
fls <- dir(system.file("cdf", package = "faahKO"), recursive = TRUE, full.names = TRUE)[1:2]
mse <- readMsExperiment(spectraFiles = fls, sampleData = data.frame(sample_name = basename(fls)))
# to create some empty spectra
spectra(mse) <- filterIntensity(spectra(mse), intensity = c(1e4, Inf))
xmse <- findChromPeaks(mse, CentWaveParam(noise = 10000, snthresh = 40, prefilter = c(3, 10000)))
adjustRtime(xmse, ObiwarpParam(binSize = 1))--> |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix:
profMat()errors (subscript out of bounds) when a file has trailing / adjacent empty spectraSummary
.insertColumn()(R/functions-utils.R) is used by theprofMat()methods tore-insert zero columns for empty spectra so that the returned profile matrix
has one column per spectrum (
ncol(profMat) == length(rtime); the fix forissue #312). The helper mis-handles two boundary cases:
Insert position past the current last column (
pos > ncol(x)) — happenswhenever the empty spectrum is the last spectrum, or a run of empty
spectra sits at the end. The
elsebranch evaluatesx[, pos[i]:ncol(x)]with
pos[i] == ncol(x) + 1, i.e.x[, (ncol+1):ncol], which is out ofbounds → error.
Insert position exactly at the last column (
pos == ncol(x)) — the codetakes a special branch that appends the column at the end
(
cbind(x, val)) instead of inserting it atpos. The new (empty) columntherefore lands one position too far to the right → silent column
misalignment between the profile matrix and the retention times.
Empty spectra are common (scans with no peaks in the requested m/z range, after
centroiding, or after
filterMz()), soprofMat()can crash on ordinary data.Related GitHub issues
reporter's traceback is this exact bug:
Error in x[, pos[i]:ncol(x)] : subscript out of boundsraised inside.insertColumn()→.local()(profMat) →.obiwarp()→adjustRtime(ObiwarpParam()). Threeindependent users hit it (2019–2020), and the suggested workaround was
filterEmptySpectra()before alignment — which confirms the empty-spectraroot cause. This fix removes the need for that workaround.
and ERROR: Dimensions of profile matrices do not match ! #676 all report obiwarp/profile-matrix failures ("Dimensions of profile
matrices do not match", "attempt to apply non-function",
bad_array_length)on data with empty/gappy spectra, with
filterEmptySpectra()repeatedly givenas the workaround. Some of these ride the legacy
retcor.obiwarppath ratherthan
.insertColumndirectly; they are listed as related, not all fixed bythis single change.
Reproducible example
End-to-end crash of the public
profMat()method onfaahKO, restricting to anm/z window that leaves several spectra — including the last one — empty:
Both failure modes can also be reproduced directly on the helper (current
source):
With this fix,
profMat(sub, step = 1)returns a matrix with one column perspectrum (1278), and the two helper calls above return
11 0 13 0and1 2 0 3respectively.