def test_simulation_cascade(): """Test that cascading operations do not overwrite data.""" # Create 10 second raw dataset with zeros in the data matrix raw_null = read_raw_fif(raw_chpi_fname, allow_maxshield='yes') raw_null.crop(0, 1).pick_types(meg=True).load_data() raw_null.apply_function(lambda x: np.zeros_like(x)) assert_array_equal(raw_null.get_data(), 0.) # Calculate independent signal additions raw_eog = raw_null.copy() add_eog(raw_eog, random_state=0) raw_ecg = raw_null.copy() add_ecg(raw_ecg, random_state=0) raw_noise = raw_null.copy() cov = make_ad_hoc_cov(raw_null.info) add_noise(raw_noise, cov, random_state=0) raw_chpi = raw_null.copy() add_chpi(raw_chpi) # Calculate Cascading signal additions raw_cascade = raw_null.copy() add_eog(raw_cascade, random_state=0) add_ecg(raw_cascade, random_state=0) add_chpi(raw_cascade) add_noise(raw_cascade, cov, random_state=0) cascade_data = raw_cascade.get_data() serial_data = 0. for raw_other in (raw_eog, raw_ecg, raw_noise, raw_chpi): serial_data += raw_other.get_data() assert_allclose(cascade_data, serial_data, atol=1e-20)
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']) + (sphere.radius, ) src = setup_volume_source_space(sphere=sphere_vol, pos=70., sphere_units='m') stcs = [_make_stc(raw, src)] * 15 # simulate data with cHPI on raw_sim = simulate_raw(raw.info, stcs, None, src, sphere, head_pos=pos_fname, interp='zero', first_samp=raw.first_samp) # need to trim extra samples off this one raw_chpi = add_chpi(raw_sim.copy(), 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 chpi_amplitudes = compute_chpi_amplitudes(raw, t_step_min=10.) coil_locs = compute_chpi_locs(raw.info, chpi_amplitudes) quats_sim = compute_head_pos(raw_chpi.info, coil_locs) quats = read_head_pos(pos_fname) _assert_quats(quats, quats_sim, dist_tol=5e-3, angle_tol=3.5, vel_atol=0.03) # velicity huge because of t_step_min above
def test_simulate_calculate_head_pos_chpi(): """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 # m/s dev_head_pos[:, 9] = 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., vel_atol=4e-3) # 4 mm/s
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.)