Пример #1
0
    def test_count_events_on_equidistant_grid_no_ids(self):
        """Ensures correct output from count_events_on_equidistant_grid.

        In this case event IDs are *not* included as input.
        """

        this_num_events_matrix, _ = grids.count_events_on_equidistant_grid(
            event_x_coords_metres=EVENT_X_COORDS_METRES,
            event_y_coords_metres=EVENT_Y_COORDS_METRES,
            integer_event_ids=None,
            grid_point_x_coords_metres=EVENT_GRID_POINTS_X_METRES,
            grid_point_y_coords_metres=EVENT_GRID_POINTS_Y_METRES)

        self.assertTrue(
            numpy.array_equal(this_num_events_matrix, NUM_EVENTS_MATRIX))
Пример #2
0
    def test_count_events_on_equidistant_grid_with_ids(self):
        """Ensures correct output from count_events_on_equidistant_grid.

        In this case event IDs are included as input.
        """

        this_num_events_matrix, _ = grids.count_events_on_equidistant_grid(
            event_x_coords_metres=EVENT_X_COORDS_METRES,
            event_y_coords_metres=EVENT_Y_COORDS_METRES,
            integer_event_ids=INTEGER_EVENT_IDS,
            grid_point_x_coords_metres=GRID_POINTS_X_FOR_COUNTING_METRES,
            grid_point_y_coords_metres=GRID_POINTS_Y_FOR_COUNTING_METRES)

        self.assertTrue(
            numpy.array_equal(this_num_events_matrix,
                              NUM_UNIQUE_EVENTS_MATRIX_EQUIDISTANT))
Пример #3
0
def _run(prediction_file_name, top_tracking_dir_name, prob_threshold,
         grid_spacing_metres, output_dir_name):
    """Plots spatial distribution of false alarms.

    This is effectively the main method.

    :param prediction_file_name: See documentation at top of file.
    :param top_tracking_dir_name: Same.
    :param prob_threshold: Same.
    :param grid_spacing_metres: Same.
    :param output_dir_name: Same.
    """

    # Process input args.
    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)
    error_checking.assert_is_greater(prob_threshold, 0.)
    error_checking.assert_is_less_than(prob_threshold, 1.)

    grid_metadata_dict = grids.create_equidistant_grid(
        min_latitude_deg=MIN_LATITUDE_DEG,
        max_latitude_deg=MAX_LATITUDE_DEG,
        min_longitude_deg=MIN_LONGITUDE_DEG,
        max_longitude_deg=MAX_LONGITUDE_DEG,
        x_spacing_metres=grid_spacing_metres,
        y_spacing_metres=grid_spacing_metres,
        azimuthal=False)

    # Read predictions and find positive forecasts and false alarms.
    print('Reading predictions from: "{0:s}"...'.format(prediction_file_name))
    prediction_dict = prediction_io.read_ungridded_predictions(
        prediction_file_name)

    observed_labels = prediction_dict[prediction_io.OBSERVED_LABELS_KEY]
    forecast_labels = (
        prediction_dict[prediction_io.PROBABILITY_MATRIX_KEY][:, -1] >=
        prob_threshold).astype(int)

    pos_forecast_indices = numpy.where(forecast_labels == 1)[0]
    false_alarm_indices = numpy.where(
        numpy.logical_and(observed_labels == 0, forecast_labels == 1))[0]

    num_examples = len(observed_labels)
    num_positive_forecasts = len(pos_forecast_indices)
    num_false_alarms = len(false_alarm_indices)

    print(('Probability threshold = {0:.3f} ... number of examples, positive '
           'forecasts, false alarms = {1:d}, {2:d}, {3:d}').format(
               prob_threshold, num_examples, num_positive_forecasts,
               num_false_alarms))

    # Find and read tracking files.
    pos_forecast_id_strings = [
        prediction_dict[prediction_io.STORM_IDS_KEY][k]
        for k in pos_forecast_indices
    ]
    pos_forecast_times_unix_sec = (
        prediction_dict[prediction_io.STORM_TIMES_KEY][pos_forecast_indices])

    file_times_unix_sec = numpy.unique(pos_forecast_times_unix_sec)
    num_files = len(file_times_unix_sec)
    storm_object_tables = [None] * num_files

    print(SEPARATOR_STRING)

    for i in range(num_files):
        this_tracking_file_name = tracking_io.find_file(
            top_tracking_dir_name=top_tracking_dir_name,
            tracking_scale_metres2=DUMMY_TRACKING_SCALE_METRES2,
            source_name=tracking_utils.SEGMOTION_NAME,
            valid_time_unix_sec=file_times_unix_sec[i],
            spc_date_string=time_conversion.time_to_spc_date_string(
                file_times_unix_sec[i]),
            raise_error_if_missing=True)

        print('Reading data from: "{0:s}"...'.format(this_tracking_file_name))
        this_table = tracking_io.read_file(this_tracking_file_name)
        storm_object_tables[i] = this_table.loc[this_table[
            tracking_utils.FULL_ID_COLUMN].isin(pos_forecast_id_strings)]

        if i == 0:
            continue

        storm_object_tables[i] = storm_object_tables[i].align(
            storm_object_tables[0], axis=1)[0]

    storm_object_table = pandas.concat(storm_object_tables,
                                       axis=0,
                                       ignore_index=True)
    print(SEPARATOR_STRING)

    # Find latitudes and longitudes of false alarms.
    all_id_strings = (
        storm_object_table[tracking_utils.FULL_ID_COLUMN].values.tolist())
    all_times_unix_sec = (
        storm_object_table[tracking_utils.VALID_TIME_COLUMN].values)
    good_indices = tracking_utils.find_storm_objects(
        all_id_strings=all_id_strings,
        all_times_unix_sec=all_times_unix_sec,
        id_strings_to_keep=pos_forecast_id_strings,
        times_to_keep_unix_sec=pos_forecast_times_unix_sec,
        allow_missing=False)

    pos_forecast_latitudes_deg = storm_object_table[
        tracking_utils.CENTROID_LATITUDE_COLUMN].values[good_indices]

    pos_forecast_longitudes_deg = storm_object_table[
        tracking_utils.CENTROID_LONGITUDE_COLUMN].values[good_indices]

    false_alarm_id_strings = [
        prediction_dict[prediction_io.STORM_IDS_KEY][k]
        for k in false_alarm_indices
    ]
    false_alarm_times_unix_sec = (
        prediction_dict[prediction_io.STORM_TIMES_KEY][false_alarm_indices])
    good_indices = tracking_utils.find_storm_objects(
        all_id_strings=all_id_strings,
        all_times_unix_sec=all_times_unix_sec,
        id_strings_to_keep=false_alarm_id_strings,
        times_to_keep_unix_sec=false_alarm_times_unix_sec,
        allow_missing=False)

    false_alarm_latitudes_deg = storm_object_table[
        tracking_utils.CENTROID_LATITUDE_COLUMN].values[good_indices]

    false_alarm_longitudes_deg = storm_object_table[
        tracking_utils.CENTROID_LONGITUDE_COLUMN].values[good_indices]

    pos_forecast_x_coords_metres, pos_forecast_y_coords_metres = (
        projections.project_latlng_to_xy(
            latitudes_deg=pos_forecast_latitudes_deg,
            longitudes_deg=pos_forecast_longitudes_deg,
            projection_object=grid_metadata_dict[grids.PROJECTION_KEY]))

    num_pos_forecasts_matrix = grids.count_events_on_equidistant_grid(
        event_x_coords_metres=pos_forecast_x_coords_metres,
        event_y_coords_metres=pos_forecast_y_coords_metres,
        grid_point_x_coords_metres=grid_metadata_dict[grids.X_COORDS_KEY],
        grid_point_y_coords_metres=grid_metadata_dict[grids.Y_COORDS_KEY])[0]
    print(SEPARATOR_STRING)

    false_alarm_x_coords_metres, false_alarm_y_coords_metres = (
        projections.project_latlng_to_xy(
            latitudes_deg=false_alarm_latitudes_deg,
            longitudes_deg=false_alarm_longitudes_deg,
            projection_object=grid_metadata_dict[grids.PROJECTION_KEY]))

    num_false_alarms_matrix = grids.count_events_on_equidistant_grid(
        event_x_coords_metres=false_alarm_x_coords_metres,
        event_y_coords_metres=false_alarm_y_coords_metres,
        grid_point_x_coords_metres=grid_metadata_dict[grids.X_COORDS_KEY],
        grid_point_y_coords_metres=grid_metadata_dict[grids.Y_COORDS_KEY])[0]
    print(SEPARATOR_STRING)

    num_pos_forecasts_matrix = num_pos_forecasts_matrix.astype(float)
    num_pos_forecasts_matrix[num_pos_forecasts_matrix == 0] = numpy.nan
    num_false_alarms_matrix = num_false_alarms_matrix.astype(float)
    num_false_alarms_matrix[num_false_alarms_matrix == 0] = numpy.nan
    far_matrix = num_false_alarms_matrix / num_pos_forecasts_matrix

    this_max_value = numpy.nanpercentile(num_false_alarms_matrix,
                                         MAX_COUNT_PERCENTILE_TO_PLOT)
    if this_max_value < 10:
        this_max_value = numpy.nanmax(num_false_alarms_matrix)

    figure_object = plotter._plot_one_value(
        data_matrix=num_false_alarms_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=CMAP_OBJECT_FOR_COUNTS,
        min_colour_value=0,
        max_colour_value=this_max_value,
        plot_cbar_min_arrow=False,
        plot_cbar_max_arrow=True)[0]

    num_false_alarms_file_name = '{0:s}/num_false_alarms.jpg'.format(
        output_dir_name)

    print('Saving figure to: "{0:s}"...'.format(num_false_alarms_file_name))
    figure_object.savefig(num_false_alarms_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    this_max_value = numpy.nanpercentile(num_pos_forecasts_matrix,
                                         MAX_COUNT_PERCENTILE_TO_PLOT)
    if this_max_value < 10:
        this_max_value = numpy.nanmax(num_pos_forecasts_matrix)

    figure_object = plotter._plot_one_value(
        data_matrix=num_pos_forecasts_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=CMAP_OBJECT_FOR_COUNTS,
        min_colour_value=0,
        max_colour_value=this_max_value,
        plot_cbar_min_arrow=False,
        plot_cbar_max_arrow=True)[0]

    num_pos_forecasts_file_name = '{0:s}/num_positive_forecasts.jpg'.format(
        output_dir_name)

    print('Saving figure to: "{0:s}"...'.format(num_pos_forecasts_file_name))
    figure_object.savefig(num_pos_forecasts_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)

    this_max_value = numpy.nanpercentile(far_matrix,
                                         MAX_FAR_PERCENTILE_TO_PLOT)
    this_min_value = numpy.nanpercentile(far_matrix,
                                         100. - MAX_FAR_PERCENTILE_TO_PLOT)

    figure_object = plotter._plot_one_value(
        data_matrix=far_matrix,
        grid_metadata_dict=grid_metadata_dict,
        colour_map_object=CMAP_OBJECT_FOR_FAR,
        min_colour_value=this_min_value,
        max_colour_value=this_max_value,
        plot_cbar_min_arrow=this_min_value > 0.,
        plot_cbar_max_arrow=this_max_value < 1.)[0]

    far_file_name = '{0:s}/false_alarm_ratio.jpg'.format(output_dir_name)

    print('Saving figure to: "{0:s}"...'.format(far_file_name))
    figure_object.savefig(far_file_name,
                          dpi=FIGURE_RESOLUTION_DPI,
                          pad_inches=0,
                          bbox_inches='tight')
    pyplot.close(figure_object)