Beispiel #1
0
 def test_ascii_load_last_empty(self):
     fname = os.path.join(get_test_catalog_root(), 'last_empty.csv')
     test_fore = load_catalog_forecast(fname)
     total_event_count = numpy.array([cat.event_count
                                      for cat in test_fore]).sum()
     self.assertEqual(1, total_event_count)
     self.assertEqual(10, test_fore.n_cat)
     numpy.testing.assert_array_equal([cat.catalog_id for cat in test_fore],
                                      numpy.arange(10))
Beispiel #2
0
 def test_ascii_some_missing_verbose(self):
     fname = os.path.join(get_test_catalog_root(), 'all_present.csv')
     test_fore = load_catalog_forecast(fname)
     total_event_count = numpy.array([cat.event_count
                                      for cat in test_fore]).sum()
     print([(cat.event_count, cat.catalog_id) for cat in test_fore])
     self.assertEqual(10, total_event_count)
     self.assertEqual(10, test_fore.n_cat)
     numpy.testing.assert_array_equal([cat.catalog_id for cat in test_fore],
                                      numpy.arange(10))
# :mod:`csep.utils` subpackage.

import numpy

import csep
from csep.core import regions
from csep.utils import datasets

####################################################################################################################################
# Load data forecast
# ---------------------
#
# PyCSEP contains some basic forecasts that can be used to test of the functionality of the package. This forecast has already
# been filtered to the California RELM region.

forecast = csep.load_catalog_forecast(
    datasets.ucerf3_ascii_format_landers_fname)

####################################################################################################################################
# Define spatial and magnitude regions
# ------------------------------------
#
# Before we can compute the bin-wise rates we need to define a spatial region and a set of magnitude bin edges. The magnitude
# bin edges # are the lower bound (inclusive) except for the last bin, which is treated as extending to infinity. We can
# bind these # to the forecast object. This can also be done by passing them as keyword arguments
# into :func:`csep.load_catalog_forecast`.

# Magnitude bins properties
min_mw = 4.95
max_mw = 8.95
dmw = 0.1
Beispiel #4
0
 def test_get_event_counts(self):
     fname = os.path.join(get_test_catalog_root(), 'all_present.csv')
     test_fore = load_catalog_forecast(fname)
     numpy.testing.assert_array_equal(numpy.ones(10),
                                      test_fore.get_event_counts())
def process_ucerf3_forecast(config):
    """ Post-processing script for ucerf3-forecasts

    Program will perform N, M, and S tests and write out evaluation results.

    Args:
        config (dict): contents of configuration needed to run the job

    """
    # Get directory of forecast file from simulation manifest
    forecast_dir = get_forecast_filepath(config['simulation_list'],
                                         config['job_idx'])
    config.update({'forecast_dir': forecast_dir})
    print(f"Working on forecast in {config['forecast_dir']}.")

    # Search for forecast files
    forecast_path = os.path.join(forecast_dir, 'results_complete.bin.gz')
    if not os.path.exists(forecast_path):
        print(
            f"Did not find a forecast at {forecast_path}. Looking for uncompressed version.",
            flush=True)
        forecast_path = os.path.join(forecast_dir, 'results_complete.bin')
        if not os.path.exists(forecast_path):
            print(f"Unable to find uncompressed forecast. Aborting.",
                  flush=True)
            sys.exit(-1)
    config['forecast_path'] = forecast_path
    print(f"Found forecast file at {config['forecast_path']}.")

    # Create output directory
    mkdirs(config['output_dir'])

    # Initialize processing tasks
    print(f"Processing forecast at {forecast_path}.", flush=True)
    config_path = os.path.join(config['forecast_dir'], 'config.json')
    with open(config_path) as json_file:
        u3etas_config = json.load(json_file)

    # Time horizon of the forecast
    start_epoch = u3etas_config['startTimeMillis']
    end_epoch = start_epoch + config['forecast_duration_millis']
    config['start_epoch'] = start_epoch
    config['end_epoch'] = end_epoch

    # Create region information from configuration file
    region_config = config['region_information']
    region = create_space_magnitude_region(region_config['name'],
                                           region_config['min_mw'],
                                           region_config['max_mw'],
                                           region_config['dmw'])
    min_magnitude = region.magnitudes[0]

    # Set up filters for forecast and catalogs
    filters = [
        f'origin_time >= {start_epoch}', f'origin_time < {end_epoch}',
        f'magnitude >= {min_magnitude}'
    ]

    # Forecast, note: filters are applied when iterating through the forecast
    forecast_basename = os.path.basename(config['forecast_dir'])
    forecast = load_catalog_forecast(forecast_path,
                                     type='ucerf3',
                                     name=f'ucerf3-{forecast_basename}',
                                     region=region,
                                     filters=filters,
                                     filter_spatial=True,
                                     apply_filters=True)

    # Sanity check to ensure that forecasts are filtered properly
    min_mws = []
    for catalog in forecast:
        if catalog.event_count > 0:
            min_mws.append(catalog.get_magnitudes().min())
    print(
        f"Overall minimum magnitude of catalogs in forecast: {np.min(min_mws)}"
    )

    # Compute expected rates for spatial test and magnitude test
    _ = forecast.get_expected_rates()
    sc = forecast.expected_rates.spatial_counts()
    sc_path = os.path.join(
        config['output_dir'],
        create_output_filepath(config['forecast_dir'],
                               'spatial_counts_arr-f8.bin'))
    with open(sc_path, 'wb') as sc_file:
        print(f"Writing spatial counts to {sc_path}")
        sc.tofile(sc_file)

    # Prepare evaluation catalog
    eval_catalog = load_catalog(config['catalog_path'],
                                region=region,
                                filters=filters,
                                name='comcat',
                                apply_filters=True)

    # Compute and store number test
    print("Computing number-test on forecast.")
    ntest_result = catalog_evaluations.number_test(forecast, eval_catalog)
    ntest_path = os.path.join(
        config['output_dir'],
        create_output_filepath(config['forecast_dir'], 'ntest_result.json'))
    try:
        write_json(ntest_result, ntest_path)
        config['ntest_path'] = ntest_path
        print(f"Writing outputs to {config['ntest_path']}.")
    except IOError:
        print("Unable to write n-test result.")

    # Compute number test over multiple magnitudes
    # print("Computing number test over multiple magnitudes")
    # ntest_results = number_test_multiple_mag(forecast, eval_catalog)
    # config['ntest_paths'] = []
    # for r in ntest_results:
    #     min_mw = r.min_mw
    #     ntest_path = os.path.join(
    #         config['output_dir'],
    #         create_output_filepath(config['forecast_dir'], 'ntest_result_' + str(min_mw).replace('.','p') + '.json')
    #     )
    #     try:
    #         write_json(ntest_result, ntest_path)
    #         config['ntest_paths'].append(ntest_path)
    #         print(f"Writing outputs to {ntest_path}.")
    #     except IOError:
    #         print("Unable to write n-test result.")

    # Compute and store magnitude test
    print("Computing magnitude-test on forecast.")
    mtest_result = catalog_evaluations.magnitude_test(forecast, eval_catalog)
    mtest_path = os.path.join(
        config['output_dir'],
        create_output_filepath(config['forecast_dir'], 'mtest_result.json'))
    try:
        write_json(mtest_result, mtest_path)
        config['mtest_path'] = mtest_path
        print(f"Writing outputs to {config['mtest_path']}.")
    except IOError:
        print("Unable to write m-test result.")

    # Compute and store spatial test
    print("Computing spatial test on forecast.")
    stest_path = os.path.join(
        config['output_dir'],
        create_output_filepath(config['forecast_dir'], 'stest_result.json'))
    stest_result = catalog_evaluations.spatial_test(forecast, eval_catalog)
    try:
        write_json(stest_result, stest_path)
        config['stest_path'] = stest_path
    except (IOError, TypeError, ValueError):
        print("Unable to write s-test result.")

    # Write calculation configuration
    config_path = os.path.join(
        config['output_dir'],
        create_output_filepath(config['forecast_dir'], 'meta.json'))
    print(f"Saving run-time configuration to {config_path}.")
    with open(config_path, 'w') as f:
        json.dump(config, f, indent=4, separators=(',', ': '))
Beispiel #6
0
####################################################################################################################################
# Load catalog forecast
# ---------------------
#
# To reduce the file size of this example, we've already filtered the catalogs to the appropriate magnitudes and
# spatial locations. The original forecast was computed for 1 year following the start date, so we still need to filter the
# catalog in time. We can do this by passing a list of filtering arguments to the forecast or updating the class.
#
# By default, the forecast loads catalogs on-demand, so the filters are applied as the catalog loads. On-demand means that
# until we loop over the forecast in some capacity, none of the catalogs are actually loaded.
#
# More fine-grain control and optimizations can be achieved by creating a :class:`csep.core.forecasts.CatalogForecast` directly.

forecast = csep.load_catalog_forecast(
    datasets.ucerf3_ascii_format_landers_fname,
    start_time=start_time,
    end_time=end_time,
    region=space_magnitude_region)

# Assign filters to forecast
forecast.filters = [
    f'origin_time >= {forecast.start_epoch}',
    f'origin_time < {forecast.end_epoch}'
]

####################################################################################################################################
# Obtain evaluation catalog from ComCat
# -------------------------------------
#
# The :class:`csep.core.forecasts.CatalogForecast` provides a method to compute the expected number of events in spatial cells. This
# requires a region with magnitude information.