def test_calculate_chpi_positions(): """Test calculation of cHPI positions """ trans, rot, t = head_pos_to_trans_rot_t(read_head_pos(pos_fname)) with warnings.catch_warnings(record=True): raw = Raw(chpi_fif_fname, allow_maxshield=True, preload=True) t -= raw.first_samp / raw.info['sfreq'] quats = _calculate_chpi_positions(raw, verbose='debug') trans_est, rot_est, t_est = head_pos_to_trans_rot_t(quats) _compare_positions((trans, rot, t), (trans_est, rot_est, t_est), 0.003) # degenerate conditions raw_no_chpi = Raw(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1., copy=False) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, verbose=True) # ignore HPI info header and [done] footer for line in log_file.getvalue().strip().split('\n')[4:-1]: assert_true('0/5 good' in line)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions """ trans, rot, t = get_chpi_positions(pos_fname) with warnings.catch_warnings(record=True): raw = Raw(raw_fif_fname, allow_maxshield=True, preload=True) t -= raw.first_samp / raw.info['sfreq'] trans_est, rot_est, t_est = _calculate_chpi_positions(raw, verbose='debug') _compare_positions((trans, rot, t), (trans_est, rot_est, t_est)) # degenerate conditions raw_no_chpi = Raw(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1., copy=False) with catch_logging() as log_file: _calculate_chpi_positions(raw_bad) for line in log_file.getvalue().split('\n')[:-1]: assert_true('0/5 acceptable' in line)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions """ trans, rot, t = head_pos_to_trans_rot_t(read_head_pos(pos_fname)) raw = Raw(chpi_fif_fname, allow_maxshield='yes', preload=True) t -= raw.first_samp / raw.info['sfreq'] quats = _calculate_chpi_positions(raw, verbose='debug') trans_est, rot_est, t_est = head_pos_to_trans_rot_t(quats) _compare_positions((trans, rot, t), (trans_est, rot_est, t_est), 0.003) # degenerate conditions raw_no_chpi = Raw(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1., copy=False) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, verbose=True) # ignore HPI info header and [done] footer for line in log_file.getvalue().strip().split('\n')[4:-1]: assert_true('0/5 good' in line) # half the rate cuts off cHPI coils raw.resample(300., npad='auto') assert_raises_regex(RuntimeError, 'above the', _calculate_chpi_positions, raw)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions """ trans, rot, t = get_chpi_positions(pos_fname) with warnings.catch_warnings(record=True): raw = Raw(raw_fif_fname, allow_maxshield=True, preload=True) t -= raw.first_samp / raw.info['sfreq'] trans_est, rot_est, t_est = _calculate_chpi_positions(raw, verbose='debug') _compare_positions((trans, rot, t), (trans_est, rot_est, t_est)) # degenerate conditions raw_no_chpi = Raw(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1., copy=False) tempdir = _TempDir() log_file = op.join(tempdir, 'temp_log.txt') set_log_file(log_file, overwrite=True) try: _calculate_chpi_positions(raw_bad) finally: set_log_file() with open(log_file, 'r') as fid: for line in fid: assert_true('0/5 acceptable' in line)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions """ trans, rot, t = head_pos_to_trans_rot_t(read_head_pos(pos_fname)) raw = Raw(chpi_fif_fname, allow_maxshield="yes", preload=True) t -= raw.first_samp / raw.info["sfreq"] quats = _calculate_chpi_positions(raw, verbose="debug") trans_est, rot_est, t_est = head_pos_to_trans_rot_t(quats) _compare_positions((trans, rot, t), (trans_est, rot_est, t_est), 0.003) # degenerate conditions raw_no_chpi = Raw(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info["dig"]: if d["kind"] == FIFF.FIFFV_POINT_HPI: d["coord_frame"] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info["dig"]: if d["kind"] == FIFF.FIFFV_POINT_HPI: d["r"] = np.ones(3) raw_bad.crop(0, 1.0, copy=False) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, verbose=True) # ignore HPI info header and [done] footer for line in log_file.getvalue().strip().split("\n")[4:-1]: assert_true("0/5 good" in line) # half the rate cuts off cHPI coils with warnings.catch_warnings(record=True): # uint cast suggestion raw.resample(300.0, npad="auto") assert_raises_regex(RuntimeError, "above the", _calculate_chpi_positions, raw)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions.""" trans, rot, t = head_pos_to_trans_rot_t(read_head_pos(pos_fname)) raw = read_raw_fif(chpi_fif_fname, allow_maxshield='yes', preload=True, add_eeg_ref=False) t -= raw.first_samp / raw.info['sfreq'] quats = _calculate_chpi_positions(raw, verbose='debug') trans_est, rot_est, t_est = head_pos_to_trans_rot_t(quats) _compare_positions((trans, rot, t), (trans_est, rot_est, t_est), 0.003) # degenerate conditions raw_no_chpi = read_raw_fif(test_fif_fname, add_eeg_ref=False) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1., copy=False) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, verbose=True) # ignore HPI info header and [done] footer assert_true('0/5 good' in log_file.getvalue().strip().split('\n')[-2]) # half the rate cuts off cHPI coils with warnings.catch_warnings(record=True): # uint cast suggestion raw.resample(300., npad='auto') assert_raises_regex(RuntimeError, 'above the', _calculate_chpi_positions, raw)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions.""" # Check to make sure our fits match MF decently mf_quats = read_head_pos(pos_fname) raw = read_raw_fif(chpi_fif_fname, allow_maxshield='yes', preload=True) # This is a little hack (aliasing while decimating) to make it much faster # for testing purposes only. We can relax this later if we find it breaks # something. raw_dec = _decimate_chpi(raw, 15) with catch_logging() as log: py_quats = _calculate_chpi_positions(raw_dec, t_step_max=1., verbose='debug') assert_true(log.getvalue().startswith('HPIFIT')) _assert_quats(py_quats, mf_quats, dist_tol=0.004, angle_tol=2.5) # degenerate conditions raw_no_chpi = read_raw_fif(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() del raw_bad.info['hpi_meas'][0]['hpi_coils'][0]['coil_freq'] assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = FIFF.FIFFV_COORD_UNKNOWN break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = FIFF.FIFFV_COORD_HEAD d['r'] = np.ones(3) raw_bad.crop(0, 1.) picks = np.concatenate([ np.arange(306, len(raw_bad.ch_names)), pick_types(raw_bad.info, meg=True)[::16] ]) raw_bad.pick_channels([raw_bad.ch_names[pick] for pick in picks]) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, t_step_min=1., verbose=True) # ignore HPI info header and [done] footer assert_true('0/5 good' in log_file.getvalue().strip().split('\n')[-2]) # half the rate cuts off cHPI coils raw.info['lowpass'] /= 2. assert_raises_regex(RuntimeError, 'above the', _calculate_chpi_positions, raw) # test on 5k artemis data raw = read_raw_artemis123(art_fname, preload=True) mf_quats = read_head_pos(art_mc_fname) with catch_logging() as log: py_quats = _calculate_chpi_positions(raw, t_step_min=2., verbose='debug') _assert_quats(py_quats, mf_quats, dist_tol=0.004, angle_tol=2.5)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions.""" # Check to make sure our fits match MF decently mf_quats = read_head_pos(pos_fname) raw = read_raw_fif(chpi_fif_fname, allow_maxshield='yes', preload=True) # This is a little hack (aliasing while decimating) to make it much faster # for testing purposes only. We can relax this later if we find it breaks # something. raw_dec = _decimate_chpi(raw, 15) with catch_logging() as log: py_quats = _calculate_chpi_positions(raw_dec, t_step_max=1., verbose='debug') assert_true(log.getvalue().startswith('HPIFIT')) _assert_quats(py_quats, mf_quats, dist_tol=0.004, angle_tol=2.5) # degenerate conditions raw_no_chpi = read_raw_fif(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() del raw_bad.info['hpi_meas'][0]['hpi_coils'][0]['coil_freq'] assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = FIFF.FIFFV_COORD_UNKNOWN break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = FIFF.FIFFV_COORD_HEAD d['r'] = np.ones(3) raw_bad.crop(0, 1.) picks = np.concatenate([np.arange(306, len(raw_bad.ch_names)), pick_types(raw_bad.info, meg=True)[::16]]) raw_bad.pick_channels([raw_bad.ch_names[pick] for pick in picks]) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, t_step_min=1., verbose=True) # ignore HPI info header and [done] footer assert_true('0/5 good' in log_file.getvalue().strip().split('\n')[-2]) # half the rate cuts off cHPI coils raw.info['lowpass'] /= 2. assert_raises_regex(RuntimeError, 'above the', _calculate_chpi_positions, raw) # test on 5k artemis data raw = read_raw_artemis123(art_fname, preload=True) mf_quats = read_head_pos(art_mc_fname) with catch_logging() as log: py_quats = _calculate_chpi_positions(raw, t_step_min=2., verbose='debug') _assert_quats(py_quats, mf_quats, dist_tol=0.004, angle_tol=2.5)
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI""" with warnings.catch_warnings(record=True): # MaxShield raw = Raw(raw_chpi_fname, allow_maxshield=True) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000.,) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname) # test that the cHPI signals make some reasonable values psd_sim, freqs_sim = compute_raw_psd(raw_sim) psd_chpi, freqs_chpi = compute_raw_psd(raw_chpi) assert_array_equal(freqs_sim, freqs_chpi) hpi_freqs = _get_hpi_info(raw.info)[0] freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) assert_allclose(psd_sim[picks_eeg], psd_chpi[picks_eeg], atol=1e-20) assert_true((psd_chpi[picks_meg][:, freq_idx] > 100 * psd_sim[picks_meg][:, freq_idx]).all()) # test localization based on cHPI information trans_sim, rot_sim, t_sim = _calculate_chpi_positions(raw_chpi) trans, rot, t = get_chpi_positions(pos_fname) t -= raw.first_samp / raw.info['sfreq'] _compare_positions((trans, rot, t), (trans_sim, rot_sim, t_sim), max_dist=0.005)
def process_raw(raw_fname): raw = read_raw_fif(raw_fname, preload=True, allow_maxshield='yes') head_pos = _calculate_chpi_positions(raw=raw) raw = mne.chpi.filter_chpi(raw) raw.fix_mag_coil_types() raw_sss = maxwell_filter(raw, head_pos=head_pos, st_duration=300) raw_sss.save(raw_fname[:-4] + '_sss.fif') return raw, head_pos
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI.""" raw = read_raw_fif(raw_chpi_fname, allow_maxshield='yes') picks = np.arange(len(raw.ch_names)) picks = np.setdiff1d(picks, pick_types(raw.info, meg=True, eeg=True)[::4]) raw.load_data().pick_channels([raw.ch_names[pick] for pick in picks]) raw.info.normalize_proj() sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000., ) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False, interp='zero', use_cps=True) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname, interp='zero', use_cps=True) # test cHPI indication hpi_freqs, hpi_pick, hpi_ons = _get_hpi_info(raw.info) assert_allclose(raw_sim[hpi_pick][0], 0.) assert_allclose(raw_chpi[hpi_pick][0], hpi_ons.sum()) # test that the cHPI signals make some reasonable values picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) for picks in [picks_meg[:3], picks_eeg[:3]]: psd_sim, freqs_sim = psd_welch(raw_sim, picks=picks) psd_chpi, freqs_chpi = psd_welch(raw_chpi, picks=picks) assert_array_equal(freqs_sim, freqs_chpi) freq_idx = np.sort( [np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) if picks is picks_meg: assert_true( (psd_chpi[:, freq_idx] > 100 * psd_sim[:, freq_idx]).all()) else: assert_allclose(psd_sim, psd_chpi, atol=1e-20) # test localization based on cHPI information quats_sim = _calculate_chpi_positions(raw_chpi, t_step_min=10.) quats = read_head_pos(pos_fname) _assert_quats(quats, quats_sim, dist_tol=5e-3, angle_tol=3.5)
def test_calculate_chpi_positions_on_chpi5_in_shorter_steps(): """Comparing estimated cHPI positions with MF results (smaller steps).""" # Check to make sure our fits match MF decently mf_quats = read_head_pos(chpi5_pos_fname) raw = read_raw_fif(chpi5_fif_fname, allow_maxshield='yes') raw = _decimate_chpi(raw.crop(0., 15.).load_data(), decim=8) py_quats = _calculate_chpi_positions(raw, t_step_min=0.1, t_step_max=0.1, t_window=0.1, verbose='debug') # needs interpolation, tolerance must be increased _assert_quats(py_quats, mf_quats, dist_tol=0.001, angle_tol=0.6)
def test_calculate_chpi_positions_on_chpi5_in_one_second_steps(): """Comparing estimated cHPI positions with MF results (one second).""" # Check to make sure our fits match MF decently mf_quats = read_head_pos(chpi5_pos_fname) raw = read_raw_fif(chpi5_fif_fname, allow_maxshield='yes') # the last two seconds contain a maxfilter problem! # fiff file timing: 26. to 43. seconds # maxfilter estimates a wrong head position for interval 16: 41.-42. sec raw = _decimate_chpi(raw.crop(0., 15.).load_data(), decim=8) # needs no interpolation, because maxfilter pos files comes with 1 s steps py_quats = _calculate_chpi_positions(raw, t_step_min=1.0, t_step_max=1.0, t_window=1.0, verbose='debug') _assert_quats(py_quats, mf_quats, dist_tol=0.0008, angle_tol=.5)
def test_calculate_chpi_positions(): """Test calculation of cHPI positions.""" # Check to make sure our fits match MF decently mf_quats = read_head_pos(pos_fname) raw = read_raw_fif(chpi_fif_fname, allow_maxshield='yes', preload=True) # This is a little hack (aliasing while decimating) to make it much faster # for testing purposes only. We can relax this later if we find it breaks # something. raw_dec = _decimate_chpi(raw, 15) with catch_logging() as log: py_quats = _calculate_chpi_positions(raw_dec, verbose='debug') assert_true(log.getvalue().startswith('HPIFIT')) _assert_quats(py_quats, mf_quats, dist_tol=0.004, angle_tol=2.5) # degenerate conditions raw_no_chpi = read_raw_fif(test_fif_fname) assert_raises(RuntimeError, _calculate_chpi_positions, raw_no_chpi) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['coord_frame'] = 999 break assert_raises(RuntimeError, _calculate_chpi_positions, raw_bad) raw_bad = raw.copy() for d in raw_bad.info['dig']: if d['kind'] == FIFF.FIFFV_POINT_HPI: d['r'] = np.ones(3) raw_bad.crop(0, 1.) with warnings.catch_warnings(record=True): # bad pos with catch_logging() as log_file: _calculate_chpi_positions(raw_bad, t_step_min=5., verbose=True) # ignore HPI info header and [done] footer assert_true('0/5 good' in log_file.getvalue().strip().split('\n')[-2]) # half the rate cuts off cHPI coils raw.info['lowpass'] /= 2. assert_raises_regex(RuntimeError, 'above the', _calculate_chpi_positions, raw)
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI""" with warnings.catch_warnings(record=True): # MaxShield raw = Raw(raw_chpi_fname, allow_maxshield=True) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000., ) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname) # test cHPI indication hpi_freqs, _, hpi_pick, hpi_on, _ = _get_hpi_info(raw.info) assert_allclose(raw_sim[hpi_pick][0], 0.) assert_allclose(raw_chpi[hpi_pick][0], hpi_on) # test that the cHPI signals make some reasonable values picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) for picks in [picks_meg, picks_eeg]: psd_sim, freqs_sim = psd_welch(raw_sim, picks=picks) psd_chpi, freqs_chpi = psd_welch(raw_chpi, picks=picks) assert_array_equal(freqs_sim, freqs_chpi) freq_idx = np.sort( [np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) if picks is picks_meg: assert_true( (psd_chpi[:, freq_idx] > 100 * psd_sim[:, freq_idx]).all()) else: assert_allclose(psd_sim, psd_chpi, atol=1e-20) # test localization based on cHPI information trans_sim, rot_sim, t_sim = _calculate_chpi_positions(raw_chpi) trans, rot, t = get_chpi_positions(pos_fname) t -= raw.first_samp / raw.info['sfreq'] _compare_positions((trans, rot, t), (trans_sim, rot_sim, t_sim), max_dist=0.005)
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI.""" raw = read_raw_fif(raw_chpi_fname, allow_maxshield='yes') picks = np.arange(len(raw.ch_names)) picks = np.setdiff1d(picks, pick_types(raw.info, meg=True, eeg=True)[::4]) raw.load_data().pick_channels([raw.ch_names[pick] for pick in picks]) raw.info.normalize_proj() sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000.,) src = setup_volume_source_space(sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, head_pos=pos_fname, interp='zero') # need to trim extra samples off this one with pytest.deprecated_call(): raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname, interp='zero') # test cHPI indication hpi_freqs, hpi_pick, hpi_ons = _get_hpi_info(raw.info) assert_allclose(raw_sim[hpi_pick][0], 0.) assert_allclose(raw_chpi[hpi_pick][0], hpi_ons.sum()) # test that the cHPI signals make some reasonable values picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) for picks in [picks_meg[:3], picks_eeg[:3]]: psd_sim, freqs_sim = psd_welch(raw_sim, picks=picks) psd_chpi, freqs_chpi = psd_welch(raw_chpi, picks=picks) assert_array_equal(freqs_sim, freqs_chpi) freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) if picks is picks_meg: assert (psd_chpi[:, freq_idx] > 100 * psd_sim[:, freq_idx]).all() else: assert_allclose(psd_sim, psd_chpi, atol=1e-20) # test localization based on cHPI information quats_sim = _calculate_chpi_positions(raw_chpi, t_step_min=10.) quats = read_head_pos(pos_fname) _assert_quats(quats, quats_sim, dist_tol=5e-3, angle_tol=3.5)
def test_simulate_raw_chpi(): """Test simulation of raw data with cHPI.""" raw = read_raw_fif(raw_chpi_fname, allow_maxshield='yes', add_eeg_ref=False) sphere = make_sphere_model('auto', 'auto', raw.info) # make sparse spherical source space sphere_vol = tuple(sphere['r0'] * 1000.) + (sphere.radius * 1000.,) src = setup_volume_source_space('sample', sphere=sphere_vol, pos=70.) stc = _make_stc(raw, src) # simulate data with cHPI on raw_sim = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=False) # need to trim extra samples off this one raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True, head_pos=pos_fname) # test cHPI indication hpi_freqs, _, hpi_pick, hpi_ons = _get_hpi_info(raw.info)[:4] assert_allclose(raw_sim[hpi_pick][0], 0.) assert_allclose(raw_chpi[hpi_pick][0], hpi_ons.sum()) # test that the cHPI signals make some reasonable values picks_meg = pick_types(raw.info, meg=True, eeg=False) picks_eeg = pick_types(raw.info, meg=False, eeg=True) for picks in [picks_meg, picks_eeg]: psd_sim, freqs_sim = psd_welch(raw_sim, picks=picks) psd_chpi, freqs_chpi = psd_welch(raw_chpi, picks=picks) assert_array_equal(freqs_sim, freqs_chpi) freq_idx = np.sort([np.argmin(np.abs(freqs_sim - f)) for f in hpi_freqs]) if picks is picks_meg: assert_true((psd_chpi[:, freq_idx] > 100 * psd_sim[:, freq_idx]).all()) else: assert_allclose(psd_sim, psd_chpi, atol=1e-20) # test localization based on cHPI information quats_sim = _calculate_chpi_positions(raw_chpi) trans_sim, rot_sim, t_sim = head_pos_to_trans_rot_t(quats_sim) trans, rot, t = head_pos_to_trans_rot_t(read_head_pos(pos_fname)) t -= raw.first_samp / raw.info['sfreq'] _compare_positions((trans, rot, t), (trans_sim, rot_sim, t_sim), max_dist=0.005)
def test_simulate_calculate_chpi_positions(): """Test calculation of cHPI positions with simulated data.""" # Read info dict from raw FIF file info = read_info(raw_fname) # Tune the info structure chpi_channel = u'STI201' ncoil = len(info['hpi_results'][0]['order']) coil_freq = 10 + np.arange(ncoil) * 5 hpi_subsystem = {'event_channel': chpi_channel, 'hpi_coils': [{'event_bits': np.array([256, 0, 256, 256], dtype=np.int32)}, {'event_bits': np.array([512, 0, 512, 512], dtype=np.int32)}, {'event_bits': np.array([1024, 0, 1024, 1024], dtype=np.int32)}, {'event_bits': np.array([2048, 0, 2048, 2048], dtype=np.int32)}], 'ncoil': ncoil} info['hpi_subsystem'] = hpi_subsystem for l, freq in enumerate(coil_freq): info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[]) info['sfreq'] = 100. # this will speed it up a lot info = pick_info(info, picks) info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201' info._update_redundant() info['projs'] = [] info_trans = info['dev_head_t']['trans'].copy() dev_head_pos_ini = np.concatenate([rot_to_quat(info_trans[:3, :3]), info_trans[:3, 3]]) ez = np.array([0, 0, 1]) # Unit vector in z-direction of head coordinates # Define some constants duration = 30 # Time / s # Quotient of head position sampling frequency # and raw sampling frequency head_pos_sfreq_quotient = 0.1 # Round number of head positions to the next integer S = int(duration / (info['sfreq'] * head_pos_sfreq_quotient)) dz = 0.001 # Shift in z-direction is 0.1mm for each step dev_head_pos = np.zeros((S, 10)) dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient dev_head_pos[:, 1:4] = dev_head_pos_ini[:3] dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \ np.outer(np.arange(S) * dz, ez) dev_head_pos[:, 7] = 1.0 # cm/s dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient) # Round number of samples to the next integer raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5))) raw = RawArray(raw_data, info) dip = Dipole(np.array([0.0, 0.1, 0.2]), np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]), np.array([1e-9, 1e-9, 1e-9]), np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]), np.array([1.0, 1.0, 1.0]), 'dip') sphere = make_sphere_model('auto', 'auto', info=info, relative_radii=(1.0, 0.9), sigmas=(0.33, 0.3)) fwd, stc = make_forward_dipole(dip, sphere, info) stc.resample(info['sfreq']) raw = simulate_raw(raw, stc, None, fwd['src'], sphere, cov=None, blink=False, ecg=False, chpi=True, head_pos=dev_head_pos, mindist=1.0, interp='zero', verbose=None, use_cps=True) quats = _calculate_chpi_positions( raw, t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient, t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient, t_window=1.0) _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)
# ############################################################################ # Simulate data # Simulate data with movement with warnings.catch_warnings(record=True): raw = Raw(fname_raw, allow_maxshield=True) raw_movement = simulate_raw(raw, stc, trans, src, bem, chpi=True, head_pos=fname_pos_orig, n_jobs=6, verbose=True) # Simulate data with no movement (use initial head position) raw_stationary = simulate_raw(raw, stc, trans, src, bem, chpi=True, n_jobs=6, verbose=True) # Extract positions trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig) t_orig -= raw.first_samp / raw.info["sfreq"] trans_move, rot_move, t_move = _calculate_chpi_positions(raw_movement) trans_stat, rot_stat, t_stat = _calculate_chpi_positions(raw_stationary) # ############################################################################ # Let's look at the results, just translation for simplicity axes = "XYZ" fig = plt.figure(dpi=200) ts = [t_orig, t_stat, t_move] transs = [trans_orig, trans_stat, trans_move] labels = ["original", "stationary", "simulated"] sizes = [10, 5, 5] colors = "kyr" for ai, axis in enumerate(axes): ax = plt.subplot(3, 1, ai + 1) lines = []
def test_simulate_calculate_chpi_positions(): """Test calculation of cHPI positions with simulated data.""" # Read info dict from raw FIF file info = read_info(raw_fname) # Tune the info structure chpi_channel = u'STI201' ncoil = len(info['hpi_results'][0]['order']) coil_freq = 10 + np.arange(ncoil) * 5 hpi_subsystem = {'event_channel': chpi_channel, 'hpi_coils': [{'event_bits': np.array([256, 0, 256, 256], dtype=np.int32)}, {'event_bits': np.array([512, 0, 512, 512], dtype=np.int32)}, {'event_bits': np.array([1024, 0, 1024, 1024], dtype=np.int32)}, {'event_bits': np.array([2048, 0, 2048, 2048], dtype=np.int32)}], 'ncoil': ncoil} info['hpi_subsystem'] = hpi_subsystem for l, freq in enumerate(coil_freq): info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[]) info['sfreq'] = 100. # this will speed it up a lot info = pick_info(info, picks) info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201' info._update_redundant() info['projs'] = [] info_trans = info['dev_head_t']['trans'].copy() dev_head_pos_ini = np.concatenate([rot_to_quat(info_trans[:3, :3]), info_trans[:3, 3]]) ez = np.array([0, 0, 1]) # Unit vector in z-direction of head coordinates # Define some constants duration = 10 # Time / s # Quotient of head position sampling frequency # and raw sampling frequency head_pos_sfreq_quotient = 0.01 # Round number of head positions to the next integer S = int(duration * info['sfreq'] * head_pos_sfreq_quotient) assert S == 10 dz = 0.001 # Shift in z-direction is 0.1mm for each step dev_head_pos = np.zeros((S, 10)) dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient dev_head_pos[:, 1:4] = dev_head_pos_ini[:3] dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \ np.outer(np.arange(S) * dz, ez) dev_head_pos[:, 7] = 1.0 # cm/s dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient) # Round number of samples to the next integer raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5))) raw = RawArray(raw_data, info) add_chpi(raw, dev_head_pos) quats = _calculate_chpi_positions( raw, t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient, t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient, t_window=1.0) _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)
verbose=True) # Simulate data with no movement (use initial head position) raw_stationary = simulate_raw(raw, stc, trans, src, bem, chpi=True, n_jobs=6, verbose=True) # Extract positions trans_orig, rot_orig, t_orig = get_chpi_positions(fname_pos_orig) t_orig -= raw.first_samp / raw.info['sfreq'] trans_move, rot_move, t_move = _calculate_chpi_positions(raw_movement) trans_stat, rot_stat, t_stat = _calculate_chpi_positions(raw_stationary) # ############################################################################ # Let's look at the results, just translation for simplicity axes = 'XYZ' fig = plt.figure(dpi=200) ts = [t_orig, t_stat, t_move] transs = [trans_orig, trans_stat, trans_move] labels = ['original', 'stationary', 'simulated'] sizes = [10, 5, 5] colors = 'kyr' for ai, axis in enumerate(axes): ax = plt.subplot(3, 1, ai + 1) lines = []
def test_simulate_calculate_chpi_positions(): """Test calculation of cHPI positions with simulated data.""" # Read info dict from raw FIF file info = read_info(raw_fname) # Tune the info structure chpi_channel = u'STI201' ncoil = len(info['hpi_results'][0]['order']) coil_freq = 10 + np.arange(ncoil) * 5 hpi_subsystem = { 'event_channel': chpi_channel, 'hpi_coils': [{ 'event_bits': np.array([256, 0, 256, 256], dtype=np.int32) }, { 'event_bits': np.array([512, 0, 512, 512], dtype=np.int32) }, { 'event_bits': np.array([1024, 0, 1024, 1024], dtype=np.int32) }, { 'event_bits': np.array([2048, 0, 2048, 2048], dtype=np.int32) }], 'ncoil': ncoil } info['hpi_subsystem'] = hpi_subsystem for l, freq in enumerate(coil_freq): info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[]) info['sfreq'] = 100. # this will speed it up a lot info = pick_info(info, picks) info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201' info._update_redundant() info['projs'] = [] info_trans = info['dev_head_t']['trans'].copy() dev_head_pos_ini = np.concatenate( [rot_to_quat(info_trans[:3, :3]), info_trans[:3, 3]]) ez = np.array([0, 0, 1]) # Unit vector in z-direction of head coordinates # Define some constants duration = 10 # Time / s # Quotient of head position sampling frequency # and raw sampling frequency head_pos_sfreq_quotient = 0.01 # Round number of head positions to the next integer S = int(duration * info['sfreq'] * head_pos_sfreq_quotient) assert S == 10 dz = 0.001 # Shift in z-direction is 0.1mm for each step dev_head_pos = np.zeros((S, 10)) dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient dev_head_pos[:, 1:4] = dev_head_pos_ini[:3] dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \ np.outer(np.arange(S) * dz, ez) dev_head_pos[:, 7] = 1.0 # cm/s dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient) # Round number of samples to the next integer raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5))) raw = RawArray(raw_data, info) add_chpi(raw, dev_head_pos) quats = _calculate_chpi_positions( raw, t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient, t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient, t_window=1.0) _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)
def test_simulate_calculate_chpi_positions(): """Test calculation of cHPI positions with simulated data.""" # Read info dict from raw FIF file info = read_info(raw_fname) # Tune the info structure chpi_channel = u'STI201' ncoil = len(info['hpi_results'][0]['order']) coil_freq = 10 + np.arange(ncoil) * 5 hpi_subsystem = { 'event_channel': chpi_channel, 'hpi_coils': [{ 'event_bits': np.array([256, 0, 256, 256], dtype=np.int32) }, { 'event_bits': np.array([512, 0, 512, 512], dtype=np.int32) }, { 'event_bits': np.array([1024, 0, 1024, 1024], dtype=np.int32) }, { 'event_bits': np.array([2048, 0, 2048, 2048], dtype=np.int32) }], 'ncoil': ncoil } info['hpi_subsystem'] = hpi_subsystem for l, freq in enumerate(coil_freq): info['hpi_meas'][0]['hpi_coils'][l]['coil_freq'] = freq picks = pick_types(info, meg=True, stim=True, eeg=False, exclude=[]) info['sfreq'] = 100. # this will speed it up a lot info = pick_info(info, picks) info['chs'][info['ch_names'].index('STI 001')]['ch_name'] = 'STI201' info._update_redundant() info['projs'] = [] info_trans = info['dev_head_t']['trans'].copy() dev_head_pos_ini = np.concatenate( [rot_to_quat(info_trans[:3, :3]), info_trans[:3, 3]]) ez = np.array([0, 0, 1]) # Unit vector in z-direction of head coordinates # Define some constants duration = 30 # Time / s # Quotient of head position sampling frequency # and raw sampling frequency head_pos_sfreq_quotient = 0.1 # Round number of head positions to the next integer S = int(duration / (info['sfreq'] * head_pos_sfreq_quotient)) dz = 0.001 # Shift in z-direction is 0.1mm for each step dev_head_pos = np.zeros((S, 10)) dev_head_pos[:, 0] = np.arange(S) * info['sfreq'] * head_pos_sfreq_quotient dev_head_pos[:, 1:4] = dev_head_pos_ini[:3] dev_head_pos[:, 4:7] = dev_head_pos_ini[3:] + \ np.outer(np.arange(S) * dz, ez) dev_head_pos[:, 7] = 1.0 # cm/s dev_head_pos[:, 9] = 100 * dz / (info['sfreq'] * head_pos_sfreq_quotient) # Round number of samples to the next integer raw_data = np.zeros((len(picks), int(duration * info['sfreq'] + 0.5))) raw = RawArray(raw_data, info) dip = Dipole(np.array([0.0, 0.1, 0.2]), np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]), np.array([1e-9, 1e-9, 1e-9]), np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]), np.array([1.0, 1.0, 1.0]), 'dip') sphere = make_sphere_model('auto', 'auto', info=info, relative_radii=(1.0, 0.9), sigmas=(0.33, 0.3)) fwd, stc = make_forward_dipole(dip, sphere, info) stc.resample(info['sfreq']) raw = simulate_raw(raw, stc, None, fwd['src'], sphere, cov=None, blink=False, ecg=False, chpi=True, head_pos=dev_head_pos, mindist=1.0, interp='zero', verbose=None) quats = _calculate_chpi_positions( raw, t_step_min=raw.info['sfreq'] * head_pos_sfreq_quotient, t_step_max=raw.info['sfreq'] * head_pos_sfreq_quotient, t_window=1.0) _assert_quats(quats, dev_head_pos, dist_tol=0.001, angle_tol=1.)