def _fast_map_meg_channels(inst, pick_from, pick_to, mode='fast'): from mne.io.pick import pick_info from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.bem import _check_origin miss = 1e-4 # Smoothing criterion for MEG def _compute_dots(info, mode='fast'): """Compute all-to-all dots. """ templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots _compute_fast_dots = mem.cache(_compute_dots) info = inst.info.copy() info['bads'] = [] # if bads is different, hash will be different info_from = pick_info(info, pick_from, copy=True) templates = _read_coil_defs() coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') self_dots, cross_dots = _compute_fast_dots(info, mode=mode) cross_dots = cross_dots[pick_to, :][:, pick_from] self_dots = self_dots[pick_from, :][:, pick_from] ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) return fmd['data']
def _fast_map_meg_channels(info, pick_from, pick_to, mode='fast'): from mne.io.pick import pick_info from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.bem import _check_origin miss = 1e-4 # Smoothing criterion for MEG # XXX: hack to silence _compute_mapping_matrix verbose = mne.get_config('MNE_LOGGING_LEVEL', 'INFO') mne.set_log_level('WARNING') def _compute_dots(info, mode='fast'): """Compute all-to-all dots.""" templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots _compute_fast_dots = mem.cache(_compute_dots, verbose=0) info['bads'] = [] # if bads is different, hash will be different info_from = pick_info(info, pick_from, copy=True) templates = _read_coil_defs() coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') # This function needs a clean input. It hates the presence of other # channels than MEG channels. Make sure all is picked. self_dots, cross_dots = _compute_fast_dots( info, mode=mode) cross_dots = cross_dots[pick_to, :][:, pick_from] self_dots = self_dots[pick_from, :][:, pick_from] ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) mne.set_log_level(verbose) return fmd['data']
def map_meg_loocv_channels(inst, pick_from, pick_to, self_dots=None, cross_dots=None, mode='fast'): from mne.io.pick import pick_info from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.bem import _check_origin info_from = pick_info(inst.info, pick_from, copy=True) info_to = pick_info(inst.info, pick_to, copy=True) # no need to apply trans because both from and to coils are in device # coordinates templates = _read_coil_defs(verbose=False) coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) coils_to = _create_meg_coils(info_to['chs'], 'normal', info_to['dev_head_t'], templates) miss = 1e-4 # Smoothing criterion for MEG int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') my_origin = _check_origin((0., 0., 0.04), info_from) if self_dots is None: self_dots = _do_self_dots(int_rad, False, coils_from, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) if cross_dots is None: cross_dots = _do_cross_dots(int_rad, False, coils_from, coils_to, my_origin, 'meg', lut_fun, n_fact).T ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) return fmd['data'], self_dots, cross_dots
def _compute_dots(info, mode='fast'): """Compute all-to-all dots.""" templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots
def _compute_dots(info, mode='fast'): """Compute all-to-all dots. """ templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots
def _fast_map_meg_channels(inst, pick_from, pick_to, mode='fast'): from mne.io.pick import pick_info from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.bem import _check_origin miss = 1e-4 # Smoothing criterion for MEG def _compute_dots(info, mode='fast'): """Compute all-to-all dots. """ templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots _compute_fast_dots = mem.cache(_compute_dots) info = inst.info.copy() info['bads'] = [] # if bads is different, hash will be different info_from = pick_info(info, pick_from, copy=True) templates = _read_coil_defs() coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') self_dots, cross_dots = _compute_fast_dots(info, mode=mode) cross_dots = cross_dots[pick_to, :][:, pick_from] self_dots = self_dots[pick_from, :][:, pick_from] ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) return fmd['data']
def _compute_dots(info, mode='fast'): """Compute all-to-all dots.""" from mne.forward._field_interpolation import _setup_dots from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.bem import _check_origin templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots
def _compute_dots(info, mode='fast'): """Compute all-to-all dots.""" from mne.forward._field_interpolation import _setup_dots from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.bem import _check_origin templates = _read_coil_defs() coils = _create_meg_coils(info['chs'], 'normal', info['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils, 'meg') self_dots = _do_self_dots(int_rad, False, coils, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) cross_dots = _do_cross_dots(int_rad, False, coils, coils, my_origin, 'meg', lut_fun, n_fact).T return self_dots, cross_dots
def _fast_map_meg_channels(info, pick_from, pick_to, dots=None, mode='fast'): from mne.io.pick import pick_info from mne.forward._field_interpolation import _compute_mapping_matrix from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.bem import _check_origin miss = 1e-4 # Smoothing criterion for MEG # XXX: hack to silence _compute_mapping_matrix verbose = mne.get_config('MNE_LOGGING_LEVEL', 'INFO') mne.set_log_level('WARNING') info_from = pick_info(info, pick_from, copy=True) templates = _read_coil_defs() coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _patch_setup_dots( mode, info_from, coils_from, 'meg') # This function needs a clean input. It hates the presence of other # channels than MEG channels. Make sure all is picked. if dots is None: dots = self_dots, cross_dots = _compute_dots(info, mode=mode) else: self_dots, cross_dots = dots self_dots, cross_dots = _pick_dots(dots, pick_from, pick_to) ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) mne.set_log_level(verbose) return fmd['data']
def map_meg_loocv_channels(inst, pick_from, pick_to, self_dots=None, cross_dots=None, mode='fast'): from mne.io.pick import pick_info from mne.forward._lead_dots import _do_self_dots, _do_cross_dots from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.bem import _check_origin info_from = pick_info(inst.info, pick_from, copy=True) info_to = pick_info(inst.info, pick_to, copy=True) # no need to apply trans because both from and to coils are in device # coordinates templates = _read_coil_defs(verbose=False) coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) coils_to = _create_meg_coils(info_to['chs'], 'normal', info_to['dev_head_t'], templates) miss = 1e-4 # Smoothing criterion for MEG int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') my_origin = _check_origin((0., 0., 0.04), info_from) if self_dots is None: self_dots = _do_self_dots(int_rad, False, coils_from, my_origin, 'meg', lut_fun, n_fact, n_jobs=1) if cross_dots is None: cross_dots = _do_cross_dots(int_rad, False, coils_from, coils_to, my_origin, 'meg', lut_fun, n_fact).T ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) return fmd['data'], self_dots, cross_dots
def _fast_map_meg_channels(info, pick_from, pick_to, dots=None, mode='fast'): from mne.io.pick import pick_info from mne.forward._field_interpolation import _setup_dots from mne.forward._field_interpolation import _compute_mapping_matrix from mne.forward._make_forward import _create_meg_coils, _read_coil_defs from mne.bem import _check_origin miss = 1e-4 # Smoothing criterion for MEG # XXX: hack to silence _compute_mapping_matrix verbose = mne.get_config('MNE_LOGGING_LEVEL', 'INFO') mne.set_log_level('WARNING') info_from = pick_info(info, pick_from, copy=True) templates = _read_coil_defs() coils_from = _create_meg_coils(info_from['chs'], 'normal', info_from['dev_head_t'], templates) my_origin = _check_origin((0., 0., 0.04), info_from) int_rad, noise, lut_fun, n_fact = _setup_dots(mode, coils_from, 'meg') # This function needs a clean input. It hates the presence of other # channels than MEG channels. Make sure all is picked. if dots is None: dots = self_dots, cross_dots = _compute_dots(info, mode=mode) else: self_dots, cross_dots = dots self_dots, cross_dots = _pick_dots(dots, pick_from, pick_to) ch_names = [c['ch_name'] for c in info_from['chs']] fmd = dict(kind='meg', ch_names=ch_names, origin=my_origin, noise=noise, self_dots=self_dots, surface_dots=cross_dots, int_rad=int_rad, miss=miss) fmd['data'] = _compute_mapping_matrix(fmd, info_from) mne.set_log_level(verbose) return fmd['data']
def test_constants(tmpdir): """Test compensation.""" tmpdir = str(tmpdir) # old pytest... dest = op.join(tmpdir, 'fiff.zip') _fetch_file( 'https://codeload.github.com/' f'{REPO}/fiff-constants/zip/{COMMIT}', dest) names = list() with zipfile.ZipFile(dest, 'r') as ff: for name in ff.namelist(): if 'Dictionary' in name: ff.extract(name, tmpdir) names.append(op.basename(name)) shutil.move(op.join(tmpdir, name), op.join(tmpdir, names[-1])) names = sorted(names) assert names == [ 'DictionaryIOD.txt', 'DictionaryIOD_MNE.txt', 'DictionaryStructures.txt', 'DictionaryTags.txt', 'DictionaryTags_MNE.txt', 'DictionaryTypes.txt', 'DictionaryTypes_MNE.txt' ] # IOD (MEGIN and MNE) fif = dict(iod=dict(), tags=dict(), types=dict(), defines=dict()) con = dict(iod=dict(), tags=dict(), types=dict(), defines=dict()) fiff_version = None for name in ['DictionaryIOD.txt', 'DictionaryIOD_MNE.txt']: with open(op.join(tmpdir, name), 'rb') as fid: for line in fid: line = line.decode('latin1').strip() if line.startswith('# Packing revision'): assert fiff_version is None fiff_version = line.split()[-1] if (line.startswith('#') or line.startswith('alias') or len(line) == 0): continue line = line.split('"') assert len(line) in (1, 2, 3) desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) in (2, 3) if len(line) == 2: kind, id_ = line else: kind, id_, tagged = line assert tagged in ('tagged', ) id_ = int(id_) if id_ not in iod_dups: assert id_ not in fif['iod'] fif['iod'][id_] = [kind, desc] # Tags (MEGIN) with open(op.join(tmpdir, 'DictionaryTags.txt'), 'rb') as fid: for line in fid: line = line.decode('ISO-8859-1').strip() if (line.startswith('#') or line.startswith('alias') or line.startswith(':') or len(line) == 0): continue line = line.split('"') assert len(line) in (1, 2, 3), line desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) == 4, line kind, id_, dtype, unit = line id_ = int(id_) val = [kind, dtype, unit] assert id_ not in fif['tags'], (fif['tags'].get(id_), val) fif['tags'][id_] = val # Tags (MNE) with open(op.join(tmpdir, 'DictionaryTags_MNE.txt'), 'rb') as fid: for li, line in enumerate(fid): line = line.decode('ISO-8859-1').strip() # ignore continuation lines (*) if (line.startswith('#') or line.startswith('alias') or line.startswith(':') or line.startswith('*') or len(line) == 0): continue # weird syntax around line 80: if line in ('/*', '"'): continue line = line.split('"') assert len(line) in (1, 2, 3), line if len(line) == 3 and len(line[2]) > 0: l2 = line[2].strip() assert l2.startswith('/*') and l2.endswith('*/'), l2 desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) == 3, (li + 1, line) kind, id_, dtype = line unit = '-' id_ = int(id_) val = [kind, dtype, unit] if id_ not in tag_dups: assert id_ not in fif['tags'], (fif['tags'].get(id_), val) fif['tags'][id_] = val # Types and enums in_ = None re_prim = re.compile(r'^primitive\((.*)\)\s*(\S*)\s*"(.*)"$') re_enum = re.compile(r'^enum\((\S*)\)\s*".*"$') re_enum_entry = re.compile(r'\s*(\S*)\s*(\S*)\s*"(.*)"$') re_defi = re.compile(r'#define\s*(\S*)\s*(\S*)\s*"(.*)"$') used_enums = list() for extra in ('', '_MNE'): with open(op.join(tmpdir, 'DictionaryTypes%s.txt' % (extra, )), 'rb') as fid: for li, line in enumerate(fid): line = line.decode('ISO-8859-1').strip() if in_ is None: p = re_prim.match(line) e = re_enum.match(line) d = re_defi.match(line) if p is not None: t, s, d = p.groups() s = int(s) assert s not in fif['types'] fif['types'][s] = [t, d] elif e is not None: # entering an enum this_enum = e.group(1) if this_enum not in fif: used_enums.append(this_enum) fif[this_enum] = dict() con[this_enum] = dict() in_ = fif[this_enum] elif d is not None: t, s, d = d.groups() s = int(s) fif['defines'][t] = [s, d] else: assert not line.startswith('enum(') else: # in an enum if line == '{': continue elif line == '}': in_ = None continue t, s, d = re_enum_entry.match(line).groups() s = int(s) if t != 'ecg' and s != 3: # ecg defined the same way assert s not in in_ in_[s] = [t, d] # # Assertions # # Version mne_version = '%d.%d' % (FIFF.FIFFC_MAJOR_VERSION, FIFF.FIFFC_MINOR_VERSION) assert fiff_version == mne_version unknowns = list() # Assert that all our constants are in the FIF def assert 'FIFFV_SSS_JOB_NOTHING' in dir(FIFF) for name in sorted(dir(FIFF)): if name.startswith('_') or name in _dir_ignore_names: continue check = None val = getattr(FIFF, name) if name in fif['defines']: assert fif['defines'][name][0] == val elif name.startswith('FIFFC_'): # Checked above assert name in ('FIFFC_MAJOR_VERSION', 'FIFFC_MINOR_VERSION', 'FIFFC_VERSION') elif name.startswith('FIFFB_'): check = 'iod' elif name.startswith('FIFFT_'): check = 'types' elif name.startswith('FIFFV_'): if name.startswith('FIFFV_MNE_') and name.endswith('_ORI'): check = 'mne_ori' elif name.startswith('FIFFV_MNE_') and name.endswith('_COV'): check = 'covariance_type' elif name.startswith('FIFFV_MNE_COORD'): check = 'coord' # weird wrapper elif name.endswith('_CH') or '_QUAT_' in name or name in \ ('FIFFV_DIPOLE_WAVE', 'FIFFV_GOODNESS_FIT', 'FIFFV_HPI_ERR', 'FIFFV_HPI_G', 'FIFFV_HPI_MOV'): check = 'ch_type' elif name.startswith('FIFFV_SUBJ_'): check = name.split('_')[2].lower() elif name in ('FIFFV_POINT_LPA', 'FIFFV_POINT_NASION', 'FIFFV_POINT_RPA', 'FIFFV_POINT_INION'): check = 'cardinal_point' else: for check in used_enums: if name.startswith('FIFFV_' + check.upper()): break else: if name not in _tag_ignore_names: raise RuntimeError('Could not find %s' % (name, )) assert check in used_enums, name if 'SSS' in check: raise RuntimeError elif name.startswith('FIFF_UNIT'): # units and multipliers check = name.split('_')[1].lower() elif name.startswith('FIFF_'): check = 'tags' else: unknowns.append((name, val)) if check is not None and name not in _tag_ignore_names: assert val in fif[check], '%s: %s, %s' % (check, val, name) if val in con[check]: msg = "%s='%s' ?" % (name, con[check][val]) assert _aliases.get(name) == con[check][val], msg else: con[check][val] = name unknowns = '\n\t'.join('%s (%s)' % u for u in unknowns) assert len(unknowns) == 0, 'Unknown types\n\t%s' % unknowns # Assert that all the FIF defs are in our constants assert set(fif.keys()) == set(con.keys()) for key in sorted(set(fif.keys()) - {'defines'}): this_fif, this_con = fif[key], con[key] assert len(set(this_fif.keys())) == len(this_fif) assert len(set(this_con.keys())) == len(this_con) missing_from_con = sorted(set(this_con.keys()) - set(this_fif.keys())) assert missing_from_con == [], key if key not in _ignore_incomplete_enums: missing_from_fif = sorted( set(this_fif.keys()) - set(this_con.keys())) assert missing_from_fif == [], key # Assert that `coil_def.dat` has accurate descriptions of all enum(coil) coil_def = _read_coil_defs() coil_desc = np.array([c['desc'] for c in coil_def]) coil_def = np.array([(c['coil_type'], c['accuracy']) for c in coil_def], int) mask = (coil_def[:, 1] == FWD.COIL_ACCURACY_ACCURATE) coil_def = coil_def[mask, 0] coil_desc = coil_desc[mask] bad_list = [] for key in fif['coil']: if key not in _missing_coil_def and key not in coil_def: bad_list.append((' %s,' % key).ljust(10) + ' # ' + fif['coil'][key][1]) assert len(bad_list) == 0, \ '\nIn fiff-constants, missing from coil_def:\n' + '\n'.join(bad_list) # Assert that enum(coil) has all `coil_def.dat` entries for key, desc in zip(coil_def, coil_desc): if key not in fif['coil']: bad_list.append((' %s,' % key).ljust(10) + ' # ' + desc) assert len(bad_list) == 0, \ 'In coil_def, missing from fiff-constants:\n' + '\n'.join(bad_list)
def test_constants(tmpdir): """Test compensation.""" tmpdir = str(tmpdir) # old pytest... dest = op.join(tmpdir, 'fiff.zip') _fetch_file('https://codeload.github.com/mne-tools/fiff-constants/zip/' + commit, dest) names = list() with zipfile.ZipFile(dest, 'r') as ff: for name in ff.namelist(): if 'Dictionary' in name: ff.extract(name, tmpdir) names.append(op.basename(name)) shutil.move(op.join(tmpdir, name), op.join(tmpdir, names[-1])) names = sorted(names) assert names == ['DictionaryIOD.txt', 'DictionaryIOD_MNE.txt', 'DictionaryStructures.txt', 'DictionaryTags.txt', 'DictionaryTags_MNE.txt', 'DictionaryTypes.txt', 'DictionaryTypes_MNE.txt'] # IOD (MEGIN and MNE) fif = dict(iod=dict(), tags=dict(), types=dict(), defines=dict()) con = dict(iod=dict(), tags=dict(), types=dict(), defines=dict()) fiff_version = None for name in ['DictionaryIOD.txt', 'DictionaryIOD_MNE.txt']: with open(op.join(tmpdir, name), 'rb') as fid: for line in fid: line = line.decode('latin1').strip() if line.startswith('# Packing revision'): assert fiff_version is None fiff_version = line.split()[-1] if (line.startswith('#') or line.startswith('alias') or len(line) == 0): continue line = line.split('"') assert len(line) in (1, 2, 3) desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) in (2, 3) if len(line) == 2: kind, id_ = line else: kind, id_, tagged = line assert tagged in ('tagged',) id_ = int(id_) if id_ not in iod_dups: assert id_ not in fif['iod'] fif['iod'][id_] = [kind, desc] # Tags (MEGIN) with open(op.join(tmpdir, 'DictionaryTags.txt'), 'rb') as fid: for line in fid: line = line.decode('ISO-8859-1').strip() if (line.startswith('#') or line.startswith('alias') or line.startswith(':') or len(line) == 0): continue line = line.split('"') assert len(line) in (1, 2, 3), line desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) == 4, line kind, id_, dtype, unit = line id_ = int(id_) val = [kind, dtype, unit] assert id_ not in fif['tags'], (fif['tags'].get(id_), val) fif['tags'][id_] = val # Tags (MNE) with open(op.join(tmpdir, 'DictionaryTags_MNE.txt'), 'rb') as fid: for li, line in enumerate(fid): line = line.decode('ISO-8859-1').strip() # ignore continuation lines (*) if (line.startswith('#') or line.startswith('alias') or line.startswith(':') or line.startswith('*') or len(line) == 0): continue # weird syntax around line 80: if line in ('/*', '"'): continue line = line.split('"') assert len(line) in (1, 2, 3), line if len(line) == 3 and len(line[2]) > 0: l2 = line[2].strip() assert l2.startswith('/*') and l2.endswith('*/'), l2 desc = '' if len(line) == 1 else line[1] line = line[0].split() assert len(line) == 3, (li + 1, line) kind, id_, dtype = line unit = '-' id_ = int(id_) val = [kind, dtype, unit] if id_ not in tag_dups: assert id_ not in fif['tags'], (fif['tags'].get(id_), val) fif['tags'][id_] = val # Types and enums in_ = None re_prim = re.compile(r'^primitive\((.*)\)\s*(\S*)\s*"(.*)"$') re_enum = re.compile(r'^enum\((\S*)\)\s*".*"$') re_enum_entry = re.compile(r'\s*(\S*)\s*(\S*)\s*"(.*)"$') re_defi = re.compile(r'#define\s*(\S*)\s*(\S*)\s*"(.*)"$') used_enums = list() for extra in ('', '_MNE'): with open(op.join(tmpdir, 'DictionaryTypes%s.txt' % (extra,)), 'rb') as fid: for li, line in enumerate(fid): line = line.decode('ISO-8859-1').strip() if in_ is None: p = re_prim.match(line) e = re_enum.match(line) d = re_defi.match(line) if p is not None: t, s, d = p.groups() s = int(s) assert s not in fif['types'] fif['types'][s] = [t, d] elif e is not None: # entering an enum this_enum = e.group(1) if this_enum not in fif: used_enums.append(this_enum) fif[this_enum] = dict() con[this_enum] = dict() in_ = fif[this_enum] elif d is not None: t, s, d = d.groups() s = int(s) fif['defines'][t] = [s, d] else: assert not line.startswith('enum(') else: # in an enum if line == '{': continue elif line == '}': in_ = None continue t, s, d = re_enum_entry.match(line).groups() s = int(s) if t != 'ecg' and s != 3: # ecg defined the same way assert s not in in_ in_[s] = [t, d] # # Assertions # # Version mne_version = '%d.%d' % (FIFF.FIFFC_MAJOR_VERSION, FIFF.FIFFC_MINOR_VERSION) assert fiff_version == mne_version unknowns = list() # Assert that all our constants are in the FIF def assert 'FIFFV_SSS_JOB_NOTHING' in dir(FIFF) for name in sorted(dir(FIFF)): if name.startswith('_') or name in _dir_ignore_names: continue check = None val = getattr(FIFF, name) if name in fif['defines']: assert fif['defines'][name][0] == val elif name.startswith('FIFFC_'): # Checked above assert name in ('FIFFC_MAJOR_VERSION', 'FIFFC_MINOR_VERSION', 'FIFFC_VERSION') elif name.startswith('FIFFB_'): check = 'iod' elif name.startswith('FIFFT_'): check = 'types' elif name.startswith('FIFFV_'): if name.startswith('FIFFV_MNE_') and name.endswith('_ORI'): check = 'mne_ori' elif name.startswith('FIFFV_MNE_') and name.endswith('_COV'): check = 'covariance_type' elif name.startswith('FIFFV_MNE_COORD'): check = 'coord' # weird wrapper elif name.endswith('_CH') or '_QUAT_' in name or name in \ ('FIFFV_DIPOLE_WAVE', 'FIFFV_GOODNESS_FIT', 'FIFFV_HPI_ERR', 'FIFFV_HPI_G', 'FIFFV_HPI_MOV'): check = 'ch_type' elif name.startswith('FIFFV_SUBJ_'): check = name.split('_')[2].lower() elif name in ('FIFFV_POINT_LPA', 'FIFFV_POINT_NASION', 'FIFFV_POINT_RPA'): check = 'cardinal_point' else: for check in used_enums: if name.startswith('FIFFV_' + check.upper()): break else: raise RuntimeError('Could not find %s' % (name,)) assert check in used_enums, name if 'SSS' in check: raise RuntimeError elif name.startswith('FIFF_UNIT'): # units and multipliers check = name.split('_')[1].lower() elif name.startswith('FIFF_'): check = 'tags' else: unknowns.append((name, val)) if check is not None and name not in _tag_ignore_names: assert val in fif[check], '%s: %s, %s' % (check, val, name) if val in con[check]: msg = "%s='%s' ?" % (name, con[check][val]) assert _aliases.get(name) == con[check][val], msg else: con[check][val] = name unknowns = '\n\t'.join('%s (%s)' % u for u in unknowns) assert len(unknowns) == 0, 'Unknown types\n\t%s' % unknowns # Assert that all the FIF defs are in our constants assert set(fif.keys()) == set(con.keys()) for key in sorted(set(fif.keys()) - {'defines'}): this_fif, this_con = fif[key], con[key] assert len(set(this_fif.keys())) == len(this_fif) assert len(set(this_con.keys())) == len(this_con) missing_from_con = sorted(set(this_con.keys()) - set(this_fif.keys())) assert missing_from_con == [], key if key not in _ignore_incomplete_enums: missing_from_fif = sorted(set(this_fif.keys()) - set(this_con.keys())) assert missing_from_fif == [], key # Assert that `coil_def.dat` has accurate descriptions of all enum(coil) coil_def = _read_coil_defs() coil_desc = np.array([c['desc'] for c in coil_def]) coil_def = np.array([(c['coil_type'], c['accuracy']) for c in coil_def], int) mask = (coil_def[:, 1] == FWD.COIL_ACCURACY_ACCURATE) coil_def = coil_def[mask, 0] coil_desc = coil_desc[mask] bad_list = [] for key in fif['coil']: if key not in _missing_coil_def and key not in coil_def: bad_list.append((' %s,' % key).ljust(10) + ' # ' + fif['coil'][key][1]) assert len(bad_list) == 0, '\n' + '\n'.join(bad_list) # Assert that enum(coil) has all `coil_def.dat` entries for key, desc in zip(coil_def, coil_desc): if key not in fif['coil']: bad_list.append((' %s,' % key).ljust(10) + ' # ' + desc) assert len(bad_list) == 0, '\n' + '\n'.join(bad_list)