From 07e605fa8ed49b1c7558051746033c2553db350e Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Mon, 5 Aug 2019 11:59:30 +0200 Subject: [PATCH] TEST: use fixture and parametrize in BrainVision date tests (#6623) --- .../brainvision/tests/data/test_bad_date.vhdr | 142 ------------------ .../brainvision/tests/data/test_bad_date.vmrk | 25 --- mne/io/brainvision/tests/test_brainvision.py | 127 ++++++++-------- 3 files changed, 59 insertions(+), 235 deletions(-) delete mode 100644 mne/io/brainvision/tests/data/test_bad_date.vhdr delete mode 100644 mne/io/brainvision/tests/data/test_bad_date.vmrk diff --git a/mne/io/brainvision/tests/data/test_bad_date.vhdr b/mne/io/brainvision/tests/data/test_bad_date.vhdr deleted file mode 100644 index d7c5a552eeb..00000000000 --- a/mne/io/brainvision/tests/data/test_bad_date.vhdr +++ /dev/null @@ -1,142 +0,0 @@ -Brain Vision Data Exchange Header File Version 1.0 -; Data created by the Vision Recorder - -[Common Infos] -Codepage=UTF-8 -DataFile=test.eeg -MarkerFile=test_bad_date.vmrk -DataFormat=BINARY -; Data orientation: MULTIPLEXED=ch1,pt1, ch2,pt1 ... -DataOrientation=MULTIPLEXED -NumberOfChannels=32 -; Sampling interval in microseconds -SamplingInterval=1000 - -[Binary Infos] -BinaryFormat=INT_16 - -[Channel Infos] -; Each entry: Ch=,, -; ,, Future extensions.. -; Fields are delimited by commas, some fields might be omitted (empty). -; Commas in channel names are coded as "\1". -Ch1=FP1,,0.5,µV -Ch2=FP2,,0.5,µV -Ch3=F3,,0.5,µV -Ch4=F4,,0.5,µV -Ch5=C3,,0.5,µV -Ch6=C4,,0.5,µV -Ch7=P3,,0.5,µV -Ch8=P4,,0.5,µV -Ch9=O1,,0.5,µV -Ch10=O2,,0.5,µV -Ch11=F7,,0.5,µV -Ch12=F8,,0.5,µV -Ch13=P7,,0.5,µV -Ch14=P8,,0.5,µV -Ch15=Fz,,0.5,µV -Ch16=FCz,,0.5,µV -Ch17=Cz,,0.5,µV -Ch18=CPz,,0.5,µV -Ch19=Pz,,0.5,µV -Ch20=POz,,0.5,µV -Ch21=FC1,,0.5,µV -Ch22=FC2,,0.5,µV -Ch23=CP1,,0.5,µV -Ch24=CP2,,0.5,µV -Ch25=FC5,,0.5,µV -Ch26=FC6,,0.5,µV -Ch27=CP5,,0.5,BS -Ch28=CP6,,0.5,µS -Ch29=HL,,0.5,ARU -Ch30=HR,,0.5,uS -Ch31=Vb,,0.5,S -Ch32=ReRef,,0.5,C - -[Comment] - -A m p l i f i e r S e t u p -============================ -Number of channels: 32 -Sampling Rate [Hz]: 1000 -Sampling Interval [µS]: 1000 - -Channels --------- -# Name Phys. Chn. Resolution / Unit Low Cutoff [s] High Cutoff [Hz] Notch [Hz] Series Res. [kOhm] Gradient Offset -1 FP1 1 0.5 µV DC 250 Off 0 -2 FP2 2 0.5 µV DC 250 Off 0 -3 F3 3 0.5 µV DC 250 Off 0 -4 F4 4 0.5 µV DC 250 Off 0 -5 C3 5 0.5 µV DC 250 Off 0 -6 C4 6 0.5 µV DC 250 Off 0 -7 P3 7 0.5 µV DC 250 Off 0 -8 P4 8 0.5 µV DC 250 Off 0 -9 O1 9 0.5 µV DC 250 Off 0 -10 O2 10 0.5 µV DC 250 Off 0 -11 F7 11 0.5 µV DC 250 Off 0 -12 F8 12 0.5 µV DC 250 Off 0 -13 P7 13 0.5 µV DC 250 Off 0 -14 P8 14 0.5 µV DC 250 Off 0 -15 Fz 15 0.5 µV DC 250 Off 0 -16 FCz 16 0.5 µV DC 250 Off 0 -17 Cz 17 0.5 µV DC 250 Off 0 -18 CPz 18 0.5 µV DC 250 Off 0 -19 Pz 19 0.5 µV DC 250 Off 0 -20 POz 20 0.5 µV DC 250 Off 0 -21 FC1 21 0.5 µV DC 250 Off 0 -22 FC2 22 0.5 µV DC 250 Off 0 -23 CP1 23 0.5 µV DC 250 Off 0 -24 CP2 24 0.5 µV DC 250 Off 0 -25 FC5 25 0.5 µV DC 250 Off 0 -26 FC6 26 0.5 µV DC 250 Off 0 -27 CP5 27 0.5 BS DC 250 Off 0 -28 CP6 28 0.5 µS DC 250 Off 0 -29 HL 29 0.5 ARU DC 250 Off 0 -30 HR 30 0.5 uS DC 250 Off 0 -31 Vb 31 0.5 S DC 250 Off 0 -32 ReRef 32 0.5 C DC 250 Off 0 - -S o f t w a r e F i l t e r s -============================== -Disabled - - -Data Electrodes Selected Impedance Measurement Range: 0 - 100 kOhm -Ground Electrode Selected Impedance Measurement Range: 0 - 10 kOhm -Reference Electrode Selected Impedance Measurement Range: 0 - 10 kOhm -Impedance [kOhm] at 16:12:27 : -FP1: ??? -FP2: ??? -F3: ??? -F4: ??? -C3: ??? -C4: ??? -P3: ??? -P4: ??? -O1: ??? -O2: ??? -F7: ??? -F8: ??? -P7: ??? -P8: ??? -Fz: ??? -FCz: ??? -Cz: ??? -CPz: ??? -Pz: ??? -POz: ??? -FC1: ??? -FC2: ??? -CP1: ??? -CP2: ??? -FC5: ??? -FC6: ??? -CP5: ??? -CP6: ??? -HL: ??? -HR: ??? -Vb: ??? -ReRef: ??? -Ref: 0 -Gnd: 4 diff --git a/mne/io/brainvision/tests/data/test_bad_date.vmrk b/mne/io/brainvision/tests/data/test_bad_date.vmrk deleted file mode 100644 index 1795695fefd..00000000000 --- a/mne/io/brainvision/tests/data/test_bad_date.vmrk +++ /dev/null @@ -1,25 +0,0 @@ -Brain Vision Data Exchange Marker File, Version 1.0 - -[Common Infos] -Codepage=UTF-8 -DataFile=test.eeg - -[Marker Infos] -; Each entry: Mk=,,, -; , -; Fields are delimited by commas, some fields might be omitted (empty). -; Commas in type or description text are coded as "\1". -Mk1=New Segment,,1,1,0,00000000000304125000 -Mk2=Stimulus,S253,487,0,0 -Mk3=Stimulus,S255,497,1,0 -Mk4=Stimulus,S254,1770,1,0 -Mk5=Stimulus,S255,1780,1,0 -Mk6=Stimulus,S254,3253,1,0 -Mk7=Stimulus,S255,3263,1,0 -Mk8=Stimulus,S253,4936,1,0 -Mk9=Stimulus,S255,4946,1,0 -Mk10=Response,R255,6000,1,0 -Mk11=Stimulus,S254,6620,1,0 -Mk12=Stimulus,S255,6630,1,0 -Mk13=SyncStatus,Sync On,7630,1,0 -Mk14=Optic,O 1,7700,1,0 diff --git a/mne/io/brainvision/tests/test_brainvision.py b/mne/io/brainvision/tests/test_brainvision.py index 6fccd54491c..b4013bf5823 100644 --- a/mne/io/brainvision/tests/test_brainvision.py +++ b/mne/io/brainvision/tests/test_brainvision.py @@ -4,7 +4,6 @@ # Stefan Appelhoff # # License: BSD (3-clause) - import os.path as op from os import unlink import shutil as sh @@ -77,82 +76,74 @@ def test_orig_units(recwarn): assert orig_units['ReRef'] == 'C' -def test_vmrk_meas_date(): - """Test successful extraction of measurement date.""" - # Test file that does have a specific date - raw = read_raw_brainvision(vhdr_path) - assert_allclose(raw.info['meas_date'], [1384359243, 794231]) - assert '2013-11-13 16:14:03 GMT' in repr(raw.info) +DATE_TEST_CASES = np.array([ + ('Mk1=New Segment,,1,1,0,20131113161403794232\n', # content + [1384359243, 794231], # meas_date internal representation + '2013-11-13 16:14:03 GMT'), # meas_date representation - # Test file with multiple dates ... we should only take the first - with pytest.warns(RuntimeWarning, match='software filter'): - raw = read_raw_brainvision(vhdr_old_path) - assert_allclose(raw.info['meas_date'], [1184588560, 937453]) - assert '2007-07-16 12:22:40 GMT' in repr(raw.info) + (('Mk1=New Segment,,1,1,0,20070716122240937454\n' + 'Mk2=New Segment,,2,1,0,20070716122240937455\n'), + [1184588560, 937453], + '2007-07-16 12:22:40 GMT'), - # Test files with no date, we should get DATE_NONE from mne.io.write - with pytest.warns(RuntimeWarning, match='coordinate information'): - raw = read_raw_brainvision(vhdr_v2_path) - assert raw.info['meas_date'] is None - assert 'unspecified' in repr(raw.info) + ('Mk1=New Segment,,1,1,0,\nMk2=New Segment,,2,1,0,20070716122240937454\n', + [1184588560, 937453], + '2007-07-16 12:22:40 GMT'), - # Test files with faulty dates introduced by segmenting a file without - # date information. Should not raise a strptime ValueError - raw = read_raw_brainvision(vhdr_bad_date) - assert raw.info['meas_date'] is None - assert 'unspecified' in repr(raw.info) - - # Reuse our vmrk to test several other cases with dates - tmpdir = _TempDir() - tmp_vhdr_file = op.join(tmpdir, op.basename(vhdr_bad_date)) - tmp_vmrk_file = tmp_vhdr_file.replace('.vhdr', '.vmrk') - tmp_eeg_file = op.join(tmpdir, op.basename(eeg_path)) - sh.copyfile(vhdr_bad_date, tmp_vhdr_file) - sh.copyfile(vhdr_bad_date.replace('.vhdr', '.vmrk'), tmp_vmrk_file) - sh.copyfile(eeg_path, tmp_eeg_file) - - # We'll exclusively manipulate the "New Segment" line in vmrk - with open(tmp_vmrk_file, 'r') as fin: + ('Mk1=STATUS,,1,1,0\n', None, 'unspecified'), + ('Mk1=New Segment,,1,1,0,\n', None, 'unspecified'), + ('Mk1=New Segment,,1,1,0\n', None, 'unspecified'), + ('Mk1=New Segment,,1,1,0,00000000000304125000', None, 'unspecified'), + +], dtype=np.dtype({ + 'names': ['content', 'meas_date', 'meas_date_repr'], + 'formats': [object, object, 'U22'] +})) + + +@pytest.fixture(scope='session') +def _mocked_meas_date_data(tmpdir_factory): + """Prepare files for mocked_meas_date_file fixture.""" + # Prepare the files + tmpdir = str(tmpdir_factory.mktemp('brainvision_mocked_meas_date')) + vhdr_fname, vmrk_fname, eeg_fname = [ + op.join(tmpdir, op.basename(ff)) + for ff in [vhdr_path, vmrk_path, eeg_path] + ] + for orig, dest in zip([vhdr_path, eeg_path], [vhdr_fname, eeg_fname]): + sh.copyfile(orig, dest) + + # Get the marker information + with open(vmrk_path, 'r') as fin: lines = fin.readlines() - idx = lines.index('Mk1=New Segment,,1,1,0,00000000000304125000\n') - # Now perform some tests - # Test that we get no error for trying to extract meas_date if there is - # no marker of type "New Segment" in the data - lines[idx] = 'Mk1=STATUS,,1,1,0\n' - with open(tmp_vmrk_file, 'w') as fout: - fout.writelines(lines) - raw = read_raw_brainvision(tmp_vhdr_file) - assert raw.info['meas_date'] is None - assert 'unspecified' in repr(raw.info) + return vhdr_fname, vmrk_fname, lines - # Test that we extract no date, if "New Segment", but no date specified - # Note the trailing comma but missing data following that comma - lines[idx] = 'Mk1=New Segment,,1,1,0,\n' - with open(tmp_vmrk_file, 'w') as fout: - fout.writelines(lines) - raw = read_raw_brainvision(tmp_vhdr_file) - assert raw.info['meas_date'] is None - assert 'unspecified' in repr(raw.info) - # Test that no error if "New Segment", but no date specified and no - # trailing comma - lines[idx] = 'Mk1=New Segment,,1,1,0\n' - with open(tmp_vmrk_file, 'w') as fout: - fout.writelines(lines) - raw = read_raw_brainvision(tmp_vhdr_file) - assert raw.info['meas_date'] is None - assert 'unspecified' in repr(raw.info) +@pytest.fixture(scope='session', params=[tt for tt in DATE_TEST_CASES]) +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 - # Test that a fine date gets recognized, use 2000-01-01:12:00:00, assuming - # UTC timezone, which would be in unix time: 946728000 - lines[idx] = 'Mk1=New Segment,,1,1,0,20000101120000000000\n' - with open(tmp_vmrk_file, 'w') as fout: + lines[MEAS_DATE_LINE] = request.param['content'] + with open(vmrk_fname, 'w') as fout: fout.writelines(lines) - raw = read_raw_brainvision(tmp_vhdr_file) - assert raw.info['meas_date'] is not None - assert raw.info['meas_date'][1] == 0 # no microseconds - assert raw.info['meas_date'][0] == 946728000 + + yield ( + vhdr_fname, request.param['meas_date'], request.param['meas_date_repr'] + ) + + +def test_meas_date(mocked_meas_date_file): + """Test successful extraction of measurement date.""" + vhdr_f, expected_meas, expected_meas_repr = mocked_meas_date_file + raw = read_raw_brainvision(vhdr_f) + assert expected_meas_repr in repr(raw.info) + if expected_meas is None: + assert raw.info['meas_date'] is None + else: + assert_allclose(raw.info['meas_date'], expected_meas) def test_vhdr_codepage_ansi():