def test_query_Vs_at_depth__query_Vs_Profile_objects(self): prof = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) # (1) Test invalid input: non-increasing array with self.assertRaisesRegex(ValueError, 'needs to be monotonically increasing'): prof.query_Vs_at_depth(np.array([1, 2, 5, 4, 6]), as_profile=True) # (2) Test invalid input: repeated values with self.assertRaisesRegex(ValueError, 'should not contain duplicate values'): prof.query_Vs_at_depth(np.array([1, 2, 4, 4, 6]), as_profile=True) # (3) Test a scalar input result = prof.query_Vs_at_depth(1.0, as_profile=True) benchmark = Vs_Profile(np.array([[1, 0], [120, 120]]).T) compare = np.allclose(result.vs_profile, benchmark.vs_profile) self.assertTrue(compare) # (4) Test a general case result \ = prof.query_Vs_at_depth(np.array([0, 1, 2, 3, 9]), as_profile=True) benchmark \ = Vs_Profile(np.array([[1, 1, 1, 6, 0], [120, 120, 190, 190, 280]]).T) compare = np.allclose(result.vs_profile, benchmark.vs_profile) self.assertTrue(compare)
def test_truncate__case_2(self): # Case 2: Truncation on the boundary of a layer data = np.array([[5, 4, 3, 2, 1], [200, 500, 700, 1000, 1200]]).T prof = Vs_Profile(data) new_prof = prof.truncate(depth=9, Vs=2000) benchmark = np.array([[5, 4, 0], [200, 500, 2000]]).T self.assertTrue(np.allclose(new_prof.vs_profile[:, :2], benchmark))
def test_amplify_by_tf(self): #---------- Case 1: An artificial transfer function ------------------- gm = GM('./files/sample_accel.txt', unit='gal') ratio_benchmark = 2.76 freq = np.arange(0.01, 50, step=0.01) tf = ratio_benchmark * np.ones_like(freq) transfer_function = Frequency_Spectrum(np.column_stack((freq, tf))) new_gm = gm.amplify_by_tf(transfer_function, show_fig=False) ratio = new_gm.accel[:, 1] / gm.accel[:, 1] self.assertTrue(np.allclose(ratio, ratio_benchmark)) #---------- Case 2: A transfer function from a Vs profile ------------- vs_prof = Vs_Profile('./files/profile_FKSH14.txt') tf_RO, tf_BH, _ = vs_prof.get_transfer_function() gm_with_tf_RO = gm.amplify_by_tf(tf_RO) gm_with_tf_BH = gm.amplify_by_tf(tf_BH) gm_with_tf_RO_ = gm.amplify(vs_prof, boundary='elastic') gm_with_tf_BH_ = gm.amplify(vs_prof, boundary='rigid') # Assert that `amplify_by_tf()` and `amplify()` can generate # nearly identical results self.assertTrue( self.nearly_identical(gm_with_tf_RO.accel, gm_with_tf_RO_.accel)) self.assertTrue( self.nearly_identical(gm_with_tf_BH.accel, gm_with_tf_BH_.accel))
def test_get_amplif_function(self): profile_FKSH14 = Vs_Profile('./files/profile_FKSH14.txt') af_RO = profile_FKSH14.get_ampl_function(freq_resolution=0.5, fmax=15)[0] af_benchmark = np.array([[0.50, 1.20218233839345], # from MATLAB [1, 2.40276180417506], [1.50, 3.35891308492276], [2, 1.52759821088595], [2.50, 1.23929961393844], [3, 1.44564547138629], [3.50, 2.43924932880498], [4, 4.01661301316906], [4.50, 2.32960159664501], [5, 1.79841404983353], [5.50, 1.96256021192571], [6, 3.12817017367637], [6.50, 3.92494425374814], [7, 2.10815322297781], [7.50, 1.66638537272089], [8, 1.95562752738785], [8.50, 3.37394970215842], [9, 2.59724801539598], [9.50, 1.57980154466212], [10, 1.42540110327715], [10.5, 1.82180321630950], [11, 3.04707962007382], [11.5, 2.60349869620899], [12, 1.84273534851058], [12.5, 1.79995928341286], [13, 2.35928076072069], [13.5, 3.59881564870728], [14, 3.31112261403936], [14.5, 2.61283127927210], [15, 2.69868407060282]]) self.assertTrue(np.allclose(af_RO.spectrum_2col, af_benchmark, atol=1e-9, rtol=0.0))
def test_plot(self): # Test that the desired data are correctly imported to the object accel_in = Ground_Motion(_join(f_dir, 'sample_accel.txt'), unit='m/s/s') accel_tmp = accel_in.accel.copy() accel_tmp[:, 1] *= 5.0 accel_out = Ground_Motion(accel_tmp, unit='m/s/s') vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) thk = vs_profile._thk depth_bound = sr.thk2dep(thk, midpoint=False) depth_midpoint = sr.thk2dep(thk, midpoint=True) max_a_v_d = np.column_stack( (depth_bound, depth_bound * 1, depth_bound * 2, depth_bound * 3)) max_gamma_tau = np.column_stack( (depth_midpoint, depth_midpoint * 1, depth_midpoint * 2)) tf_RO, _, _ = vs_profile.get_transfer_function() sim_results = Simulation_Results(accel_in, accel_out, vs_profile, max_a_v_d=max_a_v_d, max_strain_stress=max_gamma_tau, trans_func=tf_RO) sim_results.plot(save_fig=False) # Test that it can produce a plot without max profiles and trans. func. sim_results_ = Simulation_Results(accel_in, accel_out, vs_profile) sim_results_.plot(save_fig=False)
def test_truncate__case_3(self): # Case 3: Truncation beyond the total depth of original profile data = np.array([[5, 4, 3, 2, 1], [200, 500, 700, 1000, 1200]]).T prof = Vs_Profile(data) new_prof = prof.truncate(depth=30, Vs=2000) benchmark = np.array([[5, 4, 3, 2, 16, 0], [200, 500, 700, 1000, 1200, 2000]]).T self.assertTrue(np.allclose(new_prof.vs_profile[:, :2], benchmark))
def test_add_halfspace__case_1__no_half_space(self): data = np.genfromtxt(_join( f_dir, 'two_column_data_example.txt')) # no halfspace prof_1 = Vs_Profile(data, add_halfspace=False) prof_2 = Vs_Profile(data, add_halfspace=True) self.assertTrue(prof_1._thk[-1] != 0) self.assertTrue(prof_2._thk[-1] == 0) self.assertTrue(prof_1._thk[-2] != 0) self.assertTrue(prof_2._thk[-2] != 0) # assert only one "halfspace" self.assertEqual(prof_1.n_layer, 15) self.assertEqual(prof_1.n_layer, prof_2.n_layer)
def test_add_halfspace__case_1__already_a_half_space(self): data = np.genfromtxt(_join( f_dir, 'sample_profile.txt')) # already has halfspace prof_1 = Vs_Profile(data, add_halfspace=False) prof_2 = Vs_Profile(data, add_halfspace=True) self.assertTrue(prof_1._thk[-1] == 0) self.assertTrue(prof_2._thk[-1] == 0) self.assertTrue(prof_1._thk[-2] != 0) self.assertTrue(prof_2._thk[-2] != 0) # assert only one "halfspace" self.assertEqual(prof_1.n_layer, 12) self.assertEqual(prof_1.n_layer, prof_2.n_layer)
def test_Vs_profile_format__case_7(self): # Test negative values in Vs data = np.array([[10, 20, 30, 0], [100, 120, 160, 190]], dtype=float).T data[2, 1] = -1 with self.assertRaisesRegex(ValueError, 'Vs column should be all positive.'): Vs_Profile(data)
def test_Vs_profile_format__case_5(self): # Test negative values in last layer thickness data = np.array([[10, 20, 30, 0], [100, 120, 160, 190]], dtype=float).T data[-1, 0] = -1 with self.assertRaisesRegex(ValueError, 'last layer thickness should be'): Vs_Profile(data)
def test_Vs_profile_format__case_4(self): # Test non-positive values in thickness data = np.array([[10, 20, 30, 0], [100, 120, 160, 190]], dtype=float).T data[2, 0] = 0 with self.assertRaisesRegex(ValueError, 'should be all positive, except'): Vs_Profile(data)
def test_Vs_profile_format__case_3(self): # Test NaN values data = np.array([[10, 20, 30, 0], [100, 120, 160, 190]], dtype=float).T data[2, 1] = np.nan with self.assertRaisesRegex(ValueError, 'should contain no NaN values'): Vs_Profile(data)
def test_nonlinear_init(self): input_motion = Ground_Motion('./files/sample_accel.txt', unit='m') soil_profile = Vs_Profile('./files/profile_FKSH14.txt') HH_G = HH_Param_Multi_Layer('./files/HH_G_FKSH14.txt') HH_x = HH_Param_Multi_Layer('./files/HH_X_FKSH14.txt') # this should succeed Nonlinear_Simulation(soil_profile, input_motion, G_param=HH_G, xi_param=HH_x, boundary='elastic') # this should fail with ValueError HH_G_data = HH_G.param_list HH_x_data = HH_x.param_list HH_G_ = HH_Param_Multi_Layer(HH_G_data[:-1]) # exclude one layer HH_x_ = HH_Param_Multi_Layer(HH_x_data[:-1]) # exclude one layer with self.assertRaises(ValueError, msg='Not enough sets of parameters'): Nonlinear_Simulation(soil_profile, input_motion, G_param=HH_G_, xi_param=HH_x) with self.assertRaises(ValueError, msg='Not enough sets of parameters'): Nonlinear_Simulation(soil_profile, input_motion, G_param=HH_G, xi_param=HH_x_)
def __init__(self, methodName='runTest'): data, _ = hlp.read_two_column_stuff('./files/two_column_data_example.txt') data[:, 0] *= 10 data[:, 1] *= 100 prof = Vs_Profile(data) self.prof = prof super(Test_Class_Vs_Profile, self).__init__(methodName=methodName)
def test_amplify_by_tf__case_2_a_transfer_function_from_a_Vs_profile(self): gm = GM(_join(f_dir, 'sample_accel.txt'), unit='gal') vs_prof = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) tf_RO, tf_BH, _ = vs_prof.get_transfer_function() gm_with_tf_RO = gm.amplify_by_tf(tf_RO) gm_with_tf_BH = gm.amplify_by_tf(tf_BH) gm_with_tf_RO_ = gm.amplify(vs_prof, boundary='elastic') gm_with_tf_BH_ = gm.amplify(vs_prof, boundary='rigid') # Assert that `amplify_by_tf()` and `amplify()` can generate # nearly identical results self.assertTrue(self.nearly_identical(gm_with_tf_RO.accel, gm_with_tf_RO_.accel)) self.assertTrue(self.nearly_identical(gm_with_tf_BH.accel, gm_with_tf_BH_.accel))
def test_init(self): # Case 1: Not a list with self.assertRaises(TypeError, msg='`list_of_simulations` should be a list.'): Batch_Simulation(1.4) # Case 2: A list of 0 length with self.assertRaises(ValueError, msg='should have at least one element'): Batch_Simulation([]) # Case 3: Wrong type with self.assertRaises( TypeError, msg='Elements of `list_of_simulations` should be of type'): Batch_Simulation([1, 2, 3]) # Case 4: Inhomogeneous element type with self.assertRaises(TypeError, msg='should be of the same type'): gm = Ground_Motion('./files/sample_accel.txt', unit='gal') prof = Vs_Profile('./files/profile_FKSH14.txt') mgdc = Multiple_GGmax_Damping_Curves(data='./files/curve_P001.txt') lin_sim = Linear_Simulation(gm, prof) equiv_sim = Equiv_Linear_Simulation(gm, prof, mgdc) Batch_Simulation([lin_sim, equiv_sim])
def test_equiv_linear(self): soil_profile = Vs_Profile('./files/profile_FKSH14.txt') input_motion = Ground_Motion('./files/sample_accel.txt', unit='gal') curves = Multiple_GGmax_Damping_Curves(data='./files/curve_FKSH14.txt') equiv_lin_sim = Equiv_Linear_Simulation(soil_profile, input_motion, curves, boundary='elastic') output = equiv_lin_sim.run(show_fig=True) max_v = output.max_a_v_d[:, 2] max_v_benchmark = [ 0.404085, 0.403931, 0.402998, 0.399842, 0.390005, 0.389336, 0.388176, 0.386563, 0.384449, 0.381578, 0.377044, 0.371955, 0.366454, 0.36505, 0.363536, 0.361912, 0.360214, 0.358405, 0.356464, 0.354368, 0.352104, 0.349671, 0.347186, 0.344585, 0.342999, 0.344762, 0.345623, 0.346219, 0.34607, 0.344739, 0.342724, 0.339295, 0.334776, 0.32954, 0.324481, 0.319054, 0.317311, 0.316842, 0.318159, 0.319668, 0.321421, 0.323498, 0.325626, 0.326861, 0.328234, 0.328466, 0.327704, 0.326466, 0.323216, 0.322324, 0.320209, 0.316914, 0.312529, 0.308906, 0.304708, 0.300202, 0.295505, 0.29226, 0.289536, 0.287653, 0.287429, 0.290265, 0.292502 ] # from MATLAB SeismoSoil tol = 0.01 # FFT of scipy and MATLAB are different, hence a lenient tolerance self.assertTrue(np.allclose(max_v, max_v_benchmark, rtol=tol, atol=0.0))
def test_fit(self): # Case 1: users only have Vs profile vs_profile = Vs_Profile('./files/profile_FKSH14.txt') hh_c = HH_Calibration(vs_profile) HH_G_param = hh_c.fit(verbose=False) HH_G_param_benchmark = HH_Param_Multi_Layer('./files/HH_G_FKSH14.txt') self.assertTrue( np.allclose(HH_G_param.serialize_to_2D_array(), HH_G_param_benchmark.serialize_to_2D_array(), rtol=1e-5, atol=0.0)) # Case 2: users have both Vs profile and G/Gmax curves curves = Multiple_GGmax_Curves('./files/curve_FKSH14.txt') hh_c = HH_Calibration(vs_profile, GGmax_curves=curves) HH_G_param = hh_c.fit(verbose=False) HH_G_benchmark_data \ = np.array([[0.0003, 0.0001, 0.0001, 0.0001, 0.0001], [100, 100, 100, 100, 100], [0.000285072, 0.000516205, 0.000944545, 0.00129825, 0.00144835], [1.75224, 1.71444, 1.64057, 1.58664, 1.56314], [0.918975, 0.919001, 0.918973, 0.919007, 0.918999], [2.11104e+07, 6.859e+07, 1.4896e+08, 2.25441e+09, 3.28398e+09], [0.233357, 0.199149, 0.253784, 1, 1], [26501, 64856.6, 148805, 804855, 1.10785e+06], [0.937739, 0.850905, 0.861759, 0.984774, 0.981156]]) HH_G_param_benchmark = HH_Param_Multi_Layer(HH_G_benchmark_data) self.assertTrue( np.allclose(HH_G_param.serialize_to_2D_array(), HH_G_param_benchmark.serialize_to_2D_array(), rtol=1e-2, atol=0.0))
def test_init__incorrect_Tmax_length(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) curves = Multiple_GGmax_Curves(_join(f_dir, 'curve_FKSH14.txt')) Tmax = np.array([1, 2, 3]) with self.assertRaisesRegex( ValueError, 'The length of `Tmax_profile` ' 'needs to equal'): HH_Calibration(vs_profile, GGmax_curves=curves, Tmax_profile=Tmax)
def test_get_damping_curves__check_n_layers_correct(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) d_cal = Damping_Calibration(vs_profile) strain_in_pct = np.logspace(-2, 1, num=23) mdc = d_cal.get_damping_curves(strain_in_pct=strain_in_pct, use_Darendeli_Dmin=True, show_fig=True) self.assertEqual(mdc.n_layer, vs_profile.n_layer)
def test_init__incorrect_Tmax_type(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) curves = Multiple_GGmax_Curves(_join(f_dir, 'curve_FKSH14.txt')) Tmax = [1, 2, 3, 4, 5] with self.assertRaisesRegex( TypeError, '`Tmax_profile` must be a 1D ' 'numpy array.'): HH_Calibration(vs_profile, GGmax_curves=curves, Tmax_profile=Tmax)
def test_init__incorrect_length_of_curves(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) curves = Multiple_GGmax_Curves(_join(f_dir, 'curve_FKSH14.txt')) del curves[-1] # remove the last layer with self.assertRaisesRegex( ValueError, 'The number of layers implied ' 'in `GGmax_curves` and `vs_profile` must be' ' the same.'): HH_Calibration(vs_profile, GGmax_curves=curves)
def test_init__case_4_inhomogeneous_element_type(self): with self.assertRaisesRegex(TypeError, 'should be of the same type'): gm = Ground_Motion(_join(f_dir, 'sample_accel.txt'), unit='gal') prof = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) mgdc = Multiple_GGmax_Damping_Curves( data=_join(f_dir, 'curve_FKSH14.txt')) lin_sim = Linear_Simulation(prof, gm) equiv_sim = Equiv_Linear_Simulation(prof, gm, mgdc) Batch_Simulation([lin_sim, equiv_sim])
def test_Vs_profile_format__case_12(self): # Test correct number of columns data = np.array( [[10, 20, 30, 0], [100, 120, 160, 190], [0.01, 0.01, 0.01, 0.01], [1600, 1600, 1600, 1600], [1, 2, 3, 0]], dtype=float).T data_ = data[:, 0:-1] # one fewer column with self.assertRaisesRegex(ValueError, 'either 2 or 5 columns'): Vs_Profile(data_)
def test_get_H4_x_param(self): vs_profile = Vs_Profile('./files/profile_FKSH14.txt') d_cal = Damping_Calibration(vs_profile) # Only test that `get_H4_x_param()` can run without bugs d_cal.get_H4_x_param(pop_size=1, n_gen=1, save_txt=False, use_scipy=True, show_fig=True)
def test_Vs_profile_format__case_9(self): # Test "material number" column: all integers data = np.array( [[10, 20, 30, 0], [100, 120, 160, 190], [0.01, 0.01, 0.01, 0.01], [1600, 1600, 1600, 1600], [1, 2, 3, 0]], dtype=float).T data_ = data.copy() data_[1, -1] = 2.2 with self.assertRaisesRegex(ValueError, 'should be all integers'): Vs_Profile(data_)
def test_init__success_with_curves_and_Tmax(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) curves = Multiple_GGmax_Curves(_join(f_dir, 'curve_FKSH14.txt')) Tmax = np.array([1, 2, 3, 4, 5]) hh_c = HH_Calibration(vs_profile, GGmax_curves=curves, Tmax_profile=Tmax) self.assertTrue(isinstance(hh_c.vs_profile, Vs_Profile)) self.assertTrue(isinstance(hh_c.GGmax_curves, Multiple_GGmax_Curves)) self.assertTrue(isinstance(hh_c.Tmax_profile, np.ndarray))
def test_Vs_profile_format__case_8(self): # Test non-positive values in damping and density data = np.array( [[10, 20, 30, 0], [100, 120, 160, 190], [0.01, 0.01, 0.01, 0.01], [1600, 1600, 1600, 1600], [1, 2, 3, 0]], dtype=float).T data_ = data.copy() data_[2, 3] = 0 with self.assertRaisesRegex(ValueError, 'damping and density columns'): Vs_Profile(data_)
def test_fit__case_1_with_only_Vs_profile(self): vs_profile = Vs_Profile(_join(f_dir, 'profile_FKSH14.txt')) hh_c = HH_Calibration(vs_profile) HH_G_param = hh_c.fit(verbose=False) HH_G_param_benchmark = HH_Param_Multi_Layer( _join(f_dir, 'HH_G_FKSH14.txt')) self.assertTrue( np.allclose(HH_G_param.serialize_to_2D_array(), HH_G_param_benchmark.serialize_to_2D_array(), rtol=1e-5, atol=0.0))
def test_init(self): filename = './files/profile_FKSH14.txt' vs_profile_array = np.genfromtxt(filename) # Case 1: incorrect input type with self.assertRaises(TypeError, msg='must be of type Vs_Profile'): Damping_Calibration(vs_profile_array) # Case 2: correct input type vs_profile = Vs_Profile(filename) Damping_Calibration(vs_profile)