def test_rotate_gauss(self): # test 1 time = 20 # random day nmax = 4 kmax = 2 s = timer() base_1, base_2, base_3 = c.basevectors_gsm(time) matrix = c.rotate_gauss(nmax, kmax, base_1, base_2, base_3) e = timer() # load matfile test = load_matfile(MATFILE_PATH, 'test_rotate_gauss') matrix_mat = test['m_all'].transpose() # transposed in Matlab code runtime = test['runtime'] print(" Time for matrix computation (Python): ", e - s) print(" Time for matrix computation (Matlab): {:}".format( runtime[0, 0])) # absolute tolerance to account for close-to-zero matrix entries self.assertIsNone(np.testing.assert_allclose( matrix, matrix_mat, atol=1e-8)) # test 2 # rotate around y-axis to have dipole axis aligned with x-axis base_1 = np.array([0, 0, -1]) base_2 = np.array([0, 1, 0]) base_3 = np.array([1, 0, 0]) nmax = 1 # only dipole terms kmax = 1 matrix = c.rotate_gauss(nmax, kmax, base_1, base_2, base_3) desired = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) self.assertIsNone(np.testing.assert_allclose( matrix, desired, atol=1e-10)) # test 3 time = np.arange(9).reshape((3, 3)) # random day nmax = 4 kmax = 2 base_1, base_2, base_3 = c.basevectors_gsm(time) matrix = c.rotate_gauss(nmax, kmax, base_1, base_2, base_3) self.assertEqual(matrix.shape, (3, 3, 24, 8))
def test_matrix_geo_to_base(self): theta_geo = np.linspace(1, 179, 10) phi_geo = np.linspace(-179, 179, 10) time = np.linspace(-300, 10000, 10) for reference in ['sm', 'gsm', 'mag']: print(f' Testing {reference.upper()}') if reference == 'mag': base_1, base_2, base_3 = c.basevectors_mag() elif reference == 'sm': base_1, base_2, base_3 = c.basevectors_sm(time) elif reference == 'gsm': base_1, base_2, base_3 = c.basevectors_gsm(time) theta_ref, phi_ref, R = c.matrix_geo_to_base( theta_geo, phi_geo, base_1, base_2, base_3, inverse=False) theta_geo2, phi_geo2, R2 = c.matrix_geo_to_base( theta_ref, phi_ref, base_1, base_2, base_3, inverse=True) self.assertIsNone( np.testing.assert_allclose(theta_geo, theta_geo2)) self.assertIsNone( np.testing.assert_allclose(phi_geo, phi_geo2)) R_full = np.matmul(R, R2) R_full2 = np.zeros((theta_geo.size, 3, 3)) for n in range(3): R_full2[..., n, n] = 1. self.assertIsNone( np.testing.assert_allclose(R_full, R_full2, atol=1e-7))
def test_rotate_gsm_vector(self): time = 20 nmax = 1 kmax = 1 radius = R_REF theta_geo = 90/6 phi_geo = 90/8 g_gsm = np.array([1, 2, -1]) base_1, base_2, base_3 = c.basevectors_gsm(time) matrix = c.rotate_gauss(nmax, kmax, base_1, base_2, base_3) g_geo = np.matmul(matrix, g_gsm) B_geo_1 = m.synth_values(g_geo, radius, theta_geo, phi_geo) B_geo_1 = np.array(B_geo_1) theta_gsm, phi_gsm, R = c.matrix_geo_to_base(theta_geo, phi_geo, base_1, base_2, base_3) B_gsm = m.synth_values(g_gsm, radius, theta_gsm, phi_gsm) B_gsm = np.array(B_gsm) B_geo_2 = np.matmul(R.transpose(), B_gsm) self.assertIsNone(np.testing.assert_allclose( B_geo_1, B_geo_2, rtol=1e-5))
def test_synth_rotate_gauss(self): """ Tests the accuracy of the Fourier representation of tranformation matrices by comparing them with directly computed matrices (they are considered correct). """ for reference in ['gsm', 'sm']: print(f' Testing {reference.upper()} frame of reference.') # load spectrum to synthesize matrices in time-domain filepath = c.basicConfig[f'file.{reference.upper()}_spectrum'] try: data = np.load(filepath) except FileNotFoundError as e: raise ValueError( 'Reference file "frequency_spectrum_{reference}.npz"' ' not found in "chaosmagpy/lib/".' ' Correct reference?') from e frequency = data['frequency'] # oscillations per day spectrum = data['spectrum'] print(" Testing 50 times within 1996 and 2024.") for time in np.linspace(-4 * 365.25, 24 * 365.25, 50): matrix_time = c.synth_rotate_gauss(time, frequency, spectrum, scaled=data['scaled']) nmax = int(np.sqrt(spectrum.shape[1] + 1) - 1) kmax = int(np.sqrt(spectrum.shape[2] + 1) - 1) if reference == 'gsm': base_1, base_2, base_3 = c.basevectors_gsm(time) elif reference == 'sm': base_1, base_2, base_3 = c.basevectors_sm(time) matrix = c.rotate_gauss(nmax, kmax, base_1, base_2, base_3) stat = np.amax(np.abs(matrix - np.squeeze(matrix_time))) print(' Computed year {:4.2f}, ' 'max. abs. error = {:.3e}'.format( time / 365.25 + 2000, stat), end='') if stat > 0.001: print(' ' + min(int(stat / 0.001), 10) * '*') else: print('') self.assertIsNone( np.testing.assert_allclose(matrix, np.squeeze(matrix_time), rtol=1e-1, atol=1e-1))
def test_geo_to_base(self): time = np.linspace(1, 100, 10) theta_geo = np.linspace(1, 179, 10) phi_geo = np.linspace(-180, 179, 10) # TEST GSM COORDINATES # GSM test: load matfile test = load_matfile(MATFILE_PATH, 'test_geo_to_gsm') # reduce 2-D matrix to 1-D vectors theta_gsm_mat = np.ravel(test['theta_gsm']) phi_gsm_mat = np.ravel(test['phi_gsm']) gsm_1, gsm_2, gsm_3 = c.basevectors_gsm(time) theta_gsm, phi_gsm = c.geo_to_base( theta_geo, phi_geo, gsm_1, gsm_2, gsm_3) self.assertIsNone(np.testing.assert_allclose(theta_gsm, theta_gsm_mat)) self.assertIsNone(np.testing.assert_allclose(phi_gsm, phi_gsm_mat)) # test the inverse option: GEO -> GSM -> GEO theta_geo2, phi_geo2 = c.geo_to_base( theta_gsm, phi_gsm, gsm_1, gsm_2, gsm_3, inverse=True) self.assertIsNone(np.testing.assert_allclose(theta_geo, theta_geo2)) self.assertIsNone(np.testing.assert_allclose( phi_geo, c.center_azimuth(phi_geo2))) # test the inverse option: GSM -> GEO -> GSM theta_gsm2, phi_gsm2 = c.geo_to_base( theta_geo2, phi_geo2, gsm_1, gsm_2, gsm_3) self.assertIsNone(np.testing.assert_allclose(theta_gsm, theta_gsm2)) self.assertIsNone(np.testing.assert_allclose( c.center_azimuth(phi_gsm), c.center_azimuth(phi_gsm2))) # TEST SM COORDINATES # SM test: load matfile test = load_matfile(MATFILE_PATH, 'test_geo_to_sm') # reduce 2-D matrix to 1-D vectors theta_sm_mat = np.ravel(test['theta_sm']) phi_sm_mat = np.ravel(test['phi_sm']) sm_1, sm_2, sm_3 = c.basevectors_sm(time) theta_sm, phi_sm = c.geo_to_base( theta_geo, phi_geo, sm_1, sm_2, sm_3) self.assertIsNone(np.testing.assert_allclose(theta_sm, theta_sm_mat)) self.assertIsNone(np.testing.assert_allclose(phi_sm, phi_sm_mat)) # test the inverse option: GEO -> SM -> GEO theta_geo2, phi_geo2 = c.geo_to_base( theta_sm, phi_sm, sm_1, sm_2, sm_3, inverse=True) self.assertIsNone(np.testing.assert_allclose(theta_geo, theta_geo2)) self.assertIsNone(np.testing.assert_allclose(phi_geo, phi_geo2)) # test the inverse option: SM -> GEO -> SM theta_sm2, phi_sm2 = c.geo_to_base( theta_geo2, phi_geo2, sm_1, sm_2, sm_3) self.assertIsNone(np.testing.assert_allclose(theta_sm, theta_sm2)) self.assertIsNone(np.testing.assert_allclose(phi_sm, phi_sm2))