Skip to content

Fix Raw.crop with reset_first_samp=True misaligning annotations and data - #14439

Merged
drammock merged 2 commits into
mne-tools:mainfrom
mscheltienne:fix-crop-reset-first-samp
Oct 21, 2026
Merged

drammock merged 2 commits into
mne-tools:mainfrom
mscheltienne:fix-crop-reset-first-samp

Conversation

@mscheltienne

@mscheltienne mscheltienne commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Raw.crop(..., reset_first_samp=True) filtered the annotations while first_samp still held the cropped offset and never shifted their onsets, so they ended up late by first_time + tmin. The onsets are now shifted by first_time and _cropped_samp is reset before set_annotations. _first_samps / _last_samps are left untouched since they index the files, which also fixes reading wrong data from non-preloaded files and the wrong first_samp on concatenated raws.

Reproduction
import matplotlib.pyplot as plt
import mne
import numpy as np

mne.viz.set_browser_backend("matplotlib")
info = mne.create_info(["EEG1", "EEG2", "EEG3"], sfreq=100.0, ch_types="eeg")
data = np.zeros((3, 500))  # 5 s of data
data[:, 200:300] = 1.0  # square pulse from 2.0 to 3.0 s
raw = mne.io.RawArray(data, info)
raw.set_annotations(mne.Annotations(onset=2.0, duration=1.0, description="pulse"))

cropped = raw.copy().crop(tmin=1.0, tmax=4.0, reset_first_samp=True)
print(cropped.first_samp, cropped.annotations.onset)  # main: 0 [2.]  fix: 0 [1.]

kwargs = dict(
    start=0,
    scalings=dict(eeg=1.0),
    time_format="float",
    show_scrollbars=False,
    show_scalebars=False,
    block=False,
)
raw.plot(duration=5, **kwargs)  # annotation covers the pulse at 2-3 s
cropped.plot(duration=3, **kwargs)  # pulse now at 1-2 s, is the annotation too?
plt.show(block=True)

main vs fix

AI disclosure: Claude (Opus 5.5) implemented the fix and the test and produced the figure; I reviewed the changes.

@mscheltienne
mscheltienne force-pushed the fix-crop-reset-first-samp branch from 46581e8 to 2108cf3 Compare October 21, 2026 12:12
@mscheltienne
mscheltienne marked this pull request as ready for review October 21, 2026 12:13
@drammock
drammock enabled auto-merge (squash) October 21, 2026 22:11
@drammock
drammock merged commit 9249752 into mne-tools:main Oct 21, 2026
25 checks passed
@mscheltienne
mscheltienne deleted the fix-crop-reset-first-samp branch October 22, 2026 15:02
larsoner added a commit to sonoAESS/mne-python that referenced this pull request Oct 22, 2026
* upstream/main:
  FIX: Put split before desc in BIDS split file names (mne-tools#14434)
  Fix Raw.crop with reset_first_samp=True misaligning annotations and data (mne-tools#14439)
  Bump Python version for `ty` runs (mne-tools#14443)
  BUG: Explicitly import defusedxml.ElementTree and ipympl.backend_nbagg (mne-tools#14430)
  Add CircleCI scheduled-workflow issue opener [ci skip] (mne-tools#14441)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants