Test backwards compatibility with Epochs saved without annotations.
(
monkeypatch, tmp_path, meas_date, first_samp, decim
)
| 5119 | @pytest.mark.parametrize("first_samp", (0, 10000)) |
| 5120 | @pytest.mark.parametrize("decim", (1, 2)) |
| 5121 | def test_epochs_annotations_backwards_compat( |
| 5122 | monkeypatch, tmp_path, meas_date, first_samp, decim |
| 5123 | ): |
| 5124 | """Test backwards compatibility with Epochs saved without annotations.""" |
| 5125 | |
| 5126 | # loading an earlier saved file should work |
| 5127 | def no_sfreq_write_float(a, b, c): |
| 5128 | if b == FIFF.FIFF_MNE_EPOCHS_RAW_SFREQ: |
| 5129 | return |
| 5130 | return write_float(a, b, c) |
| 5131 | |
| 5132 | # force 'write_float' to not write raw_sfreq |
| 5133 | monkeypatch.setattr(mne.epochs, "write_float", no_sfreq_write_float) |
| 5134 | |
| 5135 | # create a test epochs dataset |
| 5136 | sfreq, n_epochs = 10.0, 4 |
| 5137 | data = np.linspace(0, 1, n_epochs * int(sfreq))[np.newaxis] |
| 5138 | info = create_info(ch_names=1, ch_types="eeg", sfreq=sfreq) |
| 5139 | with info._unlock(): |
| 5140 | info["lowpass"] = 1.0 |
| 5141 | raw = RawArray(data, info, first_samp) |
| 5142 | raw.set_meas_date(meas_date) |
| 5143 | # Add a single annotation that occurs between 1<t<2 |
| 5144 | annot = Annotations(1.1, 0.8, "1_less_t_less_2") |
| 5145 | raw.set_annotations(annot) |
| 5146 | annot = raw.annotations # fully adjusted, as per docstring |
| 5147 | events = make_fixed_length_events(raw) |
| 5148 | epochs = Epochs( |
| 5149 | raw, |
| 5150 | events, |
| 5151 | tmin=0, |
| 5152 | tmax=1 - 1.0 / sfreq, |
| 5153 | decim=decim, |
| 5154 | baseline=None, |
| 5155 | preload=True, |
| 5156 | ) |
| 5157 | assert len(epochs) == n_epochs |
| 5158 | |
| 5159 | # save it to disc and reload |
| 5160 | fname = tmp_path / "test_epo.fif" |
| 5161 | epochs.save(fname) |
| 5162 | epochs = read_epochs(fname) |
| 5163 | assert epochs.info["sfreq"] == epochs._raw_sfreq |
| 5164 | assert epochs.info["meas_date"] == raw.info["meas_date"] |
| 5165 | |
| 5166 | # expose the problem at a low level |
| 5167 | assert_allclose(epochs.info["sfreq"], raw.info["sfreq"] / decim) |
| 5168 | # expose it for the real use case |
| 5169 | lens = [len(ann) for ann in epochs.get_annotations_per_epoch()] |
| 5170 | want_lens = [0] * n_epochs |
| 5171 | # this should always be the case, but it only is when decim == 1! |
| 5172 | if decim == 1: |
| 5173 | want_lens[1] = 1 # the one we inserted |
| 5174 | assert lens == want_lens |
| 5175 | # but in practice, people with old -epo.fif *do not have any annotations |
| 5176 | # saved with them*, so we really only need to warn about a risk of bad |
| 5177 | # annot when using EpochsFIF *and* they do `set_annotations` *and* it's |
| 5178 | # an old-style file. It would be nice if we could only do it if they |
nothing calls this directly
no test coverage detected