def test_meas_date_orig_time(): """Test the relation between meas_time in orig_time.""" # meas_time is set and orig_time is set: # clips the annotations based on raw.data and resets the annotation based # on raw.info['meas_date] raw = _raw_annot(1, 1.5) assert raw.annotations.orig_time == _stamp_to_dt((1, 0)) assert raw.annotations.onset[0] == 1 # meas_time is set and orig_time is None: # Consider annot.orig_time to be raw.frist_sample, clip and reset # annotations to have the raw.annotations.orig_time == raw.info['meas_date] raw = _raw_annot(1, None) assert raw.annotations.orig_time == _stamp_to_dt((1, 0)) assert raw.annotations.onset[0] == 1.5 # meas_time is None and orig_time is set: # Raise error, it makes no sense to have an annotations object that we know # when was acquired and set it to a raw object that does not know when was # it acquired. with pytest.raises(RuntimeError, match='Ambiguous operation'): _raw_annot(None, 1.5) # meas_time is None and orig_time is None: # Consider annot.orig_time to be raw.first_sample and clip raw = _raw_annot(None, None) assert raw.annotations.orig_time is None assert raw.annotations.onset[0] == 1.5 assert raw.annotations.duration[0] == 0.2
def test_saving_picked(tmpdir, comp_grade): """Test saving picked CTF instances.""" temp_dir = str(tmpdir) out_fname = op.join(temp_dir, 'test_py_raw.fif') raw = read_raw_ctf(op.join(ctf_dir, ctf_fname_1_trial)) assert raw.info['meas_date'] == _stamp_to_dt((1367228160, 0)) raw.crop(0, 1).load_data() assert raw.compensation_grade == get_current_comp(raw.info) == 0 assert len(raw.info['comps']) == 5 pick_kwargs = dict(meg=True, ref_meg=False, verbose=True) raw.apply_gradient_compensation(comp_grade) with catch_logging() as log: raw_pick = raw.copy().pick_types(**pick_kwargs) assert len(raw.info['comps']) == 5 assert len(raw_pick.info['comps']) == 0 log = log.getvalue() assert 'Removing 5 compensators' in log raw_pick.save(out_fname, overwrite=True) # should work raw2 = read_raw_fif(out_fname) assert (raw_pick.ch_names == raw2.ch_names) assert_array_equal(raw_pick.times, raw2.times) assert_allclose(raw2[0:20][0], raw_pick[0:20][0], rtol=1e-6, atol=1e-20) # atol is very small but > 0 raw2 = read_raw_fif(out_fname, preload=True) assert (raw_pick.ch_names == raw2.ch_names) assert_array_equal(raw_pick.times, raw2.times) assert_allclose(raw2[0:20][0], raw_pick[0:20][0], rtol=1e-6, atol=1e-20) # atol is very small but > 0
def test_crop_when_negative_orig_time(windows_like_datetime): """Test cropping with orig_time, tmin and tmax previous to 1970.""" # Regression test for gh-6621 orig_time_stamp = -908196945.011331 # 1941-03-22 11:04:14.988669 annot = Annotations(description='foo', onset=np.arange(0, 0.999, 0.1), duration=[0], orig_time=orig_time_stamp) stamp = _dt_to_stamp(annot.orig_time) assert_allclose(stamp[0] + stamp[1] * 1e-6, orig_time_stamp) t = stamp[0] + stamp[1] * 1e-6 assert t == orig_time_stamp assert len(annot) == 10 # do not raise annot.crop(verbose='debug') assert len(annot) == 10 # Crop with negative tmin, tmax tmin, tmax = [orig_time_stamp + t for t in (0.25, .75)] assert tmin < 0 and tmax < 0 crop_annot = annot.crop(tmin=tmin, tmax=tmax) assert_allclose(crop_annot.onset, [0.3, 0.4, 0.5, 0.6, 0.7]) orig_dt = _stamp_to_dt(stamp) assert crop_annot.orig_time == orig_dt # orig_time does not change
def test_anonymize(tmp_path): """Test mne anonymize.""" check_usage(mne_anonymize) out_fname = op.join(tmp_path, 'anon_test_raw.fif') with ArgvSetter(('-f', raw_fname, '-o', out_fname)): mne_anonymize.run() info = read_info(out_fname) assert (op.exists(out_fname)) assert info['meas_date'] == _stamp_to_dt((946684800, 0))
def test_read_vhdr_annotations_and_events(): """Test load brainvision annotations and parse them to events.""" sfreq = 1000.0 expected_orig_time = _stamp_to_dt((1384359243, 794232)) expected_onset_latency = np.array( [0, 486., 496., 1769., 1779., 3252., 3262., 4935., 4945., 5999., 6619., 6629., 7629., 7699.] ) expected_annot_description = [ 'New Segment/', 'Stimulus/S253', 'Stimulus/S255', 'Event/254', 'Stimulus/S255', 'Event/254', 'Stimulus/S255', 'Stimulus/S253', 'Stimulus/S255', 'Response/R255', 'Event/254', 'Stimulus/S255', 'SyncStatus/Sync On', 'Optic/O 1' ] expected_events = np.stack([ expected_onset_latency, np.zeros_like(expected_onset_latency), [99999, 253, 255, 254, 255, 254, 255, 253, 255, 1255, 254, 255, 99998, 2001], ]).astype('int64').T expected_event_id = {'New Segment/': 99999, 'Stimulus/S253': 253, 'Stimulus/S255': 255, 'Event/254': 254, 'Response/R255': 1255, 'SyncStatus/Sync On': 99998, 'Optic/O 1': 2001} raw = read_raw_brainvision(vhdr_path, eog=eog) # validate annotations assert raw.annotations.orig_time == expected_orig_time assert_allclose(raw.annotations.onset, expected_onset_latency / sfreq) assert_array_equal(raw.annotations.description, expected_annot_description) # validate event extraction events, event_id = events_from_annotations(raw) assert_array_equal(events, expected_events) assert event_id == expected_event_id # validate that None gives us a sorted list expected_none_event_id = {desc: idx + 1 for idx, desc in enumerate(sorted( event_id.keys()))} events, event_id = events_from_annotations(raw, event_id=None) assert event_id == expected_none_event_id # Add some custom ones, plus a 2-digit one s_10 = 'Stimulus/S 10' raw.annotations.append([1, 2, 3], 10, ['ZZZ', s_10, 'YYY']) expected_event_id.update(YYY=10001, ZZZ=10002) # others starting at 10001 expected_event_id[s_10] = 10 _, event_id = events_from_annotations(raw) assert event_id == expected_event_id # Concatenating two shouldn't change the resulting event_id # (BAD and EDGE should be ignored) with pytest.warns(RuntimeWarning, match='expanding outside'): raw_concat = concatenate_raws([raw.copy(), raw.copy()]) _, event_id = events_from_annotations(raw_concat) assert event_id == expected_event_id
def mocked_meas_date_file(_mocked_meas_date_data, request): """Prepare a generator for use in test_meas_date.""" MEAS_DATE_LINE = 11 # see test.vmrk file vhdr_fname, vmrk_fname, lines = _mocked_meas_date_data lines[MEAS_DATE_LINE] = request.param['content'] with open(vmrk_fname, 'w') as fout: fout.writelines(lines) meas_date = request.param['meas_date'] if meas_date is not None: meas_date = _stamp_to_dt(meas_date) yield vhdr_fname, meas_date, request.param['meas_date_repr']
def test_5839(): """Test concatenating raw objects with annotations.""" # Global Time 0 1 2 3 4 # . # raw_A |---------XXXXXXXXXX # annot |--------------AA # latency . 0 0 1 1 2 2 3 # . 5 0 5 0 5 0 # # raw_B . |---------YYYYYYYYYY # annot . |--------------AA # latency . 0 1 # . 5 0 # . # output |---------XXXXXXXXXXYYYYYYYYYY # annot |--------------AA---|----AA # latency . 0 0 1 1 2 2 3 # . 5 0 5 0 5 0 # EXPECTED_ONSET = [1.5, 2., 2., 2.5] EXPECTED_DURATION = [0.2, 0., 0., 0.2] EXPECTED_DESCRIPTION = ['dummy', 'BAD boundary', 'EDGE boundary', 'dummy'] def raw_factory(meas_date): raw = RawArray(data=np.empty((10, 10)), info=create_info(ch_names=10, sfreq=10.), first_samp=10) raw.set_meas_date(meas_date) raw.set_annotations(annotations=Annotations(onset=[.5], duration=[.2], description='dummy', orig_time=None)) return raw raw_A, raw_B = [raw_factory((x, 0)) for x in [0, 2]] raw_A.append(raw_B) assert_array_equal(raw_A.annotations.onset, EXPECTED_ONSET) assert_array_equal(raw_A.annotations.duration, EXPECTED_DURATION) assert_array_equal(raw_A.annotations.description, EXPECTED_DESCRIPTION) assert raw_A.annotations.orig_time == _stamp_to_dt((0, 0))
def _test_raw_reader(reader, test_preloading=True, test_kwargs=True, boundary_decimal=2, test_scaling=True, test_rank=True, **kwargs): """Test reading, writing and slicing of raw classes. Parameters ---------- reader : function Function to test. test_preloading : bool Whether not preloading is implemented for the reader. If True, both cases and memory mapping to file are tested. test_kwargs : dict Test _init_kwargs support. boundary_decimal : int Number of decimals up to which the boundary should match. **kwargs : Arguments for the reader. Note: Do not use preload as kwarg. Use ``test_preloading`` instead. Returns ------- raw : instance of Raw A preloaded Raw object. """ tempdir = _TempDir() rng = np.random.RandomState(0) montage = None if "montage" in kwargs: montage = kwargs['montage'] del kwargs['montage'] if test_preloading: raw = reader(preload=True, **kwargs) rep = repr(raw) assert rep.count('<') == 1 assert rep.count('>') == 1 if montage is not None: raw.set_montage(montage) # don't assume the first is preloaded buffer_fname = op.join(tempdir, 'buffer') picks = rng.permutation(np.arange(len(raw.ch_names) - 1))[:10] picks = np.append(picks, len(raw.ch_names) - 1) # test trigger channel bnd = min(int(round(raw.buffer_size_sec * raw.info['sfreq'])), raw.n_times) slices = [slice(0, bnd), slice(bnd - 1, bnd), slice(3, bnd), slice(3, 300), slice(None), slice(1, bnd)] if raw.n_times >= 2 * bnd: # at least two complete blocks slices += [slice(bnd, 2 * bnd), slice(bnd, bnd + 1), slice(0, bnd + 100)] other_raws = [reader(preload=buffer_fname, **kwargs), reader(preload=False, **kwargs)] for sl_time in slices: data1, times1 = raw[picks, sl_time] for other_raw in other_raws: data2, times2 = other_raw[picks, sl_time] assert_allclose(data1, data2) assert_allclose(times1, times2) # test projection vs cals and data units other_raw = reader(preload=False, **kwargs) other_raw.del_proj() eeg = meg = fnirs = False if 'eeg' in raw: eeg, atol = True, 1e-18 elif 'grad' in raw: meg, atol = 'grad', 1e-24 elif 'mag' in raw: meg, atol = 'mag', 1e-24 else: assert 'fnirs_cw_amplitude' in raw, 'New channel type necessary?' fnirs, atol = 'fnirs_cw_amplitude', 1e-10 picks = pick_types( other_raw.info, meg=meg, eeg=eeg, fnirs=fnirs) col_names = [other_raw.ch_names[pick] for pick in picks] proj = np.ones((1, len(picks))) proj /= proj.shape[1] proj = Projection( data=dict(data=proj, nrow=1, row_names=None, col_names=col_names, ncol=len(picks)), active=False) assert len(other_raw.info['projs']) == 0 other_raw.add_proj(proj) assert len(other_raw.info['projs']) == 1 # Orders of projector application, data loading, and reordering # equivalent: # 1. load->apply->get data_load_apply_get = \ other_raw.copy().load_data().apply_proj().get_data(picks) # 2. apply->get (and don't allow apply->pick) apply = other_raw.copy().apply_proj() data_apply_get = apply.get_data(picks) data_apply_get_0 = apply.get_data(picks[0])[0] with pytest.raises(RuntimeError, match='loaded'): apply.copy().pick(picks[0]).get_data() # 3. apply->load->get data_apply_load_get = apply.copy().load_data().get_data(picks) data_apply_load_get_0, data_apply_load_get_1 = \ apply.copy().load_data().pick(picks[:2]).get_data() # 4. reorder->apply->load->get all_picks = np.arange(len(other_raw.ch_names)) reord = np.concatenate(( picks[1::2], picks[0::2], np.setdiff1d(all_picks, picks))) rev = np.argsort(reord) assert_array_equal(reord[rev], all_picks) assert_array_equal(rev[reord], all_picks) reorder = other_raw.copy().pick(reord) assert reorder.ch_names == [other_raw.ch_names[r] for r in reord] assert reorder.ch_names[0] == other_raw.ch_names[picks[1]] assert_allclose(reorder.get_data([0]), other_raw.get_data(picks[1])) reorder_apply = reorder.copy().apply_proj() assert reorder_apply.ch_names == reorder.ch_names assert reorder_apply.ch_names[0] == apply.ch_names[picks[1]] assert_allclose(reorder_apply.get_data([0]), apply.get_data(picks[1]), atol=1e-18) data_reorder_apply_load_get = \ reorder_apply.load_data().get_data(rev[:len(picks)]) data_reorder_apply_load_get_1 = \ reorder_apply.copy().load_data().pick([0]).get_data()[0] assert reorder_apply.ch_names[0] == apply.ch_names[picks[1]] assert (data_load_apply_get.shape == data_apply_get.shape == data_apply_load_get.shape == data_reorder_apply_load_get.shape) del apply # first check that our data are (probably) in the right units data = data_load_apply_get.copy() data = data - np.mean(data, axis=1, keepdims=True) # can be offsets np.abs(data, out=data) if test_scaling: maxval = atol * 1e16 assert_array_less(data, maxval) minval = atol * 1e6 assert_array_less(minval, np.median(data)) else: atol = 1e-7 * np.median(data) # 1e-7 * MAD # ranks should all be reduced by 1 if test_rank == 'less': cmp = np.less elif test_rank is False: cmp = None else: # anything else is like True or 'equal' assert test_rank is True or test_rank == 'equal', test_rank cmp = np.equal rank_load_apply_get = np.linalg.matrix_rank(data_load_apply_get) rank_apply_get = np.linalg.matrix_rank(data_apply_get) rank_apply_load_get = np.linalg.matrix_rank(data_apply_load_get) if cmp is not None: assert cmp(rank_load_apply_get, len(col_names) - 1) assert cmp(rank_apply_get, len(col_names) - 1) assert cmp(rank_apply_load_get, len(col_names) - 1) # and they should all match t_kw = dict( atol=atol, err_msg='before != after, likely _mult_cal_one prob') assert_allclose(data_apply_get[0], data_apply_get_0, **t_kw) assert_allclose(data_apply_load_get_1, data_reorder_apply_load_get_1, **t_kw) assert_allclose(data_load_apply_get[0], data_apply_load_get_0, **t_kw) assert_allclose(data_load_apply_get, data_apply_get, **t_kw) assert_allclose(data_load_apply_get, data_apply_load_get, **t_kw) if 'eeg' in raw: other_raw.del_proj() direct = \ other_raw.copy().load_data().set_eeg_reference().get_data() other_raw.set_eeg_reference(projection=True) assert len(other_raw.info['projs']) == 1 this_proj = other_raw.info['projs'][0]['data'] assert this_proj['col_names'] == col_names assert this_proj['data'].shape == proj['data']['data'].shape assert_allclose(this_proj['data'], proj['data']['data']) proj = other_raw.apply_proj().get_data() assert_allclose(proj[picks], data_load_apply_get, atol=1e-10) assert_allclose(proj, direct, atol=1e-10, err_msg=t_kw['err_msg']) else: raw = reader(**kwargs) assert_named_constants(raw.info) # smoke test for gh #9743 ids = [id(ch['loc']) for ch in raw.info['chs']] assert len(set(ids)) == len(ids) full_data = raw._data assert raw.__class__.__name__ in repr(raw) # to test repr assert raw.info.__class__.__name__ in repr(raw.info) assert isinstance(raw.info['dig'], (type(None), list)) data_max = full_data.max() data_min = full_data.min() # these limits could be relaxed if we actually find data with # huge values (in SI units) assert data_max < 1e5 assert data_min > -1e5 if isinstance(raw.info['dig'], list): for di, d in enumerate(raw.info['dig']): assert isinstance(d, DigPoint), (di, d) # gh-5604 meas_date = raw.info['meas_date'] assert meas_date is None or meas_date >= _stamp_to_dt((0, 0)) # test repr_html assert 'Good channels' in raw.info._repr_html_() # test resetting raw if test_kwargs: raw2 = reader(**raw._init_kwargs) assert set(raw.info.keys()) == set(raw2.info.keys()) assert_array_equal(raw.times, raw2.times) # Test saving and reading out_fname = op.join(tempdir, 'test_raw.fif') raw = concatenate_raws([raw]) raw.save(out_fname, tmax=raw.times[-1], overwrite=True, buffer_size_sec=1) # Test saving with not correct extension out_fname_h5 = op.join(tempdir, 'test_raw.h5') with pytest.raises(IOError, match='raw must end with .fif or .fif.gz'): raw.save(out_fname_h5) raw3 = read_raw_fif(out_fname) assert_named_constants(raw3.info) assert set(raw.info.keys()) == set(raw3.info.keys()) assert_allclose(raw3[0:20][0], full_data[0:20], rtol=1e-6, atol=1e-20) # atol is very small but > 0 assert_allclose(raw.times, raw3.times, atol=1e-6, rtol=1e-6) assert not math.isnan(raw3.info['highpass']) assert not math.isnan(raw3.info['lowpass']) assert not math.isnan(raw.info['highpass']) assert not math.isnan(raw.info['lowpass']) assert raw3.info['kit_system_id'] == raw.info['kit_system_id'] # Make sure concatenation works first_samp = raw.first_samp last_samp = raw.last_samp concat_raw = concatenate_raws([raw.copy(), raw]) assert concat_raw.n_times == 2 * raw.n_times assert concat_raw.first_samp == first_samp assert concat_raw.last_samp - last_samp + first_samp == last_samp + 1 idx = np.where(concat_raw.annotations.description == 'BAD boundary')[0] expected_bad_boundary_onset = raw._last_time assert_array_almost_equal(concat_raw.annotations.onset[idx], expected_bad_boundary_onset, decimal=boundary_decimal) if raw.info['meas_id'] is not None: for key in ['secs', 'usecs', 'version']: assert raw.info['meas_id'][key] == raw3.info['meas_id'][key] assert_array_equal(raw.info['meas_id']['machid'], raw3.info['meas_id']['machid']) assert isinstance(raw.annotations, Annotations) # Make a "soft" test on units: They have to be valid SI units as in # mne.io.meas_info.valid_units, but we accept any lower/upper case for now. valid_units = _get_valid_units() valid_units_lower = [unit.lower() for unit in valid_units] if raw._orig_units is not None: assert isinstance(raw._orig_units, dict) for ch_name, unit in raw._orig_units.items(): assert unit.lower() in valid_units_lower, ch_name # Test picking with and without preload if test_preloading: preload_kwargs = (dict(preload=True), dict(preload=False)) else: preload_kwargs = (dict(),) n_ch = len(raw.ch_names) picks = rng.permutation(n_ch) for preload_kwarg in preload_kwargs: these_kwargs = kwargs.copy() these_kwargs.update(preload_kwarg) # don't use the same filename or it could create problems if isinstance(these_kwargs.get('preload', None), str) and \ op.isfile(these_kwargs['preload']): these_kwargs['preload'] += '-1' whole_raw = reader(**these_kwargs) print(whole_raw) # __repr__ assert n_ch >= 2 picks_1 = picks[:n_ch // 2] picks_2 = picks[n_ch // 2:] raw_1 = whole_raw.copy().pick(picks_1) raw_2 = whole_raw.copy().pick(picks_2) data, times = whole_raw[:] data_1, times_1 = raw_1[:] data_2, times_2 = raw_2[:] assert_array_equal(times, times_1) assert_array_equal(data[picks_1], data_1) assert_array_equal(times, times_2,) assert_array_equal(data[picks_2], data_2) # Make sure that writing info to h5 format # (all fields should be compatible) if check_version('h5py'): fname_h5 = op.join(tempdir, 'info.h5') with _writing_info_hdf5(raw.info): write_hdf5(fname_h5, raw.info) new_info = Info(read_hdf5(fname_h5)) assert object_diff(new_info, raw.info) == '' # Make sure that changing directory does not break anything if test_preloading: these_kwargs = kwargs.copy() key = None for key in ('fname', 'input_fname', # artemis123 'vhdr_fname', # BV 'pdf_fname', # BTi 'directory', # CTF 'filename', # nedf ): try: fname = kwargs[key] except KeyError: key = None else: break # len(kwargs) == 0 for the fake arange reader if len(kwargs): assert key is not None, sorted(kwargs.keys()) dirname = op.dirname(fname) these_kwargs[key] = op.basename(fname) these_kwargs['preload'] = False orig_dir = os.getcwd() try: os.chdir(dirname) raw_chdir = reader(**these_kwargs) finally: os.chdir(orig_dir) raw_chdir.load_data() return raw
def _test_raw_reader(reader, test_preloading=True, test_kwargs=True, boundary_decimal=2, **kwargs): """Test reading, writing and slicing of raw classes. Parameters ---------- reader : function Function to test. test_preloading : bool Whether not preloading is implemented for the reader. If True, both cases and memory mapping to file are tested. test_kwargs : dict Test _init_kwargs support. boundary_decimal : int Number of decimals up to which the boundary should match. **kwargs : Arguments for the reader. Note: Do not use preload as kwarg. Use ``test_preloading`` instead. Returns ------- raw : instance of Raw A preloaded Raw object. """ tempdir = _TempDir() rng = np.random.RandomState(0) montage = None if "montage" in kwargs: montage = kwargs['montage'] del kwargs['montage'] if test_preloading: raw = reader(preload=True, **kwargs) rep = repr(raw) assert rep.count('<') == 1 assert rep.count('>') == 1 if montage is not None: raw.set_montage(montage) # don't assume the first is preloaded buffer_fname = op.join(tempdir, 'buffer') picks = rng.permutation(np.arange(len(raw.ch_names) - 1))[:10] picks = np.append(picks, len(raw.ch_names) - 1) # test trigger channel bnd = min(int(round(raw.buffer_size_sec * raw.info['sfreq'])), raw.n_times) slices = [ slice(0, bnd), slice(bnd - 1, bnd), slice(3, bnd), slice(3, 300), slice(None), slice(1, bnd) ] if raw.n_times >= 2 * bnd: # at least two complete blocks slices += [ slice(bnd, 2 * bnd), slice(bnd, bnd + 1), slice(0, bnd + 100) ] other_raws = [ reader(preload=buffer_fname, **kwargs), reader(preload=False, **kwargs) ] for sl_time in slices: data1, times1 = raw[picks, sl_time] for other_raw in other_raws: data2, times2 = other_raw[picks, sl_time] assert_allclose(data1, data2) assert_allclose(times1, times2) else: raw = reader(**kwargs) full_data = raw._data assert raw.__class__.__name__ in repr(raw) # to test repr assert raw.info.__class__.__name__ in repr(raw.info) assert isinstance(raw.info['dig'], (type(None), list)) data_max = full_data.max() data_min = full_data.min() # these limits could be relaxed if we actually find data with # huge values (in SI units) assert data_max < 1e5 assert data_min > -1e5 if isinstance(raw.info['dig'], list): for di, d in enumerate(raw.info['dig']): assert isinstance(d, DigPoint), (di, d) # gh-5604 meas_date = raw.info['meas_date'] assert meas_date is None or meas_date >= _stamp_to_dt((0, 0)) # test resetting raw if test_kwargs: raw2 = reader(**raw._init_kwargs) assert set(raw.info.keys()) == set(raw2.info.keys()) assert_array_equal(raw.times, raw2.times) # Test saving and reading out_fname = op.join(tempdir, 'test_raw.fif') raw = concatenate_raws([raw]) raw.save(out_fname, tmax=raw.times[-1], overwrite=True, buffer_size_sec=1) raw3 = read_raw_fif(out_fname) assert set(raw.info.keys()) == set(raw3.info.keys()) assert_allclose(raw3[0:20][0], full_data[0:20], rtol=1e-6, atol=1e-20) # atol is very small but > 0 assert_array_almost_equal(raw.times, raw3.times) assert not math.isnan(raw3.info['highpass']) assert not math.isnan(raw3.info['lowpass']) assert not math.isnan(raw.info['highpass']) assert not math.isnan(raw.info['lowpass']) assert raw3.info['kit_system_id'] == raw.info['kit_system_id'] # Make sure concatenation works first_samp = raw.first_samp last_samp = raw.last_samp concat_raw = concatenate_raws([raw.copy(), raw]) assert concat_raw.n_times == 2 * raw.n_times assert concat_raw.first_samp == first_samp assert concat_raw.last_samp - last_samp + first_samp == last_samp + 1 idx = np.where(concat_raw.annotations.description == 'BAD boundary')[0] expected_bad_boundary_onset = raw._last_time assert_array_almost_equal(concat_raw.annotations.onset[idx], expected_bad_boundary_onset, decimal=boundary_decimal) if raw.info['meas_id'] is not None: for key in ['secs', 'usecs', 'version']: assert raw.info['meas_id'][key] == raw3.info['meas_id'][key] assert_array_equal(raw.info['meas_id']['machid'], raw3.info['meas_id']['machid']) assert isinstance(raw.annotations, Annotations) # Make a "soft" test on units: They have to be valid SI units as in # mne.io.meas_info.valid_units, but we accept any lower/upper case for now. valid_units = _get_valid_units() valid_units_lower = [unit.lower() for unit in valid_units] if raw._orig_units is not None: assert isinstance(raw._orig_units, dict) for ch_name, unit in raw._orig_units.items(): assert unit.lower() in valid_units_lower, ch_name # Test picking with and without preload if test_preloading: preload_kwargs = (dict(preload=True), dict(preload=False)) else: preload_kwargs = (dict(), ) n_ch = len(raw.ch_names) picks = rng.permutation(n_ch) for preload_kwarg in preload_kwargs: these_kwargs = kwargs.copy() these_kwargs.update(preload_kwarg) # don't use the same filename or it could create problems if isinstance(these_kwargs.get('preload', None), str) and \ op.isfile(these_kwargs['preload']): these_kwargs['preload'] += '-1' whole_raw = reader(**these_kwargs) print(whole_raw) # __repr__ assert n_ch >= 2 picks_1 = picks[:n_ch // 2] picks_2 = picks[n_ch // 2:] raw_1 = whole_raw.copy().pick(picks_1) raw_2 = whole_raw.copy().pick(picks_2) data, times = whole_raw[:] data_1, times_1 = raw_1[:] data_2, times_2 = raw_2[:] assert_array_equal(times, times_1) assert_array_equal(data[picks_1], data_1) assert_array_equal( times, times_2, ) assert_array_equal(data[picks_2], data_2) return raw
def test_read_vhdr_annotations_and_events(tmp_path): """Test load brainvision annotations and parse them to events.""" # First we add a custom event that contains a comma in its description for src, dest in zip((vhdr_path, vmrk_path, eeg_path), ('test.vhdr', 'test.vmrk', 'test.eeg')): shutil.copyfile(src, tmp_path / dest) # Commas are encoded as "\1" with open(tmp_path / 'test.vmrk', 'a') as fout: fout.write(r"Mk15=Comma\1Type,CommaValue\11,7800,1,0\n") sfreq = 1000.0 expected_orig_time = _stamp_to_dt((1384359243, 794232)) expected_onset_latency = np.array( [0, 486., 496., 1769., 1779., 3252., 3262., 4935., 4945., 5999., 6619., 6629., 7629., 7699., 7799.] ) expected_annot_description = [ 'New Segment/', 'Stimulus/S253', 'Stimulus/S255', 'Event/254', 'Stimulus/S255', 'Event/254', 'Stimulus/S255', 'Stimulus/S253', 'Stimulus/S255', 'Response/R255', 'Event/254', 'Stimulus/S255', 'SyncStatus/Sync On', 'Optic/O 1', 'Comma,Type/CommaValue,1' ] expected_events = np.stack([ expected_onset_latency, np.zeros_like(expected_onset_latency), [99999, 253, 255, 254, 255, 254, 255, 253, 255, 1255, 254, 255, 99998, 2001, 10001], ]).astype('int64').T expected_event_id = {'New Segment/': 99999, 'Stimulus/S253': 253, 'Stimulus/S255': 255, 'Event/254': 254, 'Response/R255': 1255, 'SyncStatus/Sync On': 99998, 'Optic/O 1': 2001, 'Comma,Type/CommaValue,1': 10001} raw = read_raw_brainvision(tmp_path / 'test.vhdr', eog=eog) # validate annotations assert raw.annotations.orig_time == expected_orig_time assert_allclose(raw.annotations.onset, expected_onset_latency / sfreq) assert_array_equal(raw.annotations.description, expected_annot_description) # validate event extraction events, event_id = events_from_annotations(raw) assert_array_equal(events, expected_events) assert event_id == expected_event_id # validate that None gives us a sorted list expected_none_event_id = {desc: idx + 1 for idx, desc in enumerate(sorted( event_id.keys()))} events, event_id = events_from_annotations(raw, event_id=None) assert event_id == expected_none_event_id # Add some custom ones, plus a 2-digit one s_10 = 'Stimulus/S 10' raw.annotations.append([1, 2, 3], 10, ['ZZZ', s_10, 'YYY']) # others starting at 10001 ... # we already have "Comma,Type/CommaValue,1" as 10001 expected_event_id.update(YYY=10002, ZZZ=10003) expected_event_id[s_10] = 10 _, event_id = events_from_annotations(raw) assert event_id == expected_event_id # Concatenating two shouldn't change the resulting event_id # (BAD and EDGE should be ignored) with pytest.warns(RuntimeWarning, match='expanding outside'): raw_concat = concatenate_raws([raw.copy(), raw.copy()]) _, event_id = events_from_annotations(raw_concat) assert event_id == expected_event_id