def test_calculate_taper_function_zero_case(self): ''' Test case when g_function is 0.0. g_function is 0 when (obs - sel) < -100.0 * corner_mo This scenario seems to occur when the selected moment is significantly greater than the corner magnitude ''' self.assertAlmostEqual( 0.0, calculate_taper_function(moment_function(5.0), moment_function(8.0), moment_function(6.0), self.beta))
def test_calculate_taper_function_zero_case(self): ''' Test case when g_function is 0.0. g_function is 0 when (obs - sel) < -100.0 * corner_mo This scenario seems to occur when the selected moment is significantly greater than the corner magnitude ''' self.assertAlmostEqual(0.0, calculate_taper_function( moment_function(5.0), moment_function(8.0), moment_function(6.0), self.beta))
def test_continuum_seismicity(self): ''' Tests the function hmtk.strain.shift.Shift.continuum_seismicity - the python implementation of the Subroutine Continuum Seismicity from the Fortran 90 code GSRM.f90 ''' self.strain_model = GeodeticStrain() # Define a simple strain model test_data = {'longitude': np.zeros(3, dtype=float), 'latitude': np.zeros(3, dtype=float), 'exx': np.array([1E-9, 1E-8, 1E-7]), 'eyy': np.array([5E-10, 5E-9, 5E-8]), 'exy': np.array([2E-9, 2E-8, 2E-7])} self.strain_model.get_secondary_strain_data(test_data) self.model = Shift([5.66, 6.66]) threshold_moment = moment_function(np.array([5.66, 6.66])) expected_rate = np.array([[-14.43624419, -22.48168502], [-13.43624419, -21.48168502], [-12.43624419, -20.48168502]]) np.testing.assert_array_almost_equal( expected_rate, np.log10(self.model.continuum_seismicity( threshold_moment, self.strain_model.data['e1h'], self.strain_model.data['e2h'], self.strain_model.data['err'], BIRD_GLOBAL_PARAMETERS['OSRnor'])))
def test_calculate_taper_function(self): ''' Tests the function to calculate the taper part of the Tapered Gutenberg & Richter model with exhaustive data set ''' obs_mo = moment_function(np.arange(5.0, 9.5, 1.0)) sel_mo = moment_function(np.arange(5.0, 9.5, 1.0)) obs_data = np.zeros([len(obs_mo), len(sel_mo)], dtype=float) corner_mo = moment_function(8.5) for iloc, obs in enumerate(obs_mo): for jloc, sel in enumerate(sel_mo): obs_data[iloc, jloc] = calculate_taper_function( obs, sel, corner_mo, self.beta) np.testing.assert_array_almost_equal(TAPER_FUNCTION_DATA, np.log10(obs_data))
def test_moment_function(self): ''' Tests the simple function to implement the Hanks & Kanamori (1979) formula for an input magnitude ''' expected_value = 18.05 self.assertAlmostEqual(expected_value, log10(moment_function(6.0)))
def _get_base_rates(self, base_params): ''' Defines the base moment rate that should be assigned to places of zero strain (i.e. Intraplate regions). In Bird et al (2010) this is taken as basic rate of Intraplate events in GCMT catalogue above the threshold magnitude :param dict base_params: Parameters needed for calculating the base rate. Requires: 'CMT_EVENTS': The number of CMT events 'area': Total area (km ^ 2) of the region class 'CMT_duration': Duration of reference catalogue 'CMT_moment': Moment rate from CMT catalogue 'corner_mag': Corner magnitude of Tapered G-R for region 'beta': Beta value of tapered G-R for distribution ''' base_ipl_rate = base_params['CMT_EVENTS'] / ( base_params['area'] * base_params['CMT_duration']) base_rate = np.zeros(self.number_magnitudes, dtype=float) for iloc in range(0, self.number_magnitudes): base_rate[iloc] = base_ipl_rate * calculate_taper_function( base_params['CMT_moment'], self.threshold_moment[iloc], moment_function(base_params['corner_mag']), base_params['beta']) return base_rate
def test_continuum_seismicity(self): # Tests the function hmtk.strain.shift.Shift.continuum_seismicity - # the python implementation of the Subroutine Continuum Seismicity # from the Fortran 90 code GSRM.f90 self.strain_model = GeodeticStrain() # Define a simple strain model test_data = { 'longitude': np.zeros(3, dtype=float), 'latitude': np.zeros(3, dtype=float), 'exx': np.array([1E-9, 1E-8, 1E-7]), 'eyy': np.array([5E-10, 5E-9, 5E-8]), 'exy': np.array([2E-9, 2E-8, 2E-7]) } self.strain_model.get_secondary_strain_data(test_data) self.model = Shift([5.66, 6.66]) threshold_moment = moment_function(np.array([5.66, 6.66])) expected_rate = np.array([[-14.43624419, -22.48168502], [-13.43624419, -21.48168502], [-12.43624419, -20.48168502]]) np.testing.assert_array_almost_equal( expected_rate, np.log10( self.model.continuum_seismicity( threshold_moment, self.strain_model.data['e1h'], self.strain_model.data['e2h'], self.strain_model.data['err'], BIRD_GLOBAL_PARAMETERS['OSRnor'])))
def test_calculate_taper_function(self): ''' Tests the function to calculate the taper part of the Tapered Gutenberg & Richter model with exhaustive data set ''' obs_mo = moment_function(np.arange(5.0, 9.5, 1.0)) sel_mo = moment_function(np.arange(5.0, 9.5, 1.0)) obs_data = np.zeros([len(obs_mo), len(sel_mo)], dtype=float) corner_mo = moment_function(8.5) for iloc, obs in enumerate(obs_mo): for jloc, sel in enumerate(sel_mo): obs_data[iloc, jloc] = calculate_taper_function(obs, sel, corner_mo, self.beta) np.testing.assert_array_almost_equal(TAPER_FUNCTION_DATA, np.log10(obs_data))
def __init__(self, minimum_magnitude, base_params=None, region_parameter_file=None): ''' Instantiate the class, retreive minimum moments, base rates and regionalisation informaton :param float/list/np.ndarray minimum_magnitude: Target magnitudes for calculating the activity rates :param dict base_params: Regionalisation parameters for the background region type (in this case the Bird et al. Intraplate class :param str region_parameter_file: To overwrite the default Bird et al (2007) classifcations the regionalisation can be defined in a separate Yaml file ''' base_params = base_params or IPL_PARAMS self.strain = None if isinstance(minimum_magnitude, float): self.target_magnitudes = np.array([minimum_magnitude], dtype=float) elif isinstance(minimum_magnitude, list): self.target_magnitudes = np.array(minimum_magnitude, dtype=float) elif isinstance(minimum_magnitude, np.ndarray): self.target_magnitudes = minimum_magnitude else: raise ValueError('Minimum magnitudes must be float, list or array') self.number_magnitudes = len(self.target_magnitudes) self.threshold_moment = moment_function(self.target_magnitudes) # Get the base rate from the input parameters self.base_rate = self._get_base_rates(base_params) # If a regionalisation parameter file is defined then read # regionalisation from there - otherwise use Bird regionalisation if region_parameter_file: self.regionalisation = yaml.load(open(region_parameter_file, 'rt')) else: self.regionalisation = BIRD_GLOBAL_PARAMETERS
def test_moment_magnitude_function(self): ''' Tests the Hanks & Kanamori (1979) formula for an input moment ''' self.assertAlmostEqual(6.0, moment_magnitude_function(moment_function(6.0)))
'OCB': OCB_PARAMS, 'SUB': SUB_PARAMS, 'IPL': IPL_PARAMS} # This value of 25.7474 is taken from Bird's analysis - # TODO this needs to be generalised if integrating w/Modeller CMT_DURATION_S = 25.7474 * SECS_PER_YEAR # Apply SI conversion adjustments from Bird (2007)'s code # TODO This is ugly - reconsider this (maybe require only inputs in SI) for reg_type in BIRD_GLOBAL_PARAMETERS.keys(): reg = BIRD_GLOBAL_PARAMETERS[reg_type] reg['corner_moment'] = moment_function(reg['corner_mag']) if reg_type is not 'IPL': reg['CMT_pure_event_rate'] = reg['CMT_EVENTS'] / CMT_DURATION_S reg['length'] = 1000.0 * reg['length'] reg['velocity'] = (reg['velocity'] * 0.001) / SECS_PER_YEAR reg['assumed_dip'] = reg['assumed_dip'] * RADIAN_CONV reg['assumed_mu'] = reg['assumed_mu'] * 1.0E9 reg['coupled_thickness'] = reg['coupled_thickness'] * 1000. reg['lithosphere'] = reg['lithosphere'] * 1000. else: reg['CMT_pure_event_rate'] = reg['CMT_EVENTS'] / reg['CMT_duration'] BIRD_GLOBAL_PARAMETERS[reg_type] = reg STRAIN_VARIABLES = ['exx', 'eyy', 'exy', 'e1h', 'e2h', 'err', '2nd_inv', 'dilatation']
'OCB': OCB_PARAMS, 'SUB': SUB_PARAMS, 'IPL': IPL_PARAMS} # This value of 25.7474 is taken from Bird's analysis - # TODO this needs to be generalised if integrating w/Modeller CMT_DURATION_S = 25.7474 * SECS_PER_YEAR # Apply SI conversion adjustments from Bird (2007)'s code # TODO This is ugly - reconsider this (maybe require only inputs in SI) for reg_type in BIRD_GLOBAL_PARAMETERS: reg = BIRD_GLOBAL_PARAMETERS[reg_type] reg['corner_moment'] = moment_function(reg['corner_mag']) if reg_type is not 'IPL': reg['CMT_pure_event_rate'] = reg['CMT_EVENTS'] / CMT_DURATION_S reg['length'] = 1000.0 * reg['length'] reg['velocity'] = (reg['velocity'] * 0.001) / SECS_PER_YEAR reg['assumed_dip'] = reg['assumed_dip'] * RADIAN_CONV reg['assumed_mu'] = reg['assumed_mu'] * 1.0E9 reg['coupled_thickness'] = reg['coupled_thickness'] * 1000. reg['lithosphere'] = reg['lithosphere'] * 1000. else: reg['CMT_pure_event_rate'] = reg['CMT_EVENTS'] / reg['CMT_duration'] BIRD_GLOBAL_PARAMETERS[reg_type] = reg STRAIN_VARIABLES = ['exx', 'eyy', 'exy', 'e1h', 'e2h', 'err', '2nd_inv', 'dilatation']