Esempio n. 1
0
    def test_select_within_magnitude_range(self):
        '''
        Tests the function to select within the magnitude range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['magnitude'] = np.array([4., 5., 6., 7., 8.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_magnitude_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             self.catalogue.data['magnitude'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_magnitude_range(lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7., 8.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_magnitude_range(upper_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([4., 5.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_magnitude_range(upper_mag=7.5,
                                                      lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7.]))
Esempio n. 2
0
    def test_select_within_magnitude_range(self):
        '''
        Tests the function to select within the magnitude range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['magnitude'] = np.array([4., 5., 6., 7., 8.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_magnitude_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             self.catalogue.data['magnitude'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_magnitude_range(lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7., 8.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_magnitude_range(upper_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([4., 5.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_magnitude_range(upper_mag=7.5,
                                                      lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7.]))
Esempio n. 3
0
def plot_mfd(catalogue_fname,
             grd,
             label,
             store,
             tr_fname,
             compl_table=None,
             mwid=0.1,
             upper_mag=11.,
             title='',
             xlim=None,
             ylim=None,
             figsize=None):
    """
    This function plots the incremental and complementary cumulative
    distribution of the earthquakes included in a catalogue file.

    :param catalogue_fname:
        Full path to the hmtk formatted catalogue
    :param label:
        If the user provides a tectonic regionalisation file, this label (or
        list of labels with the format LAB1, LAB2) defines the tectonic regions
        to be selected.
    :param tr_fname:
        Full path to the .hdf5 file containing the TR
    :param compl_table:
        A :class:`numpy.ndarray` instance of shape (2, n) where the first
        column contains years in a decreasing order and the second column
        contains magnitude (generally) in an increasing order
    :param grd:
        A boolean indicating the need to compute GR parameters
    :param upper_mag:
        The upper magnitude threshold used to filter the catalogue. This is
        useful for example in cases when it is interesting to fit only the
        exponential component of a magnitude-frequency distribution.
    :return:
        A tuple containing the output of the Weichert method in the following
        order: gr_pars
    """
    mwid = float(mwid)
    #
    # loading catalogue
    cat = _load_catalogue(catalogue_fname)
    #
    # select earthquakes belonging to a given TR
    idx = numpy.full(cat.data['magnitude'].shape, True, dtype=bool)
    if label is not None and tr_fname is not None:
        f = h5py.File(tr_fname, 'r')
        idx = f[label][:]
        f.close()
    #
    # select catalogue
    sel = CatalogueSelector(cat, create_copy=False)
    sel.select_catalogue(idx)
    sel.within_magnitude_range(-1, upper_mag)
    tmps = 'Selecting earthquakes below magnitude {:.2f}'
    logging.info(tmps.format(upper_mag))
    #
    # find rounded min and max magnitude
    mmin, mmax = _get_extremes(cat.data['magnitude'], mwid)
    tmin, tmax = _get_extremes(cat.data['year'], 10)
    #
    # compute histogram
    bins = numpy.arange(mmin, mmax + mwid * 0.01, mwid)
    his, _ = numpy.histogram(cat.data['magnitude'], bins)
    #
    # plotting
    if figsize is None:
        figsize = (8, 6)
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(1, 1, 1)
    #
    # add cumulative plot
    cs = numpy.cumsum(his[::-1])
    plt.bar(bins[:-1], cs[::-1], mwid, align='edge', ec='cyan', fc='none')
    plt.plot(bins[:-1] + mwid / 2, cs[::-1], '-r', label='cumulative')
    #
    # add incremental plot
    plt.bar(bins[:-1], his, mwid, align='edge', ec='orange', fc='none')
    plt.plot(bins[:-1] + mwid / 2, his, '-b', label='incremental')
    #
    #
    if grd:
        if compl_table is None:
            compl_table = numpy.array([[tmin, mmin]])
        agr, bgr, asig, bsig = _compute_mfd(cat, compl_table, mwid)
    #
    # info
    num = len(cat.data['magnitude'])
    print('Number of earthquakes in the catalogue          : {:d}'.format(num))
    num = max(cs)
    print('Maximum value in the c. cumulative distribution : {:d}'.format(num))
    #
    # finish plot
    plt.legend()
    plt.yscale('log')
    plt.ylabel('Number of earthquakes')
    plt.xlabel('Magnitude')
    if label is not None:
        plt.title('label: {:s}'.format(label))
    plt.grid(linestyle='-')
    if grd:
        plt.text(0.65,
                 0.70,
                 'bval: %.3f (sigma=%.3f)' % (bgr, bsig),
                 horizontalalignment='left',
                 verticalalignment='center',
                 fontsize=8,
                 transform=ax.transAxes)
        plt.text(0.65,
                 0.75,
                 'aval: %.3f (sigma=%.3f)' % (agr, asig),
                 horizontalalignment='left',
                 verticalalignment='center',
                 fontsize=8,
                 transform=ax.transAxes)
        #
        #
        ascaled = numpy.log10(10**agr * (tmax - tmin))
        v = 10.**(-bins * bgr + ascaled)
        plt.plot(bins, v, '--g', lw=2)
    #
    # set limits
    if xlim is not None:
        plt.xlim(xlim)
    if ylim is not None:
        plt.ylim(ylim)
    #
    # Set title
    plt.title(title)
    #
    # Storing figure
    if store is not None:
        lbl = ''
        ext = 'png'
        if label is not None:
            lbl = label
        figure_fname = 'fig_mfd_{:s}.{:s}'.format(lbl, ext)
        plt.savefig(figure_fname, format=ext)
    else:
        plt.show()

    out = (bins[:-1] + mwid / 2, numpy.array([float(h) for h in his]))
    if grd:
        return out, (agr, bgr, asig, bsig)
    else:
        return out, None