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 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) raw_chpi = simulate_raw(raw, stc, None, src, sphere, cov=None, chpi=True) # XXX we need to test that the cHPI signals are actually in the correct # place, but that should be a subsequent enhancement (not trivial to do so) 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 = np.array([x['custom_ref'][0] for x in raw.info['hpi_meas'][0]['hpi_coils']]) 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]) assert_true((psd_chpi[picks_meg][:, freq_idx] > 100 * psd_sim[picks_meg][:, freq_idx]).all())
def test_simulate_raw_bem(): """Test simulation of raw data with BEM""" seed = 42 raw, src, stc, trans, sphere = _get_data() raw_sim_sph = simulate_raw(raw, stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_bem = simulate_raw(raw, stc, trans, src, bem_fname, cov=None, ecg=True, blink=True, random_state=seed, n_jobs=2) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) assert_true(np.median(np.diag(corr[:n_ch, -n_ch:])) > 0.9)
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_simulate_raw_bem(raw_data): """Test simulation of raw data with BEM.""" raw, src, stc, trans, sphere = raw_data src = setup_source_space('sample', 'oct1', subjects_dir=subjects_dir) for s in src: s['nuse'] = 3 s['vertno'] = src[1]['vertno'][:3] s['inuse'].fill(0) s['inuse'][s['vertno']] = 1 # use different / more complete STC here vertices = [s['vertno'] for s in src] stc = SourceEstimate(np.eye(sum(len(v) for v in vertices)), vertices, 0, 1. / raw.info['sfreq']) with pytest.deprecated_call(): raw_sim_sph = simulate_raw(raw, stc, trans, src, sphere, cov=None, verbose=True) with pytest.deprecated_call(): raw_sim_bem = simulate_raw(raw, stc, trans, src, bem_fname, cov=None, n_jobs=2) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) med_corr = np.median(np.diag(corr[:n_ch, -n_ch:])) assert med_corr > 0.65 # do some round-trip localization for s in src: transform_surface_to(s, 'head', trans) locs = np.concatenate([s['rr'][s['vertno']] for s in src]) tmax = (len(locs) - 1) / raw.info['sfreq'] cov = make_ad_hoc_cov(raw.info) # The tolerance for the BEM is surprisingly high (28) but I get the same # result when using MNE-C and Xfit, even when using a proper 5120 BEM :( for use_raw, bem, tol in ((raw_sim_sph, sphere, 2), (raw_sim_bem, bem_fname, 31)): events = find_events(use_raw, 'STI 014') assert len(locs) == 6 evoked = Epochs(use_raw, events, 1, 0, tmax, baseline=None).average() assert len(evoked.times) == len(locs) fits = fit_dipole(evoked, cov, bem, trans, min_dist=1.)[0].pos diffs = np.sqrt(np.sum((locs - fits)**2, axis=-1)) * 1000 med_diff = np.median(diffs) assert med_diff < tol, '%s: %s' % (bem, med_diff)
def test_simulate_round_trip(): """Test simulate_raw round trip calculations.""" # Check a diagonal round-trip raw, src, stc, trans, sphere = _get_data() raw.pick_types(meg=True, stim=True) bem = read_bem_solution(bem_1_fname) old_bem = bem.copy() old_src = src.copy() old_trans = trans.copy() fwd = make_forward_solution(raw.info, trans, src, bem) # no omissions assert (sum(len(s['vertno']) for s in src) == sum(len(s['vertno']) for s in fwd['src']) == 36) # make sure things were not modified assert ( old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) data = np.eye(fwd['nsource']) raw.crop(0, (len(data) - 1) / raw.info['sfreq']) stc = SourceEstimate(data, [s['vertno'] for s in fwd['src']], 0, 1. / raw.info['sfreq']) for use_fwd in (None, fwd): if use_fwd is None: use_trans, use_src, use_bem = trans, src, bem else: use_trans = use_src = use_bem = None for use_cps in (False, True): this_raw = simulate_raw(raw, stc, use_trans, use_src, use_bem, cov=None, use_cps=use_cps, forward=use_fwd) this_raw.pick_types(meg=True, eeg=True) assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0] ['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) this_fwd = convert_forward_solution(fwd, force_fixed=True, use_cps=use_cps) assert_allclose(this_raw[:][0], this_fwd['sol']['data'], atol=1e-12, rtol=1e-6) with pytest.raises(ValueError, match='If forward is not None then'): simulate_raw(raw, stc, trans, src, bem, forward=fwd) fwd['info']['dev_head_t']['trans'][0, 0] = 1. with pytest.raises(ValueError, match='dev_head_t.*does not match'): simulate_raw(raw, stc, None, None, None, forward=fwd)
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_bem(): """Test simulation of raw data with BEM""" seed = 42 raw, src, stc, trans, sphere = _get_data() raw_sim_sph = simulate_raw(raw, stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_bem = simulate_raw( raw, stc, trans, src, bem_fname, cov=None, ecg=True, blink=True, random_state=seed, n_jobs=2 ) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) assert_true(np.median(np.diag(corr[:n_ch, -n_ch:])) > 0.9)
def test_simulate_round_trip(): """Test simulate_raw round trip calculations.""" # Check a diagonal round-trip raw, src, stc, trans, sphere = _get_data() raw.pick_types(meg=True, stim=True) bem = read_bem_solution(bem_1_fname) old_bem = bem.copy() old_src = src.copy() old_trans = trans.copy() fwd = make_forward_solution(raw.info, trans, src, bem) # no omissions assert (sum(len(s['vertno']) for s in src) == sum(len(s['vertno']) for s in fwd['src']) == 36) # make sure things were not modified assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) data = np.eye(fwd['nsource']) raw.crop(0, (len(data) - 1) / raw.info['sfreq']) stc = SourceEstimate(data, [s['vertno'] for s in fwd['src']], 0, 1. / raw.info['sfreq']) for use_cps in (False, True): this_raw = simulate_raw(raw, stc, trans, src, bem, cov=None, use_cps=use_cps) this_raw.pick_types(meg=True, eeg=True) assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) this_fwd = convert_forward_solution(fwd, force_fixed=True, use_cps=use_cps) assert_allclose(this_raw[:][0], this_fwd['sol']['data'], atol=1e-12, rtol=1e-6)
def test_simulate_raw_bem(raw_data): """Test simulation of raw data with BEM.""" raw, src, stc, trans, sphere = raw_data src = setup_source_space('sample', 'oct1', subjects_dir=subjects_dir) for s in src: s['nuse'] = 3 s['vertno'] = src[1]['vertno'][:3] s['inuse'].fill(0) s['inuse'][s['vertno']] = 1 # use different / more complete STC here vertices = [s['vertno'] for s in src] stc = SourceEstimate(np.eye(sum(len(v) for v in vertices)), vertices, 0, 1. / raw.info['sfreq']) with pytest.deprecated_call(): raw_sim_sph = simulate_raw(raw, stc, trans, src, sphere, cov=None, verbose=True) with pytest.deprecated_call(): raw_sim_bem = simulate_raw(raw, stc, trans, src, bem_fname, cov=None, n_jobs=2) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) med_corr = np.median(np.diag(corr[:n_ch, -n_ch:])) assert med_corr > 0.65 # do some round-trip localization for s in src: transform_surface_to(s, 'head', trans) locs = np.concatenate([s['rr'][s['vertno']] for s in src]) tmax = (len(locs) - 1) / raw.info['sfreq'] cov = make_ad_hoc_cov(raw.info) # The tolerance for the BEM is surprisingly high (28) but I get the same # result when using MNE-C and Xfit, even when using a proper 5120 BEM :( for use_raw, bem, tol in ((raw_sim_sph, sphere, 2), (raw_sim_bem, bem_fname, 31)): events = find_events(use_raw, 'STI 014') assert len(locs) == 6 evoked = Epochs(use_raw, events, 1, 0, tmax, baseline=None).average() assert len(evoked.times) == len(locs) fits = fit_dipole(evoked, cov, bem, trans, min_dist=1.)[0].pos diffs = np.sqrt(np.sum((locs - fits) ** 2, axis=-1)) * 1000 med_diff = np.median(diffs) assert med_diff < tol, '%s: %s' % (bem, med_diff)
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 generate_combined_simulation(raw_fname, fwd, subject=None, subjects_dir=None, topdir=None, label_index=None, sine_amplitude=None, sine_frequency=None): """Create a combined dataset of simulated plus real data and save to the topdir/(subjid)_(AMP)_nAm_(HZ)_hz folder""" os.chdir(topdir) if label_index == None: print('Must provide a label index for simulation') exit(1) raw = mne.io.read_raw_fif(raw_fname) rng = np.random.RandomState(0) # random state (make reproducible) #Labels for simulation labels = mne.read_labels_from_annot(subject, subjects_dir=subjects_dir) labels_sim = [labels[label_index]] times = raw.times #[:int(raw.info['sfreq'] * epoch_duration)] src = fwd['src'] sig_generator = partial(data_fun, amplitude=sine_amplitude, freq=sine_frequency) stc = simulate_sparse_stc(src, n_dipoles=1, times=times, data_fun=sig_generator, labels=labels_sim, location='center', subjects_dir=subjects_dir) # Simulate raw data raw_sim = simulate_raw(raw.info, [stc] * 1, forward=fwd, verbose=True) #Load raw and save to outfolder raw.load_data() #Combine simulation w/raw comb_out_fname = '{}_{}_label_{}_nAm_{}_hz_meg.fif'.format( subject, str(label_index), sine_amplitude, sine_frequency) # comb_out_fname = op.join(outfolder, outfolder+'_meg.fif') combined = raw.copy() combined._data += raw_sim.get_data() combined.save(comb_out_fname) print('Saved {}'.format(comb_out_fname)) #Save stc for later use stc_out_fname = op.join('{}_{}_label_{}_nAm_{}_hz-stc.fif'.format( subject, str(label_index), sine_amplitude, sine_frequency)) stc.save(stc_out_fname)
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_chpi_info(raw.info, on_missing='raise') 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_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 gen_x_raw(n_trials, raw_template, stc_sim, s_dict): """Helper to simulate multiple trials of raw data""" scaled_cov = deepcopy(s_dict['inv']['noise_cov']) scaled_cov['data'] = scaled_cov['data'] * s_dict['noise_scale'] # XXX: blink rate: 9 to 21.5 blinks/min (higher than found experimentally) return simulate_raw(raw_template, stc_sim, s_dict['inv']['mri_head_t'], src=s_dict['inv']['src'], bem=s_dict['bem_fname'], cov=scaled_cov, blink=True, n_jobs=n_jobs, verbose=False)
def test_simulate_raw_sphere(raw_data, tmpdir): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = raw_data assert len(pick_types(raw.info, meg=False, ecg=True)) == 1 tempdir = str(tmpdir) # head pos head_pos_sim = _get_head_pos_sim(raw) # # Test raw simulation with basic parameters # raw.info.normalize_proj() cov = read_cov(cov_fname) cov['projs'] = raw.info['projs'] raw.info['bads'] = raw.ch_names[:1] with pytest.deprecated_call(match='cov is deprecated'): raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed, verbose=True) with pytest.warns(RuntimeWarning, match='applying projector with'): raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.raises(RuntimeError, match='Maximum number of STC iterations'): simulate_raw(raw.info, [stc] * 5, trans_fname, src_fname, sphere, cov=None, max_iter=1) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) std = dict(grad=2e-13, mag=10e-15, eeg=0.1e-6) with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, make_ad_hoc_cov(raw.info, std=std), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.deprecated_call(): raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov=std, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) sphere_norad = make_sphere_model('auto', None, raw.info) raw_meg = raw.copy().pick_types() with pytest.deprecated_call(): raw_sim = simulate_raw(raw_meg, stc, trans, src, sphere_norad, cov=None, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.deprecated_call(): raw_sim_2 = simulate_raw(raw_meg, stc, trans_fname, src_fname, sphere_norad, cov=None, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): with pytest.deprecated_call(): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) with pytest.deprecated_call(): raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert np.mean(close) > 0.7 far = ~np.isclose(raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert np.mean(far) > 0.99 del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only with pytest.deprecated_call(): raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None) for this_raw in (raw_sim_meg, raw_sim_eeg, raw_sim_meeg): add_eog(this_raw, random_state=seed) for this_raw in (raw_sim_meg, raw_sim_meeg): add_ecg(this_raw, random_state=seed) with pytest.raises(RuntimeError, match='only add ECG artifacts if MEG'): add_ecg(raw_sim_eeg) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that raw-as-info is supported n_samp = len(stc.times) raw_crop = raw.copy().crop(0., (n_samp - 1.) / raw.info['sfreq']) assert len(raw_crop.times) == len(stc.times) with pytest.deprecated_call(): raw_sim = simulate_raw(raw_crop, stc, trans, src, sphere, cov=None) with catch_logging() as log: raw_sim_2 = simulate_raw(raw_crop.info, stc, trans, src, sphere, cov=None, verbose=True) log = log.getvalue() assert '1 STC iteration provided' in log assert len(raw_sim_2.times) == n_samp assert_allclose(raw_sim[:, :n_samp][0], raw_sim_2[:, :n_samp][0], rtol=1e-5, atol=1e-30) del raw_sim, raw_sim_2 # check that different interpolations are similar given small movements with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='linear') with pytest.deprecated_call(): raw_sim_hann = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='hann') assert_allclose(raw_sim[:][0], raw_sim_hann[:][0], rtol=1e-1, atol=1e-14) del raw_sim, raw_sim_hann
np.intersect1d(l.vertices, s['vertno']) for l, s in zip(labels, src) ] data = np.zeros([sum(len(v) for v in vertices), int(raw.info['sfreq'])]) activation = np.hanning(int(raw.info['sfreq'] * 0.2)) * 1e-9 # nAm t_offset = int(np.ceil(0.2 * raw.info['sfreq'])) # 200 ms in (after baseline) data[:, t_offset:t_offset + len(activation)] = activation stc = mne.SourceEstimate(data, vertices, tmin=-0.2, tstep=1. / raw.info['sfreq']) # Simulate the movement raw = simulate_raw(raw, stc, trans_fname, src, bem_fname, head_pos=pos, interp='zero', n_jobs=-1) raw_stat = simulate_raw(raw, stc, trans_fname, src, bem_fname, head_pos=None, n_jobs=-1) # Save the results raw.save('simulated_movement_raw.fif', buffer_size_sec=1.) raw_stat.save('simulated_stationary_raw.fif', buffer_size_sec=1.) mne.chpi.write_head_quats('simulated_quats.pos', pos) stc.save('simulated_activation')
def test_simulate_raw_sphere(): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = _get_data() assert_true(len(pick_types(raw.info, meg=False, ecg=True)) == 1) # head pos head_pos_sim = dict() # these will be at 1., 2., ... sec shifts = [[0.001, 0., -0.001], [-0.001, 0.001, 0.]] for time_key, shift in enumerate(shifts): # Create 4x4 matrix transform and normalize temp_trans = deepcopy(raw.info['dev_head_t']) temp_trans['trans'][:3, 3] += shift head_pos_sim[time_key + 1.] = temp_trans['trans'] # # Test raw simulation with basic parameters # raw_sim = simulate_raw(raw, stc, trans, src, sphere, read_cov(cov_fname), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data tempdir = _TempDir() test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert_true(np.mean(close) > 0.7) far = ~np.isclose(raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert_true(np.mean(far) > 0.99) del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that different interpolations are similar given small movements raw_sim_cos = simulate_raw(raw, stc, trans, src, sphere, head_pos=head_pos_sim, random_state=seed) raw_sim_lin = simulate_raw(raw, stc, trans, src, sphere, head_pos=head_pos_sim, interp='linear', random_state=seed) assert_allclose(raw_sim_cos[:][0], raw_sim_lin[:][0], rtol=1e-5, atol=1e-20) del raw_sim_cos, raw_sim_lin # Make impossible transform (translate up into helmet) and ensure failure head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[1.][2, 3] -= 0.1 # z trans upward 10cm assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, ecg=False, blink=False, head_pos=head_pos_sim_err) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, bem_fname, ecg=False, blink=False, head_pos=head_pos_sim_err) # other degenerate conditions assert_raises(TypeError, simulate_raw, 'foo', stc, trans, src, sphere) assert_raises(TypeError, simulate_raw, raw, 'foo', trans, src, sphere) assert_raises(ValueError, simulate_raw, raw, stc.copy().crop(0, 0), trans, src, sphere) stc_bad = stc.copy() stc_bad.tstep += 0.1 assert_raises(ValueError, simulate_raw, raw, stc_bad, trans, src, sphere) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, chpi=True) # no cHPI info assert_raises(ValueError, simulate_raw, raw, stc, trans, src, sphere, interp='foo') assert_raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=1.) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=pos_fname) # ends up with t>t_end head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[-1.] = head_pos_sim_err[1.] # negative time assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=head_pos_sim_err) raw_bad = raw.copy() raw_bad.info['dig'] = None assert_raises(RuntimeError, simulate_raw, raw_bad, stc, trans, src, sphere, blink=True)
] stc = stc.in_label(labels[0] + labels[1]) stc.data.fill(0) stc.data[:, (stc.times >= pulse_tmin) & (stc.times <= pulse_tmax)] = 10e-9 # ############################################################################ # 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)
def test_simulate_raw_sphere(): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = _get_data() assert len(pick_types(raw.info, meg=False, ecg=True)) == 1 # head pos head_pos_sim = dict() # these will be at 1., 2., ... sec shifts = [[0.001, 0., -0.001], [-0.001, 0.001, 0.]] for time_key, shift in enumerate(shifts): # Create 4x4 matrix transform and normalize temp_trans = deepcopy(raw.info['dev_head_t']) temp_trans['trans'][:3, 3] += shift head_pos_sim[time_key + 1.] = temp_trans['trans'] # # Test raw simulation with basic parameters # raw_sim = simulate_raw(raw, stc, trans, src, sphere, read_cov(cov_fname), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) std = dict(grad=2e-13, mag=10e-15, eeg=0.1e-6) raw_sim = simulate_raw(raw, stc, trans, src, sphere, make_ad_hoc_cov(raw.info, std=std), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov=std, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) sphere_norad = make_sphere_model('auto', None, raw.info) raw_meg = raw.copy().pick_types() raw_sim = simulate_raw(raw_meg, stc, trans, src, sphere_norad, make_ad_hoc_cov(raw.info, std=None), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw_meg, stc, trans_fname, src_fname, sphere_norad, cov='simple', head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data tempdir = _TempDir() test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert np.mean(close) > 0.7 far = ~np.isclose( raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert np.mean(far) > 0.99 del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that raw-as-info is supported raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None) n_samp = int(round(raw.info['sfreq'])) for use_raw in (raw, raw.info): raw_sim_2 = simulate_raw(use_raw, stc, trans, src, sphere, cov=None, duration=1.) assert len(raw_sim_2.times) == n_samp assert_allclose(raw_sim[:, :n_samp][0], raw_sim_2[:, :n_samp][0], rtol=1e-5, atol=1e-30) del raw_sim, raw_sim_2 # check that different interpolations are similar given small movements raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='linear') raw_sim_hann = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='hann') assert_allclose(raw_sim[:][0], raw_sim_hann[:][0], rtol=1e-1, atol=1e-14) del raw_sim, raw_sim_hann # Make impossible transform (translate up into helmet) and ensure failure head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[1.][2, 3] -= 0.1 # z trans upward 10cm pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, ecg=False, blink=False, head_pos=head_pos_sim_err) pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, bem_fname, ecg=False, blink=False, head_pos=head_pos_sim_err) # other degenerate conditions pytest.raises(TypeError, simulate_raw, 'foo', stc, trans, src, sphere) pytest.raises(TypeError, simulate_raw, raw, 'foo', trans, src, sphere) pytest.raises(ValueError, simulate_raw, raw, stc.copy().crop(0, 0), trans, src, sphere) with pytest.raises(ValueError, match='duration cannot be None'): simulate_raw(raw.info, stc, trans, src, sphere) with pytest.raises(TypeError, match='must be an instance of Raw or Info'): simulate_raw(0, stc, trans, src, sphere) stc_bad = stc.copy() stc_bad.tstep += 0.1 pytest.raises(ValueError, simulate_raw, raw, stc_bad, trans, src, sphere) pytest.raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, cov=0) # wrong covariance type pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, chpi=True) # no cHPI info pytest.raises(ValueError, simulate_raw, raw, stc, trans, src, sphere, interp='foo') pytest.raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=1.) pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=pos_fname) # ends up with t>t_end head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[-1.] = head_pos_sim_err[1.] # negative time pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=head_pos_sim_err) raw_bad = raw.copy() raw_bad.info['dig'] = None pytest.raises(RuntimeError, simulate_raw, raw_bad, stc, trans, src, sphere, blink=True)
def run(): t0 = time.time() parser = get_optparser(__file__) parser.add_option("--raw", dest="raw_in", help="Input raw FIF file", metavar="FILE") parser.add_option("--pos", dest="pos", default=None, help="Position definition text file. Can be 'constant' " "to hold the head position fixed", metavar="FILE") parser.add_option("--dipoles", dest="dipoles", default=None, help="Dipole definition file", metavar="FILE") parser.add_option("--cov", dest="cov", help="Covariance to use for noise generation. Can be " "'simple' to use a diagonal covariance, or 'off' to " "omit noise", metavar="FILE", default='simple') parser.add_option("--duration", dest="duration", default=None, help="Duration of each epoch (sec). If omitted, the last" " time point in the dipole definition file plus 200 ms " "will be used", type="float") parser.add_option("-j", "--jobs", dest="n_jobs", help="Number of jobs to" " run in parallel", type="int", default=1) parser.add_option("--out", dest="raw_out", help="Output raw filename", metavar="FILE") parser.add_option("--plot-dipoles", dest="plot_dipoles", help="Plot " "input dipole positions", action="store_true") parser.add_option("--plot-raw", dest="plot_raw", help="Plot the resulting " "raw traces", action="store_true") parser.add_option("--plot-evoked", dest="plot_evoked", help="Plot evoked " "data", action="store_true") parser.add_option("-p", "--plot", dest="plot", help="Plot dipoles, raw, " "and evoked", action="store_true") parser.add_option("--overwrite", dest="overwrite", help="Overwrite the" "output file if it exists", action="store_true") options, args = parser.parse_args() raw_in = options.raw_in pos = options.pos raw_out = options.raw_out dipoles = options.dipoles n_jobs = options.n_jobs plot = options.plot plot_dipoles = options.plot_dipoles or plot plot_raw = options.plot_raw or plot plot_evoked = options.plot_evoked or plot overwrite = options.overwrite duration = options.duration cov = options.cov # check parameters if not (raw_out or plot_raw or plot_evoked): raise ValueError('data must either be saved (--out) or ' 'plotted (--plot-raw or --plot_evoked)') if raw_out and op.isfile(raw_out) and not overwrite: raise ValueError('output file exists, use --overwrite (%s)' % raw_out) if raw_in is None or pos is None or dipoles is None: parser.print_help() sys.exit(1) s = 'Simulate raw data with head movements' print('\n%s\n%s\n%s\n' % ('-' * len(s), s, '-' * len(s))) # setup the simulation with printer('Reading dipole definitions'): if not op.isfile(dipoles): raise IOError('dipole file not found:\n%s' % dipoles) dipoles = np.loadtxt(dipoles, skiprows=1, dtype=float) n_dipoles = dipoles.shape[0] if dipoles.shape[1] != 8: raise ValueError('dipoles must have 8 columns') rr = dipoles[:, :3] * 1e-3 nn = dipoles[:, 3:6] t = dipoles[:, 6:8] duration = t.max() + 0.2 if duration is None else duration if (t[:, 0] > t[:, 1]).any(): raise ValueError('found tmin > tmax in dipole file') if (t < 0).any(): raise ValueError('found t < 0 in dipole file') if (t > duration).any(): raise ValueError('found t > duration in dipole file') amp = np.sqrt(np.sum(nn * nn, axis=1)) * 1e-9 mne.surface._normalize_vectors(nn) nn[(nn == 0).all(axis=1)] = (1, 0, 0) src = mne.SourceSpaces([ dict(rr=rr, nn=nn, inuse=np.ones(n_dipoles, int), coord_frame=FIFF.FIFFV_COORD_HEAD) ]) for key in ['pinfo', 'nuse_tri', 'use_tris', 'patch_inds']: src[0][key] = None trans = { 'from': FIFF.FIFFV_COORD_HEAD, 'to': FIFF.FIFFV_COORD_MRI, 'trans': np.eye(4) } if (amp > 100e-9).any(): print('') warnings.warn('Largest dipole amplitude %0.1f > 100 nA' % (amp.max() * 1e9)) if pos == 'constant': print('Holding head position constant') pos = None else: with printer('Loading head positions'): pos = mne.get_chpi_positions(pos) with printer('Loading raw data file'): with warnings.catch_warnings(record=True): raw = mne.io.Raw(raw_in, preload=False, allow_maxshield=True, verbose=False) if cov == 'simple': print('Using diagonal covariance for brain noise') elif cov == 'off': print('Omitting brain noise in the simulation') cov = None else: with printer('Loading covariance file for brain noise'): cov = mne.read_cov(cov) with printer('Setting up spherical model'): bem = mne.bem.make_sphere_model('auto', 'auto', raw.info, verbose=False) # check that our sources are reasonable rad = bem['layers'][0]['rad'] r0 = bem['r0'] outside = np.sqrt(np.sum((rr - r0)**2, axis=1)) >= rad n_outside = outside.sum() if n_outside > 0: print('') raise ValueError( '%s dipole%s outside the spherical model, are your positions ' 'in mm?' % (n_outside, 's were' if n_outside != 1 else ' was')) with printer('Constructing source estimate'): tmids = t.mean(axis=1) t = np.round(t * raw.info['sfreq']).astype(int) t[:, 1] += 1 # make it inclusive n_samp = int(np.ceil(duration * raw.info['sfreq'])) data = np.zeros((n_dipoles, n_samp)) for di, (t_, amp_) in enumerate(zip(t, amp)): data[di, t_[0]:t_[1]] = amp_ * np.hanning(t_[1] - t_[0]) stc = mne.VolSourceEstimate(data, np.arange(n_dipoles), 0, 1. / raw.info['sfreq']) # do the simulation print('') raw_mv = simulate_raw(raw, stc, trans, src, bem, cov=cov, head_pos=pos, chpi=True, n_jobs=n_jobs, verbose=True) print('') if raw_out: with printer('Saving data'): raw_mv.save(raw_out, overwrite=overwrite) # plot results -- must be *after* save because we low-pass filter if plot_dipoles: with printer('Plotting dipoles'): fig, axs = plt.subplots(1, 3, figsize=(10, 3), facecolor='w') fig.canvas.set_window_title('Dipoles') meg_info = mne.pick_info( raw.info, mne.pick_types(raw.info, meg=True, eeg=False)) helmet_rr = [ ch['coil_trans'][:3, 3].copy() for ch in meg_info['chs'] ] helmet_nn = np.zeros_like(helmet_rr) helmet_nn[:, 2] = 1. surf = dict(rr=helmet_rr, nn=helmet_nn, coord_frame=FIFF.FIFFV_COORD_DEVICE) helmet_rr = mne.surface.transform_surface_to( surf, 'head', meg_info['dev_head_t'])['rr'] p = np.linspace(0, 2 * np.pi, 40) x_sphere, y_sphere = rad * np.sin(p), rad * np.cos(p) for ai, ax in enumerate(axs): others = np.setdiff1d(np.arange(3), [ai]) ax.plot(helmet_rr[:, others[0]], helmet_rr[:, others[1]], marker='o', linestyle='none', alpha=0.1, markeredgecolor='none', markerfacecolor='b', zorder=-2) ax.plot(x_sphere + r0[others[0]], y_sphere + r0[others[1]], color='y', alpha=0.25, zorder=-1) ax.quiver(rr[:, others[0]], rr[:, others[1]], amp * nn[:, others[0]], amp * nn[:, others[1]], angles='xy', units='x', color='k', alpha=0.5) ax.set_aspect('equal') ax.set_xlabel(' - ' + 'xyz'[others[0]] + ' + ') ax.set_ylabel(' - ' + 'xyz'[others[1]] + ' + ') ax.set_xticks([]) ax.set_yticks([]) plt.setp(list(ax.spines.values()), color='none') plt.tight_layout() if plot_raw or plot_evoked: with printer('Low-pass filtering simulated data'): events = mne.find_events(raw_mv, 'STI101', verbose=False) b, a = signal.butter(4, 40. / (raw.info['sfreq'] / 2.), 'low', analog=False) raw_mv.filter(None, 40., method='iir', iir_params=dict(b=b, a=a), verbose=False, n_jobs=n_jobs) if plot_raw: with printer('Plotting raw data'): raw_mv.plot(clipping='transparent', events=events, show=False) if plot_evoked: with printer('Plotting evoked data'): picks = mne.pick_types(raw_mv.info, meg=True, eeg=True) events[:, 2] = 1 evoked = mne.Epochs(raw_mv, events, { 'Simulated': 1 }, 0, duration, None, picks).average() evoked.plot_topomap(np.unique(tmids), show=False) print('\nTotal time: %0.1f sec' % (time.time() - t0)) sys.stdout.flush() if any([plot_dipoles, plot_raw, plot_evoked]): plt.show(block=True)
def test_iterable(): """Test iterable support for simulate_raw.""" raw = read_raw_fif(raw_fname_short).load_data() raw.pick_channels(raw.ch_names[:10] + ['STI 014']) src = setup_volume_source_space( pos=dict(rr=[[-0.05, 0, 0], [0.1, 0, 0]], nn=[[0, 1., 0], [0, 1., 0]])) assert src.kind == 'discrete' trans = None sphere = make_sphere_model(head_radius=None, info=raw.info) tstep = 1. / raw.info['sfreq'] rng = np.random.RandomState(0) vertices = np.array([1]) data = rng.randn(1, 2) stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) with pytest.raises(ValueError, match='at least three time points'): simulate_raw(raw.info, stc, trans, src, sphere, None) data = rng.randn(1, 1000) n_events = (len(raw.times) - 1) // 1000 + 1 stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) with catch_logging() as log: with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, None, verbose=True) log = log.getvalue() assert 'Making 15 copies of STC' in log assert_allclose(raw.times, raw_sim.times) events = find_events(raw_sim, initial_event=True) assert len(events) == n_events assert_array_equal(events[:, 2], 1) # Degenerate STCs with pytest.raises(RuntimeError, match=r'Iterable did not provide stc\[0\]'): simulate_raw(raw.info, [], trans, src, sphere, None) with pytest.raises(RuntimeError, match=r'Iterable did not provide stc\[2\].*duration'): with pytest.deprecated_call(): simulate_raw(raw, [stc, stc], trans, src, sphere, None) # tuple with ndarray event_data = np.zeros(len(stc.times), int) event_data[0] = 3 raw_new = simulate_raw(raw.info, [(stc, event_data)] * 15, trans, src, sphere, None, first_samp=raw.first_samp) assert raw_new.n_times == 15000 raw_new.crop(0, raw_sim.times[-1]) _assert_iter_sim(raw_sim, raw_new, 3) with pytest.raises(ValueError, match='event data had shape .* but need'): simulate_raw(raw.info, [(stc, event_data[:-1])], trans, src, sphere, None) with pytest.raises(ValueError, match='stim_data in a stc tuple .* int'): simulate_raw(raw.info, [(stc, event_data * 1.)], trans, src, sphere, None) # iterable def stc_iter(): stim_data = np.zeros(len(stc.times), int) stim_data[0] = 4 ii = 0 while ii < 100: ii += 1 yield (stc, stim_data) with pytest.deprecated_call(): raw_new = simulate_raw(raw, stc_iter(), trans, src, sphere, None) _assert_iter_sim(raw_sim, raw_new, 4) def stc_iter_bad(): ii = 0 while ii < 100: ii += 1 yield (stc, 4, 3) with pytest.raises(ValueError, match='stc, if tuple, must be length'): simulate_raw(raw.info, stc_iter_bad(), trans, src, sphere, None) _assert_iter_sim(raw_sim, raw_new, 4) def stc_iter_bad(): ii = 0 while ii < 100: ii += 1 stc_new = stc.copy() stc_new.vertices = np.array([ii % 2]) yield stc_new with pytest.raises(RuntimeError, match=r'Vertex mismatch for stc\[1\]'): simulate_raw(raw.info, stc_iter_bad(), trans, src, sphere, None) # Forward omission vertices = np.array([0, 1]) data = rng.randn(2, 1000) stc = VolSourceEstimate(data, vertices, 0, tstep) assert isinstance(stc.vertices, np.ndarray) # XXX eventually we should support filtering based on sphere radius, too, # by refactoring the code in source_space.py that does it! surf = _get_ico_surface(3) surf['rr'] *= 60 # mm model = _surfaces_to_bem([surf], [FIFF.FIFFV_BEM_SURF_ID_BRAIN], [0.3]) bem = make_bem_solution(model) with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw, stc, trans, src, bem, None)
info.update(sfreq=sfreq, bads=[]) # Only use gradiometers picks = mne.pick_types(info, meg='grad', stim=True, exclude=()) mne.pick_info(info, picks, copy=False) # This is the raw object that will be used as a template for the simulation. raw = mne.io.RawArray(np.zeros((info['nchan'], len(stc.times))), info) # Define a covariance matrix for the simulated noise. In this tutorial, we use # a simple diagonal matrix. cov = mne.cov.make_ad_hoc_cov(info) cov['data'] *= (20. / snr) ** 2 # Scale the noise to achieve the desired SNR # Simulate the raw data, with a lowpass filter on the noise raw = simulate_raw(raw, stc, trans_fname, src_fname, bem_fname, cov=cov, random_state=rand, iir_filter=[4, -4, 0.8]) ############################################################################### # We create an :class:`mne.Epochs` object containing two trials: one with # both noise and signal and one with just noise t0 = raw.first_samp # First sample in the data t1 = t0 + n_times - 1 # Sample just before the second trial epochs = mne.Epochs( raw, events=np.array([[t0, 0, 1], [t1, 0, 2]]), event_id=dict(signal=1, noise=2), tmin=0, tmax=10, preload=True, )
def test_simulate_raw_sphere(raw_data, tmpdir): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = raw_data assert len(pick_types(raw.info, meg=False, ecg=True)) == 1 tempdir = str(tmpdir) # head pos head_pos_sim = _get_head_pos_sim(raw) # # Test raw simulation with basic parameters # raw.info.normalize_proj() cov = read_cov(cov_fname) cov['projs'] = raw.info['projs'] raw.info['bads'] = raw.ch_names[:1] with pytest.deprecated_call(match='cov is deprecated'): raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed, verbose=True) with pytest.warns(RuntimeWarning, match='applying projector with'): raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.raises(RuntimeError, match='Maximum number of STC iterations'): simulate_raw(raw.info, [stc] * 5, trans_fname, src_fname, sphere, cov=None, max_iter=1) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) std = dict(grad=2e-13, mag=10e-15, eeg=0.1e-6) with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, make_ad_hoc_cov(raw.info, std=std), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.deprecated_call(): raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov=std, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) sphere_norad = make_sphere_model('auto', None, raw.info) raw_meg = raw.copy().pick_types() with pytest.deprecated_call(): raw_sim = simulate_raw(raw_meg, stc, trans, src, sphere_norad, cov=None, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) with pytest.deprecated_call(): raw_sim_2 = simulate_raw(raw_meg, stc, trans_fname, src_fname, sphere_norad, cov=None, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): with pytest.deprecated_call(): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) with pytest.deprecated_call(): raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert np.mean(close) > 0.7 far = ~np.isclose( raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert np.mean(far) > 0.99 del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only with pytest.deprecated_call(): raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None) for this_raw in (raw_sim_meg, raw_sim_eeg, raw_sim_meeg): add_eog(this_raw, random_state=seed) for this_raw in (raw_sim_meg, raw_sim_meeg): add_ecg(this_raw, random_state=seed) with pytest.raises(RuntimeError, match='only add ECG artifacts if MEG'): add_ecg(raw_sim_eeg) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that raw-as-info is supported n_samp = len(stc.times) raw_crop = raw.copy().crop(0., (n_samp - 1.) / raw.info['sfreq']) assert len(raw_crop.times) == len(stc.times) with pytest.deprecated_call(): raw_sim = simulate_raw(raw_crop, stc, trans, src, sphere, cov=None) with catch_logging() as log: raw_sim_2 = simulate_raw(raw_crop.info, stc, trans, src, sphere, cov=None, verbose=True) log = log.getvalue() assert '1 STC iteration provided' in log assert len(raw_sim_2.times) == n_samp assert_allclose(raw_sim[:, :n_samp][0], raw_sim_2[:, :n_samp][0], rtol=1e-5, atol=1e-30) del raw_sim, raw_sim_2 # check that different interpolations are similar given small movements with pytest.deprecated_call(): raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='linear') with pytest.deprecated_call(): raw_sim_hann = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='hann') assert_allclose(raw_sim[:][0], raw_sim_hann[:][0], rtol=1e-1, atol=1e-14) del raw_sim_hann # check that new Generator objects can be used if check_version('numpy', '1.17'): random_state = np.random.default_rng(seed) add_ecg(raw_sim, random_state=random_state) add_eog(raw_sim, random_state=random_state)
def test_degenerate(raw_data): """Test degenerate conditions.""" raw, src, stc, trans, sphere = raw_data info = raw.info # Make impossible transform (translate up into helmet) and ensure failure hp_err = _get_head_pos_sim(raw) hp_err[1.][2, 3] -= 0.1 # z trans upward 10cm with pytest.raises(RuntimeError, match='collided with inner skull'): simulate_raw(info, stc, trans, src, sphere, cov=None, head_pos=hp_err) # other degenerate conditions with pytest.raises(TypeError, match='info must be an instance of'): simulate_raw('foo', stc, trans, src, sphere) with pytest.raises(TypeError, match='stc must be an instance of'): simulate_raw(info, 'foo', trans, src, sphere) with pytest.raises(ValueError, match='stc must have at least three time'): simulate_raw(info, stc.copy().crop(0, 0), trans, src, sphere) with pytest.raises(TypeError, match='must be an instance of Raw or Info'): simulate_raw(0, stc, trans, src, sphere) stc_bad = stc.copy() stc_bad.tstep += 0.1 with pytest.raises(ValueError, match='same sample rate'): simulate_raw(info, stc_bad, trans, src, sphere) with pytest.raises(TypeError, match='Covariance matrix type'): with pytest.deprecated_call(): simulate_raw(info, stc, trans, src, sphere, cov=0) with pytest.raises(RuntimeError, match='cHPI information not found'): with pytest.deprecated_call(): simulate_raw(info, stc, trans, src, sphere, chpi=True) with pytest.raises(ValueError, match='interp must be one of'): simulate_raw(info, stc, trans, src, sphere, interp='foo') with pytest.raises(TypeError, match='unknown head_pos type'): simulate_raw(info, stc, trans, src, sphere, head_pos=1.) with pytest.raises(RuntimeError, match='All position times'): with pytest.deprecated_call(): simulate_raw(raw, stc, trans, src, sphere, head_pos=pos_fname) head_pos_sim_err = _get_head_pos_sim(raw) head_pos_sim_err[-1.] = head_pos_sim_err[1.] # negative time with pytest.raises(RuntimeError, match='All position times'): simulate_raw(info, stc, trans, src, sphere, head_pos=head_pos_sim_err) raw_bad = raw.copy() raw_bad.info['dig'] = None with pytest.raises(RuntimeError, match='Cannot fit headshape'): with pytest.deprecated_call(): simulate_raw(raw_bad, stc, trans, src, sphere, blink=True) with pytest.raises(RuntimeError, match='Cannot fit headshape'): add_eog(raw_bad)
def run(): t0 = time.time() parser = get_optparser(__file__) parser.add_option("--raw", dest="raw_in", help="Input raw FIF file", metavar="FILE") parser.add_option("--pos", dest="pos", default=None, help="Position definition text file. Can be 'constant' " "to hold the head position fixed", metavar="FILE") parser.add_option("--dipoles", dest="dipoles", default=None, help="Dipole definition file", metavar="FILE") parser.add_option("--cov", dest="cov", help="Covariance to use for noise generation. Can be " "'simple' to use a diagonal covariance, or 'off' to " "omit noise", metavar="FILE", default='simple') parser.add_option("--duration", dest="duration", default=None, help="Duration of each epoch (sec). If omitted, the last" " time point in the dipole definition file plus 200 ms " "will be used", type="float") parser.add_option("-j", "--jobs", dest="n_jobs", help="Number of jobs to" " run in parallel", type="int", default=1) parser.add_option("--out", dest="raw_out", help="Output raw filename", metavar="FILE") parser.add_option("--plot-dipoles", dest="plot_dipoles", help="Plot " "input dipole positions", action="store_true") parser.add_option("--plot-raw", dest="plot_raw", help="Plot the resulting " "raw traces", action="store_true") parser.add_option("--plot-evoked", dest="plot_evoked", help="Plot evoked " "data", action="store_true") parser.add_option("-p", "--plot", dest="plot", help="Plot dipoles, raw, " "and evoked", action="store_true") parser.add_option("--overwrite", dest="overwrite", help="Overwrite the" "output file if it exists", action="store_true") options, args = parser.parse_args() raw_in = options.raw_in pos = options.pos raw_out = options.raw_out dipoles = options.dipoles n_jobs = options.n_jobs plot = options.plot plot_dipoles = options.plot_dipoles or plot plot_raw = options.plot_raw or plot plot_evoked = options.plot_evoked or plot overwrite = options.overwrite duration = options.duration cov = options.cov # check parameters if not (raw_out or plot_raw or plot_evoked): raise ValueError('data must either be saved (--out) or ' 'plotted (--plot-raw or --plot_evoked)') if raw_out and op.isfile(raw_out) and not overwrite: raise ValueError('output file exists, use --overwrite (%s)' % raw_out) if raw_in is None or pos is None or dipoles is None: parser.print_help() sys.exit(1) s = 'Simulate raw data with head movements' print('\n%s\n%s\n%s\n' % ('-' * len(s), s, '-' * len(s))) # setup the simulation with printer('Reading dipole definitions'): if not op.isfile(dipoles): raise IOError('dipole file not found:\n%s' % dipoles) dipoles = np.loadtxt(dipoles, skiprows=1, dtype=float) n_dipoles = dipoles.shape[0] if dipoles.shape[1] != 8: raise ValueError('dipoles must have 8 columns') rr = dipoles[:, :3] * 1e-3 nn = dipoles[:, 3:6] t = dipoles[:, 6:8] duration = t.max() + 0.2 if duration is None else duration if (t[:, 0] > t[:, 1]).any(): raise ValueError('found tmin > tmax in dipole file') if (t < 0).any(): raise ValueError('found t < 0 in dipole file') if (t > duration).any(): raise ValueError('found t > duration in dipole file') amp = np.sqrt(np.sum(nn * nn, axis=1)) * 1e-9 mne.surface._normalize_vectors(nn) nn[(nn == 0).all(axis=1)] = (1, 0, 0) src = mne.SourceSpaces([ dict(rr=rr, nn=nn, inuse=np.ones(n_dipoles, int), coord_frame=FIFF.FIFFV_COORD_HEAD)]) for key in ['pinfo', 'nuse_tri', 'use_tris', 'patch_inds']: src[0][key] = None trans = {'from': FIFF.FIFFV_COORD_HEAD, 'to': FIFF.FIFFV_COORD_MRI, 'trans': np.eye(4)} if (amp > 100e-9).any(): print('') warnings.warn('Largest dipole amplitude %0.1f > 100 nA' % (amp.max() * 1e9)) if pos == 'constant': print('Holding head position constant') pos = None else: with printer('Loading head positions'): pos = mne.get_chpi_positions(pos) with printer('Loading raw data file'): with warnings.catch_warnings(record=True): raw = mne.io.Raw(raw_in, preload=False, allow_maxshield=True, verbose=False) if cov == 'simple': print('Using diagonal covariance for brain noise') elif cov == 'off': print('Omitting brain noise in the simulation') cov = None else: with printer('Loading covariance file for brain noise'): cov = mne.read_cov(cov) with printer('Setting up spherical model'): bem = mne.bem.make_sphere_model('auto', 'auto', raw.info, verbose=False) # check that our sources are reasonable rad = bem['layers'][0]['rad'] r0 = bem['r0'] outside = np.sqrt(np.sum((rr - r0) ** 2, axis=1)) >= rad n_outside = outside.sum() if n_outside > 0: print('') raise ValueError( '%s dipole%s outside the spherical model, are your positions ' 'in mm?' % (n_outside, 's were' if n_outside != 1 else ' was')) with printer('Constructing source estimate'): tmids = t.mean(axis=1) t = np.round(t * raw.info['sfreq']).astype(int) t[:, 1] += 1 # make it inclusive n_samp = int(np.ceil(duration * raw.info['sfreq'])) data = np.zeros((n_dipoles, n_samp)) for di, (t_, amp_) in enumerate(zip(t, amp)): data[di, t_[0]:t_[1]] = amp_ * np.hanning(t_[1] - t_[0]) stc = mne.VolSourceEstimate(data, np.arange(n_dipoles), 0, 1. / raw.info['sfreq']) # do the simulation print('') raw_mv = simulate_raw(raw, stc, trans, src, bem, cov=cov, head_pos=pos, chpi=True, n_jobs=n_jobs, verbose=True) print('') if raw_out: with printer('Saving data'): raw_mv.save(raw_out, overwrite=overwrite) # plot results -- must be *after* save because we low-pass filter if plot_dipoles: with printer('Plotting dipoles'): fig, axs = plt.subplots(1, 3, figsize=(10, 3), facecolor='w') fig.canvas.set_window_title('Dipoles') meg_info = mne.pick_info(raw.info, mne.pick_types(raw.info, meg=True, eeg=False)) helmet_rr = [ch['coil_trans'][:3, 3].copy() for ch in meg_info['chs']] helmet_nn = np.zeros_like(helmet_rr) helmet_nn[:, 2] = 1. surf = dict(rr=helmet_rr, nn=helmet_nn, coord_frame=FIFF.FIFFV_COORD_DEVICE) helmet_rr = mne.surface.transform_surface_to( surf, 'head', meg_info['dev_head_t'])['rr'] p = np.linspace(0, 2 * np.pi, 40) x_sphere, y_sphere = rad * np.sin(p), rad * np.cos(p) for ai, ax in enumerate(axs): others = np.setdiff1d(np.arange(3), [ai]) ax.plot(helmet_rr[:, others[0]], helmet_rr[:, others[1]], marker='o', linestyle='none', alpha=0.1, markeredgecolor='none', markerfacecolor='b', zorder=-2) ax.plot(x_sphere + r0[others[0]], y_sphere + r0[others[1]], color='y', alpha=0.25, zorder=-1) ax.quiver(rr[:, others[0]], rr[:, others[1]], amp * nn[:, others[0]], amp * nn[:, others[1]], angles='xy', units='x', color='k', alpha=0.5) ax.set_aspect('equal') ax.set_xlabel(' - ' + 'xyz'[others[0]] + ' + ') ax.set_ylabel(' - ' + 'xyz'[others[1]] + ' + ') ax.set_xticks([]) ax.set_yticks([]) plt.setp(list(ax.spines.values()), color='none') plt.tight_layout() if plot_raw or plot_evoked: with printer('Low-pass filtering simulated data'): events = mne.find_events(raw_mv, 'STI101', verbose=False) b, a = signal.butter(4, 40. / (raw.info['sfreq'] / 2.), 'low', analog=False) raw_mv.filter(None, 40., method='iir', iir_params=dict(b=b, a=a), verbose=False, n_jobs=n_jobs) if plot_raw: with printer('Plotting raw data'): raw_mv.plot(clipping='transparent', events=events, show=False) if plot_evoked: with printer('Plotting evoked data'): picks = mne.pick_types(raw_mv.info, meg=True, eeg=True) events[:, 2] = 1 evoked = mne.Epochs(raw_mv, events, {'Simulated': 1}, 0, duration, None, picks).average() evoked.plot_topomap(np.unique(tmids), show=False) print('\nTotal time: %0.1f sec' % (time.time() - t0)) sys.stdout.flush() if any([plot_dipoles, plot_raw, plot_evoked]): plt.show(block=True)
# limit activation to a square pulse in time at two vertices in space labels = [ read_labels_from_annot(subject, "aparc.a2009s", hemi, regexp="G_temp_sup-G_T_transv")[0] for hi, hemi in enumerate(("lh", "rh")) ] stc = stc.in_label(labels[0] + labels[1]) stc.data.fill(0) stc.data[:, (stc.times >= pulse_tmin) & (stc.times <= pulse_tmax)] = 10e-9 # ############################################################################ # 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)
info.update(sfreq=sfreq, bads=[]) # Only use gradiometers picks = mne.pick_types(info, meg='grad', stim=True, exclude=()) mne.pick_info(info, picks, copy=False) # Define a covariance matrix for the simulated noise. In this tutorial, we use # a simple diagonal matrix. cov = mne.cov.make_ad_hoc_cov(info) cov['data'] *= (20. / snr) ** 2 # Scale the noise to achieve the desired SNR # Simulate the raw data, with a lowpass filter on the noise stcs = [(stc_signal, unit_impulse(n_samp, dtype=int) * 1), (stc_noise, unit_impulse(n_samp, dtype=int) * 2)] # stacked in time duration = (len(stc_signal.times) * 2) / sfreq raw = simulate_raw(info, stcs, forward=fwd) add_noise(raw, cov, iir_filter=[4, -4, 0.8], random_state=rand) ############################################################################### # We create an :class:`mne.Epochs` object containing two trials: one with # both noise and signal and one with just noise events = mne.find_events(raw, initial_event=True) tmax = (len(stc_signal.times) - 1) / sfreq epochs = mne.Epochs(raw, events, event_id=dict(signal=1, noise=2), tmin=0, tmax=tmax, baseline=None, preload=True) assert len(epochs) == 2 # ensure that we got the two expected events # Plot some of the channels of the simulated data that are situated above one # of our simulated sources.
def test_simulate_raw_bem(raw_data): """Test simulation of raw data with BEM.""" raw, src_ss, stc, trans, sphere = raw_data src = setup_source_space('sample', 'oct1', subjects_dir=subjects_dir) for s in src: s['nuse'] = 3 s['vertno'] = src[1]['vertno'][:3] s['inuse'].fill(0) s['inuse'][s['vertno']] = 1 # use different / more complete STC here vertices = [s['vertno'] for s in src] stc = SourceEstimate(np.eye(sum(len(v) for v in vertices)), vertices, 0, 1. / raw.info['sfreq']) stcs = [stc] * 15 raw_sim_sph = simulate_raw(raw.info, stcs, trans, src, sphere) raw_sim_bem = simulate_raw(raw.info, stcs, trans, src, bem_fname) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) med_corr = np.median(np.diag(corr[:n_ch, -n_ch:])) assert med_corr > 0.65 # do some round-trip localization for s in src: transform_surface_to(s, 'head', trans) locs = np.concatenate([s['rr'][s['vertno']] for s in src]) tmax = (len(locs) - 1) / raw.info['sfreq'] cov = make_ad_hoc_cov(raw.info) # The tolerance for the BEM is surprisingly high (28) but I get the same # result when using MNE-C and Xfit, even when using a proper 5120 BEM :( for use_raw, bem, tol in ((raw_sim_sph, sphere, 2), (raw_sim_bem, bem_fname, 31)): events = find_events(use_raw, 'STI 014') assert len(locs) == 6 evoked = Epochs(use_raw, events, 1, 0, tmax, baseline=None).average() assert len(evoked.times) == len(locs) fits = fit_dipole(evoked, cov, bem, trans, min_dist=1.)[0].pos diffs = np.sqrt(np.sum((locs - fits) ** 2, axis=-1)) * 1000 med_diff = np.median(diffs) assert med_diff < tol, '%s: %s' % (bem, med_diff) # also test event timings with SourceSimulator first_samp = raw.first_samp events = find_events(raw, initial_event=True, verbose=False) evt_times = events[:, 0] assert len(events) == 3 labels_sim = [[], [], []] # random l+r hemisphere points labels_sim[0] = Label([src_ss[0]['vertno'][1]], hemi='lh') labels_sim[1] = Label([src_ss[0]['vertno'][4]], hemi='lh') labels_sim[2] = Label([src_ss[1]['vertno'][2]], hemi='rh') wf_sim = np.array([2, 1, 0]) for this_fs in (0, first_samp): ss = SourceSimulator(src_ss, 1. / raw.info['sfreq'], first_samp=this_fs) for i in range(3): ss.add_data(labels_sim[i], wf_sim, events[np.newaxis, i]) assert ss.n_times == evt_times[-1] + len(wf_sim) - this_fs raw_sim = simulate_raw(raw.info, ss, src=src_ss, bem=bem_fname, first_samp=first_samp) data = raw_sim.get_data() amp0 = data[:, evt_times - first_samp].max() amp1 = data[:, evt_times + 1 - first_samp].max() amp2 = data[:, evt_times + 2 - first_samp].max() assert_allclose(amp0 / amp1, wf_sim[0] / wf_sim[1], rtol=1e-5) assert amp2 == 0 assert raw_sim.n_times == ss.n_times
def test_simulate_raw_sphere(): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = _get_data() assert_true(len(pick_types(raw.info, meg=False, ecg=True)) == 1) # head pos head_pos_sim = dict() # these will be at 1., 2., ... sec shifts = [[0.001, 0., -0.001], [-0.001, 0.001, 0.]] for time_key, shift in enumerate(shifts): # Create 4x4 matrix transform and normalize temp_trans = deepcopy(raw.info['dev_head_t']) temp_trans['trans'][:3, 3] += shift head_pos_sim[time_key + 1.] = temp_trans['trans'] # # Test raw simulation with basic parameters # raw_sim = simulate_raw(raw, stc, trans, src, sphere, read_cov(cov_fname), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data tempdir = _TempDir() test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert_true(np.mean(close) > 0.7) far = ~np.isclose( raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert_true(np.mean(far) > 0.99) del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that different interpolations are similar given small movements raw_sim_cos = simulate_raw(raw, stc, trans, src, sphere, head_pos=head_pos_sim, random_state=seed) raw_sim_lin = simulate_raw(raw, stc, trans, src, sphere, head_pos=head_pos_sim, interp='linear', random_state=seed) assert_allclose(raw_sim_cos[:][0], raw_sim_lin[:][0], rtol=1e-5, atol=1e-20) del raw_sim_cos, raw_sim_lin # Make impossible transform (translate up into helmet) and ensure failure head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[1.][2, 3] -= 0.1 # z trans upward 10cm assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, ecg=False, blink=False, head_pos=head_pos_sim_err) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, bem_fname, ecg=False, blink=False, head_pos=head_pos_sim_err) # other degenerate conditions assert_raises(TypeError, simulate_raw, 'foo', stc, trans, src, sphere) assert_raises(TypeError, simulate_raw, raw, 'foo', trans, src, sphere) assert_raises(ValueError, simulate_raw, raw, stc.copy().crop(0, 0), trans, src, sphere) stc_bad = stc.copy() stc_bad.tstep += 0.1 assert_raises(ValueError, simulate_raw, raw, stc_bad, trans, src, sphere) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, chpi=True) # no cHPI info assert_raises(ValueError, simulate_raw, raw, stc, trans, src, sphere, interp='foo') assert_raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=1.) assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=pos_fname) # ends up with t>t_end head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[-1.] = head_pos_sim_err[1.] # negative time assert_raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=head_pos_sim_err) raw_bad = raw.copy() raw_bad.info['dig'] = None assert_raises(RuntimeError, simulate_raw, raw_bad, stc, trans, src, sphere, blink=True)
def test_simulate_raw_sphere(raw_data, tmpdir): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = raw_data assert len(pick_types(raw.info, meg=False, ecg=True)) == 1 tempdir = str(tmpdir) # head pos head_pos_sim = _get_head_pos_sim(raw) # # Test raw simulation with basic parameters # raw.info.normalize_proj() cov = read_cov(cov_fname) cov['projs'] = raw.info['projs'] raw.info['bads'] = raw.ch_names[:1] sphere_norad = make_sphere_model('auto', None, raw.info) raw_meg = raw.copy().pick_types() raw_sim = simulate_raw(raw_meg.info, stc, trans, src, sphere_norad, head_pos=head_pos_sim) # Test IO on processed data test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim # make sure it works with EEG-only and MEG-only raw_sim_meg = simulate_raw( raw.copy().pick_types(meg=True, eeg=False).info, stc, trans, src, sphere) raw_sim_eeg = simulate_raw( raw.copy().pick_types(meg=False, eeg=True).info, stc, trans, src, sphere) raw_sim_meeg = simulate_raw( raw.copy().pick_types(meg=True, eeg=True).info, stc, trans, src, sphere) for this_raw in (raw_sim_meg, raw_sim_eeg, raw_sim_meeg): add_eog(this_raw, random_state=seed) for this_raw in (raw_sim_meg, raw_sim_meeg): add_ecg(this_raw, random_state=seed) with pytest.raises(RuntimeError, match='only add ECG artifacts if MEG'): add_ecg(raw_sim_eeg) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that raw-as-info is supported n_samp = len(stc.times) raw_crop = raw.copy().crop(0., (n_samp - 1.) / raw.info['sfreq']) assert len(raw_crop.times) == len(stc.times) raw_sim = simulate_raw(raw_crop.info, stc, trans, src, sphere) with catch_logging() as log: raw_sim_2 = simulate_raw(raw_crop.info, stc, trans, src, sphere, verbose=True) log = log.getvalue() assert '1 STC iteration provided' in log assert len(raw_sim_2.times) == n_samp assert_allclose(raw_sim[:, :n_samp][0], raw_sim_2[:, :n_samp][0], rtol=1e-5, atol=1e-30) del raw_sim, raw_sim_2 # check that different interpolations are similar given small movements raw_sim = simulate_raw(raw.info, stc, trans, src, sphere, head_pos=head_pos_sim, interp='linear') raw_sim_hann = simulate_raw(raw.info, stc, trans, src, sphere, head_pos=head_pos_sim, interp='hann') assert_allclose(raw_sim[:][0], raw_sim_hann[:][0], rtol=1e-1, atol=1e-14) del raw_sim_hann # check that new Generator objects can be used if check_version('numpy', '1.17'): random_state = np.random.default_rng(seed) add_ecg(raw_sim, random_state=random_state) add_eog(raw_sim, random_state=random_state)
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.)
def test_simulate_raw_sphere(): """Test simulation of raw data with sphere model.""" seed = 42 raw, src, stc, trans, sphere = _get_data() assert len(pick_types(raw.info, meg=False, ecg=True)) == 1 # head pos head_pos_sim = dict() # these will be at 1., 2., ... sec shifts = [[0.001, 0., -0.001], [-0.001, 0.001, 0.]] for time_key, shift in enumerate(shifts): # Create 4x4 matrix transform and normalize temp_trans = deepcopy(raw.info['dev_head_t']) temp_trans['trans'][:3, 3] += shift head_pos_sim[time_key + 1.] = temp_trans['trans'] # # Test raw simulation with basic parameters # raw_sim = simulate_raw(raw, stc, trans, src, sphere, read_cov(cov_fname), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov_fname, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) std = dict(grad=2e-13, mag=10e-15, eeg=0.1e-6) raw_sim = simulate_raw(raw, stc, trans, src, sphere, make_ad_hoc_cov(raw.info, std=std), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw, stc, trans_fname, src_fname, sphere, cov=std, head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) sphere_norad = make_sphere_model('auto', None, raw.info) raw_meg = raw.copy().pick_types() raw_sim = simulate_raw(raw_meg, stc, trans, src, sphere_norad, make_ad_hoc_cov(raw.info, std=None), head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) raw_sim_2 = simulate_raw(raw_meg, stc, trans_fname, src_fname, sphere_norad, cov='simple', head_pos=head_pos_sim, blink=True, ecg=True, random_state=seed) assert_array_equal(raw_sim_2[:][0], raw_sim[:][0]) # Test IO on processed data tempdir = _TempDir() test_outname = op.join(tempdir, 'sim_test_raw.fif') raw_sim.save(test_outname) raw_sim_loaded = read_raw_fif(test_outname, preload=True) assert_allclose(raw_sim_loaded[:][0], raw_sim[:][0], rtol=1e-6, atol=1e-20) del raw_sim, raw_sim_2 # with no cov (no noise) but with artifacts, most time periods should match # but the EOG/ECG channels should not for ecg, eog in ((True, False), (False, True), (True, True)): raw_sim_3 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=eog, ecg=ecg, random_state=seed) raw_sim_4 = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, blink=False, ecg=False, random_state=seed) picks = np.arange(len(raw.ch_names)) diff_picks = pick_types(raw.info, meg=False, ecg=ecg, eog=eog) these_picks = np.setdiff1d(picks, diff_picks) close = np.isclose(raw_sim_3[these_picks][0], raw_sim_4[these_picks][0], atol=1e-20) assert np.mean(close) > 0.7 far = ~np.isclose(raw_sim_3[diff_picks][0], raw_sim_4[diff_picks][0], atol=1e-20) assert np.mean(far) > 0.99 del raw_sim_3, raw_sim_4 # make sure it works with EEG-only and MEG-only raw_sim_meg = simulate_raw(raw.copy().pick_types(meg=True, eeg=False), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_eeg = simulate_raw(raw.copy().pick_types(meg=False, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) raw_sim_meeg = simulate_raw(raw.copy().pick_types(meg=True, eeg=True), stc, trans, src, sphere, cov=None, ecg=True, blink=True, random_state=seed) assert_allclose(np.concatenate((raw_sim_meg[:][0], raw_sim_eeg[:][0])), raw_sim_meeg[:][0], rtol=1e-7, atol=1e-20) del raw_sim_meg, raw_sim_eeg, raw_sim_meeg # check that raw-as-info is supported raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None) n_samp = int(round(raw.info['sfreq'])) for use_raw in (raw, raw.info): raw_sim_2 = simulate_raw(use_raw, stc, trans, src, sphere, cov=None, duration=1.) assert len(raw_sim_2.times) == n_samp assert_allclose(raw_sim[:, :n_samp][0], raw_sim_2[:, :n_samp][0], rtol=1e-5, atol=1e-30) del raw_sim, raw_sim_2 # check that different interpolations are similar given small movements raw_sim = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='linear') raw_sim_hann = simulate_raw(raw, stc, trans, src, sphere, cov=None, head_pos=head_pos_sim, interp='hann') assert_allclose(raw_sim[:][0], raw_sim_hann[:][0], rtol=1e-1, atol=1e-14) del raw_sim, raw_sim_hann # Make impossible transform (translate up into helmet) and ensure failure head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[1.][2, 3] -= 0.1 # z trans upward 10cm pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, ecg=False, blink=False, head_pos=head_pos_sim_err) pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, bem_fname, ecg=False, blink=False, head_pos=head_pos_sim_err) # other degenerate conditions pytest.raises(TypeError, simulate_raw, 'foo', stc, trans, src, sphere) pytest.raises(TypeError, simulate_raw, raw, 'foo', trans, src, sphere) pytest.raises(ValueError, simulate_raw, raw, stc.copy().crop(0, 0), trans, src, sphere) with pytest.raises(ValueError, match='duration cannot be None'): simulate_raw(raw.info, stc, trans, src, sphere) with pytest.raises(TypeError, match='must be an instance of Raw or Info'): simulate_raw(0, stc, trans, src, sphere) stc_bad = stc.copy() stc_bad.tstep += 0.1 pytest.raises(ValueError, simulate_raw, raw, stc_bad, trans, src, sphere) pytest.raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, cov=0) # wrong covariance type pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, chpi=True) # no cHPI info pytest.raises(ValueError, simulate_raw, raw, stc, trans, src, sphere, interp='foo') pytest.raises(TypeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=1.) pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=pos_fname) # ends up with t>t_end head_pos_sim_err = deepcopy(head_pos_sim) head_pos_sim_err[-1.] = head_pos_sim_err[1.] # negative time pytest.raises(RuntimeError, simulate_raw, raw, stc, trans, src, sphere, head_pos=head_pos_sim_err) raw_bad = raw.copy() raw_bad.info['dig'] = None pytest.raises(RuntimeError, simulate_raw, raw_bad, stc, trans, src, sphere, blink=True)
pos = np.zeros((len(rots), 10)) for ii in range(len(pos)): pos[ii] = np.concatenate([[ii], rot_to_quat(rots[ii]), center, [0] * 3]) pos[:, 0] += raw.first_samp / raw.info['sfreq'] # initial offset # Let's activate a vertices bilateral auditory cortices src = mne.read_source_spaces(src_fname) labels = mne.read_labels_from_annot('sample', 'aparc.a2009s', 'both', regexp='G_temp_sup-Plan_tempo', subjects_dir=subjects_dir) assert len(labels) == 2 # one left, one right vertices = [np.intersect1d(l.vertices, s['vertno']) for l, s in zip(labels, src)] data = np.zeros([sum(len(v) for v in vertices), int(raw.info['sfreq'])]) activation = np.hanning(int(raw.info['sfreq'] * 0.2)) * 1e-9 # nAm t_offset = int(np.ceil(0.2 * raw.info['sfreq'])) # 200 ms in (after baseline) data[:, t_offset:t_offset + len(activation)] = activation stc = mne.SourceEstimate(data, vertices, tmin=-0.2, tstep=1. / raw.info['sfreq']) # Simulate the movement raw = simulate_raw(raw, stc, trans_fname, src, bem_fname, head_pos=pos, interp='zero', n_jobs=-1) raw_stat = simulate_raw(raw, stc, trans_fname, src, bem_fname, head_pos=None, n_jobs=-1) # Save the results raw.save('simulated_movement_raw.fif', buffer_size_sec=1.) raw_stat.save('simulated_stationary_raw.fif', buffer_size_sec=1.) mne.chpi.write_head_quats('simulated_quats.pos', pos) stc.save('simulated_activation')
info.update(sfreq=sfreq, bads=[]) # Only use gradiometers picks = mne.pick_types(info, meg='grad', stim=True, exclude=()) mne.pick_info(info, picks, copy=False) # Define a covariance matrix for the simulated noise. In this tutorial, we use # a simple diagonal matrix. cov = mne.cov.make_ad_hoc_cov(info) cov['data'] *= (20. / snr)**2 # Scale the noise to achieve the desired SNR # Simulate the raw data, with a lowpass filter on the noise stcs = [(stc_signal, unit_impulse(n_samp, dtype=int) * 1), (stc_noise, unit_impulse(n_samp, dtype=int) * 2)] # stacked in time duration = (len(stc_signal.times) * 2) / sfreq raw = simulate_raw(info, stcs, forward=fwd) add_noise(raw, cov, iir_filter=[4, -4, 0.8], random_state=rand) ############################################################################### # We create an :class:`mne.Epochs` object containing two trials: one with # both noise and signal and one with just noise events = mne.find_events(raw, initial_event=True) tmax = (len(stc_signal.times) - 1) / sfreq epochs = mne.Epochs(raw, events, event_id=dict(signal=1, noise=2), tmin=0, tmax=tmax, baseline=None, preload=True)
data = 25e-9 * np.sin(2. * np.pi * 10. * n * times) data *= window return data times = raw.times[:int(raw.info['sfreq'] * epoch_duration)] src = read_source_spaces(src_fname) stc = simulate_sparse_stc(src, n_dipoles=n_dipoles, times=times, data_fun=data_fun, random_state=0) # look at our source data fig, ax = plt.subplots(1) ax.plot(times, 1e9 * stc.data.T) ax.set(ylabel='Amplitude (nAm)', xlabel='Time (sec)') mne.viz.utils.plt_show() ############################################################################## # Simulate raw data raw_sim = simulate_raw(raw, stc, trans_fname, src, bem_fname, cov='simple', iir_filter=[0.2, -0.2, 0.04], ecg=True, blink=True, n_jobs=1, verbose=True) raw_sim.plot() ############################################################################## # Plot evoked data events = find_events(raw_sim) # only 1 pos, so event number == 1 epochs = Epochs(raw_sim, events, 1, -0.2, epoch_duration) cov = compute_covariance(epochs, tmax=0., method='empirical', verbose='error') # quick calc evoked = epochs.average() evoked.plot_white(cov)
def SimulateRaw(amp1=50, amp2=100, freq=1., batch=1): """Create simulated raw data and events of two kinds Keyword Args: amp1 (float): amplitude of first condition effect amp2 (float): ampltiude of second condition effect, null hypothesis amp1=amp2 freq (float): Frequency of simulated signal 1. for ERP 10. for alpha batch (int): number of groups of 255 trials in each condition Returns: raw: simulated EEG MNE raw object with two event types event_id: dict of the two events for input to PreProcess() """ data_path = sample.data_path() raw_fname = data_path + '/MEG/sample/sample_audvis_raw.fif' trans_fname = data_path + '/MEG/sample/sample_audvis_raw-trans.fif' src_fname = data_path + '/subjects/sample/bem/sample-oct-6-src.fif' bem_fname = (data_path + '/subjects/sample/bem/sample-5120-5120-5120-bem-sol.fif') raw_single = mne.io.read_raw_fif(raw_fname, preload=True) raw_single.set_eeg_reference(projection=True) raw_single = raw_single.crop(0., 255.) raw_single = raw_single.copy().pick_types(meg=False, eeg=True, eog=True, stim=True) #concatenate 4 raws together to make 1000 trials raw = [] for i in range(batch): raw.append(raw_single) raw = concatenate_raws(raw) epoch_duration = 1. def data_fun(amp, freq): """Create function to create fake signal""" def data_fun_inner(times): """Create fake signal with no noise""" n_samp = len(times) window = np.zeros(n_samp) start, stop = [int(ii * float(n_samp) / 2) for ii in (0, 1)] window[start:stop] = np.hamming(stop - start) data = amp * 1e-9 * np.sin(2. * np.pi * freq * times) data *= window return data return data_fun_inner times = raw.times[:int(raw.info['sfreq'] * epoch_duration)] src = read_source_spaces(src_fname) stc_zero = simulate_sparse_stc(src, n_dipoles=1, times=times, data_fun=data_fun(amp1, freq), random_state=0) stc_one = simulate_sparse_stc(src, n_dipoles=1, times=times, data_fun=data_fun(amp2, freq), random_state=0) raw_sim_zero = simulate_raw(raw, stc_zero, trans_fname, src, bem_fname, cov='simple', blink=True, n_jobs=1, verbose=True) raw_sim_one = simulate_raw(raw, stc_one, trans_fname, src, bem_fname, cov='simple', blink=True, n_jobs=1, verbose=True) stim_pick = raw_sim_one.info['ch_names'].index('STI 014') raw_sim_one._data[stim_pick][np.where( raw_sim_one._data[stim_pick] == 1)] = 2 raw = concatenate_raws([raw_sim_zero, raw_sim_one]) event_id = {'CondZero': 1, 'CondOne': 2} return raw, event_id
n_noise_dipoles, times, data_fun=generate_random, random_state=config.random, labels=labels) ########################################################################### # Project to sensor space ########################################################################### stc = add_stcs(stc_signal, config.noise * stc_noise) raw = simulate_raw( info, stc, trans=None, src=None, bem=None, forward=fwd, cov=None, random_state=config.random, duration=config.trial_length, ) raw_list.append(raw) print('%02d/%02d' % (i + 1, config.n_trials)) raw = mne.concatenate_raws(raw_list) ############################################################################### # Use empty room noise as sensor noise ############################################################################### er_raw = mne.io.read_raw_fif(fname.ernoise, preload=True)
def test_simulate_round_trip(raw_data): """Test simulate_raw round trip calculations.""" # Check a diagonal round-trip raw, src, stc, trans, sphere = raw_data raw.pick_types(meg=True, stim=True) bem = read_bem_solution(bem_1_fname) old_bem = bem.copy() old_src = src.copy() old_trans = trans.copy() fwd = make_forward_solution(raw.info, trans, src, bem) # no omissions assert (sum(len(s['vertno']) for s in src) == sum(len(s['vertno']) for s in fwd['src']) == 36) # make sure things were not modified assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) data = np.eye(fwd['nsource']) raw.crop(0, (len(data) - 1) / raw.info['sfreq']) stc = SourceEstimate(data, [s['vertno'] for s in fwd['src']], 0, 1. / raw.info['sfreq']) for use_fwd in (None, fwd): if use_fwd is None: use_trans, use_src, use_bem = trans, src, bem else: use_trans = use_src = use_bem = None with pytest.deprecated_call(): this_raw = simulate_raw(raw, stc, use_trans, use_src, use_bem, cov=None, forward=use_fwd) this_raw.pick_types(meg=True, eeg=True) assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) this_fwd = convert_forward_solution(fwd, force_fixed=True) assert_allclose(this_raw[:][0], this_fwd['sol']['data'], atol=1e-12, rtol=1e-6) with pytest.raises(ValueError, match='If forward is not None then'): simulate_raw(raw.info, stc, trans, src, bem, forward=fwd) # Not iterable with pytest.raises(TypeError, match='SourceEstimate, tuple, or iterable'): simulate_raw(raw.info, 0., trans, src, bem, None) # STC with a source that `src` does not have assert 0 not in src[0]['vertno'] vertices = [[0, fwd['src'][0]['vertno'][0]], []] stc_bad = SourceEstimate(data[:2], vertices, 0, 1. / raw.info['sfreq']) with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw.info, stc_bad, trans, src, bem) assert 0 not in fwd['src'][0]['vertno'] with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw.info, stc_bad, None, None, None, forward=fwd) # dev_head_t mismatch fwd['info']['dev_head_t']['trans'][0, 0] = 1. with pytest.raises(ValueError, match='dev_head_t.*does not match'): simulate_raw(raw.info, stc, None, None, None, forward=fwd)
def simulate_raw_data(self): """ Simulates raw data """ def expand_sim_stc_data(orig_times, t_index, data, interval): template = np.zeros((data.shape[0], len(orig_times))) template[:, t_index:t_index + interval] = data return template print("Generating simulated raw data...") if not self.data_template: self.data_template = self.__create_data_template() if self.n_dipoles == 1: time_steps = int(self.samples_per_dipole * self.spacing_t_steps * (1 + self.empty_signal)) else: time_steps = int(self.samples_per_dipole * (self.n_simulations + self.spacing_t_steps) * (1 + self.empty_signal)) data_template = self.data_template.copy() data_template = data_template.crop( 0., data_template.times[time_steps]) # Crop a suitable piece of data t_delta = np.mean(np.gradient(data_template.times)) times = np.arange(time_steps) * t_delta sim_stc = simulate_sparse_stc( self.src, n_dipoles=0, times=times, data_fun=self.data_func) # Create empty time series s = 0 lh_labels = mne.Label(self.lh_labels, hemi="lh") rh_labels = mne.Label(self.rh_labels, hemi="rh") lh_labels.values = np.zeros(lh_labels.values.shape) rh_labels.values = np.zeros(rh_labels.values.shape) # TODO: selection of hemisphere(s) self.times_per_dipole = int(self.samples_per_dipole * (1 + self.empty_signal)) if self.n_dipoles == 1: print( "Simulating 1 dipole in each vertex of the right hemisphere.") for rh in range(0, len(rh_labels.values)): template = sim_stc.copy() #lh_labels2 = lh_labels #lh_labels2.values[rh] = 1. rh_labels2 = rh_labels rh_labels2.values[rh] = 1. sim_stc2 = simulate_sparse_stc( self.src, n_dipoles=1, times=times[s:s + self.times_per_dipole], data_fun=self.data_func, labels=[rh_labels2]) # TODO: use labels for deterministically simulating all vertices sim_stc.expand(sim_stc2.vertices), sim_stc2.expand( sim_stc.vertices), template.expand(sim_stc2.vertices) template.data[:, :] = expand_sim_stc_data( times, s, sim_stc2.data, self.times_per_dipole) sim_stc += template s += self.times_per_dipole else: print("Simulating up to %s dipoles on the right hemisphere." % self.n_dipoles) for t in range(0, len(times), self.times_per_dipole): template = sim_stc.copy() dipoles = random.randint(2, self.n_dipoles) label_indices = sorted( random.sample(range(0, len(rh_labels)), dipoles)) chosen_label = rh_labels chosen_labels = [] for l in label_indices: chosen_label.values[l] = 1. chosen_labels.append(chosen_label) chosen_label.values[l] = 0. # TODO there may be a bug in MNE-Python 0.14.1 where forward model dipoles are mapped to non-unique # source space vertices, e.g. in this case rh vertices 298 and 411 both map to source space vertex # 112071 which raises an error in source_estimate.py at line 434 try: sim_stc2 = simulate_sparse_stc( self.src, n_dipoles=dipoles, times=times[t:t + self.times_per_dipole], data_fun=self.data_func, labels=chosen_labels) except ValueError: s -= self.times_per_dipole continue sim_stc.expand(sim_stc2.vertices), sim_stc2.expand( sim_stc.vertices), template.expand(sim_stc2.vertices) template.data[:, :] = expand_sim_stc_data( times, t, sim_stc2.data, self.times_per_dipole) sim_stc.data[:, :] = sim_stc.data + template.data t += 1 if s >= self.n_simulations: break # Remove unnecessary zeros from series # sim_stc._data = sim_stc.data[:, ~np.all(abs(sim_stc.data) < 1e-20, axis=0)] # TODO: add some zeroes to compensate? #sim_stc.times = sim_stc.times[:sim_stc.data.shape[1]] #template_times = np.arange(sim_stc.data.shape[1]) * (t_delta * (1 + self.empty_signal)) #data_template = data_template.crop(0., template_times[-1]) self.sim_data = simulate_raw(data_template, sim_stc, self.trans_path, self.src, self.bem_path, cov='simple', iir_filter=self.iir_filter, ecg=self.ecg, blink=self.blink, n_jobs=CPU_THREADS, verbose=self.verbose, use_cps=True) # self.cov = self.compute_covariance(self.simulate_evokeds(self.sim_data)) self.sim_data = self.raw_preprocessing(self.sim_data) self.sim_stc = sim_stc self.cov = mne.compute_raw_covariance(self.sim_data, reject=self.reject, n_jobs=CPU_THREADS) return self.sim_data, self.sim_stc
def test_simulate_round_trip(raw_data): """Test simulate_raw round trip calculations.""" # Check a diagonal round-trip raw, src, stc, trans, sphere = raw_data raw.pick_types(meg=True, stim=True) bem = read_bem_solution(bem_1_fname) old_bem = bem.copy() old_src = src.copy() old_trans = trans.copy() fwd = make_forward_solution(raw.info, trans, src, bem) # no omissions assert (sum(len(s['vertno']) for s in src) == sum(len(s['vertno']) for s in fwd['src']) == 36) # make sure things were not modified assert ( old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0]['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) data = np.eye(fwd['nsource']) raw.crop(0, (len(data) - 1) / raw.info['sfreq']) stc = SourceEstimate(data, [s['vertno'] for s in fwd['src']], 0, 1. / raw.info['sfreq']) for use_fwd in (None, fwd): if use_fwd is None: use_trans, use_src, use_bem = trans, src, bem else: use_trans = use_src = use_bem = None with pytest.deprecated_call(): this_raw = simulate_raw(raw, stc, use_trans, use_src, use_bem, cov=None, forward=use_fwd) this_raw.pick_types(meg=True, eeg=True) assert (old_bem['surfs'][0]['coord_frame'] == bem['surfs'][0] ['coord_frame']) assert trans == old_trans _compare_source_spaces(src, old_src) this_fwd = convert_forward_solution(fwd, force_fixed=True) assert_allclose(this_raw[:][0], this_fwd['sol']['data'], atol=1e-12, rtol=1e-6) with pytest.raises(ValueError, match='If forward is not None then'): simulate_raw(raw.info, stc, trans, src, bem, forward=fwd) # Not iterable with pytest.raises(TypeError, match='SourceEstimate, tuple, or iterable'): simulate_raw(raw.info, 0., trans, src, bem, None) # STC with a source that `src` does not have assert 0 not in src[0]['vertno'] vertices = [[0, fwd['src'][0]['vertno'][0]], []] stc_bad = SourceEstimate(data[:2], vertices, 0, 1. / raw.info['sfreq']) with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw.info, stc_bad, trans, src, bem) assert 0 not in fwd['src'][0]['vertno'] with pytest.warns(RuntimeWarning, match='1 of 2 SourceEstimate vertices'): simulate_raw(raw.info, stc_bad, None, None, None, forward=fwd) # dev_head_t mismatch fwd['info']['dev_head_t']['trans'][0, 0] = 1. with pytest.raises(ValueError, match='dev_head_t.*does not match'): simulate_raw(raw.info, stc, None, None, None, forward=fwd)
times = raw.times[:int(raw.info['sfreq'] * epoch_duration)] fwd = mne.read_forward_solution(fwd_fname) src = fwd['src'] stc = simulate_sparse_stc(src, n_dipoles=n_dipoles, times=times, data_fun=data_fun, random_state=rng) # look at our source data fig, ax = plt.subplots(1) ax.plot(times, 1e9 * stc.data.T) ax.set(ylabel='Amplitude (nAm)', xlabel='Time (sec)') mne.viz.utils.plt_show() ############################################################################## # Simulate raw data raw_sim = simulate_raw(raw.info, [stc] * 10, forward=fwd, verbose=True) cov = make_ad_hoc_cov(raw_sim.info) add_noise(raw_sim, cov, iir_filter=[0.2, -0.2, 0.04], random_state=rng) add_ecg(raw_sim, random_state=rng) add_eog(raw_sim, random_state=rng) raw_sim.plot() ############################################################################## # Plot evoked data events = find_events(raw_sim) # only 1 pos, so event number == 1 epochs = Epochs(raw_sim, events, 1, tmin=-0.2, tmax=epoch_duration) cov = compute_covariance(epochs, tmax=0., method='empirical', verbose='error') # quick calc evoked = epochs.average() evoked.plot_white(cov, time_unit='s')
picks = mne.pick_types(info, meg='grad', stim=True, exclude=()) mne.pick_info(info, picks, copy=False) # This is the raw object that will be used as a template for the simulation. raw = mne.io.RawArray(np.zeros((info['nchan'], len(stc.times))), info) # Define a covariance matrix for the simulated noise. In this tutorial, we use # a simple diagonal matrix. cov = mne.cov.make_ad_hoc_cov(info) cov['data'] *= (20. / snr)**2 # Scale the noise to achieve the desired SNR # Simulate the raw data, with a lowpass filter on the noise raw = simulate_raw(raw, stc, trans_fname, src_fname, bem_fname, cov=cov, random_state=rand, iir_filter=[4, -4, 0.8]) ############################################################################### # We create an :class:`mne.Epochs` object containing two trials: one with # both noise and signal and one with just noise t0 = raw.first_samp # First sample in the data t1 = t0 + n_times - 1 # Sample just before the second trial epochs = mne.Epochs( raw, events=np.array([[t0, 0, 1], [t1, 0, 2]]), event_id=dict(signal=1, noise=2), tmin=0,
def simulate_eeg(label_names, signal_generator, epoch_duration=3.0, n_trials=10): # Getting the paths to filenames of dataset data_path = sample.data_path() raw_fname = data_path + '/MEG/sample/sample_audvis_raw.fif' trans_fname = data_path + '/MEG/sample/sample_audvis_raw-trans.fif' bem_fname = (data_path + '/subjects/sample/bem/sample-5120-5120-5120-bem-sol.fif') # Load real data as the template raw = mne.io.read_raw_fif(raw_fname) raw = raw.crop(0., n_trials * epoch_duration) # Loading parameters for the forward solution fwd_fname = data_path + '/MEG/sample/sample_audvis-meg-eeg-oct-6-fwd.fif' fwd = mne.read_forward_solution(fwd_fname, force_fixed=True, surf_ori=True) fwd = mne.pick_types_forward(fwd, meg=False, eeg=True, ref_meg=False, exclude=raw.info['bads']) # Get the labels and their centers labels = [ mne.read_label(data_path + '/MEG/sample/labels/%s.label' % ln) for ln in label_names ] subjects_dir = data_path + '/subjects' hemi_to_ind = {'lh': 0, 'rh': 1} for i, label in enumerate(labels): # The `center_of_mass` function needs labels to have values. labels[i].values.fill(1.) # Restrict the eligible vertices to be those on the surface under # consideration and within the label. surf_vertices = fwd['src'][hemi_to_ind[label.hemi]]['vertno'] restrict_verts = np.intersect1d(surf_vertices, label.vertices) com = labels[i].center_of_mass(subject='sample', subjects_dir=subjects_dir, restrict_vertices=restrict_verts, surf='white') # Convert the center of vertex index from surface vertex list # to Label's vertex list. cent_idx = np.where(label.vertices == com)[0][0] # Create a mask with 1 at center vertex and zeros elsewhere. labels[i].values.fill(0.) labels[i].values[cent_idx] = 1. n_labels = len(label_names) times = raw.times[:int(raw.info['sfreq'] * epoch_duration)] signal = signal_generator(n_labels, times) # Generate the sources in each label dt = times[1] - times[0] stc = simulate_stc(fwd['src'], labels, signal, times[0], dt, value_fun=lambda x: x) # Simulate raw data raw_sim = simulate_raw(raw, stc, trans_fname, fwd['src'], bem_fname, cov='simple', iir_filter=[2, -2, 0.4], ecg=False, blink=False, n_jobs=1, verbose=True) # Get just the EEG data and the stimulus channel raw_eeg = raw_sim.load_data().pick_types(meg=False, eeg=True, stim=True) return raw_eeg
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.)
len(s_dict['lab'].vertices) # Generate a template raw object raw_template = mne.io.RawArray(np.zeros((len(s_dict['info']['chs']), stc_activation.shape[1])), info=s_dict['info']) # Get scalar for noise covariance to achieve desired SNR noiseless_act = np.ones((1, 3)) * sim_amplitude raw_template_noiseless = mne.io.RawArray(np.zeros((len(s_dict['info']['chs']), noiseless_act.shape[1])), info=s_dict['info']) stc_noiseless = simulate_stc(subj_d[di]['inv']['src'], [subj_d[di]['lab']], stc_data=noiseless_act, tmin=0, tstep=0.001) eeg_noiseless = simulate_raw(raw_template_noiseless, stc_noiseless, s_dict['inv']['mri_head_t'], src=s_dict['inv']['src'], bem=s_dict['bem_fname'], cov=None, blink=True, n_jobs=n_jobs, verbose=False) s_dict['noise_scale'] = get_noise_scale(eeg_noiseless, s_dict) print 'Noise covariance scalar calculated: %s' % s_dict['noise_scale'] # Simulate cortical activations. # Maintain: Noise # Switch: Noise + [unit current / label area] in RTPJ raw_sim = [] stc_est = [] stc_est_sph = [] for act_scale, trial_type in zip([0, 1], ['switch', 'maintain']): # Generate simulated stc activation stc_sim = simulate_stc(subj_d[di]['inv']['src'], [subj_d[di]['lab']],