def test_build_smoothing_constraints(self, name, model, expected_H, expected_h): sm = define_models.ModelParams('junk') # need PREM path only H, h, label = weights._build_smoothing_constraints(model, sm) self.assertEqual(label, 'roughness') np.testing.assert_allclose(H, expected_H) np.testing.assert_allclose(h, expected_h) n_bls = model.boundary_inds.shape[0] n_layers = expected_h.shape[0] - n_bls damp_s = pd.DataFrame({'Depth': np.cumsum(model.thickness)}) damp_t = pd.DataFrame({'Depth': [0] * n_bls}) layers = define_models.EarthLayerIndices( np.arange(2), np.arange(2, 3), np.arange(3, 4), np.arange(4, n_layers), np.arange(n_layers, n_layers + n_bls), np.arange(0)) weights._set_layer_values( (1, 1, 1, 1, 10), layers, damp_s, damp_t, 'roughness', ) H_sc, h_sc = weights._damp_constraints((H, h, label), damp_s, damp_t) self.assertEqual(label, 'roughness') np.testing.assert_allclose(H_sc, expected_H) np.testing.assert_allclose(h_sc, expected_h)
def run_test_G(): model_params = define_models.ModelParams('testcase', np.array([25., 120.]), np.array([5, 20]), np.array([10, 30]), np.array([3.6, 4.0, 4.4, 4.3]), np.array([0, 300])) periods = [5, 8, 10, 15, 20, 30, 40, 60, 80, 100, 120] model_perturbation = ([1.05] * 5 + [0.95] * 5 + [1.02] * 5 + [0.99] * 5 + [1.06] * 5 + [0.97] * 5 + [1.01] * 5 + [1] + [1.1] * 2) dc_mineos, dc_Gdm = test_G(model_params, periods, model_perturbation) print(dc_mineos, dc_Gdm)
def test_damping(): #n_iter lab = 'roughness_1b' print(lab) vs_SL14 = pd.read_csv('data/earth_models/CP_SL14.csv', header=None).values cp_outline = pd.read_csv('data/earth_models/CP_outline.csv').values vs_SLall = pd.read_csv('data/earth_models/SchmandtLinVs_only.csv', header=None).values.flatten() # To save spave, have saved the lat, lon, depth ranges of the Schmandt & Lin # model just as three lines in a csv vs_lats = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=0, nrows=1, header=None).values.flatten() vs_lons = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=1, nrows=1, header=None).values.flatten() vs_deps = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=2, nrows=1, header=None).values.flatten() vs_SLall = vs_SLall.reshape((vs_lats.size, vs_lons.size, vs_deps.size)) for lat in [40]: #[33]: #range(33, 41, 2):#range(34, 41): for lon in [-115]: #[-111, -115]: #range(-115, -105, 2): for t_LAB in [5.]: #[30., 25., 20., 15., 10.]: location = (lat, lon) print('*********************** {}N, {}W, {}km LAB'.format( lat, -lon, t_LAB)) model_params = define_models.ModelParams( 'test_damp' + lab, boundaries=(('Moho', 'LAB'), [3., t_LAB]), depth_limits=(0, 300), ) #location = (35, -112) obs, std_obs, periods = constraints.extract_observations( location, model_params.id, model_params.boundaries, model_params.vpv_vsv_ratio, ) model = define_models.setup_starting_model( model_params, location) run_plot_inversion(model_params, model, obs, std_obs, periods, location)
def run_with_no_inputs(): model_params = define_models.ModelParams( depth_limits=np.array([0., 200.]), boundary_vsv=np.array([3.5, 4.0, 4.2, 4.1]), boundary_widths=np.array([5., 10.]), boundary_depth_uncertainty=np.array([ 3., 10., ]), boundary_depths=np.array([35., 90]), id='test') location = (35, -104) return run_inversion(model_params, loc)
def test_ModelParams(self, name, inputs, expected): """ Test that the ModelParams class defaults work as expected. """ id, bds, bw, dl, mlt, svsh, ps, pvph, eta, csv = inputs self.assertModelParamsEqual( define_models.ModelParams( id=id, boundaries=(bds, bw), min_layer_thickness=mlt, depth_limits=dl, vsv_vsh_ratio=svsh, vpv_vph_ratio=pvph, vpv_vsv_ratio=ps, eta=eta, ref_card_csv_name=csv, ), expected)
class PipelineTest(unittest.TestCase): # ========================================================================= # Set up specific assertions for locally defined classes # ========================================================================= def assertModelParamsEqual(self, actual, expected): self.assertEqual(actual.id, expected.id) act_bnames, act_bwidths = actual.boundaries exp_bnames, exp_bwidths = expected.boundaries self.assertTupleEqual(act_bnames, exp_bnames) self.assertEqual(act_bwidths, exp_bwidths) self.assertTupleEqual(actual.depth_limits, expected.depth_limits) self.assertEqual(actual.min_layer_thickness, expected.min_layer_thickness) self.assertEqual(actual.vsv_vsh_ratio, expected.vsv_vsh_ratio) self.assertEqual(actual.vpv_vsv_ratio, expected.vpv_vsv_ratio) self.assertEqual(actual.vpv_vph_ratio, expected.vpv_vph_ratio) self.assertEqual(actual.eta, expected.eta) self.assertEqual(actual.ref_card_csv_name, expected.ref_card_csv_name) def assertVsvModelEqual(self, actual, expected): np.testing.assert_almost_equal(actual.vsv, expected.vsv, decimal=4) # Cannot compare values == 0 to relative precision via. assert_allclose np.testing.assert_allclose(actual.thickness, expected.thickness, atol=1e-3) np.testing.assert_array_equal(actual.boundary_inds, expected.boundary_inds) np.testing.assert_array_equal(actual.d_inds, expected.d_inds) # ========================================================================= # The tests to run # ========================================================================= # ************************* # # define_models.py # # ************************* # # test_ModelParams @parameterized.expand([( "Using default values", ( 'moho lab', ('Moho', 'LAB'), [3., 10.], (0, 400), 6, 1, 1.75, 1, 1, 'data/earth_models/prem.csv', ), define_models.ModelParams('moho lab'), ), ("Moho only, no defaults", ( 'moho', ('Moho', ), [5.], (-10., 100.), 10., 1.1, 1.8, 0.9, 1.04, 'prem.csv', ), define_models.ModelParams( id='moho', boundaries=(('Moho', ), [5.]), depth_limits=(-10., 100.), min_layer_thickness=10., vsv_vsh_ratio=1.1, vpv_vsv_ratio=1.8, vpv_vph_ratio=0.9, eta=1.04, ref_card_csv_name='prem.csv', ))]) def test_ModelParams(self, name, inputs, expected): """ Test that the ModelParams class defaults work as expected. """ id, bds, bw, dl, mlt, svsh, ps, pvph, eta, csv = inputs self.assertModelParamsEqual( define_models.ModelParams( id=id, boundaries=(bds, bw), min_layer_thickness=mlt, depth_limits=dl, vsv_vsh_ratio=svsh, vpv_vph_ratio=pvph, vpv_vsv_ratio=ps, eta=eta, ref_card_csv_name=csv, ), expected) # test_fill_in_base_of_model @parameterized.expand([ ('basic model', define_models.ModelParams( 'testcase', ref_card_csv_name='data/earth_models/test.csv'), ([0], [4.3]), ([0.] + [400 / 66] * 66, [4.3] + [3.2 + i * (4.7699 - 3.2) / 66 for i in range(1, 67)])), ('prem', define_models.ModelParams('testcase', min_layer_thickness=5., depth_limits=(0., 80.)), ([0], [3.2]), ([0.] + [5.] * 16, ([3.2] * 4 + [3.9] + [(25. + i * 5. - 24.41) / (42.933 - 24.41) * (4.40029 - 3.9) + 3.9 for i in range(4)] + [(45. + i * 5. - 42.933) / (61.467 - 42.933) * (4.40456 - 4.40029) + 4.40029 for i in range(4)] + [(65. + i * 5. - 61.467) / (80. - 61.467) * (4.40883 - 4.40456) + 4.40456 for i in range(4)]))), ('complex starting model', define_models.ModelParams( 'testcase', ref_card_csv_name='data/earth_models/test.csv'), ([0., 30., 3., 40., 10.], [3.4, 3.6, 4.0, 4.2, 4.15]), ( [0., 30., 3., 40., 10.] + [317. / 52.] * 52, ([3.4, 3.6, 4.0, 4.2, 4.15] + [(83. + i * 317. / 52.) / 400 * (4.7699 - 3.2) + 3.2 for i in range(1, 53)]), )), ( 'starting model matches depth lims', define_models.ModelParams('testcase', depth_limits=(0., 50.)), ([0., 5., 5., 10., 10., 10., 10.], [3.4 + 0.1 * i for i in range(7)]), ([0., 5., 5., 10., 10., 10., 10.], [3.4 + 0.1 * i for i in range(6)] + [4.4019181]), ), ( 'starting model exceeds depth lims', define_models.ModelParams('testcase', depth_limits=(0., 50.)), ([0., 5., 5., 10., 10., 10., 12.], [3.4 + 0.1 * i for i in range(7)]), ([0., 5., 5., 10., 10., 10., 10.], [3.4 + 0.1 * i for i in range(6)] + [4.4019181]), ), ]) def test_fill_in_base_of_model(self, name, model_params, inputs, expected): """ """ t, vs = inputs define_models._fill_in_base_of_model(t, vs, model_params) exp_t, exp_vs = expected self.assertEqual(t, exp_t) np.testing.assert_almost_equal(vs, exp_vs) # test_add_BLs_to_starting_model @parameterized.expand([ ( 'basic model', define_models.ModelParams('testcase'), [0.] + [50.] * 8, ([0., 50., 50., 3., 50., 50., 10., 50., 137.], [2, 5]), ), ( 'crustal model on top', define_models.ModelParams('testcase', depth_limits=(0., 216.)), [0., 5., 15., 16.] + [6.] * 30, ([0., 5., 15., 16.] + [6.] * 3 + [3.] + [6.] * 9 + [10.] + [6.] * 15 + [5.], [6, 16]), ), ( 'more complicated BLs', define_models.ModelParams( 'testcase', (('Mid-crust', 'Moho', 'MLD', 'LAB'), [2.5, 3., 5., 10.]), ), [0.] + [5.] * 80, (([0.] + [5.] * 14 + [2.5] + [5.] * 13 + [3.] + [5.] * 12 + [5.] + [5.] * 13 + [10.] + [5.] * 23 + [4.5]), [14, 28, 41, 55]), ), ]) def test_add_BLs_to_starting_model(self, name, model_params, thicknesses, expected): """ Test the addition of the boundary layer frameworks. Requires some shallower model with the starting thickness and Vs to base the rest off. """ calc_bi = define_models._add_BLs_to_starting_model( thicknesses, model_params) exp_t, exp_bi = expected self.assertEqual(thicknesses, exp_t) self.assertEqual(calc_bi, exp_bi) # test_add_noise_to_starting_model @parameterized.expand([ ( 'basic model', define_models.VsvModel( np.array([[3.4, 3.6, 4.0, 4.2, 4.1, 4.4]]).T, np.array([[0., 30., 3., 40., 10., 137.]]).T, np.array([1, 3]), np.arange(5)), (0, 220), 42, define_models.VsvModel( np.array([[3.4993, 3.5723, 4.1295, 4.5046, 4.0532, 4.4]]).T, np.array([[0., 29.2976, 3., 46.3169, 10., 131.3855]]).T, np.array([1, 3]), np.arange(5)), ), ]) def test_add_noise_to_starting_model(self, name, in_model, depth_limits, seed, expected): """ """ np.random.seed(seed) calc_model = define_models._add_noise_to_starting_model( in_model, depth_limits) self.assertVsvModelEqual(calc_model, expected) # test_return_evenly_spaced_model @parameterized.expand([ ( 'basic model', ( np.array([0, 30., 3., 24., 10., 30.])[np.newaxis].T, # t np.array([3.0, 3.5, 4.0, 4.6, 4.4, 4.65])[np.newaxis].T, # vs np.array([1, 3]), # bi 6. #min layer thickness ), ( np.array([ 0., 6., 6., 6., 6., 6., 3., 6., 6., 6., 6., 10., 6., 6., 6., 6., 6. ])[np.newaxis].T, # expected t np.array([ 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 4.0, 4.15, 4.3, 4.45, 4.6, 4.4, 4.45, 4.5, 4.55, 4.6, 4.65 ])[np.newaxis].T, # expected vs np.array([5, 10]) # expected bi ), ), ]) def test_return_evenly_spaced_model(self, name, inputs, expected): """ """ t, vs, bi, min_layer_thickness = inputs thickness, vsv, bound_inds = define_models._return_evenly_spaced_model( define_models.VsvModel(vs, t, bi, []), min_layer_thickness, ) exp_t, exp_vs, exp_bi = expected np.testing.assert_array_equal(thickness, exp_t) np.testing.assert_allclose(vsv, exp_vs, rtol=0.01, atol=0.05) np.testing.assert_array_equal(bound_inds, exp_bi) # ************************* # # mineos.py # # ************************* # # test_mineos @parameterized.expand([( 'NoMelt models and results, courtesy Josh Russell, 2019', 'NoMeltRayleigh', [15.5556, 16.4706, 20, 25, 32, 40, 50, 60, 80, 100, 120, 140, 150], )]) @unittest.skipIf(skipMINEOS, "MINEOS runs too slow to test every time") def test_mineos(self, name, model_id, periods): """ card = pd.read_csv('files_for_testing/mineos/' + model_id + '.card', skiprows=3, header=None, sep='\s+') card.columns = ['r','rho', 'vpv', 'vsv', 'q_kappa', 'q_mu', 'vph', 'vsh', 'eta'] n = 0 p = periods[n] ke = kernels_calc[kernels_calc.period == p] kj = kernels_expected[kernels_expected.period == p] plt.plot(ke.vsv, ke.z) plt.plot(kj.vsv * card.vsv.values[::-1] / phv_calc[n], kj.z, '--') plt.gca().set_ylim([400, 0]) maxk = 1.1 * max((kj.loc[kj.z < 400, 'vsv'].max(), ke.loc[ke.z < 400, 'vsv'].max())) mink = min((kj.loc[kj.z < 400, 'vsv'].min(), ke.loc[ke.z < 400, 'vsv'].min())) if mink < 0: mink *= 1.1; else: mink *= 0.9 plt.gca().set_xlim([mink, maxk]) n += 1 p = periods[n] ke = kernels_calc[kernels_calc.period == p] plt.plot(ke.vsv, ke.z) plt.gca().set_ylim([400, 0]) n += 1 """ # All previously calculated test outputs should be saved in expected_output_dir = './files_for_testing/mineos/' # And newly calculated test outputs should be saved in actual_output_dir = 'output/testcase/' # Copy the test card into the right directory for the workflow if not os.path.exists('output'): os.mkdir('output') if os.path.exists(actual_output_dir): shutil.rmtree(actual_output_dir) os.mkdir(actual_output_dir) shutil.copyfile(expected_output_dir + model_id + '.card', actual_output_dir + 'testcase.card') # Run MINEOS params = mineos.RunParameters( freq_max=1000 / min(periods) + 1, qmod_path=expected_output_dir + model_id + '.qmod', ) phv_calc, kernels_calc = mineos.run_mineos_and_kernels( params, periods, 'testcase') # Load previously calculated test outputs phv_expected = mineos._read_qfile( expected_output_dir + model_id + '.q', periods) # Something super weird with the kernels that Josh sent me kernels_expected = mineos._read_kernels(expected_output_dir + model_id, periods) kernels_expected['type'] = params.Rayleigh_or_Love np.testing.assert_allclose(phv_calc, phv_expected, rtol=1e-7) kernels_expected.drop(columns=['eta', 'rho'], inplace=True) kernels_calc.drop(columns=['eta', 'rho'], inplace=True) # Make Josh's kernels into m/s units (from 1e-3 m/s) kernels_expected.loc[:, ['vsv', 'vpv', 'vsh', 'vph']] *= 1e3 # Make calculated kernels into m/s units (from km/s) kernels_calc.loc[:, ['vsv', 'vpv', 'vsh', 'vph']] *= 1e-3 # check_less_precise is the number of sig figs that must match pd.testing.assert_frame_equal( kernels_calc, kernels_expected, check_exact=False, check_less_precise=1, ) # ************************* # # inversion.py # # ************************* # # test_G @parameterized.expand([ ( 'basic model', define_models.ModelParams('testcase', depth_limits=(0, 200)), (35, -110), [10, 20, 30, 40, 60, 80, 100], [1.05] + [1] * 33, ), # ( # 'more perturbed', # define_models.ModelParams('testcase', depth_limits=(0, 150)), # (35, -120), # [5, 8, 10, 15, 20, 30, 40, 60, 80, 100, 120], # ([1.025] * 5 + [0.975] * 5 + [1.02] * 5 + [0.99] * 5 + [1.06] * 2 + [1] # + [1.1] * 2), # ), # ( # 'small perturbations', # define_models.ModelParams('testcase', depth_limits=(0, 175)), # (35, -100), # [10, 20, 30, 40, 60, 80, 100], # ([1.005] * 5 + [0.995] * 5 + [1.01] * 5 + [0.997] * 5 # + [1.001] * 4 + [0.999] * 2 + [1] # + [1.05] * 2), # ), # ( # 'sharp LAB', # define_models.ModelParams( # 'testcase', boundaries=(('Moho', 'LAB'), [3., 3.]), # depth_limits=(0, 150) # ), # (35, -110), # [10, 20, 30, 40, 60, 80, 100], # ([1.005] * 5 + [0.995] * 5 + [1.01] * 5 + [0.997] * 5 + [1.0001] * 4 + [1] # + [1.05] * 2), # ), ]) @unittest.skipIf(skipMINEOS, "MINEOS runs too slow to test every time") def test_G_sw(self, name, model_params, location, periods, model_perturbation): """ Test G by comparing the dV from G * dm to the dV output from MINEOS. From a given starting model, calculate phase velocities and kernels in MINEOS, and convert to the inversion G. Convert the starting model to the column vector. Perturb the column vector in some way, and then convert it back to a MINEOS card. Rerun MINEOS to get phase velocities. Note that the mistmatch between these two methods gets worse for larger model perturbations, especially at shorter periods. As G is dV/dm, then G * dm == mineos(m_perturbed) - mineos(m0). Plot this comparison: plt.figure(figsize=(10,8)) a1 = plt.subplot(1, 3, 1) plt.plot(model.vsv, np.cumsum(model.thickness), 'b-o') plt.plot(model_perturbed.vsv, np.cumsum(model_perturbed.thickness), 'r-o') plt.title('Vsv Models\nblue: original; red: perturbed') plt.gca().set_ylim([200, 0]) plt.xlabel('Vsv (km/s)') plt.ylabel('Depth (km)') a2 = plt.subplot(2, 2, 2) im = plt.scatter(dc_mineos, dc_from_Gdm, 10, periods) plt.xlabel('dc from MINEOS') plt.ylabel('dc from G calculation') cbar = plt.gcf().colorbar(im) cbar.set_label('Periods (s)', rotation=90) a3 = plt.subplot(2, 2, 4) im = plt.scatter(periods, (dc_from_Gdm - dc_mineos) / dc_mineos, 10, dc_mineos) plt.xlabel('Period (s)') plt.ylabel('(Gdm - dc) / dc') cbar2 = plt.gcf().colorbar(im) cbar2.set_label('dc from MINEOS (km/s)', rotation=90) """ # Calculate the G matrix from a starting model np.random.seed(42) # need to set the seed because model length can be # different depending on the random variation model = define_models.setup_starting_model(model_params, location) # No need for output on MINEOS model as saved to .card file _ = define_models.convert_vsv_model_to_mineos_model( model, model_params) params = mineos.RunParameters( freq_max=1000 / min(periods) + 1, max_run_N=5, ) ph_vel_pred, kernels = mineos.run_mineos_and_kernels( params, periods, model_params.id) G = partial_derivatives._build_partial_derivatives_matrix_sw( kernels, model, model_params, ) # Apply the perturbation p = inversion._build_model_vector(model, model_params.depth_limits) p_perturbed = p.copy() * np.array(model_perturbation)[:, np.newaxis] perturbation = p_perturbed - p model_perturbed = inversion._build_inversion_model_from_model_vector( p_perturbed, model) _ = define_models.convert_vsv_model_to_mineos_model( model_perturbed, model_params._replace(id='testcase_perturbed')) ph_vel_perturbed, _ = mineos.run_mineos(params, periods, 'testcase_perturbed') # calculate dv dc_mineos = ph_vel_perturbed - ph_vel_pred dc_from_Gdm = np.matmul(G, perturbation).flatten() np.testing.assert_allclose( dc_mineos, dc_from_Gdm, atol=0.01, rtol=0.05, ) # ************************* # # partial_derivatives.py # # ************************* # # test_build_MINEOS_G_matrix @parameterized.expand([ ('simple', pd.DataFrame({ 'z': [0, 10, 20, 0, 10, 20], 'period': [10, 10, 10, 30, 30, 30], 'vsv': [0.11, 0.12, 0.13, 0.101, 0.102, 0.103], 'vpv': [0.21, 0.22, 0.23, 0.201, 0.202, 0.203], 'vsh': [0.31, 0.32, 0.33, 0.301, 0.302, 0.303], 'vph': [0.41, 0.42, 0.43, 0.401, 0.402, 0.403], 'eta': [0.51, 0.52, 0.53, 0.501, 0.502, 0.503], 'rho': [0.61, 0.62, 0.63, 0.601, 0.602, 0.603], 'type': ['Rayleigh'] * 6, }), np.array([ [ 0.11, 0.12, 0.13, 0, 0, 0, 0.21, 0.22, 0.23, 0.41, 0.42, 0.43, 0.51, 0.52, 0.53 ], [ 0.101, 0.102, 0.103, 0, 0, 0, 0.201, 0.202, 0.203, 0.401, 0.402, 0.403, 0.501, 0.502, 0.503 ], ])), ]) def test_build_MINEOS_G_matrix(self, name, kernels, expected_G_MINEOS): """ """ np.testing.assert_allclose( partial_derivatives._build_MINEOS_G_matrix(kernels), expected_G_MINEOS) # test_calculate_dm_ds @parameterized.expand([ ( 'Simple', define_models.VsvModel( vsv=np.array([[3.5, 4, 4.5, 4.6, 4.7]]).T, thickness=np.array([[0., 30., 40., 50., 20.]]).T, boundary_inds=[], d_inds=[], ), np.arange(0, 150, 10), np.array([ [1., 0., 0., 0., 0.], [2. / 3., 1. / 3., 0, 0, 0.], [1. / 3., 2. / 3., 0, 0, 0.], [0, 1., 0, 0, 0.], [0, 3. / 4., 1. / 4., 0, 0.], [0, 1. / 2., 1. / 2., 0, 0.], [0, 1. / 4., 3. / 4., 0, 0.], [0, 0, 1., 0, 0.], [0, 0, 4. / 5., 1. / 5., 0.], [0, 0, 3. / 5., 2. / 5., 0.], [0, 0, 2. / 5., 3. / 5., 0.], [0, 0, 1. / 5., 4. / 5, 0.], [0, 0, 0, 1., 0.], [0, 0, 0, 1. / 2., 1. / 2.], [0, 0, 0, 0, 1.], ]), ), ( 'Moho & LAB', define_models.VsvModel( vsv=np.array([[3.5, 3.6, 4., 4.2, 4.4, 4.3, 4.35, 4.4]]).T, thickness=np.array([[0., 30., 10., 22., 22., 15., 22., 22.]]).T, boundary_inds=np.array([1, 4]), d_inds=[], ), np.arange(0, 150, 10), np.array([ [1., 0., 0., 0., 0., 0., 0., 0.], [2. / 3., 1. / 3., 0., 0., 0., 0., 0., 0.], [1. / 3., 2. / 3., 0., 0., 0., 0., 0., 0.], [0., 1., 0., 0., 0., 0., 0., 0.], [0., 0., 1., 0., 0., 0., 0., 0.], [0., 0., 12. / 22., 10. / 22., 0., 0., 0., 0.], [0., 0., 2. / 22., 20. / 22, 0., 0., 0., 0.], [0., 0., 0., 14. / 22., 8. / 22., 0., 0., 0.], [0., 0., 0., 4. / 22., 18. / 22., 0., 0., 0.], [0., 0., 0., 0., 9. / 15., 6. / 15., 0., 0.], [0., 0., 0., 0., 0., 21. / 22., 1. / 22., 0.], [0., 0., 0., 0., 0., 11. / 22., 11. / 22., 0.], [0., 0., 0., 0., 0., 1. / 22., 21. / 22., 0.], [0., 0., 0., 0., 0., 0., 13. / 22., 9. / 22.], [0., 0., 0., 0., 0., 0., 3. / 22., 19. / 22.], ]), ), ]) def test_calculate_dm_ds(self, name, model, depth, expected): """ """ np.testing.assert_allclose( partial_derivatives._calculate_dm_ds(model, depth), expected) # test_convert_kernels_d_shallowerm_by_d_s @parameterized.expand([ ('Simple', define_models.VsvModel( vsv=np.array([[3.5, 4, 4.5, 4.6, 4.7]]).T, thickness=np.array([[0, 30, 40, 50, 10]]).T, boundary_inds=[], d_inds=[], ), np.arange(0, 150, 10), np.array([ [0, 0, 0, 0], [0, 10 / 30, 0, 0], [0, 20 / 30, 0, 0], [0, 30 / 30, 0, 0], [0, 0, 10 / 40, 0], [0, 0, 20 / 40, 0], [0, 0, 30 / 40, 0], [0, 0, 40 / 40, 0], [0, 0, 0, 10 / 50], [0, 0, 0, 20 / 50], [0, 0, 0, 30 / 50], [0, 0, 0, 40 / 50], [0, 0, 0, 50 / 50], [0, 0, 0, 0], [0, 0, 0, 0], ])), ]) def test_convert_kernels_d_shallowerm_by_d_s(self, name, model, depth, expected_dm_ds): """ """ n_layers = model.vsv.size - 1 dm_ds_mat = np.zeros((depth.size, n_layers)) for i in range(1, n_layers): dm_ds_mat = ( partial_derivatives._convert_kernels_d_shallowerm_by_d_s( model, i, depth, dm_ds_mat)) np.testing.assert_allclose(dm_ds_mat, expected_dm_ds) # test_convert_kernels_d_deeperm_by_d_s @parameterized.expand([ ('Simple', define_models.VsvModel( vsv=np.array([[3.5, 4, 4.5, 4.6, 4.7]]).T, thickness=np.array([[0, 30, 40, 55, 10]]).T, boundary_inds=[], d_inds=[], ), np.arange(0, 150, 10), np.array([ [30 / 30, 0, 0, 0], [20 / 30, 0, 0, 0], [10 / 30, 0, 0, 0], [0, 40 / 40, 0, 0], [0, 30 / 40, 0, 0], [0, 20 / 40, 0, 0], [0, 10 / 40, 0, 0], [0, 0, 55 / 55, 0], [0, 0, 45 / 55, 0], [0, 0, 35 / 55, 0], [0, 0, 25 / 55, 0], [0, 0, 15 / 55, 0], [0, 0, 5 / 55, 0], [0, 0, 0, 5 / 10], [0, 0, 0, 0], ])), ]) def test_convert_kernels_d_deeperm_by_d_s(self, name, model, depth, expected_dm_ds): """ """ n_layers = model.vsv.size - 1 dm_ds_mat = np.zeros((depth.size, n_layers)) for i in range(n_layers): dm_ds_mat = (partial_derivatives._convert_kernels_d_deeperm_by_d_s( model, i, depth, dm_ds_mat)) np.testing.assert_allclose(dm_ds_mat, expected_dm_ds) # test_calculate_dm_dt @parameterized.expand([ ( 'Moho & LAB', define_models.VsvModel( vsv=np.array([[3.5, 3.6, 4., 4.2, 4.4, 4.3, 4.35, 4.4]]).T, thickness=np.array([[0., 30., 10., 22., 21., 15., 23., 24.]]).T, boundary_inds=np.array([1, 4]), d_inds=[], ), np.arange(0, 150, 10), np.array([ [0, 0], # 0 - pegged [(3.5 - 3.6) * 10 / 30**2, 0], # 10 [(3.5 - 3.6) * 20 / 30**2, 0], # 20 [(3.6 - 4.) / 10, 0], # 30 [(4. - 4.2) * 22 / 22**2, 0], # 40 [(4. - 4.2) * 12 / 22**2, 0], # 50 [(4. - 4.2) * 2 / 22**2, 0], # 60 [0, (4.2 - 4.4) * 8 / 21**2], # 70 [0, (4.2 - 4.4) * 18 / 21**2], # 80 [0, (4.4 - 4.3) / 15], # 90 [0, (4.3 - 4.35) * 21 / 23**2], # 100 [0, (4.3 - 4.35) * 11 / 23**2], # 110 [0, (4.3 - 4.35) * 1 / 23**2], # 120 [0, 0], # 130 - pegged [0, 0], # 140 - pegged ])), ]) def test_calculate_dm_dt(self, name, model, depth, expected): """ """ np.testing.assert_allclose( partial_derivatives._calculate_dm_dt(model, depth), expected) # test_convert_to_model_kernels @parameterized.expand([( 'Moho & LAB', define_models.VsvModel( vsv=np.array([[3.5, 3.6, 4., 4.2, 4.4, 4.3, 4.35, 4.4]]).T, thickness=np.array([[0., 30., 10., 22., 21., 15., 23., 24.]]).T, boundary_inds=np.array([1, 4]), d_inds=[], ), np.arange(0, 150, 10), np.array([ [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 0 [2 / 3, 1 / 3, 0, 0, 0, 0, 0, 0, (3.5 - 3.6) * 10 / 30**2, 0], # 10 [1 / 3, 2 / 3, 0, 0, 0, 0, 0, 0, (3.5 - 3.6) * 20 / 30**2, 0], # 20 [0, 1, 0, 0, 0, 0, 0, 0, (3.6 - 4.) / 10, 0], # 30 [0, 0, 1, 0, 0, 0, 0, 0, (4. - 4.2) * 22 / 22**2, 0], # 40 [0, 0, 12 / 22, 10 / 22, 0, 0, 0, 0, (4. - 4.2) * 12 / 22**2, 0], # 50 [0, 0, 2 / 22, 20 / 22, 0, 0, 0, 0, (4. - 4.2) * 2 / 22**2, 0], # 60 [0, 0, 0, 13 / 21, 8 / 21, 0, 0, 0, 0, (4.2 - 4.4) * 8 / 21**2], # 70 [0, 0, 0, 3 / 21, 18 / 21, 0, 0, 0, 0, (4.2 - 4.4) * 18 / 21**2], # 80 [0, 0, 0, 0, 8 / 15, 7 / 15, 0, 0, 0, (4.4 - 4.3) / 15], # 90 [0, 0, 0, 0, 0, 21 / 23, 2 / 23, 0, 0, (4.3 - 4.35) * 21 / 23**2], # 100 [0, 0, 0, 0, 0, 11 / 23, 12 / 23, 0, 0, (4.3 - 4.35) * 11 / 23**2], # 110 [0, 0, 0, 0, 0, 1 / 23, 22 / 23, 0, 0, (4.3 - 4.35) * 1 / 23**2], # 120 [0, 0, 0, 0, 0, 0, 15 / 24, 9 / 24, 0, 0], # 130 - pegged [0, 0, 0, 0, 0, 0, 5 / 24, 19 / 24, 0, 0], # 140 - pegged ]))]) def test_convert_to_model_kernels(self, name, model, depth, expected): """ """ np.testing.assert_allclose( partial_derivatives._convert_to_model_kernels(depth, model), expected) # test_scale_dvsv_dp_to_other_variables @parameterized.expand([ ( 'Simple', np.array([ [30 / 30, 0, 0, 0], [20 / 30, 10 / 30, 0, 0], [10 / 30, 20 / 30, 0, 0], [0, 40 / 40, 0, 0], ]), define_models.ModelParams('basic', vsv_vsh_ratio=1.1, vpv_vsv_ratio=1.8, vpv_vph_ratio=0.9, ref_card_csv_name='prem.csv'), np.array([ [1, 0, 0, 0], # vsv [2 / 3, 1 / 3, 0, 0], [1 / 3, 2 / 3, 0, 0], [0, 1, 0, 0], [1 / 1.1, 0, 0, 0], # vsh [2 / 3 / 1.1, 1 / 3 / 1.1, 0, 0], [1 / 3 / 1.1, 2 / 3 / 1.1, 0, 0], [0, 1 / 1.1, 0, 0], [1.8, 0, 0, 0], # vpv [2 / 3 * 1.8, 1 / 3 * 1.8, 0, 0], [1 / 3 * 1.8, 2 / 3 * 1.8, 0, 0], [0, 1.8, 0, 0], [2, 0, 0, 0], # vph [4 / 3, 2 / 3, 0, 0], [2 / 3, 4 / 3, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], # eta [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], ]), ), ]) def test_scale_dvsv_dp_to_other_variables(self, name, dvsv_dp, model_params, expected): """ """ np.testing.assert_allclose( partial_derivatives._scale_dvsv_dp_to_other_variables( dvsv_dp, model_params), expected, ) # ************************* # # weights.py # # ************************* # # test_set_layer_values @parameterized.expand([ ('simple', define_models.EarthLayerIndices(np.arange(2), np.arange(2, 5), np.arange(5, 10), np.arange(10, 16), np.arange(16, 20), np.arange(0, 16 * 3, 3)), (1, 2, [3, 4, 5, 6, 7], 2, [1, 2, 3, 4]), pd.DataFrame({ 'Depth': np.arange(0, 16 * 3, 3), 'simple': [1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2] }), pd.DataFrame({ 'Depth': [0, 1, 2, 3], 'simple': [1, 2, 3, 4] })) ]) def test_set_layer_values(self, name, layers, damping, expected_s, expected_t): damp_s = pd.DataFrame({'Depth': layers.depth}) damp_t = pd.DataFrame( {'Depth': np.arange(len(layers.boundary_layers))}) weights._set_layer_values(damping, layers, damp_s, damp_t, name) pd.testing.assert_frame_equal(damp_s, expected_s) pd.testing.assert_frame_equal(damp_t, expected_t) # test_damp_constraints @parameterized.expand([ ( 'simple_square', np.array([[1, 2, 3, 1, 2, 3, 1, 2, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2], [1, 8, 3, 1, 2, 3, 1, 2, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2], [1, 2, 2, 1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3, 1, 2, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2], [1, 2, 3, 1, 2, 3, 1, 2, 3], [0, 8, 2, 0, 1, 2, 0, 1, 2]]), np.array([10, 20, 10, 20, 10, 30, 10, 40, 10])[:, np.newaxis], pd.DataFrame({'simple_square': [1] * 2 + [2] + [4, 5, 6, 7]}), pd.DataFrame({'simple_square': [1, 2]}), np.array([[1, 2, 3, 1, 2, 3, 1, 2, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2], [2, 16, 6, 2, 4, 6, 2, 4, 6], [0, 4, 8, 0, 4, 8, 0, 4, 8], [5, 10, 10, 5, 10, 15, 5, 10, 15], [6, 12, 18, 6, 12, 18, 6, 12, 18], [0, 7, 14, 0, 7, 14, 0, 7, 14], [1, 2, 3, 1, 2, 3, 1, 2, 3], [0, 16, 4, 0, 2, 4, 0, 2, 4]]), np.array([10, 20, 20, 80, 50, 180, 70, 40, 20])[:, np.newaxis], ), ]) def test_damp_constraints(self, name, H, h, damp_s, damp_t, expected_H, expected_h): H, h = weights._damp_constraints((H, h, name), damp_s, damp_t) np.testing.assert_array_equal(H, expected_H) np.testing.assert_array_equal(h, expected_h) # test_build_smoothing_constraints @parameterized.expand([ ( 'simple', define_models.VsvModel( vsv=np.array([3] * 13)[:, np.newaxis], thickness=np.array([0] + [6] * 3 + [7, 5, 4] + [6] * 1 + [10, 15, 12] + [6] * 1)[:, np.newaxis], boundary_inds=np.array([4, 8]), d_inds=[], ), np.array([ [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [6, -12, 6, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 6., -12., 6., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 7., -13., 6., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 7., -13., 6., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 6., -10., 4., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 6., -10., 4., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 10., -16., 6., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 10., -16., 6., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 6., -18., 12., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 6., -18., 12., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 10., -16., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], ]), np.array([0] * 11 + [-6 * 4.411829121] + [0] * 2)[:, np.newaxis], ), ]) def test_build_smoothing_constraints(self, name, model, expected_H, expected_h): sm = define_models.ModelParams('junk') # need PREM path only H, h, label = weights._build_smoothing_constraints(model, sm) self.assertEqual(label, 'roughness') np.testing.assert_allclose(H, expected_H) np.testing.assert_allclose(h, expected_h) n_bls = model.boundary_inds.shape[0] n_layers = expected_h.shape[0] - n_bls damp_s = pd.DataFrame({'Depth': np.cumsum(model.thickness)}) damp_t = pd.DataFrame({'Depth': [0] * n_bls}) layers = define_models.EarthLayerIndices( np.arange(2), np.arange(2, 3), np.arange(3, 4), np.arange(4, n_layers), np.arange(n_layers, n_layers + n_bls), np.arange(0)) weights._set_layer_values( (1, 1, 1, 1, 10), layers, damp_s, damp_t, 'roughness', ) H_sc, h_sc = weights._damp_constraints((H, h, label), damp_s, damp_t) self.assertEqual(label, 'roughness') np.testing.assert_allclose(H_sc, expected_H) np.testing.assert_allclose(h_sc, expected_h) # test_build_constraint_damp_to_m0 @parameterized.expand([ ( 'simple', np.array([1, 2, 3, 4, 5])[:, np.newaxis], np.array([ [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1], ]), np.array([1, 2, 3, 4, 5])[:, np.newaxis], ), ]) def test_build_constraint_damp_to_m0(self, name, p, expected_H, expected_h): H, h, label = weights._build_constraint_damp_to_m0(p) self.assertEqual(label, 'to_m0') np.testing.assert_array_equal(H, expected_H) np.testing.assert_array_equal(h, expected_h) # test_build_constraint_damp_original_gradient @parameterized.expand([ ( 'simple', define_models.VsvModel( vsv=np.array([1, 2, 3, 4, 5, 6., 7., 8.])[:, np.newaxis], thickness=np.array([6., 6., 6., 6., 6., 6., 6., 6.])[:, np.newaxis], boundary_inds=np.array([2, 4]), d_inds=[], ), np.array([ [1. / 1., -1. / 2., 0, 0, 0, 0, 0, 0, 0], [0, 1. / 2., -1. / 3., 0, 0, 0, 0, 0, 0], [0, 0, 1. / 3., -1. / 4., 0, 0, 0, 0, 0], [0, 0, 0, 1. / 4., -1. / 5., 0, 0, 0, 0], [0, 0, 0, 0, 1. / 5., -1. / 6., 0, 0, 0], [0, 0, 0, 0, 0, 1. / 6., -1. / 7., 0, 0], [0, 0, 0, 0, 0, 0, 1. / 7., 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ]), np.array([0, 0, 0, 0, 0, 0, 1, 0, 0])[:, np.newaxis], ), ]) def test_build_constraint_damp_original_gradient(self, name, model, expected_H, expected_h): H, h, label = weights._build_constraint_damp_original_gradient(model) self.assertEqual(label, 'to_m0_grad') np.testing.assert_array_equal(H, expected_H) np.testing.assert_array_equal(h, expected_h)
def try_run(location: tuple, t_BLs: tuple, id: str): t_Moho, t_LAB = t_BLs mp = define_models.ModelParams( id, min_layer_thickness=6, depth_limits=(0, 350), boundaries=(('Moho', 'LAB'), [t_Moho, t_LAB]), ) t, v = constraints.get_vels_ShenRitzwoller2016(location) #d = np.cumsum(t) #v[0:3] = [v[3]] * 3 # remove lowest velocity layer #v[64:200] = [v[64]] * (200 - 64) # add in a clear high velocity lid #v[64:] = [v[64]] * (len(v) - 64) # Add in boundary layers at arbitary places bi = np.array([63, 199]) t[bi[0] + 1] = t_Moho t[bi[1] + 1] = t_LAB define_models._fill_in_base_of_model(t, v, mp) t = np.array(t) v = np.array(v) # Smooth from base of the lithosphere to the base of the model # v = np.hstack(( # v[:200], np.interp(sum(t[:200]) + np.cumsum(t[200:]), # [sum(t[:200]), sum(t)], # [v[200], v[-1]] # ) # )) thickness, vsv, boundary_inds = define_models._return_evenly_spaced_model( define_models.VsvModel(define_models._list_to_col(v), define_models._list_to_col(t), np.array(bi), []), mp.min_layer_thickness, ) m = define_models.VsvModel( vsv=vsv[np.newaxis].T, thickness=thickness[np.newaxis].T, boundary_inds=np.array(boundary_inds), d_inds=define_models._find_depth_indices(thickness, mp.depth_limits), ) # mineos_model = define_models.convert_vsv_model_to_mineos_model(m, mp) # Get predicted values # rf_p = inversion._predict_RF_vals(m) obs, std_obs, periods = constraints.extract_observations( location, mp.id, mp.boundaries, mp.vpv_vsv_ratio) #ph_vel_pred = mineos.calculate_c_from_card(mp, m, periods) m0 = define_models.VsvModel( vsv=vsv[np.newaxis].T * 0 + vsv[-1], thickness=thickness[np.newaxis].T, boundary_inds=np.array(boundary_inds), d_inds=define_models._find_depth_indices(thickness, mp.depth_limits), ) max_runs = 10 # return run_plot_inversion(mp, m0, np.hstack((ph_vel_pred, rf_p))[:, np.newaxis], # std_obs, periods, location, m, max_runs # ) return run_plot_inversion(mp, m0, obs, std_obs, periods, location, m, max_runs)
def test_MonteCarlo(n_MonteCarlo): #n_iter vs_SL14 = pd.read_csv('data/earth_models/CP_SL14.csv', header=None).values cp_outline = pd.read_csv('data/earth_models/CP_outline.csv').values vs_SLall = pd.read_csv('data/earth_models/SchmandtLinVs_only.csv', header=None).values.flatten() # To save space, have saved the lat, lon, depth ranges of the Schmandt & Lin # model just as three lines in a csv vs_lats = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=0, nrows=1, header=None).values.flatten() vs_lons = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=1, nrows=1, header=None).values.flatten() vs_deps = pd.read_csv('data/earth_models/SL_coords.csv', skiprows=2, nrows=1, header=None).values.flatten() vs_SLall = vs_SLall.reshape((vs_lats.size, vs_lons.size, vs_deps.size)) lat = 35. lon = -111. t_LAB = 5. location = (lat, lon) print('*********************** {}N, {}W, {}km LAB'.format( lat, -lon, t_LAB)) model_params = define_models.ModelParams( 'test_MC', boundaries=(('Moho', 'LAB'), [3., t_LAB]), depth_limits=(0, 420), ) obs, std_obs, periods = constraints.extract_observations( location, model_params.id, model_params.boundaries, model_params.vpv_vsv_ratio, ) ic = list(range(len(obs) - 2 * len(model_params.boundaries[0]))) i_rf = list(range(ic[-1] + 1, len(obs))) #model_params = model_params._replace(boundary_names = []) save_name = 'output/{0}/{0}.q'.format(model_params.id) lat, lon = location f = plt.figure() f.set_size_inches((15, 7)) ax_m0 = f.add_axes([0.2, 0.3, 0.1, 0.6]) ax_m150 = f.add_axes([0.35, 0.3, 0.2, 0.6]) ax_mDeep = f.add_axes([0.35, 0.1, 0.2, 0.12]) ax_c = f.add_axes([0.6, 0.6, 0.35, 0.3]) ax_map = f.add_axes([0.84, 0.1, 0.1, 0.2]) ax_dc = f.add_axes([0.6, 0.375, 0.35, 0.15]) im = ax_map.contourf(np.arange(-119, -100.9, 0.2), np.arange(30, 45.1, 0.2), vs_SL14, levels=20, cmap=plt.cm.RdBu, vmin=4, vmax=4.7) ax_map.plot(lon, lat, 'k*') ax_map.plot(cp_outline[:, 1], cp_outline[:, 0], 'k:') ax_c.set_title('{:.1f}N, {:.1f}W: {:.0f} km LAB'.format(lat, -lon, t_LAB)) ax_rf = f.add_axes([0.6, 0.1, 0.2, 0.2]) # Plot on data and Schmandt & Lin Vs model line, = ax_c.plot(periods, obs[ic], 'k-', linewidth=3, label='data') plots.plot_rf_data_std(obs[i_rf], std_obs[i_rf], 'data', ax_rf) vs_ilon = np.argmin(abs(vs_lons - lon)) vs_ilat = np.argmin(abs(vs_lats - lat)) ax_m150.plot(vs_SLall[vs_ilat, vs_ilon, :], vs_deps, 'k-', linewidth=3, label='SL14') ax_mDeep.plot(vs_SLall[vs_ilat, vs_ilon, :], vs_deps, 'k-', linewidth=3, label='SL14') for trial in range(n_MonteCarlo): m = define_models.setup_starting_model(model_params, location) plots.plot_model_simple(m, 'm0 ' + str(trial), ax_m0, (0, 150)) dc = np.ones_like(periods) old_dc = np.zeros_like(periods) n = -1 while np.sum(abs(dc - old_dc)) > 0.005 * periods.size and n < 10: n += 1 old_dc = dc.copy() print('****** ITERATION ' + str(n) + ' ******') m, G = inversion._inversion_iteration(model_params, m, location) c = mineos._read_qfile(save_name, periods) dc = np.array([c[i] - obs[ic[i]] for i in range(len(c))]) # Plot up the model that reached convergence plots.plot_model_simple(m, 'm' + str(n + 1), ax_m150, (0, 150)) plots.plot_model_simple(m, 'm' + str(n + 1), ax_mDeep, (150, model_params.depth_limits[1]), False) p_rf = inversion._predict_RF_vals(m) plots.plot_rf_data(p_rf, 'm' + str(n + 1), ax_rf) # Run MINEOS on final model params = mineos.RunParameters(freq_max=1000 / min(periods) + 1) _ = define_models.convert_vsv_model_to_mineos_model(m, model_params) c, _ = mineos.run_mineos(params, periods, model_params.id) plots.plot_ph_vel_simple(periods, c, ax_c) dc = [c[i] - obs[ic[i]] for i in range(len(c))] plots.plot_ph_vel_simple(periods, dc, ax_dc) ax_dc.plot(periods, [0] * len(periods), 'k--') plots.make_plot_symmetric_in_y_around_zero(ax_dc) plots.make_plot_symmetric_in_y_around_zero(ax_rf) print(trial + 1, ' TRIALS') save_name = 'output/{0}/{0}'.format(model_params.id) f.savefig( '/media/sf_VM_Shared/rftests/MC_{}N_{}W_{}kmLAB_{}trials.png'.format( location[0], -location[1], round(t_LAB), trial + 1, ))