def test_get_observed_mmax(self): ''' Tests the function to _get_observed_mmax from data ''' test_catalogue = { 'magnitude': np.array([3.4, 4.5, 7.6, 5.4, 4.3]), 'sigmaMagnitude': np.array([0.1, 0.2, 0.3, 0.2, 0.1]) } # Test 1: Finds the mmax from the catalogue with defined sigma mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 7.6) self.assertAlmostEqual(mmax_sig, 0.3) # Test 2: Finds the mmax from the catalogue with default sigma (0.2) test_catalogue['sigmaMagnitude'] = None mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 7.6) self.assertAlmostEqual(mmax_sig, 0.2) # Test 3: Finds the mmax from the input file self.config['input_mmax'] = 8.5 self.config['input_mmax_uncertainty'] = 0.35 mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 8.5) self.assertAlmostEqual(mmax_sig, 0.35)
def _get_observed_mmax_error(self, test_catalogue, test_config): """ Tests the get_observed_mmax exceptions are raised """ with self.assertRaises(ValueError) as ae: mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertEqual(ae.exception.message, 'Input mmax uncertainty must be specified!')
def test_get_observed_mmax_good_data(self): # Asserts that the observed Mmax and corresponding sigma MMax are # returned when data are availavle test_catalogue = { 'magnitude': np.array([3.4, 4.5, 7.6, 5.4, 4.3]), 'sigmaMagnitude': np.array([0.1, 0.2, 0.3, 0.2, 0.1]) } # Test 1: Finds the mmax from the catalogue with defined sigma mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 7.6) self.assertAlmostEqual(mmax_sig, 0.3)
def test_mmax_uncertainty_largest_in_catalogue(self): # When largest mmax has a NaN sigmaMagnitude, take the largest # sigmaMagnitude found in catalogue self.config['input_mmax'] = None self.config['input_mmax_uncertainty'] = None test_catalogue = { 'magnitude': np.array([3.4, 4.5, 7.6, 5.4, 4.3]), 'sigmaMagnitude': np.array([0.1, 0.4, np.nan, 0.2, 0.1]) } mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 7.6) self.assertAlmostEqual(mmax_sig, 0.4)
def test_observed_mmax_catalogue_uncertainty_config(self): # Tests the case when the observed Mmax must be read from the catalogue # but the uncertainty is specified in the config self.config['input_mmax'] = None self.config['input_mmax_uncertainty'] = 0.5 test_catalogue = { 'magnitude': np.array([3.4, 4.5, 7.6, 5.4, 4.3]), 'sigmaMagnitude': np.array([]) } mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 7.6) self.assertAlmostEqual(mmax_sig, 0.5)
def test_get_observed_mmax_from_input(self): # Tests that the input mmax and its uncertainty are returned when # specified in the config # Test 3: Finds the mmax from the input file self.config['input_mmax'] = 8.5 self.config['input_mmax_uncertainty'] = 0.35 test_catalogue = { 'magnitude': np.array([3.4, 4.5, 7.6, 5.4, 4.3]), 'sigmaMagnitude': None } mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertAlmostEqual(mmax, 8.5) self.assertAlmostEqual(mmax_sig, 0.35)
def get_mmax(self, catalogue, config): ''' Calculates Maximum magnitude :param catalogue: Earthquake catalogue as instance of :class: hmtk.seismicity.catalogue.Catalogue :param dict config: Configuration file for algorithm, contains the attributes: * 'b-value': b-value (positive float) * 'input_mmin': Minimum magnitude for integral (if less than minimum observed magnitude, will be overwritten by minimum observed magnitude) * 'tolerance': Tolerance of stabilising of iterator * 'maximum_interations': Maximum number of iterations :returns: **mmax** Maximum magnitude and **mmax_sig** corresponding uncertainty ''' config = check_config(config, catalogue.data) obsmax, obsmaxsig = _get_observed_mmax(catalogue.data, config) mmin = config['input_mmin'] beta = config['b-value'] * np.log(10.) neq, mmin = _get_magnitude_vector_properties(catalogue.data, config) mmax = np.copy(obsmax) d_t = np.inf iterator = 0 while d_t > config['tolerance']: delta = quadrature(self._ks_intfunc, mmin, mmax, args=(neq, mmax, mmin, beta))[0] #print mmin, neq, delta, mmax tmmax = obsmax + delta d_t = np.abs(tmmax - mmax) mmax = np.copy(tmmax) iterator += 1 if iterator > config['maximum_iterations']: print 'Kijko-Sellevol estimator reached maximum # of iterations' d_t = -np.inf return mmax.item(), np.sqrt(obsmaxsig**2. + delta**2.)
def get_mmax(self, catalogue, config): ''' Calculates Maximum magnitude :param catalogue: Earthquake catalogue as instance of :class: hmtk.seismicity.catalogue.Catalogue :param dict config: Configuration file for algorithm, contains the attributes: * 'b-value': b-value (positive float) * 'input_mmin': Minimum magnitude for integral (if less than minimum observed magnitude, will be overwritten by minimum observed magnitude) * 'tolerance': Tolerance of stabilising of iterator * 'maximum_interations': Maximum number of iterations :returns: **mmax** Maximum magnitude and **mmax_sig** corresponding uncertainty ''' config = check_config(config, catalogue.data) obsmax, obsmaxsig = _get_observed_mmax(catalogue.data, config) mmin = config['input_mmin'] beta = config['b-value'] * np.log(10.) neq, mmin = _get_magnitude_vector_properties(catalogue.data, config) mmax = np.copy(obsmax) d_t = np.inf iterator = 0 while d_t > config['tolerance']: delta = quadrature(self._ks_intfunc, mmin, mmax, args=(neq, mmax, mmin, beta))[0] #print mmin, neq, delta, mmax tmmax = obsmax + delta d_t = np.abs(tmmax - mmax) mmax = np.copy(tmmax) iterator += 1 if iterator > config['maximum_iterations']: print ('Kijko-Sellevol estimator reached ' 'maximum # of iterations') d_t = -np.inf return mmax.item(), np.sqrt(obsmaxsig ** 2. + delta ** 2.)
def get_mmax(self, catalogue, config): '''Calculate maximum magnitude :return: **mmax** Maximum magnitude and **mmax_sig** corresponding uncertainty :rtype: Float ''' # Check configuration file config = check_config(config, catalogue.data) # Negative b-values will return nan - this simply skips the integral if config['b-value'] <= 0.0: return np.nan, np.nan obsmax, obsmaxsig = _get_observed_mmax(catalogue.data, config) beta = config['b-value'] * np.log(10.) sigbeta = config['sigma-b'] * np.log(10.) neq, mmin = _get_magnitude_vector_properties(catalogue.data, config) pval = beta / (sigbeta ** 2.) qval = (beta / sigbeta) ** 2. mmax = np.copy(obsmax) d_t = np.inf iterator = 0 while d_t > config['tolerance']: rval = pval / (pval + mmax - mmin) ldelt = (1. / (1. - (rval ** qval))) ** neq delta = ldelt * quadrature(self._ksb_intfunc, mmin, mmax, args=(neq, mmin, pval, qval))[0] tmmax = obsmax + delta d_t = np.abs(tmmax - mmax) mmax = np.copy(tmmax) iterator += 1 if iterator > config['maximum_iterations']: print 'Kijko-Sellevol-Bayes estimator reached' print 'maximum # of iterations' d_t = -np.inf return mmax.item(), np.sqrt(obsmaxsig ** 2. + delta ** 2.)
def _get_observed_mmax_error(self, test_catalogue, test_config): # Tests the get_observed_mmax exceptions are raised with self.assertRaises(ValueError) as ae: mmax, mmax_sig = _get_observed_mmax(test_catalogue, self.config) self.assertEqual(str(ae.exception), 'Input mmax uncertainty must be specified!')