def test_multipolar_bases(): """Test multipolar moment basis calculation using sensor information""" from scipy.io import loadmat # Test our basis calculations info = read_info(raw_fname) coils = _prep_meg_channels(info, accurate=True, elekta_defs=True)[0] # Check against a known benchmark sss_data = loadmat(bases_fname) for origin in ((0, 0, 0.04), (0, 0.02, 0.02)): o_str = ''.join('%d' % (1000 * n) for n in origin) S_tot = _sss_basis_basic(origin, coils, int_order, ext_order, method='alternative') # Test our real<->complex conversion functions S_tot_complex = _bases_real_to_complex(S_tot, int_order, ext_order) S_tot_round = _bases_complex_to_real(S_tot_complex, int_order, ext_order) assert_allclose(S_tot, S_tot_round, atol=1e-7) S_tot_mat = np.concatenate( [sss_data['Sin' + o_str], sss_data['Sout' + o_str]], axis=1) S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8) assert_allclose(S_tot, S_tot_mat_real, rtol=1e-4, atol=1e-8) # Now normalize our columns S_tot /= np.sqrt(np.sum(S_tot * S_tot, axis=0))[np.newaxis] S_tot_complex /= np.sqrt( np.sum((S_tot_complex * S_tot_complex.conj()).real, axis=0))[np.newaxis] # Check against a known benchmark S_tot_mat = np.concatenate( [sss_data['SNin' + o_str], sss_data['SNout' + o_str]], axis=1) # Check this roundtrip S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8) # Now test our optimized version S_tot = _sss_basis_basic(origin, coils, int_order, ext_order) S_tot_fast = _sss_basis(origin, coils, int_order, ext_order) S_tot_fast *= _get_coil_scale(coils) # there are some sign differences for columns (order/degrees) # in here, likely due to Condon-Shortley. Here we use a # Magnetometer channel to figure out the flips because the # gradiometer channels have effectively zero values for first three # external components (i.e., S_tot[grad_picks, 80:83]) flips = (np.sign(S_tot_fast[2]) != np.sign(S_tot[2])) flips = 1 - 2 * flips assert_allclose(S_tot, S_tot_fast * flips, atol=1e-16)
def test_multipolar_bases(): """Test multipolar moment basis calculation using sensor information""" from scipy.io import loadmat # Test our basis calculations info = read_info(raw_fname) coils = _prep_meg_channels(info, accurate=True, elekta_defs=True)[0] # Check against a known benchmark sss_data = loadmat(bases_fname) for origin in ((0, 0, 0.04), (0, 0.02, 0.02)): o_str = ''.join('%d' % (1000 * n) for n in origin) S_tot = _sss_basis_basic(origin, coils, int_order, ext_order, method='alternative') # Test our real<->complex conversion functions S_tot_complex = _bases_real_to_complex(S_tot, int_order, ext_order) S_tot_round = _bases_complex_to_real(S_tot_complex, int_order, ext_order) assert_allclose(S_tot, S_tot_round, atol=1e-7) S_tot_mat = np.concatenate([sss_data['Sin' + o_str], sss_data['Sout' + o_str]], axis=1) S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8) assert_allclose(S_tot, S_tot_mat_real, rtol=1e-4, atol=1e-8) # Now normalize our columns S_tot /= np.sqrt(np.sum(S_tot * S_tot, axis=0))[np.newaxis] S_tot_complex /= np.sqrt(np.sum( (S_tot_complex * S_tot_complex.conj()).real, axis=0))[np.newaxis] # Check against a known benchmark S_tot_mat = np.concatenate([sss_data['SNin' + o_str], sss_data['SNout' + o_str]], axis=1) # Check this roundtrip S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8) # Now test our optimized version S_tot = _sss_basis_basic(origin, coils, int_order, ext_order) S_tot_fast = _sss_basis(origin, coils, int_order, ext_order) S_tot_fast *= _get_coil_scale(coils) # there are some sign differences for columns (order/degrees) # in here, likely due to Condon-Shortley. Here we use a # Magnetometer channel to figure out the flips because the # gradiometer channels have effectively zero values for first three # external components (i.e., S_tot[grad_picks, 80:83]) flips = (np.sign(S_tot_fast[2]) != np.sign(S_tot[2])) flips = 1 - 2 * flips assert_allclose(S_tot, S_tot_fast * flips, atol=1e-16)
def test_multipolar_bases(): """Test multipolar moment basis calculation using sensor information""" from scipy.io import loadmat # Test our basis calculations info = read_info(raw_fname) coils = _prep_meg_channels(info, accurate=True, elekta_defs=True, verbose=False)[0] # Check against a known benchmark sss_data = loadmat(bases_fname) for origin in ((0, 0, 0.04), (0, 0.02, 0.02)): o_str = ''.join('%d' % (1000 * n) for n in origin) S_tot = _sss_basis(origin, coils, int_order, ext_order, method='alternative') # Test our real<->complex conversion functions S_tot_complex = _bases_real_to_complex(S_tot, int_order, ext_order) S_tot_round = _bases_complex_to_real(S_tot_complex, int_order, ext_order) assert_allclose(S_tot, S_tot_round, atol=1e-7) S_tot_mat = np.concatenate([sss_data['Sin' + o_str], sss_data['Sout' + o_str]], axis=1) mu0 = 4e-7 * np.pi # Permeability of vacuum S_tot_mat /= mu0 # divide out the magnetic permeability S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8) assert_allclose(S_tot, S_tot_mat_real, rtol=1e-4, atol=1e-8) # Now normalize our columns S_tot /= np.sqrt(np.sum(S_tot * S_tot, axis=0))[np.newaxis] S_tot_complex /= np.sqrt(np.sum( (S_tot_complex * S_tot_complex.conj()).real, axis=0))[np.newaxis] # Check against a known benchmark S_tot_mat = np.concatenate([sss_data['SNin' + o_str], sss_data['SNout' + o_str]], axis=1) # Check this roundtrip S_tot_mat_real = _bases_complex_to_real(S_tot_mat, int_order, ext_order) S_tot_mat_round = _bases_real_to_complex(S_tot_mat_real, int_order, ext_order) assert_allclose(S_tot_mat, S_tot_mat_round, atol=1e-7) assert_allclose(S_tot_complex, S_tot_mat, rtol=1e-4, atol=1e-8)
def test_maxwell_filter(): """Test multipolar moment and Maxwell filter""" # TODO: Future tests integrate with mne/io/tests/test_proc_history # Load testing data (raw, SSS std origin, SSS non-standard origin) with warnings.catch_warnings(record=True): # maxshield raw = Raw(raw_fname, preload=False, proj=False, allow_maxshield=True).crop(0., 1., False) raw.preload_data() with warnings.catch_warnings(record=True): # maxshield, naming sss_std = Raw(sss_std_fname, preload=True, proj=False, allow_maxshield=True) sss_nonStd = Raw(sss_nonstd_fname, preload=True, proj=False, allow_maxshield=True) raw_err = Raw(raw_fname, preload=False, proj=True, allow_maxshield=True).crop(0., 0.1, False) assert_raises(RuntimeError, maxwell.maxwell_filter, raw_err) # Create coils all_coils, _, _, meg_info = _prep_meg_channels(raw.info, ignore_ref=True, elekta_defs=True) picks = [ raw.info['ch_names'].index(ch) for ch in [coil['chname'] for coil in all_coils] ] coils = [all_coils[ci] for ci in picks] ncoils = len(coils) int_order, ext_order = 8, 3 n_int_bases = int_order**2 + 2 * int_order n_ext_bases = ext_order**2 + 2 * ext_order nbases = n_int_bases + n_ext_bases # Check number of bases computed correctly assert_equal(maxwell.get_num_moments(int_order, ext_order), nbases) # Check multipolar moment basis set S_in, S_out = maxwell._sss_basis(origin=np.array([0, 0, 40]), coils=coils, int_order=int_order, ext_order=ext_order) assert_equal(S_in.shape, (ncoils, n_int_bases), 'S_in has incorrect shape') assert_equal(S_out.shape, (ncoils, n_ext_bases), 'S_out has incorrect shape') # Test sss computation at the standard head origin raw_sss = maxwell.maxwell_filter(raw, origin=[0., 0., 40.], int_order=int_order, ext_order=ext_order) assert_array_almost_equal(raw_sss._data[picks, :], sss_std._data[picks, :], decimal=11, err_msg='Maxwell filtered data at ' 'standard origin incorrect.') # Confirm SNR is above 100 bench_rms = np.sqrt(np.mean(sss_std._data[picks, :]**2, axis=1)) error = raw_sss._data[picks, :] - sss_std._data[picks, :] error_rms = np.sqrt(np.mean(error**2, axis=1)) assert_true(np.mean(bench_rms / error_rms) > 1000, 'SNR < 1000') # Test sss computation at non-standard head origin raw_sss = maxwell.maxwell_filter(raw, origin=[0., 20., 20.], int_order=int_order, ext_order=ext_order) assert_array_almost_equal(raw_sss._data[picks, :], sss_nonStd._data[picks, :], decimal=11, err_msg='Maxwell filtered data at non-std ' 'origin incorrect.') # Confirm SNR is above 100 bench_rms = np.sqrt(np.mean(sss_nonStd._data[picks, :]**2, axis=1)) error = raw_sss._data[picks, :] - sss_nonStd._data[picks, :] error_rms = np.sqrt(np.mean(error**2, axis=1)) assert_true(np.mean(bench_rms / error_rms) > 1000, 'SNR < 1000') # Check against SSS functions from proc_history sss_info = raw_sss.info['proc_history'][0]['max_info'] assert_equal(maxwell.get_num_moments(int_order, 0), proc_history._get_sss_rank(sss_info))
def test_maxwell_filter(): """Test multipolar moment and Maxwell filter""" # TODO: Future tests integrate with mne/io/tests/test_proc_history # Load testing data (raw, SSS std origin, SSS non-standard origin) with warnings.catch_warnings(record=True): # maxshield raw = Raw(raw_fname, preload=False, proj=False, allow_maxshield=True).crop(0., 1., False) raw.load_data() with warnings.catch_warnings(record=True): # maxshield, naming sss_std = Raw(sss_std_fname, preload=True, proj=False, allow_maxshield=True) sss_nonStd = Raw(sss_nonstd_fname, preload=True, proj=False, allow_maxshield=True) raw_err = Raw(raw_fname, preload=False, proj=True, allow_maxshield=True).crop(0., 0.1, False) assert_raises(RuntimeError, maxwell.maxwell_filter, raw_err) # Create coils all_coils, _, _, meg_info = _prep_meg_channels(raw.info, ignore_ref=True, elekta_defs=True) picks = [raw.info['ch_names'].index(ch) for ch in [coil['chname'] for coil in all_coils]] coils = [all_coils[ci] for ci in picks] ncoils = len(coils) int_order, ext_order = 8, 3 n_int_bases = int_order ** 2 + 2 * int_order n_ext_bases = ext_order ** 2 + 2 * ext_order nbases = n_int_bases + n_ext_bases # Check number of bases computed correctly assert_equal(maxwell.get_num_moments(int_order, ext_order), nbases) # Check multipolar moment basis set S_in, S_out = maxwell._sss_basis(origin=np.array([0, 0, 40]), coils=coils, int_order=int_order, ext_order=ext_order) assert_equal(S_in.shape, (ncoils, n_int_bases), 'S_in has incorrect shape') assert_equal(S_out.shape, (ncoils, n_ext_bases), 'S_out has incorrect shape') # Test sss computation at the standard head origin raw_sss = maxwell.maxwell_filter(raw, origin=[0., 0., 40.], int_order=int_order, ext_order=ext_order) assert_array_almost_equal(raw_sss._data[picks, :], sss_std._data[picks, :], decimal=11, err_msg='Maxwell filtered data at ' 'standard origin incorrect.') # Confirm SNR is above 100 bench_rms = np.sqrt(np.mean(sss_std._data[picks, :] ** 2, axis=1)) error = raw_sss._data[picks, :] - sss_std._data[picks, :] error_rms = np.sqrt(np.mean(error ** 2, axis=1)) assert_true(np.mean(bench_rms / error_rms) > 1000, 'SNR < 1000') # Test sss computation at non-standard head origin raw_sss = maxwell.maxwell_filter(raw, origin=[0., 20., 20.], int_order=int_order, ext_order=ext_order) assert_array_almost_equal(raw_sss._data[picks, :], sss_nonStd._data[picks, :], decimal=11, err_msg='Maxwell filtered data at non-std ' 'origin incorrect.') # Confirm SNR is above 100 bench_rms = np.sqrt(np.mean(sss_nonStd._data[picks, :] ** 2, axis=1)) error = raw_sss._data[picks, :] - sss_nonStd._data[picks, :] error_rms = np.sqrt(np.mean(error ** 2, axis=1)) assert_true(np.mean(bench_rms / error_rms) > 1000, 'SNR < 1000') # Check against SSS functions from proc_history sss_info = raw_sss.info['proc_history'][0]['max_info'] assert_equal(maxwell.get_num_moments(int_order, 0), proc_history._get_sss_rank(sss_info))