@@ -1568,7 +1568,15 @@ def rescale(self, scalings, *, verbose=None):
15681568 return self
15691569
15701570 @verbose
1571- def crop (self , tmin = 0.0 , tmax = None , include_tmax = True , * , verbose = None ):
1571+ def crop (
1572+ self ,
1573+ tmin = 0.0 ,
1574+ tmax = None ,
1575+ include_tmax = True ,
1576+ * ,
1577+ reset_first_samp = False ,
1578+ verbose = None ,
1579+ ):
15721580 """Crop raw data file.
15731581
15741582 Limit the data from the raw file to go between specific times. Note
@@ -1585,12 +1593,51 @@ def crop(self, tmin=0.0, tmax=None, include_tmax=True, *, verbose=None):
15851593 %(tmin_raw)s
15861594 %(tmax_raw)s
15871595 %(include_tmax)s
1596+ reset_first_samp : bool
1597+ If True, reset :term:`first_samp` to 0 after cropping, treating
1598+ the cropped segment as an independent recording. Note that this
1599+ can break things if you extracted events before cropping and try
1600+ to use them afterward. Default is False.
1601+
1602+ .. versionadded:: 1.12
15881603 %(verbose)s
15891604
15901605 Returns
15911606 -------
15921607 raw : instance of Raw
15931608 The cropped raw object, modified in-place.
1609+
1610+ Notes
1611+ -----
1612+ After cropping, :term:`first_samp` is updated to reflect the new
1613+ start of the data, preserving the original recording timeline.
1614+ This means ``raw.times`` will still start at ``0.0``, but
1615+ ``raw.first_samp`` will reflect the offset from the original
1616+ recording. If you want to treat the cropped segment as an
1617+ independent signal with ``first_samp=0``, you can convert it
1618+ to a :class:`~mne.io.RawArray`::
1619+
1620+ raw_array = mne.io.RawArray(raw.get_data(), raw.info)
1621+
1622+ Examples
1623+ --------
1624+ By default, cropping preserves the original recording timeline,
1625+ so :term:`first_samp` remains non-zero after cropping::
1626+
1627+ >>> raw = mne.io.read_raw_fif(fname) # doctest: +SKIP
1628+ >>> print(raw.first_samp) # doctest: +SKIP
1629+ 25800
1630+ >>> raw.crop(tmin=10, tmax=20) # doctest: +SKIP
1631+ >>> print(raw.first_samp) # doctest: +SKIP
1632+ 27810
1633+
1634+ If you want to treat the cropped segment as an independent
1635+ recording, use ``reset_first_samp=True``::
1636+
1637+ >>> raw2 = raw.copy().crop(tmin=10, tmax=20,
1638+ ... reset_first_samp=True) # doctest: +SKIP
1639+ >>> print(raw2.first_samp) # doctest: +SKIP
1640+ 0
15941641 """
15951642 max_time = (self .n_times - 1 ) / self .info ["sfreq" ]
15961643 if tmax is None :
@@ -1648,7 +1695,11 @@ def crop(self, tmin=0.0, tmax=None, include_tmax=True, *, verbose=None):
16481695 # set_annotations will put it back.
16491696 annotations .onset -= self .first_time
16501697 self .set_annotations (annotations , False )
1651-
1698+ if reset_first_samp :
1699+ delta = self ._first_samps [0 ]
1700+ self ._first_samps -= delta
1701+ self ._last_samps -= delta
1702+ self ._cropped_samp -= delta
16521703 return self
16531704
16541705 @verbose
0 commit comments