def test_catch_exceptions(self): with pytest.raises(PyfkError) as execinfo: _ = SeisModel(TestClassSeisModel.test_model_6column[:, :2], flattening=False, use_kappa=False) assert str(execinfo.value ) == 'Must provide at least three columns for the model' with pytest.raises(PyfkError) as execinfo: _ = SeisModel(TestClassSeisModel.test_model_6column.tolist(), flattening=False, use_kappa=False) assert str(execinfo.value) == 'Earth Model must be a 2D numpy array.' with pytest.raises(PyfkError) as execinfo: _ = SeisModel(TestClassSeisModel.test_model_6column.flatten(), flattening=False, use_kappa=False) assert str(execinfo.value) == 'Earth Model must be a 2D numpy array.' with pytest.raises(PyfkError) as execinfo: _ = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False, r_planet="test") assert str( execinfo.value) == 'r_planet should be a float or integer number' with pytest.raises(PyfkError) as execinfo: _ = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False, r_planet=-6) assert str(execinfo.value) == 'r_planet must be a positive value'
def test_free_surface(self): test_model_data = np.array([ [10.5, 3.64, 6.301, 2.55, 700, 1300], ]) test_model = SeisModel(test_model_data, flattening=False, use_kappa=False) test_source = SourceModel(sdep=-12, srcType="dc") with pytest.raises(PyfkError) as execinfo: _ = Config(model=test_model, source=test_source, receiver_distance=[10, 20, 30]) assert str(execinfo.value ) == "The source or receivers are located in the air." test_model_data = np.array([[5.5, 3.18, 5.501, 2.53, 600, 1100], [10.5, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [90.0, 4.50, 7.799, 2.6, 900, 1800]]) test_model = SeisModel(test_model_data, flattening=False, use_kappa=False) test_source = SourceModel(sdep=-12, srcType="dc") with pytest.raises(PyfkError) as execinfo: _ = Config(model=test_model, source=test_source, receiver_distance=[10, 20, 30]) assert str(execinfo.value ) == "The source or receivers are located in the air."
def test_remove_topo(self): to_test = TestClassSeisModel.test_model_6column.copy() to_test[0, 0] = -to_test[0, 0] test_model = SeisModel(to_test, flattening=False, use_kappa=False) test_model.remove_topo() prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 prefered_output[0, 0] = 0 assert np.allclose(test_model.model_values, prefered_output)
def test_add_layer(self): test_model_6column_with_source = np.array( [[5.5, 3.18, 5.501, 2.53, 600, 1100], [3, 3.64, 6.301, 2.55, 700, 1300], [7.5, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [0, 4.50, 7.799, 2.6, 900, 1800]]) test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) test_model.add_layer(7.5, 1) assert np.all( test_model.model_values == test_model_6column_with_source)
def test_prem(self): model_data = TestFunctionTaup.gen_test_model("prem") model_prem = SeisModel(model=model_data) source_prem = SourceModel(sdep=16.5) # * note, use larger distance will integrate more, the waveform of only calculating 10km and calculating to 100km will be grealy different config_prem = Config(model=model_prem, source=source_prem, npt=512, dt=0.1, receiver_distance=np.arange(10, 20, 10)) gf = calculate_gf(config_prem) # # * calculate sync_prem_gcmt for the event event = obspy.read_events( join(dirname(__file__), "../data/sync_prem_gcmt/test_gcmt"))[0] source_prem.update_source_mechanism(event) # # * generate a source time function source_time_function = generate_source_time_function( 4, 0.5, gf[0][0].stats.delta) sync_result = calculate_sync(gf, config_prem, 30, source_time_function) # * test if the cc value is large enough for index, component in enumerate(["z", "r", "t"]): sac_path = join(dirname(__file__), f"../data/sync_prem_gcmt/prem.{component}") sac_wave = obspy.read(sac_path)[0].data coef = np.corrcoef( sac_wave, sync_result[0][index].data, )[0, 1] assert coef > 0.9999
def test_earth_models(self): for earth_model_name in ["prem", "ak135f_no_mud", "1066a"]: earthmodel = TauPyModel(model=earth_model_name) for source_depth in [12, 50, 200]: model_data = self.gen_test_model(earth_model_name) test_model = SeisModel(model_data, flattening=True, use_kappa=False) test_source = SourceModel(sdep=source_depth, srcType="dc") receiver_distance = [1, 10, 50] test_config = Config(model=test_model, source=test_source, receiver_distance=receiver_distance, degrees=True) t0_list, _, _, _ = taup( test_config.src_layer, test_config.rcv_layer, test_config.model.th.astype(np.float64), test_config.model.vp.astype(np.float64), test_config.receiver_distance.astype(np.float64)) for index, each_distance in enumerate(receiver_distance): arrivals = earthmodel.get_travel_times( source_depth_in_km=source_depth, distance_in_degree=each_distance, phase_list=["p", "P"]) assert np.allclose(arrivals[0].time, t0_list[index], rtol=0.01)
def test_topo(self): test_model_data = np.array([ [-5.5, 3.18, 5.501, 2.53, 600, 1100], [10.5, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [90.0, 4.50, 7.799, 2.6, 900, 1800] ]) test_model = SeisModel( test_model_data, flattening=False, use_kappa=False) test_source = SourceModel(sdep=12, srcType="dc") test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30]) newmodel = np.array([ [0., 3.18, 5.501, 2.53, 600, 1100], [5.5, 3.64, 6.301, 2.55, 700, 1300], [5, 3.64, 6.301, 2.55, 700, 1300], [7.0, 3.87, 6.699, 2.59, 800, 1600], [9.0, 3.87, 6.699, 2.59, 800, 1600], [0., 4.50, 7.799, 2.6, 900, 1800] ]) assert np.all(test_config.model.model_values == newmodel)
def test_init_noflattening_kappa_6column(self): to_test = TestClassSeisModel.test_model_6column.copy() to_test[:, 2] = to_test[:, 2] / to_test[:, 1] test_model = SeisModel(to_test, flattening=False, use_kappa=True) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 assert np.allclose(test_model.model_values, prefered_output)
def test_init_noflattening_nokappa_6column(self): test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 assert np.allclose(test_model.model_values, prefered_output)
def test_hk(): # * perl fk.pl -Mhk/15/k -N512/0.1 10 20 30 model_path = join(dirname(__file__), f"../data/hk") model_data = np.loadtxt(model_path) model_hk = SeisModel(model=model_data, use_kappa=True) source_hk = SourceModel(sdep=15) config_hk = Config(model=model_hk, source=source_hk, npt=512, dt=0.1, receiver_distance=[10, 20, 30]) result = calculate_gf(config_hk) # * for all the gf in data/hk_gf, test if the results are close (in FK, it uses float but we are using double) for irec, each_rec in enumerate([10, 20, 30]): for icomn in range(9): hk_gf_data = obspy.read( join(dirname(__file__), f"../data/hk_gf/{each_rec}.grn.{icomn}"))[0] coef = np.corrcoef( hk_gf_data.data, result[irec][icomn].data, )[0, 1] if np.isnan(coef): coef = 1.0 assert coef > 0.99
def test_init_noflattening_nokappa_4column_normal(self): test_model_4column = TestClassSeisModel.test_model_6column[:, :-2] test_model = SeisModel( test_model_4column, flattening=False, use_kappa=False) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 prefered_output[:, -1] = 1000. prefered_output[:, -2] = 500. assert np.allclose(test_model.model_values, prefered_output)
def test_copy(self): from copy import copy test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) copied_model = copy(test_model) assert np.all(copied_model.model_values == test_model.model_values) copied_model.model_values[:, :] += 1 assert np.all(copied_model.model_values != test_model.model_values)
def test_get_attribute(self): test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) assert np.all(test_model.th[:-1] == TestClassSeisModel. test_model_6column[:-1, 0]) and test_model.th[-1] == 0 assert np.all( test_model.vs == TestClassSeisModel.test_model_6column[:, 1]) assert np.all( test_model.vp == TestClassSeisModel.test_model_6column[:, 2]) assert np.all( test_model.rh == TestClassSeisModel.test_model_6column[:, 3]) assert np.all( test_model.qs == TestClassSeisModel.test_model_6column[:, 4]) assert np.all( test_model.qp == TestClassSeisModel.test_model_6column[:, 5]) test_model.flattening = True assert test_model.flattening is True test_model.flattening = False
def test_init_noflattening_nokappa_3column(self): # have rho in the column test_model_3column = TestClassSeisModel.test_model_6column[:, :-3] test_model = SeisModel( test_model_3column, flattening=False, use_kappa=False) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 prefered_output[:, -1] = 1000. prefered_output[:, -2] = 500. prefered_output[:, -3] = 0.77 + 0.32 * prefered_output[:, 2] assert np.allclose(test_model.model_values, prefered_output)
def test_init_noflattening_nokappa_4column_abnormal(self): # have rho in the column test_model_4column = TestClassSeisModel.test_model_6column[:, :-2].copy( ) test_model_4column[:, 3] = TestClassSeisModel.test_model_6column[:, 4] test_model = SeisModel( test_model_4column, flattening=False, use_kappa=False) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 prefered_output[:, 3] = 0.77 + 0.32 * prefered_output[:, 2] prefered_output[:, 5] = prefered_output[:, 4] * 2 assert np.allclose(test_model.model_values, prefered_output)
def test__flattening(self): test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=True, use_kappa=False) test_source = SourceModel(sdep=12, srcType="dc") test_config = Config(model=test_model, source=test_source, receiver_distance=[10, 20, 30], rdep=22) assert test_config.source.sdep == R_EARTH * \ np.log(R_EARTH / (R_EARTH - 12)) assert test_config.rdep == R_EARTH * \ np.log(R_EARTH / (R_EARTH - 22))
def test_catch_exceptions(self): with pytest.raises(PyfkError) as execinfo: _ = SeisModel( TestClassSeisModel.test_model_6column[:, :2], flattening=False, use_kappa=False) assert str( execinfo.value) == 'Must provide at least three columns for the model' with pytest.raises(PyfkError) as execinfo: _ = SeisModel( TestClassSeisModel.test_model_6column.tolist(), flattening=False, use_kappa=False) assert str( execinfo.value) == 'Earth Model must be a 2D numpy array.' with pytest.raises(PyfkError) as execinfo: _ = SeisModel( TestClassSeisModel.test_model_6column.flatten(), flattening=False, use_kappa=False) assert str( execinfo.value) == 'Earth Model must be a 2D numpy array.'
def test_big_array(self): # model_data = TestFunctionTaup.gen_test_model("prem") # there is a possibility that we write x=f(x) where x is a memoryview in the code # this might cause segmentation fault model_data = np.loadtxt(join(dirname(__file__), f"../data/hk")) model_hk = SeisModel(model=model_data) source_hk = SourceModel(sdep=16.5) config_hk = Config(model=model_hk, source=source_hk, npt=512, dt=0.1, receiver_distance=np.arange(10, 40, 10)) _ = calculate_gf(config_hk)
def test_catch_warning(self): test_model = SeisModel(TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) test_source = SourceModel(sdep=12, srcType="dc") # dk with pytest.warns(PyfkWarning) as execinfo: _ = Config(model=test_model, source=test_source, receiver_distance=[10, 20, 30], dk=0.05) assert len(execinfo[0].message.args) == 1 assert execinfo[0].message.args[ 0] == "dk is recommended to be within (0.1,0.4)"
def test_init_flattening_kappa_6column(self): to_test = TestClassSeisModel.test_model_6column.copy() to_test[:, 2] = to_test[:, 2] / to_test[:, 1] test_model = SeisModel(to_test, flattening=True, use_kappa=True) r = R_EARTH fl = np.ones(TestClassSeisModel.test_model_6column.shape[0], dtype=float) for irow in range(TestClassSeisModel.test_model_6column.shape[0]): r = r - TestClassSeisModel.test_model_6column[irow, 0] fl[irow] = R_EARTH / \ (r + 0.5 * TestClassSeisModel.test_model_6column[irow, 0]) prefered_output = TestClassSeisModel.test_model_6column.copy() prefered_output[-1, 0] = 0 prefered_output[:, 0] *= fl prefered_output[:, 1] *= fl prefered_output[:, 2] *= fl assert np.allclose(test_model.model_values, prefered_output)
def test_static_source(self): model_data = TestFunctionTaup.gen_test_model("prem") model_prem = SeisModel(model=model_data) source_prem = SourceModel(sdep=16.5, srcType="dc") config_prem = Config(model=model_prem, source=source_prem, npt=1, dt=1, receiver_distance=[50]) gf = calculate_gf(config_prem) ref_gf = [ -0.242E-06, -0.103E-05, 0.000E+00, 0.236E-06, 0.118E-05, -0.548E-07, -0.942E-07, -0.156E-05, 0.285E-06 ] coef = np.corrcoef( gf, ref_gf, )[0, 1] assert coef > 0.99999
def test_prem_sf(self): model_data = TestFunctionTaup.gen_test_model("prem") model_prem = SeisModel(model=model_data) source_prem = SourceModel(sdep=16.5, srcType="sf") config_prem = Config(model=model_prem, source=source_prem, npt=512, dt=1, receiver_distance=[50]) gf = calculate_gf(config_prem) for index, comnname in enumerate(range(6)): gf_data = obspy.read( join(dirname(__file__), f"../data/sync_prem_sf/50.grn.{comnname}"))[0] coef = np.corrcoef( gf_data.data, gf[0][index].data, )[0, 1] if np.isnan(coef): coef = 1. assert coef > 0.99
def test_exceptions(self): model_data = TestFunctionTaup.gen_test_model("prem") model_prem = SeisModel(model=model_data) source_prem = SourceModel(sdep=16.5) # * note, use larger distance will integrate more, the waveform of only calculating 10km and calculating to 100km will be grealy different # ! note receiver_distance can not be 0 config_prem = Config(model=model_prem, source=source_prem, npt=512, dt=0.1, receiver_distance=np.arange(1, 10)) gf = calculate_gf(config_prem) event = obspy.read_events( join(dirname(__file__), "../data/sync_prem_gcmt/test_gcmt"))[0] source_prem.update_source_mechanism(event) source_time_function = generate_source_time_function( 4, 0.5, gf[0][0].stats.delta) # * the main tests with pytest.raises(PyfkError) as execinfo: _ = calculate_sync(gf, config_prem, [30], source_time_function) assert str(execinfo.value) == "az must be a number" with pytest.raises(PyfkError) as execinfo: _ = calculate_sync(gf, config_prem, 30, None) assert str(execinfo.value) == "must provide a source time function" with pytest.raises(PyfkError) as execinfo: source_time_function_abnormal = generate_source_time_function( 4, 0.5, 1.2) _ = calculate_sync(None, config_prem, 30, source_time_function_abnormal) assert str(execinfo.value) == "check input Green's function" with pytest.raises(PyfkError) as execinfo: source_time_function_abnormal = generate_source_time_function( 4, 0.5, 1.2) _ = calculate_sync(gf, config_prem, 30, source_time_function_abnormal) assert str( execinfo.value ) == "delta for the source time function and the Green's function should be the same"
def test_catch_exceptions(self): test_model = SeisModel( TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) test_source = SourceModel(sdep=12, srcType="dc") # receiver_distance with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source) assert str( execinfo.value) == "Must provide a list of receiver distance" with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=np.arange(10)) assert str( execinfo.value) == "Can't set receiver distance as 0, please consider to use a small value instead" # taper with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], taper=-0.2) assert str( execinfo.value) == "Taper must be with (0,1)" # npt with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], npt=-4) assert str( execinfo.value) == "npt should be positive." # dt with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], dt=-0.4) assert str( execinfo.value) == "dt should be positive." # dk with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], dk=0.7) assert str( execinfo.value) == "dk should be within (0,0.5)" # smth with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], smth=0) assert str( execinfo.value) == "smth should be positive." # pmin with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], pmin=1.2) assert str( execinfo.value) == "pmin should be within [0,1]" # pmax with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], pmax=1.2) assert str( execinfo.value) == "pmax should be within [0,1]" with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], pmax=0.3, pmin=0.8) assert str( execinfo.value) == "pmin should be smaller than pmax" # kmax with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], kmax=1.2) assert str( execinfo.value) == "kmax should be larger or equal to 10" # updn with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], updn="bbq") assert str( execinfo.value) == "the selection of phases should be either 'up', 'down' or 'all'" # samples_before_first_arrival with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], samples_before_first_arrival=- 12) assert str( execinfo.value) == "samples_before_first_arrival should be positive" # source and receiver with pytest.raises(PyfkError) as execinfo: _ = Config( source=test_source, receiver_distance=[10, 20, 30]) assert str( execinfo.value) == "Must provide a seisModel" with pytest.raises(PyfkError) as execinfo: _ = Config( model=1, source=test_source, receiver_distance=[10, 20, 30]) assert str( execinfo.value) == "Must provide a seisModel" with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, receiver_distance=[10, 20, 30]) assert str( execinfo.value) == "Must provide a source" with pytest.raises(PyfkError) as execinfo: _ = Config( source=1, model=test_model, receiver_distance=[10, 20, 30]) assert str( execinfo.value) == "Must provide a source" # source located at real interface test_source_interface = SourceModel(sdep=16, srcType="dc") with pytest.raises(PyfkError) as execinfo: _ = Config( model=test_model, source=test_source_interface, receiver_distance=[ 10, 20, 30]) assert str( execinfo.value) == "The source is located at a real interface."
def test_init(self): test_model = SeisModel( TestClassSeisModel.test_model_6column, flattening=False, use_kappa=False) test_source = SourceModel(sdep=12, srcType="dc") test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30]) newmodel = np.array([ [5.5, 3.18, 5.501, 2.53, 600, 1100], [6.5, 3.64, 6.301, 2.55, 700, 1300], [4, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [0, 4.50, 7.799, 2.6, 900, 1800] ]) assert np.all(test_config.model.model_values == newmodel) test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], rdep=16, degrees=True) receiver_distance_km = [degrees2kilometers( 10), degrees2kilometers(20), degrees2kilometers(30)] assert np.allclose(test_config.receiver_distance, receiver_distance_km) test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], rdep=16) assert np.all(test_config.model.model_values == newmodel) test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], rdep=30) newmodel = np.array([ [5.5, 3.18, 5.501, 2.53, 600, 1100], [6.5, 3.64, 6.301, 2.55, 700, 1300], [4, 3.64, 6.301, 2.55, 700, 1300], [14.0, 3.87, 6.699, 2.59, 800, 1600], [2.0, 3.87, 6.699, 2.59, 800, 1600], [0, 4.50, 7.799, 2.6, 900, 1800] ]) assert np.all(test_config.model.model_values == newmodel) test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], rdep=13) newmodel = np.array([ [5.5, 3.18, 5.501, 2.53, 600, 1100], [6.5, 3.64, 6.301, 2.55, 700, 1300], [1, 3.64, 6.301, 2.55, 700, 1300], [3, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [0, 4.50, 7.799, 2.6, 900, 1800] ]) assert np.all(test_config.model.model_values == newmodel) test_config = Config( model=test_model, source=test_source, receiver_distance=[ 10, 20, 30], rdep=7) newmodel = np.array([ [5.5, 3.18, 5.501, 2.53, 600, 1100], [1.5, 3.64, 6.301, 2.55, 700, 1300], [5, 3.64, 6.301, 2.55, 700, 1300], [4, 3.64, 6.301, 2.55, 700, 1300], [16.0, 3.87, 6.699, 2.59, 800, 1600], [0, 4.50, 7.799, 2.6, 900, 1800] ]) assert np.all(test_config.model.model_values == newmodel)