Exemplo n.º 1
0
def latlng_limits_to_rowcol_limits(min_latitude_deg,
                                   max_latitude_deg,
                                   min_longitude_deg,
                                   max_longitude_deg,
                                   model_name,
                                   grid_id=None):
    """Converts lat-long limits to row-column limits in the given model grid.

    :param min_latitude_deg: Minimum latitude (deg N).
    :param max_latitude_deg: Max latitude (deg N).
    :param min_longitude_deg: Minimum longitude (deg E).
    :param max_longitude_deg: Max longitude (deg E).
    :param model_name: Name of NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :param grid_id: Grid for NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :return: row_limits: length-2 numpy array, containing min and max rows in
        model grid, respectively.
    :return: column_limits: Same but for columns.
    """

    error_checking.assert_is_valid_latitude(min_latitude_deg)
    error_checking.assert_is_valid_latitude(max_latitude_deg)
    error_checking.assert_is_greater(max_latitude_deg, min_latitude_deg)

    both_longitudes_deg = numpy.array([min_longitude_deg, max_longitude_deg])
    both_longitudes_deg = lng_conversion.convert_lng_positive_in_west(
        both_longitudes_deg)

    min_longitude_deg = both_longitudes_deg[0]
    max_longitude_deg = both_longitudes_deg[1]
    error_checking.assert_is_greater(max_longitude_deg, min_longitude_deg)

    grid_point_lat_matrix_deg, grid_point_lng_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(model_name=model_name,
                                                       grid_name=grid_id))

    good_lat_flag_matrix = numpy.logical_and(
        grid_point_lat_matrix_deg >= min_latitude_deg,
        grid_point_lat_matrix_deg <= max_latitude_deg)
    good_lng_flag_matrix = numpy.logical_and(
        grid_point_lng_matrix_deg >= min_longitude_deg,
        grid_point_lng_matrix_deg <= max_longitude_deg)

    good_row_indices, good_column_indices = numpy.where(
        numpy.logical_and(good_lat_flag_matrix, good_lng_flag_matrix))

    row_limits = numpy.array(
        [numpy.min(good_row_indices),
         numpy.max(good_row_indices)], dtype=int)

    column_limits = numpy.array(
        [numpy.min(good_column_indices),
         numpy.max(good_column_indices)],
        dtype=int)

    return row_limits, column_limits
Exemplo n.º 2
0
    def test_wind_rotation_angles_grid130(self):
        """Ensures approx correctness of wind-rotation angles on NCEP 130 grid.

        This method ensures that the wind-rotation angle for all grid points can
        be generated accurately from lat-long coordinates.  Specifically, the
        mean sine and cosine error must be <= 10^-5 and max error must be
        <= 10^-4.

        NOTE: This test relies on methods other than get_wind_rotation_angles,
              so it is not a unit test.
        """

        num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
            model_name=nwp_model_utils.RAP_MODEL_NAME,
            grid_id=nwp_model_utils.ID_FOR_130GRID)

        expected_cos_vector, expected_sin_vector = numpy.loadtxt(
            GRID130_WIND_ROTATION_FILE_NAME, unpack=True)
        expected_cos_matrix = numpy.reshape(
            expected_cos_vector, (num_grid_rows, num_grid_columns))
        expected_sin_matrix = numpy.reshape(
            expected_sin_vector, (num_grid_rows, num_grid_columns))

        grid_point_lat_matrix_deg, grid_point_lng_matrix_deg = (
            nwp_model_utils.get_latlng_grid_point_matrices(
                model_name=nwp_model_utils.RAP_MODEL_NAME,
                grid_id=nwp_model_utils.ID_FOR_130GRID))
        rotation_angle_cos_matrix, rotation_angle_sin_matrix = (
            nwp_model_utils.get_wind_rotation_angles(
                grid_point_lat_matrix_deg, grid_point_lng_matrix_deg,
                model_name=nwp_model_utils.RAP_MODEL_NAME))

        cos_error_matrix = numpy.absolute(
            rotation_angle_cos_matrix - expected_cos_matrix)
        sin_error_matrix = numpy.absolute(
            rotation_angle_sin_matrix - expected_sin_matrix)

        self.assertTrue(
            numpy.mean(cos_error_matrix) <= MAX_MEAN_SIN_OR_COS_ERROR)
        self.assertTrue(numpy.max(cos_error_matrix) <= MAX_MAX_SIN_OR_COS_ERROR)

        self.assertTrue(
            numpy.mean(sin_error_matrix) <= MAX_MEAN_SIN_OR_COS_ERROR)
        self.assertTrue(numpy.max(sin_error_matrix) <= MAX_MAX_SIN_OR_COS_ERROR)
    def test_wind_rotation_angles_grid252(self):
        """Ensures approx correctness of rotation angles for NCEP 252 grid."""

        num_grid_rows, num_grid_columns = nwp_model_utils.get_grid_dimensions(
            model_name=nwp_model_utils.RAP_MODEL_NAME,
            grid_name=nwp_model_utils.NAME_OF_252GRID)

        expected_cos_vector, expected_sin_vector = numpy.loadtxt(
            GRID252_WIND_ROTATION_FILE_NAME, unpack=True)
        expected_cos_matrix = numpy.reshape(expected_cos_vector,
                                            (num_grid_rows, num_grid_columns))
        expected_sin_matrix = numpy.reshape(expected_sin_vector,
                                            (num_grid_rows, num_grid_columns))

        latitude_matrix_deg, longitude_matrix_deg = (
            nwp_model_utils.get_latlng_grid_point_matrices(
                model_name=nwp_model_utils.RAP_MODEL_NAME,
                grid_name=nwp_model_utils.NAME_OF_252GRID))

        rotation_angle_cos_matrix, rotation_angle_sin_matrix = (
            nwp_model_utils.get_wind_rotation_angles(
                latitudes_deg=latitude_matrix_deg,
                longitudes_deg=longitude_matrix_deg,
                model_name=nwp_model_utils.RAP_MODEL_NAME))

        cos_error_matrix = numpy.absolute(rotation_angle_cos_matrix -
                                          expected_cos_matrix)
        sin_error_matrix = numpy.absolute(rotation_angle_sin_matrix -
                                          expected_sin_matrix)

        self.assertTrue(
            numpy.mean(cos_error_matrix) <= MAX_MEAN_SIN_OR_COS_ERROR)
        self.assertTrue(
            numpy.max(cos_error_matrix) <= MAX_MAX_SIN_OR_COS_ERROR)

        self.assertTrue(
            numpy.mean(sin_error_matrix) <= MAX_MEAN_SIN_OR_COS_ERROR)
        self.assertTrue(
            numpy.max(sin_error_matrix) <= MAX_MAX_SIN_OR_COS_ERROR)
Exemplo n.º 4
0
def _get_grid_point_coords(model_name,
                           first_row_in_full_grid,
                           last_row_in_full_grid,
                           first_column_in_full_grid,
                           last_column_in_full_grid,
                           grid_id=None,
                           basemap_object=None):
    """Returns x-y and lat-long coords for a subgrid of the full model grid.

    This method generates different x-y coordinates than
    `nwp_model_utils.get_xy_grid_point_matrices`, because (like
    `mpl_toolkits.basemap.Basemap`) this method sets false easting = false
    northing = 0 metres.

    :param model_name: Name of NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :param first_row_in_full_grid: Row 0 in the subgrid is row
        `first_row_in_full_grid` in the full grid.
    :param last_row_in_full_grid: Last row in the subgrid is row
        `last_row_in_full_grid` in the full grid.  If you want last row in the
        subgrid to equal last row in the full grid, make this -1.
    :param first_column_in_full_grid: Column 0 in the subgrid is column
        `first_column_in_full_grid` in the full grid.
    :param last_column_in_full_grid: Last column in the subgrid is column
        `last_column_in_full_grid` in the full grid.  If you want last column in
        the subgrid to equal last column in the full grid, make this -1.
    :param grid_id: Grid for NWP model (must be accepted by
        `nwp_model_utils.check_grid_name`).
    :param basemap_object: Instance of `mpl_toolkits.basemap.Basemap` for the
        given NWP model.  If you don't have one, no big deal -- leave this
        argument empty.
    :return: coordinate_dict: Dictionary with the following keys.
    coordinate_dict['grid_point_x_matrix_metres']: M-by-N numpy array of
        x-coordinates.
    coordinate_dict['grid_point_y_matrix_metres']: M-by-N numpy array of
        y-coordinates.
    coordinate_dict['grid_point_lat_matrix_deg']: M-by-N numpy array of
        latitudes (deg N).
    coordinate_dict['grid_point_lng_matrix_deg']: M-by-N numpy array of
        longitudes (deg E).
    """

    num_rows_in_full_grid, num_columns_in_full_grid = (
        nwp_model_utils.get_grid_dimensions(model_name=model_name,
                                            grid_name=grid_id))

    error_checking.assert_is_integer(first_row_in_full_grid)
    error_checking.assert_is_geq(first_row_in_full_grid, 0)
    error_checking.assert_is_integer(last_row_in_full_grid)
    if last_row_in_full_grid < 0:
        last_row_in_full_grid += num_rows_in_full_grid

    error_checking.assert_is_greater(last_row_in_full_grid,
                                     first_row_in_full_grid)
    error_checking.assert_is_less_than(last_row_in_full_grid,
                                       num_rows_in_full_grid)

    error_checking.assert_is_integer(first_column_in_full_grid)
    error_checking.assert_is_geq(first_column_in_full_grid, 0)
    error_checking.assert_is_integer(last_column_in_full_grid)
    if last_column_in_full_grid < 0:
        last_column_in_full_grid += num_columns_in_full_grid

    error_checking.assert_is_greater(last_column_in_full_grid,
                                     first_column_in_full_grid)
    error_checking.assert_is_less_than(last_column_in_full_grid,
                                       num_columns_in_full_grid)

    grid_point_lat_matrix_deg, grid_point_lng_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(model_name=model_name,
                                                       grid_name=grid_id))

    grid_point_lat_matrix_deg = grid_point_lat_matrix_deg[
        first_row_in_full_grid:(last_row_in_full_grid + 1),
        first_column_in_full_grid:(last_column_in_full_grid + 1)]

    grid_point_lng_matrix_deg = grid_point_lng_matrix_deg[
        first_row_in_full_grid:(last_row_in_full_grid + 1),
        first_column_in_full_grid:(last_column_in_full_grid + 1)]

    if basemap_object is None:
        standard_latitudes_deg, central_longitude_deg = (
            nwp_model_utils.get_projection_params(model_name))

        projection_object = projections.init_lcc_projection(
            standard_latitudes_deg=standard_latitudes_deg,
            central_longitude_deg=central_longitude_deg)

        grid_point_x_matrix_metres, grid_point_y_matrix_metres = (
            projections.project_latlng_to_xy(
                latitudes_deg=grid_point_lat_matrix_deg,
                longitudes_deg=grid_point_lng_matrix_deg,
                projection_object=projection_object,
                false_northing_metres=0.,
                false_easting_metres=0.))
    else:
        grid_point_x_matrix_metres, grid_point_y_matrix_metres = basemap_object(
            grid_point_lng_matrix_deg, grid_point_lat_matrix_deg)

    return {
        X_COORD_MATRIX_KEY: grid_point_x_matrix_metres,
        Y_COORD_MATRIX_KEY: grid_point_y_matrix_metres,
        LATITUDE_MATRIX_KEY: grid_point_lat_matrix_deg,
        LONGITUDE_MATRIX_KEY: grid_point_lng_matrix_deg,
    }
Exemplo n.º 5
0
FOURTH_LONGITUDES_DEG = numpy.array([246., 246.5])

THIS_DICT = {
    front_utils.LATITUDES_COLUMN:
        [FIRST_LATITUDES_DEG, SECOND_LATITUDES_DEG, THIRD_LATITUDES_DEG,
         FOURTH_LATITUDES_DEG],
    front_utils.LONGITUDES_COLUMN:
        [FIRST_LONGITUDES_DEG, SECOND_LONGITUDES_DEG, THIRD_LONGITUDES_DEG,
         FOURTH_LONGITUDES_DEG],
    front_utils.TIME_COLUMN: THESE_TIMES_UNIX_SEC,
    front_utils.FRONT_TYPE_COLUMN: THESE_STRINGS
}
POLYLINE_TABLE_BEFORE_MASK = pandas.DataFrame.from_dict(THIS_DICT)

(THIS_LATITUDE_MATRIX_DEG, THIS_LONGITUDE_MATRIX_DEG
) = nwp_model_utils.get_latlng_grid_point_matrices(
    model_name=nwp_model_utils.NARR_MODEL_NAME)

THIS_LATITUDE_FLAG_MATRIX = numpy.logical_and(
    THIS_LATITUDE_MATRIX_DEG >= 30., THIS_LATITUDE_MATRIX_DEG <= 75.)
THIS_LONGITUDE_FLAG_MATRIX = numpy.logical_and(
    THIS_LONGITUDE_MATRIX_DEG >= 220., THIS_LONGITUDE_MATRIX_DEG <= 320.)
NARR_MASK_MATRIX = numpy.logical_and(
    THIS_LATITUDE_FLAG_MATRIX, THIS_LONGITUDE_FLAG_MATRIX
).astype(int)

THIS_DICT = {
    front_utils.LATITUDES_COLUMN:
        [FIRST_LATITUDES_DEG, SECOND_LATITUDES_DEG, THIRD_LATITUDES_DEG],
    front_utils.LONGITUDES_COLUMN:
        [FIRST_LONGITUDES_DEG, SECOND_LONGITUDES_DEG, THIRD_LONGITUDES_DEG],
    front_utils.TIME_COLUMN: THESE_TIMES_UNIX_SEC[:-1],
def _run(top_narr_dir_name, top_front_line_dir_name, top_wpc_bulletin_dir_name,
         first_time_string, last_time_string, pressure_level_mb,
         thermal_field_name, thermal_colour_map_name,
         max_thermal_prctile_for_colours, first_letter_label, letter_interval,
         output_dir_name):
    """Plots predictors on full NARR grid.

    This is effectively the main method.

    :param top_narr_dir_name: See documentation at top of file.
    :param top_front_line_dir_name: Same.
    :param top_wpc_bulletin_dir_name: Same.
    :param first_time_string: Same.
    :param last_time_string: Same.
    :param pressure_level_mb: Same.
    :param thermal_field_name: Same.
    :param thermal_colour_map_name: Same.
    :param max_thermal_prctile_for_colours: Same.
    :param first_letter_label: Same.
    :param letter_interval: Same.
    :param output_dir_name: Same.
    :raises: ValueError: if
        `thermal_field_name not in VALID_THERMAL_FIELD_NAMES`.
    """

    # Check input args.
    if top_wpc_bulletin_dir_name in ['', 'None']:
        top_wpc_bulletin_dir_name = None

    if first_letter_label in ['', 'None']:
        first_letter_label = None

    if thermal_field_name not in VALID_THERMAL_FIELD_NAMES:
        error_string = (
            '\n{0:s}\nValid thermal fields (listed above) do not include '
            '"{1:s}".'
        ).format(str(VALID_THERMAL_FIELD_NAMES), thermal_field_name)

        raise ValueError(error_string)

    thermal_colour_map_object = pyplot.cm.get_cmap(thermal_colour_map_name)

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    first_time_unix_sec = time_conversion.string_to_unix_sec(
        first_time_string, DEFAULT_TIME_FORMAT)
    last_time_unix_sec = time_conversion.string_to_unix_sec(
        last_time_string, DEFAULT_TIME_FORMAT)

    valid_times_unix_sec = time_periods.range_and_interval_to_list(
        start_time_unix_sec=first_time_unix_sec,
        end_time_unix_sec=last_time_unix_sec,
        time_interval_sec=NARR_TIME_INTERVAL_SEC, include_endpoint=True)

    # Read metadata for NARR grid.
    narr_latitude_matrix_deg, narr_longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME)
    )

    narr_rotation_cos_matrix, narr_rotation_sin_matrix = (
        nwp_model_utils.get_wind_rotation_angles(
            latitudes_deg=narr_latitude_matrix_deg,
            longitudes_deg=narr_longitude_matrix_deg,
            model_name=nwp_model_utils.NARR_MODEL_NAME)
    )

    narr_row_limits, narr_column_limits = (
        nwp_plotting.latlng_limits_to_rowcol_limits(
            min_latitude_deg=MIN_LATITUDE_DEG,
            max_latitude_deg=MAX_LATITUDE_DEG,
            min_longitude_deg=MIN_LONGITUDE_DEG,
            max_longitude_deg=MAX_LONGITUDE_DEG,
            model_name=nwp_model_utils.NARR_MODEL_NAME)
    )

    narr_rotation_cos_matrix = narr_rotation_cos_matrix[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ]

    narr_rotation_sin_matrix = narr_rotation_sin_matrix[
        narr_row_limits[0]:(narr_row_limits[1] + 1),
        narr_column_limits[0]:(narr_column_limits[1] + 1)
    ]

    # Do plotting.
    narr_field_names = [
        processed_narr_io.U_WIND_GRID_RELATIVE_NAME,
        processed_narr_io.V_WIND_GRID_RELATIVE_NAME,
        thermal_field_name
    ]

    this_letter_label = None

    for this_time_unix_sec in valid_times_unix_sec:
        this_file_name = fronts_io.find_file_for_one_time(
            top_directory_name=top_front_line_dir_name,
            file_type=fronts_io.POLYLINE_FILE_TYPE,
            valid_time_unix_sec=this_time_unix_sec)

        print 'Reading data from: "{0:s}"...'.format(this_file_name)
        this_polyline_table = fronts_io.read_polylines_from_file(this_file_name)

        if top_wpc_bulletin_dir_name is None:
            this_high_low_table = None
        else:
            this_file_name = wpc_bulletin_io.find_file(
                top_directory_name=top_wpc_bulletin_dir_name,
                valid_time_unix_sec=this_time_unix_sec)

            print 'Reading data from: "{0:s}"...'.format(this_file_name)
            this_high_low_table = wpc_bulletin_io.read_highs_and_lows(
                this_file_name)

        this_predictor_matrix = None

        for this_field_name in narr_field_names:
            this_file_name = processed_narr_io.find_file_for_one_time(
                top_directory_name=top_narr_dir_name,
                field_name=this_field_name,
                pressure_level_mb=pressure_level_mb,
                valid_time_unix_sec=this_time_unix_sec)

            print 'Reading data from: "{0:s}"...'.format(this_file_name)
            this_field_matrix = processed_narr_io.read_fields_from_file(
                this_file_name
            )[0][0, ...]

            this_field_matrix = utils.fill_nans(this_field_matrix)
            this_field_matrix = this_field_matrix[
                narr_row_limits[0]:(narr_row_limits[1] + 1),
                narr_column_limits[0]:(narr_column_limits[1] + 1)
            ]

            if this_field_name in [processed_narr_io.TEMPERATURE_NAME,
                                   processed_narr_io.WET_BULB_THETA_NAME]:
                this_field_matrix -= ZERO_CELSIUS_IN_KELVINS

            if this_field_name == processed_narr_io.SPECIFIC_HUMIDITY_NAME:
                this_field_matrix = this_field_matrix * KG_TO_GRAMS

            this_field_matrix = numpy.expand_dims(this_field_matrix, axis=-1)

            if this_predictor_matrix is None:
                this_predictor_matrix = this_field_matrix + 0.
            else:
                this_predictor_matrix = numpy.concatenate(
                    (this_predictor_matrix, this_field_matrix), axis=-1)

        u_wind_index = narr_field_names.index(
            processed_narr_io.U_WIND_GRID_RELATIVE_NAME)
        v_wind_index = narr_field_names.index(
            processed_narr_io.V_WIND_GRID_RELATIVE_NAME)

        (this_predictor_matrix[..., u_wind_index],
         this_predictor_matrix[..., v_wind_index]
        ) = nwp_model_utils.rotate_winds_to_earth_relative(
            u_winds_grid_relative_m_s01=this_predictor_matrix[
                ..., u_wind_index],
            v_winds_grid_relative_m_s01=this_predictor_matrix[
                ..., v_wind_index],
            rotation_angle_cosines=narr_rotation_cos_matrix,
            rotation_angle_sines=narr_rotation_sin_matrix)

        this_title_string = time_conversion.unix_sec_to_string(
            this_time_unix_sec, NICE_TIME_FORMAT)

        if pressure_level_mb == 1013:
            this_title_string += ' at surface'
        else:
            this_title_string += ' at {0:d} mb'.format(pressure_level_mb)

        this_default_time_string = time_conversion.unix_sec_to_string(
            this_time_unix_sec, DEFAULT_TIME_FORMAT)

        this_output_file_name = '{0:s}/predictors_{1:s}.jpg'.format(
            output_dir_name, this_default_time_string)

        if first_letter_label is not None:
            if this_letter_label is None:
                this_letter_label = first_letter_label
            else:
                this_letter_label = chr(
                    ord(this_letter_label) + letter_interval
                )

        _plot_one_time(
            predictor_matrix=this_predictor_matrix,
            predictor_names=narr_field_names,
            front_polyline_table=this_polyline_table,
            high_low_table=this_high_low_table,
            thermal_colour_map_object=thermal_colour_map_object,
            max_thermal_prctile_for_colours=max_thermal_prctile_for_colours,
            narr_row_limits=narr_row_limits,
            narr_column_limits=narr_column_limits,
            title_string=this_title_string, letter_label=this_letter_label,
            output_file_name=this_output_file_name)

        print '\n'
Exemplo n.º 7
0
def _run(top_input_dir_name, first_time_string, last_time_string,
         input_field_name, pressure_level_mb, top_output_dir_name):
    """Converts NARR data to a more convenient file format.

    This is effectively the main method.

    :param top_input_dir_name: See documentation at top of file.
    :param first_time_string: Same.
    :param last_time_string: Same.
    :param input_field_name: Same.
    :param pressure_level_mb: Same.
    :param top_output_dir_name: Same.
    """

    if pressure_level_mb <= 0:
        pressure_level_mb = None

    if pressure_level_mb is None:
        output_pressure_level_mb = DUMMY_PRESSURE_LEVEL_MB + 0
    else:
        output_pressure_level_mb = pressure_level_mb + 0

    first_time_unix_sec = time_conversion.string_to_unix_sec(
        first_time_string, INPUT_TIME_FORMAT)
    last_time_unix_sec = time_conversion.string_to_unix_sec(
        last_time_string, INPUT_TIME_FORMAT)

    valid_times_unix_sec = time_periods.range_and_interval_to_list(
        start_time_unix_sec=first_time_unix_sec,
        end_time_unix_sec=last_time_unix_sec,
        time_interval_sec=TIME_INTERVAL_SECONDS)

    if input_field_name == processed_narr_io.U_WIND_EARTH_RELATIVE_NAME:
        input_field_name_other = (processed_narr_io.V_WIND_EARTH_RELATIVE_NAME)
    elif input_field_name == processed_narr_io.V_WIND_EARTH_RELATIVE_NAME:
        input_field_name_other = (processed_narr_io.U_WIND_EARTH_RELATIVE_NAME)
    else:
        input_field_name_other = None

    input_field_name_grib1 = _std_to_grib1_field_name(
        field_name=input_field_name, pressure_level_mb=pressure_level_mb)

    if input_field_name in WIND_FIELD_NAMES:
        input_field_name_other_grib1 = _std_to_grib1_field_name(
            field_name=input_field_name_other,
            pressure_level_mb=pressure_level_mb)

        output_field_name = processed_narr_io.field_name_to_grid_relative(
            input_field_name)

        output_field_name_other = (
            processed_narr_io.field_name_to_grid_relative(
                input_field_name_other))

        (narr_latitude_matrix_deg, narr_longitude_matrix_deg
         ) = nwp_model_utils.get_latlng_grid_point_matrices(
             model_name=nwp_model_utils.NARR_MODEL_NAME)

        (narr_rotation_cosine_matrix,
         narr_rotation_sine_matrix) = nwp_model_utils.get_wind_rotation_angles(
             latitudes_deg=narr_latitude_matrix_deg,
             longitudes_deg=narr_longitude_matrix_deg,
             model_name=nwp_model_utils.NARR_MODEL_NAME)
    else:
        input_field_name_other_grib1 = None
        output_field_name = input_field_name + ''
        output_field_name_other = None

    num_times = len(valid_times_unix_sec)

    for i in range(num_times):
        if input_field_name in WIND_FIELD_NAMES:
            this_field_matrix_other = None

        if valid_times_unix_sec[i] > LAST_GRIB_TIME_UNIX_SEC:
            this_month_string = time_conversion.unix_sec_to_string(
                valid_times_unix_sec[i], MONTH_TIME_FORMAT)

            this_netcdf_file_name = narr_netcdf_io.find_file(
                top_directory_name=top_input_dir_name,
                field_name=input_field_name,
                month_string=this_month_string,
                is_surface=pressure_level_mb is None)

            print 'Reading data from: "{0:s}"...'.format(this_netcdf_file_name)
            this_field_matrix = narr_netcdf_io.read_file(
                netcdf_file_name=this_netcdf_file_name,
                field_name=input_field_name,
                valid_time_unix_sec=valid_times_unix_sec[i],
                pressure_level_mb=pressure_level_mb)

            if input_field_name in WIND_FIELD_NAMES:
                this_netcdf_file_name_other = narr_netcdf_io.find_file(
                    top_directory_name=top_input_dir_name,
                    field_name=input_field_name_other,
                    month_string=this_month_string,
                    is_surface=pressure_level_mb is None)

                print 'Reading data from: "{0:s}"...'.format(
                    this_netcdf_file_name_other)

                this_field_matrix_other = narr_netcdf_io.read_file(
                    netcdf_file_name=this_netcdf_file_name_other,
                    field_name=input_field_name_other,
                    valid_time_unix_sec=valid_times_unix_sec[i],
                    pressure_level_mb=pressure_level_mb)
        else:
            this_grib_file_name = nwp_model_io.find_grib_file(
                top_directory_name=top_input_dir_name,
                model_name=nwp_model_utils.NARR_MODEL_NAME,
                init_time_unix_sec=valid_times_unix_sec[i],
                lead_time_hours=0)

            print 'Reading data from: "{0:s}"...'.format(this_grib_file_name)
            this_field_matrix = nwp_model_io.read_field_from_grib_file(
                grib_file_name=this_grib_file_name,
                field_name_grib1=input_field_name_grib1,
                model_name=nwp_model_utils.NARR_MODEL_NAME,
                wgrib_exe_name=WGRIB_EXE_NAME,
                wgrib2_exe_name=WGRIB2_EXE_NAME)

            if input_field_name in WIND_FIELD_NAMES:
                this_field_matrix_other = (
                    nwp_model_io.read_field_from_grib_file(
                        grib_file_name=this_grib_file_name,
                        field_name_grib1=input_field_name_other_grib1,
                        model_name=nwp_model_utils.NARR_MODEL_NAME,
                        wgrib_exe_name=WGRIB_EXE_NAME,
                        wgrib2_exe_name=WGRIB2_EXE_NAME))

        if input_field_name in WIND_FIELD_NAMES:
            print 'Rotating Earth-relative winds to grid-relative...'

            if input_field_name == processed_narr_io.U_WIND_EARTH_RELATIVE_NAME:
                this_field_matrix, this_field_matrix_other = (
                    nwp_model_utils.rotate_winds_to_grid_relative(
                        u_winds_earth_relative_m_s01=this_field_matrix,
                        v_winds_earth_relative_m_s01=this_field_matrix_other,
                        rotation_angle_cosines=narr_rotation_cosine_matrix,
                        rotation_angle_sines=narr_rotation_sine_matrix))
            else:
                this_field_matrix_other, this_field_matrix = (
                    nwp_model_utils.rotate_winds_to_grid_relative(
                        u_winds_earth_relative_m_s01=this_field_matrix_other,
                        v_winds_earth_relative_m_s01=this_field_matrix,
                        rotation_angle_cosines=narr_rotation_cosine_matrix,
                        rotation_angle_sines=narr_rotation_sine_matrix))

        this_output_file_name = processed_narr_io.find_file_for_one_time(
            top_directory_name=top_output_dir_name,
            field_name=output_field_name,
            pressure_level_mb=output_pressure_level_mb,
            valid_time_unix_sec=valid_times_unix_sec[i],
            raise_error_if_missing=False)

        print 'Writing processed data to: "{0:s}"...'.format(
            this_output_file_name)

        processed_narr_io.write_fields_to_file(
            pickle_file_name=this_output_file_name,
            field_matrix=numpy.expand_dims(this_field_matrix, axis=0),
            field_name=output_field_name,
            pressure_level_pascals=output_pressure_level_mb * MB_TO_PASCALS,
            valid_times_unix_sec=valid_times_unix_sec[[i]])

        if input_field_name not in WIND_FIELD_NAMES:
            print '\n'
            continue

        this_output_file_name = processed_narr_io.find_file_for_one_time(
            top_directory_name=top_output_dir_name,
            field_name=output_field_name_other,
            pressure_level_mb=output_pressure_level_mb,
            valid_time_unix_sec=valid_times_unix_sec[i],
            raise_error_if_missing=False)

        print 'Writing processed data to: "{0:s}"...\n'.format(
            this_output_file_name)

        processed_narr_io.write_fields_to_file(
            pickle_file_name=this_output_file_name,
            field_matrix=numpy.expand_dims(this_field_matrix_other, axis=0),
            field_name=output_field_name_other,
            pressure_level_pascals=output_pressure_level_mb * MB_TO_PASCALS,
            valid_times_unix_sec=valid_times_unix_sec[[i]])
def _run():
    """Plots weird WPC fronts, along with theta_w and wind barbs from NARR.
    This is effectively the main method.
    """

    narr_latitude_matrix_deg, narr_longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    narr_rotation_cos_matrix, narr_rotation_sin_matrix = (
        nwp_model_utils.get_wind_rotation_angles(
            latitudes_deg=narr_latitude_matrix_deg,
            longitudes_deg=narr_longitude_matrix_deg,
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    num_panels = len(VALID_TIME_STRINGS)
    panel_file_names = [''] * num_panels
    this_annotation_string = None

    for i in range(num_panels):
        this_time_unix_sec = time_conversion.string_to_unix_sec(
            VALID_TIME_STRINGS[i], DEFAULT_TIME_FORMAT)
        this_title_string = time_conversion.unix_sec_to_string(
            this_time_unix_sec, NICE_TIME_FORMAT)

        if PRESSURE_LEVELS_MB[i] == 1000:
            this_title_string += ' at 1000 mb'
        else:
            this_title_string += ' at surface'

        if this_annotation_string is None:
            this_annotation_string = '(a)'
        else:
            this_orig_character = this_annotation_string[1]
            this_new_character = chr(ord(this_orig_character) + 1)
            this_annotation_string = this_annotation_string.replace(
                this_orig_character, this_new_character)

        this_file_name = _plot_one_time(
            valid_time_string=VALID_TIME_STRINGS[i],
            pressure_level_mb=PRESSURE_LEVELS_MB[i],
            title_string=this_title_string,
            annotation_string=this_annotation_string,
            narr_rotation_cos_matrix=narr_rotation_cos_matrix,
            narr_rotation_sin_matrix=narr_rotation_sin_matrix)

        panel_file_names[i] = this_file_name
        print '\n'

    concat_file_name = '{0:s}/weird_fronts.jpg'.format(OUTPUT_DIR_NAME)

    print 'Concatenating figures to: "{0:s}"...'.format(concat_file_name)

    num_panels = len(panel_file_names)
    num_panel_columns = int(numpy.ceil(float(num_panels) / 2))

    imagemagick_utils.concatenate_images(input_file_names=panel_file_names,
                                         output_file_name=concat_file_name,
                                         num_panel_rows=NUM_PANEL_ROWS,
                                         num_panel_columns=num_panel_columns)

    imagemagick_utils.trim_whitespace(input_file_name=concat_file_name,
                                      output_file_name=concat_file_name)

    imagemagick_utils.resize_image(input_file_name=concat_file_name,
                                   output_file_name=concat_file_name,
                                   output_size_pixels=CONCAT_SIZE_PIXELS)
Exemplo n.º 9
0
def get_xy_grid_point_matrices(first_row_in_narr_grid,
                               last_row_in_narr_grid,
                               first_column_in_narr_grid,
                               last_column_in_narr_grid,
                               basemap_object=None):
    """Returns coordinate matrices for a contiguous subset of the NARR grid.

    However, this subset need not be *strictly* a subset.  In other words, the
    "subset" could be the full NARR grid.

    This method generates different x- and y-coordinates than
    `nwp_model_utils.get_xy_grid_point_matrices`, because (like
    `mpl_toolkits.basemap.Basemap`) this method assumes that false easting and
    northing are zero.

    :param first_row_in_narr_grid: Row 0 in the subgrid is row
        `first_row_in_narr_grid` in the full NARR grid.
    :param last_row_in_narr_grid: Last row (index -1) in the subgrid is row
        `last_row_in_narr_grid` in the full NARR grid.
    :param first_column_in_narr_grid: Column 0 in the subgrid is row
        `first_column_in_narr_grid` in the full NARR grid.
    :param last_column_in_narr_grid: Last column (index -1) in the subgrid is
        row `last_column_in_narr_grid` in the full NARR grid.
    :param basemap_object: Instance of `mpl_toolkits.basemap.Basemap` created
        for the NARR grid.  If you don't have one, no big deal -- leave this
        argument empty.
    :return: grid_point_x_matrix_metres: M-by-N numpy array of x-coordinates.
    :return: grid_point_y_matrix_metres: M-by-N numpy array of y-coordinates.
    """

    error_checking.assert_is_integer(first_row_in_narr_grid)
    error_checking.assert_is_geq(first_row_in_narr_grid, 0)
    error_checking.assert_is_integer(last_row_in_narr_grid)
    error_checking.assert_is_greater(last_row_in_narr_grid,
                                     first_row_in_narr_grid)
    error_checking.assert_is_less_than(last_row_in_narr_grid,
                                       NUM_ROWS_IN_NARR_GRID)

    error_checking.assert_is_integer(first_column_in_narr_grid)
    error_checking.assert_is_geq(first_column_in_narr_grid, 0)
    error_checking.assert_is_integer(last_column_in_narr_grid)
    error_checking.assert_is_greater(last_column_in_narr_grid,
                                     first_column_in_narr_grid)
    error_checking.assert_is_less_than(last_column_in_narr_grid,
                                       NUM_COLUMNS_IN_NARR_GRID)

    latitude_matrix_deg, longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    latitude_matrix_deg = latitude_matrix_deg[first_row_in_narr_grid:(
        last_row_in_narr_grid +
        1), first_column_in_narr_grid:(last_column_in_narr_grid + 1)]
    longitude_matrix_deg = longitude_matrix_deg[first_row_in_narr_grid:(
        last_row_in_narr_grid +
        1), first_column_in_narr_grid:(last_column_in_narr_grid + 1)]

    if basemap_object is None:
        standard_latitudes_deg, central_longitude_deg = (
            nwp_model_utils.get_projection_params(
                nwp_model_utils.NARR_MODEL_NAME))
        projection_object = projections.init_lambert_conformal_projection(
            standard_latitudes_deg=standard_latitudes_deg,
            central_longitude_deg=central_longitude_deg)

        grid_point_x_matrix_metres, grid_point_y_matrix_metres = (
            projections.project_latlng_to_xy(
                latitude_matrix_deg,
                longitude_matrix_deg,
                projection_object=projection_object,
                false_northing_metres=0.,
                false_easting_metres=0.))

    else:
        grid_point_x_matrix_metres, grid_point_y_matrix_metres = (
            basemap_object(longitude_matrix_deg, latitude_matrix_deg))

    return grid_point_x_matrix_metres, grid_point_y_matrix_metres
Exemplo n.º 10
0
def _run(example_file_name, top_front_line_dir_name, num_examples,
         example_indices, thetaw_colour_map_name, thetaw_max_colour_percentile,
         output_dir_name):
    """Plots one or more input examples.

    This is effectively the main method.

    :param example_file_name: See documentation at top of file.
    :param top_front_line_dir_name: Same.
    :param num_examples: Same.
    :param example_indices: Same.
    :param thetaw_colour_map_name: Same.
    :param thetaw_max_colour_percentile: Same.
    :param output_dir_name: Same.
    """

    if num_examples <= 0:
        num_examples = None

    if num_examples is None:
        error_checking.assert_is_geq_numpy_array(example_indices, 0)
    else:
        error_checking.assert_is_greater(num_examples, 0)

    error_checking.assert_is_geq(thetaw_max_colour_percentile, 0)
    error_checking.assert_is_leq(thetaw_max_colour_percentile, 100)
    thetaw_colour_map_object = pyplot.cm.get_cmap(thetaw_colour_map_name)

    file_system_utils.mkdir_recursive_if_necessary(
        directory_name=output_dir_name)

    print 'Reading normalized examples from: "{0:s}"...'.format(
        example_file_name)

    example_dict = trainval_io.read_downsized_3d_examples(
        netcdf_file_name=example_file_name,
        num_half_rows_to_keep=NUM_HALF_ROWS,
        num_half_columns_to_keep=NUM_HALF_COLUMNS,
        predictor_names_to_keep=NARR_PREDICTOR_NAMES)

    # TODO(thunderhoser): This is a HACK (assuming that normalization method is
    # z-score and not min-max).
    mean_value_matrix = example_dict[trainval_io.FIRST_NORM_PARAM_KEY]
    standard_deviation_matrix = example_dict[trainval_io.SECOND_NORM_PARAM_KEY]

    normalization_dict = {
        ml_utils.MIN_VALUE_MATRIX_KEY: None,
        ml_utils.MAX_VALUE_MATRIX_KEY: None,
        ml_utils.MEAN_VALUE_MATRIX_KEY: mean_value_matrix,
        ml_utils.STDEV_MATRIX_KEY: standard_deviation_matrix
    }

    example_dict[trainval_io.PREDICTOR_MATRIX_KEY] = (
        ml_utils.denormalize_predictors(
            predictor_matrix=example_dict[trainval_io.PREDICTOR_MATRIX_KEY],
            normalization_dict=normalization_dict))

    narr_latitude_matrix_deg, narr_longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    narr_rotation_cos_matrix, narr_rotation_sin_matrix = (
        nwp_model_utils.get_wind_rotation_angles(
            latitudes_deg=narr_latitude_matrix_deg,
            longitudes_deg=narr_longitude_matrix_deg,
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    num_examples_total = len(example_dict[trainval_io.TARGET_TIMES_KEY])
    example_indices = numpy.linspace(0,
                                     num_examples_total - 1,
                                     num=num_examples_total,
                                     dtype=int)

    if num_examples is not None:
        num_examples = min([num_examples, num_examples_total])
        example_indices = numpy.random.choice(example_indices,
                                              size=num_examples,
                                              replace=False)

    thetaw_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.WET_BULB_THETA_NAME)
    u_wind_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.U_WIND_GRID_RELATIVE_NAME)
    v_wind_index = NARR_PREDICTOR_NAMES.index(
        processed_narr_io.V_WIND_GRID_RELATIVE_NAME)

    for i in example_indices:
        this_center_row_index = example_dict[trainval_io.ROW_INDICES_KEY][i]
        this_first_row_index = this_center_row_index - NUM_HALF_ROWS
        this_last_row_index = this_center_row_index + NUM_HALF_ROWS

        this_center_column_index = example_dict[
            trainval_io.COLUMN_INDICES_KEY][i]
        this_first_column_index = this_center_column_index - NUM_HALF_COLUMNS
        this_last_column_index = this_center_column_index + NUM_HALF_COLUMNS

        this_u_wind_matrix_m_s01 = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., u_wind_index]
        this_v_wind_matrix_m_s01 = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., v_wind_index]
        this_cos_matrix = narr_rotation_cos_matrix[this_first_row_index:(
            this_last_row_index +
            1), this_first_column_index:(this_last_column_index + 1)]
        this_sin_matrix = narr_rotation_sin_matrix[this_first_row_index:(
            this_last_row_index +
            1), this_first_column_index:(this_last_column_index + 1)]

        this_u_wind_matrix_m_s01, this_v_wind_matrix_m_s01 = (
            nwp_model_utils.rotate_winds_to_earth_relative(
                u_winds_grid_relative_m_s01=this_u_wind_matrix_m_s01,
                v_winds_grid_relative_m_s01=this_v_wind_matrix_m_s01,
                rotation_angle_cosines=this_cos_matrix,
                rotation_angle_sines=this_sin_matrix))

        _, axes_object, basemap_object = nwp_plotting.init_basemap(
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            first_row_in_full_grid=this_first_row_index,
            last_row_in_full_grid=this_last_row_index,
            first_column_in_full_grid=this_first_column_index,
            last_column_in_full_grid=this_last_column_index,
            resolution_string='i')

        plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                       axes_object=axes_object,
                                       line_colour=BORDER_COLOUR,
                                       line_width=BORDER_WIDTH)
        plotting_utils.plot_countries(basemap_object=basemap_object,
                                      axes_object=axes_object,
                                      line_colour=BORDER_COLOUR,
                                      line_width=BORDER_WIDTH)
        plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                                 axes_object=axes_object,
                                                 line_colour=BORDER_COLOUR,
                                                 line_width=BORDER_WIDTH)
        plotting_utils.plot_parallels(
            basemap_object=basemap_object,
            axes_object=axes_object,
            bottom_left_lat_deg=-90.,
            upper_right_lat_deg=90.,
            parallel_spacing_deg=PARALLEL_SPACING_DEG)
        plotting_utils.plot_meridians(
            basemap_object=basemap_object,
            axes_object=axes_object,
            bottom_left_lng_deg=0.,
            upper_right_lng_deg=360.,
            meridian_spacing_deg=MERIDIAN_SPACING_DEG)

        this_thetaw_matrix_kelvins = example_dict[
            trainval_io.PREDICTOR_MATRIX_KEY][i, ..., thetaw_index]

        this_min_value = numpy.percentile(this_thetaw_matrix_kelvins,
                                          100. - thetaw_max_colour_percentile)
        this_max_value = numpy.percentile(this_thetaw_matrix_kelvins,
                                          thetaw_max_colour_percentile)

        nwp_plotting.plot_subgrid(
            field_matrix=this_thetaw_matrix_kelvins,
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            colour_map=thetaw_colour_map_object,
            min_value_in_colour_map=this_min_value,
            max_value_in_colour_map=this_max_value,
            first_row_in_full_grid=this_first_row_index,
            first_column_in_full_grid=this_first_column_index)

        colour_bar_object = plotting_utils.add_linear_colour_bar(
            axes_object_or_list=axes_object,
            values_to_colour=this_thetaw_matrix_kelvins,
            colour_map=thetaw_colour_map_object,
            colour_min=this_min_value,
            colour_max=this_max_value,
            orientation='vertical',
            extend_min=True,
            extend_max=True,
            fraction_of_axis_length=0.8)

        colour_bar_object.set_label(
            r'Wet-bulb potential temperature ($^{\circ}$C)')

        nwp_plotting.plot_wind_barbs_on_subgrid(
            u_wind_matrix_m_s01=this_u_wind_matrix_m_s01,
            v_wind_matrix_m_s01=this_v_wind_matrix_m_s01,
            model_name=nwp_model_utils.NARR_MODEL_NAME,
            axes_object=axes_object,
            basemap_object=basemap_object,
            first_row_in_full_grid=this_first_row_index,
            first_column_in_full_grid=this_first_column_index,
            barb_length=WIND_BARB_LENGTH,
            empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
            fill_empty_barb=False,
            colour_map=WIND_COLOUR_MAP_OBJECT,
            colour_minimum_kt=MIN_COLOUR_WIND_SPEED_KT,
            colour_maximum_kt=MAX_COLOUR_WIND_SPEED_KT)

        this_front_file_name = fronts_io.find_file_for_one_time(
            top_directory_name=top_front_line_dir_name,
            file_type=fronts_io.POLYLINE_FILE_TYPE,
            valid_time_unix_sec=example_dict[trainval_io.TARGET_TIMES_KEY][i])

        print time_conversion.unix_sec_to_string(
            example_dict[trainval_io.TARGET_TIMES_KEY][i], '%Y-%m-%d-%H')

        this_polyline_table = fronts_io.read_polylines_from_file(
            this_front_file_name)
        this_num_fronts = len(this_polyline_table.index)

        for j in range(this_num_fronts):
            this_front_type_string = this_polyline_table[
                front_utils.FRONT_TYPE_COLUMN].values[j]

            if this_front_type_string == front_utils.WARM_FRONT_STRING_ID:
                this_colour = WARM_FRONT_COLOUR
            else:
                this_colour = COLD_FRONT_COLOUR

            front_plotting.plot_front_with_markers(
                line_latitudes_deg=this_polyline_table[
                    front_utils.LATITUDES_COLUMN].values[j],
                line_longitudes_deg=this_polyline_table[
                    front_utils.LONGITUDES_COLUMN].values[j],
                axes_object=axes_object,
                basemap_object=basemap_object,
                front_type_string=this_polyline_table[
                    front_utils.FRONT_TYPE_COLUMN].values[j],
                marker_colour=this_colour,
                marker_size=FRONT_MARKER_SIZE,
                marker_spacing_metres=FRONT_SPACING_METRES)

        this_output_file_name = '{0:s}/example{1:06d}.jpg'.format(
            output_dir_name, i)

        print 'Saving figure to: "{0:s}"...'.format(this_output_file_name)
        pyplot.savefig(this_output_file_name, dpi=FIGURE_RESOLUTION_DPI)
        pyplot.close()
Exemplo n.º 11
0
def _plot_rapruc_one_example(
        full_storm_id_string, storm_time_unix_sec, top_tracking_dir_name,
        latitude_buffer_deg, longitude_buffer_deg, lead_time_seconds,
        field_name_grib1, output_dir_name, rap_file_name=None,
        ruc_file_name=None):
    """Plots RAP or RUC field for one example.

    :param full_storm_id_string: Full storm ID.
    :param storm_time_unix_sec: Valid time.
    :param top_tracking_dir_name: See documentation at top of file.
    :param latitude_buffer_deg: Same.
    :param longitude_buffer_deg: Same.
    :param lead_time_seconds: Same.
    :param field_name_grib1: Same.
    :param output_dir_name: Same.
    :param rap_file_name: Path to file with RAP analysis.
    :param ruc_file_name: [used only if `rap_file_name is None`]
        Path to file with RUC analysis.
    """

    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=storm_time_unix_sec,
        spc_date_string=
        time_conversion.time_to_spc_date_string(storm_time_unix_sec),
        raise_error_if_missing=True
    )

    print('Reading data from: "{0:s}"...'.format(tracking_file_name))
    storm_object_table = tracking_io.read_file(tracking_file_name)
    storm_object_table = storm_object_table.loc[
        storm_object_table[tracking_utils.FULL_ID_COLUMN] ==
        full_storm_id_string
    ]

    extrap_times_sec = numpy.array([0, lead_time_seconds], dtype=int)
    storm_object_table = soundings._create_target_points_for_interp(
        storm_object_table=storm_object_table,
        lead_times_seconds=extrap_times_sec
    )

    orig_latitude_deg = (
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values[0]
    )
    orig_longitude_deg = (
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values[0]
    )
    extrap_latitude_deg = (
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values[1]
    )
    extrap_longitude_deg = (
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values[1]
    )

    if rap_file_name is None:
        grib_file_name = ruc_file_name
        model_name = nwp_model_utils.RUC_MODEL_NAME
    else:
        grib_file_name = rap_file_name
        model_name = nwp_model_utils.RAP_MODEL_NAME

    pathless_grib_file_name = os.path.split(grib_file_name)[-1]
    grid_name = pathless_grib_file_name.split('_')[1]

    host_name = socket.gethostname()

    if 'casper' in host_name:
        wgrib_exe_name = '/glade/work/ryanlage/wgrib/wgrib'
        wgrib2_exe_name = '/glade/work/ryanlage/wgrib2/wgrib2/wgrib2'
    else:
        wgrib_exe_name = '/condo/swatwork/ralager/wgrib/wgrib'
        wgrib2_exe_name = '/condo/swatwork/ralager/grib2/wgrib2/wgrib2'

    print('Reading field "{0:s}" from: "{1:s}"...'.format(
        field_name_grib1, grib_file_name
    ))
    main_field_matrix = nwp_model_io.read_field_from_grib_file(
        grib_file_name=grib_file_name, field_name_grib1=field_name_grib1,
        model_name=model_name, grid_id=grid_name,
        wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name
    )

    u_wind_name_grib1 = 'UGRD:{0:s}'.format(
        field_name_grib1.split(':')[-1]
    )
    u_wind_name_grib1 = u_wind_name_grib1.replace('2 m', '10 m')
    print('Reading field "{0:s}" from: "{1:s}"...'.format(
        u_wind_name_grib1, grib_file_name
    ))
    u_wind_matrix_m_s01 = nwp_model_io.read_field_from_grib_file(
        grib_file_name=grib_file_name, field_name_grib1=u_wind_name_grib1,
        model_name=model_name, grid_id=grid_name,
        wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name
    )

    v_wind_name_grib1 = 'VGRD:{0:s}'.format(
        u_wind_name_grib1.split(':')[-1]
    )
    print('Reading field "{0:s}" from: "{1:s}"...'.format(
        v_wind_name_grib1, grib_file_name
    ))
    v_wind_matrix_m_s01 = nwp_model_io.read_field_from_grib_file(
        grib_file_name=grib_file_name, field_name_grib1=v_wind_name_grib1,
        model_name=model_name, grid_id=grid_name,
        wgrib_exe_name=wgrib_exe_name, wgrib2_exe_name=wgrib2_exe_name
    )

    latitude_matrix_deg, longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=model_name, grid_name=grid_name)
    )
    cosine_matrix, sine_matrix = nwp_model_utils.get_wind_rotation_angles(
        latitudes_deg=latitude_matrix_deg, longitudes_deg=longitude_matrix_deg,
        model_name=model_name
    )
    u_wind_matrix_m_s01, v_wind_matrix_m_s01 = (
        nwp_model_utils.rotate_winds_to_earth_relative(
            u_winds_grid_relative_m_s01=u_wind_matrix_m_s01,
            v_winds_grid_relative_m_s01=v_wind_matrix_m_s01,
            rotation_angle_cosines=cosine_matrix,
            rotation_angle_sines=sine_matrix)
    )

    min_plot_latitude_deg = (
        min([orig_latitude_deg, extrap_latitude_deg]) - latitude_buffer_deg
    )
    max_plot_latitude_deg = (
        max([orig_latitude_deg, extrap_latitude_deg]) + latitude_buffer_deg
    )
    min_plot_longitude_deg = (
        min([orig_longitude_deg, extrap_longitude_deg]) - longitude_buffer_deg
    )
    max_plot_longitude_deg = (
        max([orig_longitude_deg, extrap_longitude_deg]) + longitude_buffer_deg
    )

    row_limits, column_limits = nwp_plotting.latlng_limits_to_rowcol_limits(
        min_latitude_deg=min_plot_latitude_deg,
        max_latitude_deg=max_plot_latitude_deg,
        min_longitude_deg=min_plot_longitude_deg,
        max_longitude_deg=max_plot_longitude_deg,
        model_name=model_name, grid_id=grid_name
    )

    main_field_matrix = main_field_matrix[
        row_limits[0]:(row_limits[1] + 1),
        column_limits[0]:(column_limits[1] + 1)
    ]
    u_wind_matrix_m_s01 = u_wind_matrix_m_s01[
        row_limits[0]:(row_limits[1] + 1),
        column_limits[0]:(column_limits[1] + 1)
    ]
    v_wind_matrix_m_s01 = v_wind_matrix_m_s01[
        row_limits[0]:(row_limits[1] + 1),
        column_limits[0]:(column_limits[1] + 1)
    ]

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=model_name, grid_id=grid_name,
        first_row_in_full_grid=row_limits[0],
        last_row_in_full_grid=row_limits[1],
        first_column_in_full_grid=column_limits[0],
        last_column_in_full_grid=column_limits[1]
    )

    plotting_utils.plot_coastlines(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_countries(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_states_and_provinces(
        basemap_object=basemap_object, axes_object=axes_object,
        line_colour=BORDER_COLOUR
    )
    plotting_utils.plot_parallels(
        basemap_object=basemap_object, axes_object=axes_object,
        num_parallels=NUM_PARALLELS
    )
    plotting_utils.plot_meridians(
        basemap_object=basemap_object, axes_object=axes_object,
        num_meridians=NUM_MERIDIANS
    )

    min_colour_value = numpy.nanpercentile(
        main_field_matrix, 100. - MAX_COLOUR_PERCENTILE
    )
    max_colour_value = numpy.nanpercentile(
        main_field_matrix, MAX_COLOUR_PERCENTILE
    )

    nwp_plotting.plot_subgrid(
        field_matrix=main_field_matrix,
        model_name=model_name, grid_id=grid_name,
        axes_object=axes_object, basemap_object=basemap_object,
        colour_map_object=COLOUR_MAP_OBJECT, min_colour_value=min_colour_value,
        max_colour_value=max_colour_value,
        first_row_in_full_grid=row_limits[0],
        first_column_in_full_grid=column_limits[0]
    )

    nwp_plotting.plot_wind_barbs_on_subgrid(
        u_wind_matrix_m_s01=u_wind_matrix_m_s01,
        v_wind_matrix_m_s01=v_wind_matrix_m_s01,
        model_name=model_name, grid_id=grid_name,
        axes_object=axes_object, basemap_object=basemap_object,
        first_row_in_full_grid=row_limits[0],
        first_column_in_full_grid=column_limits[0],
        plot_every_k_rows=PLOT_EVERY_KTH_WIND_BARB,
        plot_every_k_columns=PLOT_EVERY_KTH_WIND_BARB,
        barb_length=WIND_BARB_LENGTH, empty_barb_radius=EMPTY_WIND_BARB_RADIUS,
        fill_empty_barb=True, colour_map=WIND_COLOUR_MAP_OBJECT,
        colour_minimum_kt=MIN_WIND_SPEED_KT, colour_maximum_kt=MAX_WIND_SPEED_KT
    )

    orig_x_metres, orig_y_metres = basemap_object(
        orig_longitude_deg, orig_latitude_deg
    )
    axes_object.plot(
        orig_x_metres, orig_y_metres, linestyle='None',
        marker=ORIGIN_MARKER_TYPE, markersize=ORIGIN_MARKER_SIZE,
        markeredgewidth=ORIGIN_MARKER_EDGE_WIDTH,
        markerfacecolor=MARKER_COLOUR, markeredgecolor=MARKER_COLOUR
    )

    extrap_x_metres, extrap_y_metres = basemap_object(
        extrap_longitude_deg, extrap_latitude_deg
    )
    axes_object.plot(
        extrap_x_metres, extrap_y_metres, linestyle='None',
        marker=EXTRAP_MARKER_TYPE, markersize=EXTRAP_MARKER_SIZE,
        markeredgewidth=EXTRAP_MARKER_EDGE_WIDTH,
        markerfacecolor=MARKER_COLOUR, markeredgecolor=MARKER_COLOUR
    )

    plotting_utils.plot_linear_colour_bar(
        axes_object_or_matrix=axes_object, data_matrix=main_field_matrix,
        colour_map_object=COLOUR_MAP_OBJECT,
        min_value=min_colour_value, max_value=max_colour_value,
        orientation_string='vertical'
    )

    output_file_name = '{0:s}/{1:s}_{2:s}.jpg'.format(
        output_dir_name, full_storm_id_string.replace('_', '-'),
        time_conversion.unix_sec_to_string(
            storm_time_unix_sec, FILE_NAME_TIME_FORMAT
        )
    )

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    pyplot.savefig(
        output_file_name, dpi=FIGURE_RESOLUTION_DPI,
        pad_inches=0, bbox_inches='tight'
    )
    pyplot.close()
def _plot_one_time(predicted_region_table,
                   title_string,
                   letter_label,
                   output_file_name,
                   class_probability_matrix=None,
                   predicted_label_matrix=None,
                   plot_wf_colour_bar=True,
                   plot_cf_colour_bar=True):
    """Plots predictions at one time.

    Either `class_probability_matrix` or `predicted_label_matrix` will be
    plotted -- not both.

    M = number of rows in NARR grid
    N = number of columns in NARR grid

    :param predicted_region_table: Subset of pandas DataFrame returned by
        `object_eval.read_predictions_and_obs`, containing predicted fronts at
        only one time.
    :param title_string: Title (will be placed above figure).
    :param letter_label: Letter label.  If this is "a", the label "(a)" will be
        printed at the top left of the figure.
    :param output_file_name: Path to output file.
    :param class_probability_matrix: M-by-N-by-3 numpy array of class
        probabilities.
    :param predicted_label_matrix: M-by-N numpy array of predicted labels
        (integers in `front_utils.VALID_INTEGER_IDS`).
    :param plot_wf_colour_bar: Boolean flag.  If True, will plot colour bar for
        warm-front probability.
    :param plot_cf_colour_bar: Boolean flag.  If True, will plot colour bar for
        cold-front probability.
    """

    narr_row_limits, narr_column_limits = (
        nwp_plotting.latlng_limits_to_rowcol_limits(
            min_latitude_deg=MIN_LATITUDE_DEG,
            max_latitude_deg=MAX_LATITUDE_DEG,
            min_longitude_deg=MIN_LONGITUDE_DEG,
            max_longitude_deg=MAX_LONGITUDE_DEG,
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    _, axes_object, basemap_object = nwp_plotting.init_basemap(
        model_name=nwp_model_utils.NARR_MODEL_NAME,
        first_row_in_full_grid=narr_row_limits[0],
        last_row_in_full_grid=narr_row_limits[1],
        first_column_in_full_grid=narr_column_limits[0],
        last_column_in_full_grid=narr_column_limits[1])

    plotting_utils.plot_coastlines(basemap_object=basemap_object,
                                   axes_object=axes_object,
                                   line_colour=BORDER_COLOUR)
    plotting_utils.plot_countries(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  line_colour=BORDER_COLOUR)
    plotting_utils.plot_states_and_provinces(basemap_object=basemap_object,
                                             axes_object=axes_object,
                                             line_colour=BORDER_COLOUR)
    plotting_utils.plot_parallels(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lat_deg=-90.,
                                  upper_right_lat_deg=90.,
                                  parallel_spacing_deg=PARALLEL_SPACING_DEG)
    plotting_utils.plot_meridians(basemap_object=basemap_object,
                                  axes_object=axes_object,
                                  bottom_left_lng_deg=0.,
                                  upper_right_lng_deg=360.,
                                  meridian_spacing_deg=MERIDIAN_SPACING_DEG)

    if class_probability_matrix is None:
        this_matrix = predicted_label_matrix[narr_row_limits[0]:(
            narr_row_limits[1] +
            1), narr_column_limits[0]:(narr_column_limits[1] + 1)]

        front_plotting.plot_narr_grid(
            frontal_grid_matrix=this_matrix,
            axes_object=axes_object,
            basemap_object=basemap_object,
            first_row_in_narr_grid=narr_row_limits[0],
            first_column_in_narr_grid=narr_column_limits[0],
            opacity=0.25)
    else:
        this_wf_probability_matrix = class_probability_matrix[
            narr_row_limits[0]:(narr_row_limits[1] + 1),
            narr_column_limits[0]:(narr_column_limits[1] + 1),
            front_utils.WARM_FRONT_INTEGER_ID]
        this_wf_probability_matrix[numpy.isnan(
            this_wf_probability_matrix)] = 0.

        prediction_plotting.plot_narr_grid(
            probability_matrix=this_wf_probability_matrix,
            front_string_id=front_utils.WARM_FRONT_STRING_ID,
            axes_object=axes_object,
            basemap_object=basemap_object,
            first_row_in_narr_grid=narr_row_limits[0],
            first_column_in_narr_grid=narr_column_limits[0],
            opacity=0.5)

        this_cf_probability_matrix = class_probability_matrix[
            narr_row_limits[0]:(narr_row_limits[1] + 1),
            narr_column_limits[0]:(narr_column_limits[1] + 1),
            front_utils.COLD_FRONT_INTEGER_ID]
        this_cf_probability_matrix[numpy.isnan(
            this_cf_probability_matrix)] = 0.

        prediction_plotting.plot_narr_grid(
            probability_matrix=this_cf_probability_matrix,
            front_string_id=front_utils.COLD_FRONT_STRING_ID,
            axes_object=axes_object,
            basemap_object=basemap_object,
            first_row_in_narr_grid=narr_row_limits[0],
            first_column_in_narr_grid=narr_column_limits[0],
            opacity=0.5)

        if plot_wf_colour_bar:
            this_colour_map_object, this_colour_norm_object = (
                prediction_plotting.get_warm_front_colour_map()[:2])

            plotting_utils.add_colour_bar(
                axes_object_or_list=axes_object,
                colour_map=this_colour_map_object,
                colour_norm_object=this_colour_norm_object,
                values_to_colour=this_wf_probability_matrix,
                orientation='horizontal',
                extend_min=True,
                extend_max=False,
                fraction_of_axis_length=0.9)

        if plot_cf_colour_bar:
            this_colour_map_object, this_colour_norm_object = (
                prediction_plotting.get_cold_front_colour_map()[:2])

            plotting_utils.add_colour_bar(
                axes_object_or_list=axes_object,
                colour_map=this_colour_map_object,
                colour_norm_object=this_colour_norm_object,
                values_to_colour=this_cf_probability_matrix,
                orientation='horizontal',
                extend_min=True,
                extend_max=False,
                fraction_of_axis_length=0.9)

    narr_latitude_matrix_deg, narr_longitude_matrix_deg = (
        nwp_model_utils.get_latlng_grid_point_matrices(
            model_name=nwp_model_utils.NARR_MODEL_NAME))

    num_objects = len(predicted_region_table.index)

    for i in range(num_objects):
        these_rows = predicted_region_table[
            object_eval.ROW_INDICES_COLUMN].values[i]
        these_columns = predicted_region_table[
            object_eval.COLUMN_INDICES_COLUMN].values[i]

        front_plotting.plot_polyline(
            latitudes_deg=narr_latitude_matrix_deg[these_rows, these_columns],
            longitudes_deg=narr_longitude_matrix_deg[these_rows,
                                                     these_columns],
            axes_object=axes_object,
            basemap_object=basemap_object,
            front_type=predicted_region_table[
                front_utils.FRONT_TYPE_COLUMN].values[i],
            line_width=4)

    # predicted_object_matrix = object_eval.regions_to_images(
    #     predicted_region_table=predicted_region_table,
    #     num_grid_rows=num_grid_rows, num_grid_columns=num_grid_columns)
    #
    # this_matrix = predicted_object_matrix[
    #     0,
    #     narr_row_limits[0]:(narr_row_limits[1] + 1),
    #     narr_column_limits[0]:(narr_column_limits[1] + 1)
    # ]
    #
    # front_plotting.plot_narr_grid(
    #     frontal_grid_matrix=this_matrix, axes_object=axes_object,
    #     basemap_object=basemap_object,
    #     first_row_in_narr_grid=narr_row_limits[0],
    #     first_column_in_narr_grid=narr_column_limits[0], opacity=1.)

    pyplot.title(title_string)
    if letter_label is not None:
        plotting_utils.annotate_axes(
            axes_object=axes_object,
            annotation_string='({0:s})'.format(letter_label))

    print 'Saving figure to: "{0:s}"...'.format(output_file_name)
    pyplot.savefig(output_file_name, dpi=FIGURE_RESOLUTION_DPI)
    pyplot.close()

    imagemagick_utils.trim_whitespace(input_file_name=output_file_name,
                                      output_file_name=output_file_name)