code: def test_crop(tmp_path):
      """Test cropping with annotations."""
      raw = read_raw_fif(fif_fname)
      events = mne.find_events(raw)
      onset = events[events[:, 2] == 1, 0] / raw.info["sfreq"]
      duration = np.full_like(onset, 0.5)
      description = ["bad %d" % k for k in range(len(onset))]
      annot = mne.Annotations(
          onset, duration, description, orig_time=raw.info["meas_date"]
      )
      raw.set_annotations(annot)
  
      split_time = raw.times[-1] / 2.0 + 2.0
      split_idx = len(onset) // 2 + 1
      raw_cropped_left = raw.copy().crop(
          0.0, split_time - 1.0 / raw.info["sfreq"]
      )
      assert_array_equal(
          raw_cropped_left.annotations.description,
          raw.annotations.description[:split_idx],
      )
      assert_allclose(
          raw_cropped_left.annotations.duration,
          raw.annotations.duration[:split_idx],
      )
      assert_allclose(
          raw_cropped_left.annotations.onset,
          raw.annotations.onset[:split_idx],
      )
      raw_cropped_right = raw.copy().crop(split_time, None)
      assert_array_equal(
          raw_cropped_right.annotations.description,
          raw.annotations.description[split_idx:],
      )
      assert_allclose(
          raw_cropped_right.annotations.duration,
          raw.annotations.duration[split_idx:],
      )
      assert_allclose(
          raw_cropped_right.annotations.onset,
          raw.annotations.onset[split_idx:],
      )
      raw_concat = mne.concatenate_raws(
          [raw_cropped_left, raw_cropped_right], verbose="debug"
      )
      assert_allclose(raw_concat.times, raw.times)
      assert_allclose(raw_concat[:][0], raw[:][0], atol=1e-20)
      assert_and_remove_boundary_annot(raw_concat)
      # Ensure we annotations survive round-trip crop->concat
      assert_array_equal(
          raw_concat.annotations.description,
          raw.annotations.description,
      )
      for attr in ("onset", "duration"):
          assert_allclose(
              getattr(raw_concat.annotations, attr),
              getattr(raw.annotations, attr),
              err_msg="Failed for %s:" % (attr,),
          )
  
      raw.set_annotations(None)  # undo
  
      # Test concatenating annotations with and without orig_time.
      raw2 = raw.copy()
      raw.set_annotations(
          Annotations([45.0], [3], "test", raw.info["meas_date"])
      )
      raw2.set_annotations(Annotations([2.0], [3], "BAD", None))
      expected_onset = [45.0, 2.0 + raw._last_time]
      raw = concatenate_raws([raw, raw2])
      assert_and_remove_boundary_annot(raw)
      assert_array_almost_equal(
          raw.annotations.onset, expected_onset, decimal=2
      )
  
      # Test IO
      fname = tmp_path / "test-annot.fif"
      raw.annotations.save(fname)
      annot_read = read_annotations(fname)
      for attr in ("onset", "duration"):
          assert_allclose(
              getattr(annot_read, attr), getattr(raw.annotations, attr)
          )
      assert annot_read.orig_time == raw.annotations.orig_time
      assert_array_equal(
          annot_read.description, raw.annotations.description
      )
      annot = Annotations((), (), ())
      annot.save(fname, overwrite=True)
      pytest.raises(
          OSError, read_annotations, fif_fname
      )  # none in old raw
      annot = read_annotations(fname)
      assert isinstance(annot, Annotations)
      assert len(annot) == 0
      annot.crop()  # test if cropping empty annotations doesn't raise an error
      # Test that empty annotations can be saved with an object
      fname = tmp_path / "test_raw.fif"
      raw.set_annotations(annot)
      raw.save(fname)
      raw_read = read_raw_fif(fname)
      assert isinstance(raw_read.annotations, Annotations)
      assert len(raw_read.annotations) == 0
      raw.set_annotations(None)
      raw.save(fname, overwrite=True)
      raw_read = read_raw_fif(fname)
      assert raw_read.annotations is not None
      assert len(raw_read.annotations.onset) == 0
      # test saving and reloading cropped annotations in raw instance
      info = create_info(
          [f"EEG{i + 1}" for i in range(3)],
          ch_types=["eeg"] * 3,
          sfreq=50,
      )
      raw = RawArray(np.zeros((3, 50 * 20)), info)
      annotation = mne.Annotations([8, 12, 15], [2] * 3, [1, 2, 3])
      raw = raw.set_annotations(annotation)
      raw_copied = raw.copy().crop(5, 18)
      fname = tmp_path / "test_raw.fif"
      raw_copied.save(fname, overwrite=True)
      raw_loaded = mne.io.read_raw(str(fname))
      for attr in ("onset", "duration"):
          assert_allclose(
              getattr(raw.annotations, attr),
              getattr(raw_copied.annotations, attr),
          )
          assert_allclose(
              getattr(raw_copied.annotations, attr),
              getattr(raw_loaded.annotations, attr),
          )
  
imports: import sys
  from collections import OrderedDict
  from datetime import datetime, timedelta, timezone
  from itertools import repeat
  from pathlib import Path
  import numpy
  import pytest
  from numpy.testing import assert_allclose, assert_array_almost_equal, assert_array_equal, assert_equal
  from pytest import approx
  import mne
  from mne import Annotations, Epochs, annotations_from_events, count_annotations, create_info, events_from_annotations, read_annotations
  from mne.annotations import _handle_meas_date, _read_annotations_txt_parse_header, _sync_onset
  from mne.datasets import testing
  from mne.io import RawArray, concatenate_raws, read_raw_fif
  from mne.utils import _dt_to_stamp, _raw_annot, _record_warnings, _stamp_to_dt, assert_and_remove_boundary_annot, catch_logging, check_version
label_desc: Use image node_id 5 for calling a global function with example usage: test_crop(tmp_path) without return types