Пример #1
0
def _add_iris_coord(cube, name, points, dim, calendar=None):
    """
    Add a Coord to a Cube from a Pandas index or columns array.

    If no calendar is specified for a time series, Gregorian is assumed.

    """
    units = Unit("unknown")
    if calendar is None:
        calendar = cf_units.CALENDAR_GREGORIAN

    # Convert pandas datetime objects to python datetime obejcts.
    if isinstance(points, DatetimeIndex):
        points = np.array([i.to_datetime() for i in points])

    # Convert datetime objects to Iris' current datetime representation.
    if points.dtype == object:
        dt_types = (datetime.datetime, netcdftime.datetime)
        if all([isinstance(i, dt_types) for i in points]):
            units = Unit("hours since epoch", calendar=calendar)
            points = units.date2num(points)

    points = np.array(points)
    if (np.issubdtype(points.dtype, np.number) and
            iris.util.monotonic(points, strict=True)):
                coord = DimCoord(points, units=units)
                coord.rename(name)
                cube.add_dim_coord(coord, dim)
    else:
        coord = AuxCoord(points, units=units)
        coord.rename(name)
        cube.add_aux_coord(coord, dim)
Пример #2
0
def _add_iris_coord(cube, name, points, dim, calendar=None):
    """
    Add a Coord to a Cube from a Pandas index or columns array.

    If no calendar is specified for a time series, Gregorian is assumed.

    """
    units = Unit("unknown")
    if calendar is None:
        calendar = cf_units.CALENDAR_GREGORIAN

    # Convert pandas datetime objects to python datetime obejcts.
    if isinstance(points, DatetimeIndex):
        points = np.array([i.to_pydatetime() for i in points])

    # Convert datetime objects to Iris' current datetime representation.
    if points.dtype == object:
        dt_types = (datetime.datetime, cftime.datetime)
        if all([isinstance(i, dt_types) for i in points]):
            units = Unit("hours since epoch", calendar=calendar)
            points = units.date2num(points)

    points = np.array(points)
    if (np.issubdtype(points.dtype, np.number)
            and iris.util.monotonic(points, strict=True)):
        coord = DimCoord(points, units=units)
        coord.rename(name)
        cube.add_dim_coord(coord, dim)
    else:
        coord = AuxCoord(points, units=units)
        coord.rename(name)
        cube.add_aux_coord(coord, dim)
Пример #3
0
def _get_coords(ctl):
    """Get correct coordinates for cube."""
    # Time
    time_units = Unit('days since 1950-1-1 00:00:00', calendar='standard')
    time_start = datetime.strptime(ctl['t_start'], '%d%b%Y')
    times = [
        _add_months(time_start, d) + timedelta(days=14)
        for d in int(ctl['t_delta'][0]) * np.arange(ctl['t_size'])
    ]
    times = [time_units.date2num(time) for time in times]
    time_coord = iris.coords.DimCoord(times,
                                      standard_name='time',
                                      long_name='time',
                                      var_name='time',
                                      units=time_units)

    # Latitude
    lats = float(
        ctl['y_start']) + (float(ctl['y_delta']) * np.arange(ctl['y_size']))
    lat_coord = iris.coords.DimCoord(lats,
                                     standard_name='latitude',
                                     long_name='latitude',
                                     var_name='lat',
                                     units='degrees_north')

    # Longitude
    lons = float(
        ctl['x_start']) + (float(ctl['x_delta']) * np.arange(ctl['x_size']))
    lon_coord = iris.coords.DimCoord(lons,
                                     standard_name='longitude',
                                     long_name='longitude',
                                     var_name='lon',
                                     units='degrees_east')

    return [(time_coord, 0), (lat_coord, 1), (lon_coord, 2)]
Пример #4
0
def _create_frt_type_coord(
    cube: Cube, point: datetime, name: str = "forecast_reference_time"
) -> DimCoord:
    """Create a new auxiliary coordinate based on forecast reference time

    Args:
        cube:
            Input cube with scalar forecast reference time coordinate
        points
            Single datetime point for output coord
        name
            Name of aux coord to be returned

    Returns:
        New auxiliary coordinate
    """
    frt_coord_name = "forecast_reference_time"
    coord_type_spec = TIME_COORDS[frt_coord_name]
    coord_units = Unit(coord_type_spec.units)
    new_points = round_close([coord_units.date2num(point)], dtype=coord_type_spec.dtype)
    try:
        new_coord = DimCoord(new_points, standard_name=name, units=coord_units)
    except ValueError:
        new_coord = DimCoord(new_points, long_name=name, units=coord_units)
    return new_coord
Пример #5
0
def _get_coords(year, filename, cfg):
    """Get correct coordinates for cube."""
    filename = os.path.basename(filename)
    time_units = Unit('days since 1950-1-1 00:00:00', calendar='standard')

    # Extract date from filename
    time_str = filename.replace(cfg['binary_prefix'], '')
    month = MONTHS[time_str[4:7]]
    day = DAYS[time_str[7:8]]
    date = datetime(year, month, day)

    # Build time coordinate
    time_data = [time_units.date2num(date)]
    time_coord = iris.coords.DimCoord(time_data,
                                      standard_name='time',
                                      long_name='time',
                                      var_name='time',
                                      units=time_units)

    # Build latitude/Longitude coordinates
    latitude_data = np.linspace(UPPER_LEFT_LAT, LOWER_RIGHT_LAT, N_LAT)
    longitude_data = np.linspace(UPPER_LEFT_LON, LOWER_RIGHT_LON, N_LON)
    lat_coord = iris.coords.DimCoord(latitude_data,
                                     standard_name='latitude',
                                     long_name='latitude',
                                     var_name='lat',
                                     units='degrees')
    lon_coord = iris.coords.DimCoord(longitude_data,
                                     standard_name='longitude',
                                     long_name='longitude',
                                     var_name='lon',
                                     units='degrees')

    return [(time_coord, 0), (lat_coord, 1), (lon_coord, 2)]
def _fix_time_coord(cube):
    """Set time points to central day of month."""
    time_coord = cube.coord('time')
    new_unit = Unit('days since 1850-01-01 00:00:00', calendar='standard')
    time_coord.convert_units(new_unit)
    old_time = new_unit.num2date(time_coord.points)
    new_time = [d.replace(day=15) for d in old_time]
    time_coord.points = new_unit.date2num(new_time)
Пример #7
0
 def _convert_datetime_to_coord_unit(coord, dt):
     """Converts a datetime to be in the unit of a specified Coord.
     """
     if isinstance(coord, iris.coords.Coord):
         # The unit class is then cf_units.Unit.
         iris_unit = coord.units
     else:
         iris_unit = Unit(coord.units)
     return iris_unit.date2num(dt)
Пример #8
0
def unify_forecast_reference_time(cubes, cycletime):
    """Function to unify the forecast_reference_time across the input cubes
    provided. The cycletime specified is used as the forecast_reference_time.
    This function is intended for use in grid blending, where the models
    being blended may not have been run at the same cycle time, but should
    be given the same forecast period weightings.

    Args:
        cubes (iris.cube.CubeList or iris.cube.Cube):
            Cubes that will have their forecast_reference_time unified.
            If a single cube is provided the forecast_reference_time will be
            updated. Any bounds on the forecast_reference_time coord will be
            discarded.
        cycletime (datetime.datetime):
            Datetime for the cycletime that will be used to replace the
            forecast_reference_time on the individual cubes.

    Returns:
        result_cubes (iris.cube.CubeList):
            Cubes that have had their forecast_reference_time unified.

    Raises:
        ValueError: if forecast_reference_time is a dimension coordinate
    """
    if isinstance(cubes, iris.cube.Cube):
        cubes = iris.cube.CubeList([cubes])

    result_cubes = iris.cube.CubeList([])
    for cube in cubes:
        frt_units = cube.coord('forecast_reference_time').units
        frt_type = cube.coord('forecast_reference_time').dtype
        new_frt_units = Unit('seconds since 1970-01-01 00:00:00')
        frt_points = np.round([new_frt_units.date2num(cycletime)
                               ]).astype(frt_type)
        frt_coord = build_coordinate(
            frt_points,
            standard_name="forecast_reference_time",
            bounds=None,
            template_coord=cube.coord('forecast_reference_time'),
            units=new_frt_units)
        frt_coord.convert_units(frt_units)
        frt_coord.points = frt_coord.points.astype(frt_type)
        cube.remove_coord("forecast_reference_time")
        cube.add_aux_coord(frt_coord, data_dims=None)

        # If a forecast period coordinate already exists on a cube, replace
        # this coordinate, otherwise create a new coordinate.
        fp_units = "seconds"
        if cube.coords("forecast_period"):
            fp_units = cube.coord("forecast_period").units
            cube.remove_coord("forecast_period")
        fp_coord = forecast_period_coord(cube,
                                         force_lead_time_calculation=True,
                                         result_units=fp_units)
        cube.add_aux_coord(fp_coord, data_dims=cube.coord_dims("time"))
        result_cubes.append(cube)
    return result_cubes
Пример #9
0
def _unify_time_coord(cube):
    """Unify time coordinate of cube."""
    if not cube.coords('time', dim_coords=True):
        return
    time_coord = cube.coord('time')
    dates_points = time_coord.units.num2date(time_coord.points)
    dates_bounds = time_coord.units.num2date(time_coord.bounds)
    new_units = Unit('days since 1850-01-01 00:00:00')
    new_time_coord = iris.coords.DimCoord(
        new_units.date2num(dates_points),
        bounds=new_units.date2num(dates_bounds),
        var_name='time',
        standard_name='time',
        long_name='time',
        units=new_units,
    )
    coord_dims = cube.coord_dims('time')
    cube.remove_coord('time')
    cube.add_dim_coord(new_time_coord, coord_dims)
Пример #10
0
def _get_time_coord(year, month):
    """Get time coordinate."""
    point = datetime(year=year, month=month, day=15)
    bound_low = datetime(year=year, month=month, day=1)
    if month == 12:
        month_bound_up = 1
        year_bound_up = year + 1
    else:
        month_bound_up = month + 1
        year_bound_up = year
    bound_up = datetime(year=year_bound_up, month=month_bound_up, day=1)
    time_units = Unit('days since 1950-01-01 00:00:00', calendar='standard')
    time_coord = iris.coords.DimCoord(
        time_units.date2num(point),
        bounds=time_units.date2num([bound_low, bound_up]),
        var_name='time',
        standard_name='time',
        long_name='time',
        units=time_units,
    )
    return time_coord
Пример #11
0
def unify_cycletime(cubes, cycletime):
    """
    Function to unify the forecast_reference_time and update forecast_period.
    The cycletime specified is used as the forecast_reference_time, and the
    forecast_period is recalculated using the time coordinate and updated
    forecast_reference_time.

    Args:
        cubes (iris.cube.CubeList or list of iris.cube.Cube):
            Cubes that will have their forecast_reference_time and
            forecast_period updated. Any bounds on the forecast_reference_time
            coordinate will be discarded.
        cycletime (datetime.datetime):
            Datetime for the cycletime that will be used to replace the
            forecast_reference_time on the individual cubes.

    Returns:
        iris.cube.CubeList:
            Updated cubes

    Raises:
        ValueError: if forecast_reference_time is a dimension coordinate
    """
    result_cubes = iris.cube.CubeList([])
    for cube in cubes:
        cube = cube.copy()
        frt_units = cube.coord('forecast_reference_time').units
        frt_type = cube.coord('forecast_reference_time').dtype
        new_frt_units = Unit(TIME_REFERENCE_UNIT)
        frt_points = np.round([new_frt_units.date2num(cycletime)
                               ]).astype(frt_type)
        frt_coord = build_coordinate(
            frt_points,
            standard_name="forecast_reference_time",
            bounds=None,
            template_coord=cube.coord('forecast_reference_time'),
            units=new_frt_units)
        frt_coord.convert_units(frt_units)
        frt_coord.points = frt_coord.points.astype(frt_type)
        cube.remove_coord("forecast_reference_time")
        cube.add_aux_coord(frt_coord, data_dims=None)

        # Update the forecast period for consistency within each cube
        if cube.coords("forecast_period"):
            cube.remove_coord("forecast_period")
        fp_coord = forecast_period_coord(cube,
                                         force_lead_time_calculation=True)
        cube.add_aux_coord(fp_coord, data_dims=cube.coord_dims("time"))
        result_cubes.append(cube)
    return result_cubes
Пример #12
0
    def test_unify_time_coordinates(self):
        """Test set common calenar."""
        cube1 = self.cube1
        time1 = cube1.coord('time')
        t_unit1 = time1.units
        dates = t_unit1.num2date(time1.points)

        t_unit2 = Unit('days since 1850-01-01', calendar='gregorian')
        time2 = t_unit2.date2num(dates)
        cube2 = self.cube1.copy()
        cube2.coord('time').points = time2
        cube2.coord('time').units = t_unit2
        _unify_time_coordinates([cube1, cube2])
        self.assertEqual(cube1.coord('time'), cube2.coord('time'))
class Test(tests.IrisGribTest):
    def setUp(self):
        self.section = {
            'year': 2007,
            'month': 1,
            'day': 15,
            'hour': 0,
            'minute': 3,
            'second': 0
        }
        self.unit = Unit('hours since epoch', calendar=CALENDAR_GREGORIAN)
        dt = datetime(self.section['year'], self.section['month'],
                      self.section['day'], self.section['hour'],
                      self.section['minute'], self.section['second'])
        self.point = self.unit.date2num(dt)

    def _check(self, section, standard_name=None):
        expected = DimCoord(self.point,
                            standard_name=standard_name,
                            units=self.unit)
        # The call being tested.
        coord = reference_time_coord(section)
        self.assertEqual(coord, expected)

    def test_start_of_forecast__0(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 0
        self._check(section, 'forecast_reference_time')

    def test_start_of_forecast__1(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 1
        self._check(section, 'forecast_reference_time')

    def test_observation_time(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 3
        self._check(section, 'time')

    def test_unknown_significance(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 5
        emsg = 'unsupported significance'
        with self.assertRaisesRegex(TranslationError, emsg):
            self._check(section)
Пример #14
0
def unify_cycletime(cubes, cycletime):
    """
    Function to unify the forecast_reference_time and update forecast_period.
    The cycletime specified is used as the forecast_reference_time, and the
    forecast_period is recalculated using the time coordinate and updated
    forecast_reference_time.

    Args:
        cubes (iris.cube.CubeList or list of iris.cube.Cube):
            Cubes that will have their forecast_reference_time and
            forecast_period updated. Any bounds on the forecast_reference_time
            coordinate will be discarded.
        cycletime (datetime.datetime):
            Datetime for the cycletime that will be used to replace the
            forecast_reference_time on the individual cubes.

    Returns:
        iris.cube.CubeList:
            Updated cubes

    Raises:
        ValueError: if forecast_reference_time is a dimension coordinate
    """
    result_cubes = iris.cube.CubeList([])
    for cube in cubes:
        cube = cube.copy()
        frt_coord_name = "forecast_reference_time"
        coord_type_spec = TIME_COORDS[frt_coord_name]
        coord_units = Unit(coord_type_spec.units)
        frt_points = round_close([coord_units.date2num(cycletime)],
                                 dtype=coord_type_spec.dtype)
        frt_coord = cube.coord(frt_coord_name).copy(points=frt_points)
        cube.remove_coord(frt_coord_name)
        cube.add_aux_coord(frt_coord, data_dims=None)

        # Update the forecast period for consistency within each cube
        if cube.coords("forecast_period"):
            cube.remove_coord("forecast_period")
        fp_coord = forecast_period_coord(cube,
                                         force_lead_time_calculation=True)
        cube.add_aux_coord(fp_coord, data_dims=cube.coord_dims("time"))
        result_cubes.append(cube)
    return result_cubes
Пример #15
0
class Test(tests.IrisTest):
    def setUp(self):
        self.section = {'year': 2007,
                        'month': 1,
                        'day': 15,
                        'hour': 0,
                        'minute': 3,
                        'second': 0}
        self.unit = Unit('hours since epoch', calendar=CALENDAR_GREGORIAN)
        dt = datetime(self.section['year'], self.section['month'],
                      self.section['day'], self.section['hour'],
                      self.section['minute'], self.section['second'])
        self.point = self.unit.date2num(dt)

    def _check(self, section, standard_name=None):
        expected = DimCoord(self.point, standard_name=standard_name,
                            units=self.unit)
        # The call being tested.
        coord = reference_time_coord(section)
        self.assertEqual(coord, expected)

    def test_start_of_forecast_0(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 0
        self._check(section, 'forecast_reference_time')

    def test_start_of_forecast_1(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 1
        self._check(section, 'forecast_reference_time')

    def test_observation_time(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 3
        self._check(section, 'time')

    def test_unknown_significance(self):
        section = deepcopy(self.section)
        section['significanceOfReferenceTime'] = 5
        emsg = 'unsupported significance'
        with self.assertRaisesRegexp(TranslationError, emsg):
            self._check(section)
Пример #16
0
def timecoord(frequency,
              calendar='gregorian',
              offset='days since 1850-01-01',
              num=3):
    """Return a time coordinate with the given time points and calendar."""

    time_points = range(1, num + 1)

    if frequency == 'hourly':
        dates = [datetime(1850, 1, 1, i, 0, 0) for i in time_points]
    if frequency == 'daily':
        dates = [datetime(1850, 1, i, 0, 0, 0) for i in time_points]
    elif frequency == 'monthly':
        dates = [datetime(1850, i, 15, 0, 0, 0) for i in time_points]
    elif frequency == 'yearly':
        dates = [datetime(1850, 7, i, 0, 0, 0) for i in time_points]

    unit = Unit(offset, calendar=calendar)
    points = unit.date2num(dates)
    return iris.coords.DimCoord(points, standard_name='time', units=unit)
Пример #17
0
def generate_cube_from_dates(
    dates,
    calendar='gregorian',
    offset='days since 1850-01-01',
    fill_val=1,
    len_data=3,
    var_name=None,
):
    """Generate test cube from list of dates / frequency specification.

    Parameters
    ----------
    calendar : str or list
        Date frequency: 'hourly' / 'daily' / 'monthly' / 'yearly' or
        list of datetimes.
    offset : str
        Offset to use
    fill_val : int
        Value to fill the data with
    len_data : int
        Number of data / time points
    var_name : str
        Name of the data variable

    Returns
    -------
    iris.cube.Cube
    """
    if isinstance(dates, str):
        time = timecoord(dates, calendar, offset=offset, num=len_data)
    else:
        unit = Unit(offset, calendar=calendar)
        time = iris.coords.DimCoord(unit.date2num(dates),
                                    standard_name='time',
                                    units=unit)

    return Cube((fill_val, ) * len_data,
                dim_coords_and_dims=[(time, 0)],
                var_name=var_name)
Пример #18
0
def _get_coords(data_table):
    """Extract coordinates."""
    time_units = Unit('days since 1850-01-01 00:00:00')
    times = [datetime(year=year, month=6, day=15) for year in data_table.index]
    time_dim = iris.coords.DimCoord(time_units.date2num(times),
                                    var_name='time',
                                    standard_name='time',
                                    long_name='time',
                                    units=time_units)
    time_dim.guess_bounds()
    lat_dim = iris.coords.DimCoord([0.0],
                                   bounds=[[-90.0, 90.0]],
                                   var_name='lat',
                                   standard_name='latitude',
                                   long_name='latitude',
                                   units=Unit('degrees_north'))
    lon_dim = iris.coords.DimCoord([180.0],
                                   bounds=[[0.0, 360.0]],
                                   var_name='lon',
                                   standard_name='longitude',
                                   long_name='longitude',
                                   units=Unit('degrees_east'))
    return [(time_dim, 0), (lat_dim, 1), (lon_dim, 2)]
Пример #19
0
    def test_3d_spot_cube_for_time(self):
        """Test output with two extra dimensions, one of which is time with
        forecast_period as an auxiliary coordinate"""
        data = np.ones((3, 2, 4), dtype=np.float32)
        time_spec = TIME_COORDS["time"]
        time_units = Unit(time_spec.units)
        time_as_dt = [
            datetime(2021, 12, 25, 12, 0),
            datetime(2021, 12, 25, 12, 1)
        ]
        time_points = round_close(
            np.array([time_units.date2num(t) for t in time_as_dt]),
            dtype=time_spec.dtype,
        )
        time_coord = DimCoord(time_points,
                              units=time_units,
                              standard_name="time")

        fp_spec = TIME_COORDS["forecast_period"]
        fp_units = Unit(fp_spec.units)
        fp_points = np.array([0, 3600], dtype=fp_spec.dtype)
        fp_coord = AuxCoord(fp_points,
                            units=fp_units,
                            standard_name="forecast_period")

        result = build_spotdata_cube(
            data,
            *self.args,
            grid_attributes=self.grid_attributes,
            additional_dims=[time_coord],
            additional_dims_aux=[[fp_coord]],
        )

        self.assertArrayAlmostEqual(result.data, data)
        self.assertEqual(result.coord_dims("grid_attributes")[0], 0)
        self.assertEqual(result.coord_dims("time")[0], 1)
        self.assertEqual(result.coord_dims("forecast_period")[0], 1)
Пример #20
0
class Test(tests.IrisTest):
    def setUp(self):
        self.section = {"year": 2007, "month": 1, "day": 15, "hour": 0, "minute": 3, "second": 0}
        self.unit = Unit("hours since epoch", calendar=CALENDAR_GREGORIAN)
        dt = datetime(
            self.section["year"],
            self.section["month"],
            self.section["day"],
            self.section["hour"],
            self.section["minute"],
            self.section["second"],
        )
        self.point = self.unit.date2num(dt)

    def _check(self, section, standard_name=None):
        expected = DimCoord(self.point, standard_name=standard_name, units=self.unit)
        # The call being tested.
        coord = reference_time_coord(section)
        self.assertEqual(coord, expected)

    def test_start_of_forecast(self):
        section = deepcopy(self.section)
        section["significanceOfReferenceTime"] = 1
        self._check(section, "forecast_reference_time")

    def test_observation_time(self):
        section = deepcopy(self.section)
        section["significanceOfReferenceTime"] = 3
        self._check(section, "time")

    def test_unknown_significance(self):
        section = deepcopy(self.section)
        section["significanceOfReferenceTime"] = 0
        emsg = "unsupported significance"
        with self.assertRaisesRegexp(TranslationError, emsg):
            self._check(section)
Пример #21
0
def NAME_to_cube(filenames, callback):
    """
    Returns a generator of cubes given a list of filenames and a callback.
    """

    for filename in filenames:
        header, column_headings, data_arrays = load_NAME_III(filename)

        for i, data_array in enumerate(data_arrays):
            # turn the dictionary of column headers with a list of header
            # information for each field into a dictionary of headers for just
            # this field. Ignore the first 4 columns of grid position (data was
            # located with the data array).
            field_headings = dict((k, v[i + 4])
                                  for k, v in column_headings.items())

            # make an cube
            cube = iris.cube.Cube(data_array)

            # define the name and unit
            name = ('%s %s' % (field_headings['species'],
                               field_headings['quantity']))
            name = name.upper().replace(' ', '_')
            cube.rename(name)
            # Some units are badly encoded in the file, fix this by putting a
            # space in between. (if gs is not found, then the string will be
            # returned unchanged)
            cube.units = field_headings['unit'].replace('gs', 'g s')

            # define and add the singular coordinates of the field (flight
            # level, time etc.)
            cube.add_aux_coord(icoords.AuxCoord(field_headings['z_level'],
                                                long_name='flight_level',
                                                units='1'))

            # define the time unit and use it to serialise the datetime for the
            # time coordinate
            time_unit = Unit('hours since epoch', calendar=CALENDAR_GREGORIAN)
            time_coord = icoords.AuxCoord(
                time_unit.date2num(field_headings['time']),
                standard_name='time',
                units=time_unit)
            cube.add_aux_coord(time_coord)

            # build a coordinate system which can be referenced by latitude and
            # longitude coordinates
            lat_lon_coord_system = icoord_systems.GeogCS(6371229)

            # build regular latitude and longitude coordinates which have
            # bounds
            start = header['X grid origin'] + header['X grid resolution']
            step = header['X grid resolution']
            count = header['X grid size']
            pts = start + np.arange(count, dtype=np.float32) * step
            lon_coord = icoords.DimCoord(pts, standard_name='longitude',
                                         units='degrees',
                                         coord_system=lat_lon_coord_system)
            lon_coord.guess_bounds()

            start = header['Y grid origin'] + header['Y grid resolution']
            step = header['Y grid resolution']
            count = header['Y grid size']
            pts = start + np.arange(count, dtype=np.float32) * step
            lat_coord = icoords.DimCoord(pts, standard_name='latitude',
                                         units='degrees',
                                         coord_system=lat_lon_coord_system)
            lat_coord.guess_bounds()

            # add the latitude and longitude coordinates to the cube, with
            # mappings to data dimensions
            cube.add_dim_coord(lat_coord, 0)
            cube.add_dim_coord(lon_coord, 1)

            # implement standard iris callback capability. Although callbacks
            # are not used in this example, the standard mechanism for a custom
            # loader to implement a callback is shown:
            cube = iris.io.run_callback(callback, cube,
                                        [header, field_headings, data_array],
                                        filename)

            # yield the cube created (the loop will continue when the next()
            # element is requested)
            yield cube
Пример #22
0
class TestCategoriseCoordFunctionForTime:

    def __init__(self):
        self.u = Unit('days since 1600-01-01 00:00:00', calendar=CALENDAR_STANDARD)
        self.points = np.arange(1, 5, 1)
        self.coord = iris.coords.DimCoord(self.points, units=self.u)
        self.start = datetime.datetime(2000, 1, 1)
        self.end = datetime.datetime(2003, 4, 24)
        self.start = self.u.date2num(self.start)
        self.end = self.u.date2num(self.end)

    def setup_func(self):
        self.__init__()

    @with_setup(setup_func)
    def test_categorise_coord_function_time_year_only(self):
        delta = date_delta_creator(1)
        result_function = categorise_coord_function(self.start, self.end, delta, True)
        expected = np.array([self.u.date2num(datetime.datetime(2000, 7, 1, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2001, 7, 1, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2002, 7, 1, 0, 0, 0))])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2000, 1, 1, 0, 0, 0))), expected[0])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2001, 3, 3, 0, 0, 0))), expected[1])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2002, 5, 8, 0, 0, 0))), expected[2])

    @with_setup(setup_func)
    def test_categorise_coord_function_time_year_month(self):
        delta = date_delta_creator(1, 1)
        result_function = categorise_coord_function(self.start, self.end, delta, True)
        expected = np.array([self.u.date2num(datetime.datetime(2000, 7, 15, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2001, 8, 15, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2002, 9, 15, 0, 0, 0))])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2000, 1, 1, 0, 0, 0))), expected[0])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2001, 3, 3, 0, 0, 0))), expected[1])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2002, 5, 8, 0, 0, 0))), expected[2])

    @with_setup(setup_func)
    def test_categorise_coord_function_with_month_going_past_december(self):
        start = datetime.datetime(2000, 11, 3)
        start = self.u.date2num(start)
        end = datetime.datetime(2004, 11, 3)
        end = self.u.date2num(end)
        delta = date_delta_creator(1, 2)
        result_function = categorise_coord_function(start, end, delta, True)
        expected = np.array([self.u.date2num(datetime.datetime(2001, 6, 3, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2002, 8, 3, 0, 0, 0)),
                             self.u.date2num(datetime.datetime(2003, 10, 3, 0, 0, 0))])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(1999, 1, 1, 0, 0, 0))), expected[0])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2001, 3, 3, 0, 0, 0))), expected[0])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2002, 3, 3, 0, 0, 0))), expected[1])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2005, 5, 8, 0, 0, 0))), expected[2])

    @with_setup(setup_func)
    def test_categorise_coord_function_time_year_month_day_hour_minute_second(self):
        delta = date_delta_creator(1, 3, 2, 4, 5, 6)
        result_function = categorise_coord_function(self.start, self.end, delta, True)
        expected = np.array([self.u.date2num(datetime.datetime(2000, 8, 16, 2, 2, 33)),
                             self.u.date2num(datetime.datetime(2001, 11, 18, 6, 7, 39)),
                             self.u.date2num(datetime.datetime(2003, 2, 20, 10, 12, 45))])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2000, 1, 1, 0, 0, 0))), expected[0])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2001, 7, 3, 0, 0, 0))), expected[1])
        assert_equal(result_function(self.coord, self.u.date2num(datetime.datetime(2002, 9, 8, 0, 0, 0))), expected[2])
Пример #23
0
def NAME_to_cube(filenames, callback):
    """
    Returns a generator of cubes given a list of filenames and a callback.
    """

    for filename in filenames:
        header, column_headings, data_arrays = load_NAME_III(filename)

        for i, data_array in enumerate(data_arrays):
            # turn the dictionary of column headers with a list of header
            # information for each field into a dictionary of headers for just
            # this field. Ignore the first 4 columns of grid position (data was
            # located with the data array).
            field_headings = dict(
                (k, v[i + 4]) for k, v in column_headings.items())

            # make an cube
            cube = iris.cube.Cube(data_array)

            # define the name and unit
            name = "%s %s" % (
                field_headings["species"],
                field_headings["quantity"],
            )
            name = name.upper().replace(" ", "_")
            cube.rename(name)
            # Some units are badly encoded in the file, fix this by putting a
            # space in between. (if gs is not found, then the string will be
            # returned unchanged)
            cube.units = field_headings["unit"].replace("gs", "g s")

            # define and add the singular coordinates of the field (flight
            # level, time etc.)
            cube.add_aux_coord(
                icoords.AuxCoord(
                    field_headings["z_level"],
                    long_name="flight_level",
                    units="1",
                ))

            # define the time unit and use it to serialise the datetime for the
            # time coordinate
            time_unit = Unit("hours since epoch", calendar=CALENDAR_GREGORIAN)
            time_coord = icoords.AuxCoord(
                time_unit.date2num(field_headings["time"]),
                standard_name="time",
                units=time_unit,
            )
            cube.add_aux_coord(time_coord)

            # build a coordinate system which can be referenced by latitude and
            # longitude coordinates
            lat_lon_coord_system = icoord_systems.GeogCS(6371229)

            # build regular latitude and longitude coordinates which have
            # bounds
            start = header["X grid origin"] + header["X grid resolution"]
            step = header["X grid resolution"]
            count = header["X grid size"]
            pts = start + np.arange(count, dtype=np.float32) * step
            lon_coord = icoords.DimCoord(
                pts,
                standard_name="longitude",
                units="degrees",
                coord_system=lat_lon_coord_system,
            )
            lon_coord.guess_bounds()

            start = header["Y grid origin"] + header["Y grid resolution"]
            step = header["Y grid resolution"]
            count = header["Y grid size"]
            pts = start + np.arange(count, dtype=np.float32) * step
            lat_coord = icoords.DimCoord(
                pts,
                standard_name="latitude",
                units="degrees",
                coord_system=lat_lon_coord_system,
            )
            lat_coord.guess_bounds()

            # add the latitude and longitude coordinates to the cube, with
            # mappings to data dimensions
            cube.add_dim_coord(lat_coord, 0)
            cube.add_dim_coord(lon_coord, 1)

            # implement standard iris callback capability. Although callbacks
            # are not used in this example, the standard mechanism for a custom
            # loader to implement a callback is shown:
            cube = iris.io.run_callback(callback, cube,
                                        [header, field_headings, data_array],
                                        filename)

            # yield the cube created (the loop will continue when the next()
            # element is requested)
            yield cube