Example #1
0
def daily_statistics(cube, operator='mean'):
    """Compute daily statistics.

    Chunks time in daily periods and computes statistics over them;

    Parameters
    ----------
    cube: iris.cube.Cube
        input cube.

    operator: str, optional
        Select operator to apply.
        Available operators: 'mean', 'median', 'std_dev', 'sum', 'min',
        'max', 'rms'

    Returns
    -------
    iris.cube.Cube
        Daily statistics cube
    """
    if not cube.coords('day_of_year'):
        iris.coord_categorisation.add_day_of_year(cube, 'time')
    if not cube.coords('year'):
        iris.coord_categorisation.add_year(cube, 'time')

    operator = get_iris_analysis_operation(operator)
    cube = cube.aggregated_by(['day_of_year', 'year'], operator)

    cube.remove_coord('day_of_year')
    cube.remove_coord('year')
    return cube
Example #2
0
def climate_statistics(cube,
                       operator='mean',
                       period='full',
                       seasons=('DJF', 'MAM', 'JJA', 'SON')):
    """Compute climate statistics with the specified granularity.

    Computes statistics for the whole dataset. It is possible to get them for
    the full period or with the data grouped by day, month or season

    Parameters
    ----------
    cube: iris.cube.Cube
        input cube.

    operator: str, optional
        Select operator to apply.
        Available operators: 'mean', 'median', 'std_dev', 'sum', 'min',
        'max', 'rms'

    period: str, optional
        Period to compute the statistic over.
        Available periods: 'full', 'season', 'seasonal', 'monthly', 'month',
        'mon', 'daily', 'day'

    seasons: list or tuple of str, optional
        Seasons to use if needed. Defaults to ('DJF', 'MAM', 'JJA', 'SON')

    Returns
    -------
    iris.cube.Cube
        Monthly statistics cube
    """
    period = period.lower()

    if period in ('full', ):
        operator_method = get_iris_analysis_operation(operator)
        if operator_accept_weights(operator):
            time_weights = get_time_weights(cube)
            if time_weights.min() == time_weights.max():
                # No weighting needed.
                cube = cube.collapsed('time', operator_method)
            else:
                cube = cube.collapsed('time',
                                      operator_method,
                                      weights=time_weights)
        else:
            cube = cube.collapsed('time', operator_method)
        return cube

    clim_coord = _get_period_coord(cube, period, seasons)
    operator = get_iris_analysis_operation(operator)
    clim_cube = cube.aggregated_by(clim_coord, operator)
    clim_cube.remove_coord('time')
    if clim_cube.coord(clim_coord.name()).is_monotonic():
        iris.util.promote_aux_coord_to_dim_coord(clim_cube, clim_coord.name())
    else:
        clim_cube = iris.cube.CubeList(clim_cube.slices_over(
            clim_coord.name())).merge_cube()
    cube.remove_coord(clim_coord)
    return clim_cube
Example #3
0
 def test_bounded_level(self):
     cube = iris.load_cube(
         tests.get_data_path(("GRIB", "uk_t", "uk_t.grib2")))
     # Changing pressure to altitude due to grib api bug:
     # https://github.com/SciTools/iris/pull/715#discussion_r5901538
     cube.remove_coord("pressure")
     cube.add_aux_coord(
         iris.coords.AuxCoord(
             1030.0,
             long_name="altitude",
             units="m",
             bounds=np.array([111.0, 1949.0]),
         ))
     with self.temp_filename(".grib2") as testfile:
         iris.save(cube, testfile)
         with open(testfile, "rb") as saved_file:
             g = gribapi.grib_new_from_file(saved_file)
             self.assertEqual(
                 gribapi.grib_get_double(g,
                                         "scaledValueOfFirstFixedSurface"),
                 111.0,
             )
             self.assertEqual(
                 gribapi.grib_get_double(g,
                                         "scaledValueOfSecondFixedSurface"),
                 1949.0,
             )
Example #4
0
 def test_missing_coords(self):
     cube = iris.tests.stock.realistic_4d()
     cube.remove_coord('time')
     cube.remove_coord('model_level_number')
     self.assertString(repr(cube),
                       ('cdm', 'str_repr', 'missing_coords_cube.repr.txt'))
     self.assertString(str(cube),
                       ('cdm', 'str_repr', 'missing_coords_cube.str.txt'))
Example #5
0
 def test_missing_coords(self):
     cube = iris.tests.stock.realistic_4d()
     cube.remove_coord('time')
     cube.remove_coord('model_level_number')
     self.assertString(repr(cube),
                       ('cdm', 'str_repr', 'missing_coords_cube.repr.txt'))
     self.assertString(str(cube),
                       ('cdm', 'str_repr', 'missing_coords_cube.str.txt'))
Example #6
0
    def test_fully_wrapped_not_circular(self):
        cube = stock.lat_lon_cube()
        new_long = cube.coord('longitude').copy(
            cube.coord('longitude').points + 710)
        cube.remove_coord('longitude')
        cube.add_dim_coord(new_long, 1)

        interpolator = LinearInterpolator(cube, ['longitude'])
        res = interpolator([-10])
        self.assertArrayEqual(res.data, cube[:, 1].data)
    def test_fully_wrapped_not_circular(self):
        cube = stock.lat_lon_cube()
        new_long = cube.coord("longitude").copy(
            cube.coord("longitude").points + 710)
        cube.remove_coord("longitude")
        cube.add_dim_coord(new_long, 1)

        interpolator = RectilinearInterpolator(cube, ["longitude"], LINEAR,
                                               EXTRAPOLATE)
        res = interpolator([-10])
        self.assertArrayEqual(res.data, cube[:, 1].data)
Example #8
0
 def test_irregular(self):
     cube = self._load_basic()
     lat_coord = cube.coord("latitude")
     cube.remove_coord("latitude")
    
     new_lats = np.append(lat_coord.points[:-1], lat_coord.points[0])  # Irregular
     cube.add_aux_coord(iris.coords.AuxCoord(new_lats, "latitude", units="degrees", coord_system=lat_coord.coord_system), 0) 
     
     saved_grib = iris.util.create_temp_filename(suffix='.grib2')
     self.assertRaises(iris.exceptions.TranslationError, iris.save, cube, saved_grib)
     os.remove(saved_grib)
Example #9
0
    def test_irregular(self):
        cube = self._load_basic()
        lat_coord = cube.coord("latitude")
        cube.remove_coord("latitude")

        new_lats = np.append(lat_coord.points[:-1], lat_coord.points[0])  # Irregular
        cube.add_aux_coord(iris.coords.AuxCoord(new_lats, "latitude", units="degrees", coord_system=lat_coord.coord_system), 0)

        saved_grib = iris.util.create_temp_filename(suffix='.grib2')
        self.assertRaises(iris.exceptions.TranslationError, iris.save, cube, saved_grib)
        os.remove(saved_grib)
Example #10
0
def extract_season(cube, season):
    """Slice cube to get only the data belonging to a specific season.

    Parameters
    ----------
    cube: iris.cube.Cube
        Original data
    season: str
        Season to extract. Available: DJF, MAM, JJA, SON
        and all sequentially correct combinations: e.g. JJAS

    Returns
    -------
    iris.cube.Cube
        data cube for specified season.

    Raises
    ------
    ValueError
        if requested season is not present in the cube
    """
    season = season.upper()

    allmonths = 'JFMAMJJASOND' * 2
    if season not in allmonths:
        raise ValueError(f"Unable to extract Season {season} "
                         f"combination of months not possible.")
    sstart = allmonths.index(season)
    res_season = allmonths[sstart + len(season):sstart + 12]
    seasons = [season, res_season]
    coords_to_remove = []

    if not cube.coords('clim_season'):
        iris.coord_categorisation.add_season(cube,
                                             'time',
                                             name='clim_season',
                                             seasons=seasons)
        coords_to_remove.append('clim_season')

    if not cube.coords('season_year'):
        iris.coord_categorisation.add_season_year(cube,
                                                  'time',
                                                  name='season_year',
                                                  seasons=seasons)
        coords_to_remove.append('season_year')

    result = cube.extract(iris.Constraint(clim_season=season))
    for coord in coords_to_remove:
        cube.remove_coord(coord)
    if result is None:
        raise ValueError(f'Season {season!r} not present in cube {cube}')
    return result
Example #11
0
 def test_anonymous(self):
     cubes = []
     y = (0, 2)
     cubes.append(_make_cube((0, 2), y, 1))
     cubes.append(_make_cube((2, 4), y, 2))
     cube = _make_cube((4, 6), y, 3)
     cube.remove_coord('x')
     cubes.append(cube)
     result = concatenate(cubes)
     self.assertCML(result, ('concatenate', 'concat_anonymous.cml'))
     self.assertEqual(len(result), 2)
     self.assertEqual(result[0].shape, (2, 4))
     self.assertEqual(result[1].shape, (2, 2))
Example #12
0
 def test_missing_latlon(self):
     cube = self.cube.copy()
     cube.remove_coord('grid_latitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(cube, self.target_proj)
     cube = self.cube.copy()
     cube.remove_coord('grid_longitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(cube, self.target_proj)
     self.cube.remove_coord('grid_longitude')
     self.cube.remove_coord('grid_latitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(self.cube, self.target_proj)
 def test_anonymous(self):
     cubes = []
     y = (0, 2)
     cubes.append(_make_cube((0, 2), y, 1))
     cubes.append(_make_cube((2, 4), y, 2))
     cube = _make_cube((4, 6), y, 3)
     cube.remove_coord('x')
     cubes.append(cube)
     result = concatenate(cubes)
     self.assertCML(result, ('concatenate', 'concat_anonymous.cml'))
     self.assertEqual(len(result), 2)
     self.assertEqual(result[0].shape, (2, 4))
     self.assertEqual(result[1].shape, (2, 2))
Example #14
0
 def test_missing_latlon(self):
     cube = self.cube.copy()
     cube.remove_coord('grid_latitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(cube, self.target_proj)
     cube = self.cube.copy()
     cube.remove_coord('grid_longitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(cube, self.target_proj)
     self.cube.remove_coord('grid_longitude')
     self.cube.remove_coord('grid_latitude')
     with self.assertRaises(ValueError):
         iris.analysis.cartography.project(self.cube, self.target_proj)
Example #15
0
 def test_one_cube_has_anon_dim(self):
     cubes = []
     y = (0, 2)
     cubes.append(_make_cube((0, 2), y, 1))
     cubes.append(_make_cube((2, 4), y, 2))
     cube = _make_cube((4, 6), y, 3)
     cube.remove_coord("x")
     cubes.append(cube)
     result = concatenate(cubes)
     self.assertCML(result, ("concatenate", "concat_anonymous.cml"))
     self.assertEqual(len(result), 2)
     self.assertEqual(result[0].shape, (2, 4))
     self.assertEqual(result[1].shape, (2, 2))
Example #16
0
 def test_bounded_level(self):
     cube = iris.load_cube(tests.get_data_path(("GRIB", "uk_t", "uk_t.grib2")))
     # Changing pressure to altitude due to grib api bug:
     # https://github.com/SciTools/iris/pull/715#discussion_r5901538
     cube.remove_coord("pressure")
     cube.add_aux_coord(
         iris.coords.AuxCoord(1030.0, long_name="altitude", units="m", bounds=np.array([111.0, 1949.0]))
     )
     with self.temp_filename(".grib2") as testfile:
         iris.save(cube, testfile)
         with open(testfile, "rb") as saved_file:
             g = gribapi.grib_new_from_file(saved_file)
             self.assertEqual(gribapi.grib_get_double(g, "scaledValueOfFirstFixedSurface"), 111.0)
             self.assertEqual(gribapi.grib_get_double(g, "scaledValueOfSecondFixedSurface"), 1949.0)
Example #17
0
def _compute_anomalies(cube, reference, period, seasons):
    cube_coord = _get_period_coord(cube, period, seasons)
    ref_coord = _get_period_coord(reference, period, seasons)

    data = cube.core_data()
    cube_time = cube.coord('time')
    ref = {}
    for ref_slice in reference.slices_over(ref_coord):
        ref[ref_slice.coord(ref_coord).points[0]] = ref_slice.core_data()

    cube_coord_dim = cube.coord_dims(cube_coord)[0]
    slicer = [slice(None)] * len(data.shape)
    new_data = []
    for i in range(cube_time.shape[0]):
        slicer[cube_coord_dim] = i
        new_data.append(data[tuple(slicer)] - ref[cube_coord.points[i]])
    data = da.stack(new_data, axis=cube_coord_dim)
    cube = cube.copy(data)
    cube.remove_coord(cube_coord)
    return cube
Example #18
0
    def test_multi_d(self):
        cube = iris.tests.stock.realistic_4d()

        # TODO: Re-instate surface_altitude & hybrid-height once we're
        # using the post-CF test results.
        cube.remove_aux_factory(cube.aux_factories[0])
        cube.remove_coord('surface_altitude')

        self.assertCML(cube, ('cube_collapsed', 'original.cml'))

        # Compare 2-stage collapsing with a single stage collapse over 2 Coords.
        self.collapse_test_common(cube, 'grid_latitude', 'grid_longitude', decimal=1)
        self.collapse_test_common(cube, 'grid_longitude', 'grid_latitude', decimal=1)

        self.collapse_test_common(cube, 'time', 'grid_latitude', decimal=1)
        self.collapse_test_common(cube, 'grid_latitude', 'time', decimal=1)

        self.collapse_test_common(cube, 'time', 'grid_longitude', decimal=1)
        self.collapse_test_common(cube, 'grid_longitude', 'time', decimal=1)

        self.collapse_test_common(cube, 'grid_latitude', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'grid_latitude', decimal=1)

        self.collapse_test_common(cube, 'grid_longitude', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'grid_longitude', decimal=1)

        self.collapse_test_common(cube, 'time', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'time', decimal=1)

        self.collapse_test_common(cube, 'model_level_number', 'time', decimal=1)
        self.collapse_test_common(cube, 'time', 'model_level_number', decimal=1)

        # Collapse 3 things at once.
        triple_collapse = cube.collapsed(['model_level_number', 'time', 'grid_longitude'], iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed', 'triple_collapse_ml_pt_lon.cml'), decimal=1)

        triple_collapse = cube.collapsed(['grid_latitude', 'model_level_number', 'time'], iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed', 'triple_collapse_lat_ml_pt.cml'), decimal=1)

        # Ensure no side effects
        self.assertCML(cube, ('cube_collapsed', 'original.cml'))
Example #19
0
    def test_multi_d(self):
        cube = iris.tests.stock.realistic_4d()

        # TODO: Re-instate surface_altitude & hybrid-height once we're
        # using the post-CF test results.
        cube.remove_aux_factory(cube.aux_factories[0])
        cube.remove_coord('surface_altitude')

        self.assertCML(cube, ('cube_collapsed', 'original.cml'))

        # Compare 2-stage collapsing with a single stage collapse over 2 Coords.
        self.collapse_test_common(cube, 'grid_latitude', 'grid_longitude', decimal=1)
        self.collapse_test_common(cube, 'grid_longitude', 'grid_latitude', decimal=1)

        self.collapse_test_common(cube, 'time', 'grid_latitude', decimal=1)
        self.collapse_test_common(cube, 'grid_latitude', 'time', decimal=1)

        self.collapse_test_common(cube, 'time', 'grid_longitude', decimal=1)
        self.collapse_test_common(cube, 'grid_longitude', 'time', decimal=1)

        self.collapse_test_common(cube, 'grid_latitude', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'grid_latitude', decimal=1)

        self.collapse_test_common(cube, 'grid_longitude', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'grid_longitude', decimal=1)

        self.collapse_test_common(cube, 'time', 'model_level_number', decimal=1)
        self.collapse_test_common(cube, 'model_level_number', 'time', decimal=1)

        self.collapse_test_common(cube, 'model_level_number', 'time', decimal=1)
        self.collapse_test_common(cube, 'time', 'model_level_number', decimal=1)

        # Collapse 3 things at once.
        triple_collapse = cube.collapsed(['model_level_number', 'time', 'grid_longitude'], iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed', 'triple_collapse_ml_pt_lon.cml'), decimal=1)

        triple_collapse = cube.collapsed(['grid_latitude', 'model_level_number', 'time'], iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed', 'triple_collapse_lat_ml_pt.cml'), decimal=1)

        # Ensure no side effects
        self.assertCML(cube, ('cube_collapsed', 'original.cml'))
Example #20
0
def hourly_statistics(cube, hours, operator='mean'):
    """Compute hourly statistics.

    Chunks time in x hours periods and computes statistics over them.

    Parameters
    ----------
    cube: iris.cube.Cube
        input cube.

    hours: int
        Number of hours per period. Must be a divisor of 24
        (1, 2, 3, 4, 6, 8, 12)

    operator: str, optional
        Select operator to apply.
        Available operators: 'mean', 'median', 'std_dev', 'sum', 'min', 'max'

    Returns
    -------
    iris.cube.Cube
        Hourly statistics cube
    """
    if not cube.coords('hour_group'):
        iris.coord_categorisation.add_categorised_coord(
            cube,
            'hour_group',
            'time',
            lambda coord, value: coord.units.num2date(value).hour // hours,
            units='1')
    if not cube.coords('day_of_year'):
        iris.coord_categorisation.add_day_of_year(cube, 'time')
    if not cube.coords('year'):
        iris.coord_categorisation.add_year(cube, 'time')

    operator = get_iris_analysis_operation(operator)
    cube = cube.aggregated_by(['hour_group', 'day_of_year', 'year'], operator)

    cube.remove_coord('hour_group')
    cube.remove_coord('day_of_year')
    cube.remove_coord('year')
    return cube
Example #21
0
 def test_no_coord(self):
     cube = _point_cube(59, iris.unit.CALENDAR_GREGORIAN)
     constraint = TimeRangeConstraint(day_of_year=[(3, 1), (9, 30)])
     cube.remove_coord('time')
     with self.assertRaises(AttributeError):
         result = self.constraint.extract(cube)
Example #22
0
def low_res_4d():
    cube = iris.tests.stock.realistic_4d_no_derived()
    cube = cube[0:2, 0:3, ::10, ::10]
    cube.remove_coord('surface_altitude')
    return cube
Example #23
0
def regrid_time(cube, frequency):
    """Align time axis for cubes so they can be subtracted.

    Operations on time units, time points and auxiliary
    coordinates so that any cube from cubes can be subtracted from any
    other cube from cubes. Currently this function supports
    yearly (frequency=yr), monthly (frequency=mon),
    daily (frequency=day), 6-hourly (frequency=6hr),
    3-hourly (frequency=3hr) and hourly (frequency=1hr) data time frequencies.

    Parameters
    ----------
    cube: iris.cube.Cube
        input cube.
    frequency: str
        data frequency: mon, day, 1hr, 3hr or 6hr

    Returns
    -------
    iris.cube.Cube
        cube with converted time axis and units.
    """
    # standardize time points
    time_c = [cell.point for cell in cube.coord('time').cells()]
    if frequency == 'yr':
        time_cells = [datetime.datetime(t.year, 7, 1, 0, 0, 0) for t in time_c]
    elif frequency == 'mon':
        time_cells = [
            datetime.datetime(t.year, t.month, 15, 0, 0, 0) for t in time_c
        ]
    elif frequency == 'day':
        time_cells = [
            datetime.datetime(t.year, t.month, t.day, 0, 0, 0) for t in time_c
        ]
    elif frequency == '1hr':
        time_cells = [
            datetime.datetime(t.year, t.month, t.day, t.hour, 0, 0)
            for t in time_c
        ]
    elif frequency == '3hr':
        time_cells = [
            datetime.datetime(t.year, t.month, t.day, t.hour - t.hour % 3, 0,
                              0) for t in time_c
        ]
    elif frequency == '6hr':
        time_cells = [
            datetime.datetime(t.year, t.month, t.day, t.hour - t.hour % 6, 0,
                              0) for t in time_c
        ]

    cube.coord('time').points = [
        cube.coord('time').units.date2num(cl) for cl in time_cells
    ]

    # uniformize bounds
    cube.coord('time').bounds = None
    cube.coord('time').bounds = _get_time_bounds(cube.coord('time'), frequency)

    # remove aux coords that will differ
    reset_aux = ['day_of_month', 'day_of_year']
    for auxcoord in cube.aux_coords:
        if auxcoord.long_name in reset_aux:
            cube.remove_coord(auxcoord)

    # re-add the converted aux coords
    iris.coord_categorisation.add_day_of_month(cube,
                                               cube.coord('time'),
                                               name='day_of_month')
    iris.coord_categorisation.add_day_of_year(cube,
                                              cube.coord('time'),
                                              name='day_of_year')

    return cube
Example #24
0
 def test_missing_latlon(self):
     cube = low_res_4d()
     cube.remove_coord('grid_longitude')
     cube.remove_coord('grid_latitude')
     with self.assertRaises(ValueError):
         project(cube, ROBINSON)
Example #25
0
def fix_bpch2coards(cube, field, filename):
    """
    An Iris load callback for properly loading the NetCDF files
    created by BPCH2COARDS (GAMAP v2-17+).

    """
    global _coordcache2

    # units
    units = field.units
    try:
        cube.units = units
    except ValueError:
        # Try to get equivalent units compatible with udunits.
        # Store original unit as cube attribute
        conform_units = ctm2cf.get_cfcompliant_units(units)
        try:
            cube.units = conform_units
        except ValueError:
            warnings.warn("Invalid udunits2 '{0}'".format(units))
    cube.attributes["ctm_units"] = units

    # a hack for keeping cube's long_name but show var_name in cube summary
    iris.std_names.STD_NAMES[cube.var_name] = {'canonical_units': cube.units}
    cube.standard_name = cube.var_name

    # attributes
    # TODO: don't remove all attributes
    cube.attributes.clear()

    # longitude coordinate (non strictly monotonic) degrees -> degrees_east
    try:
        lon = cube.coord('longitude')
        lon_dim = cube.coord_dims(lon)[0]
        cache_key = 'longitude', filename

        if _coordcache2.get(cache_key) is None:
            west_ind = np.nonzero(lon.points >= 180.)
            lon.points[west_ind] = -1. * (360. - lon.points)
            lon.units = 'degrees_east'
            _coordcache2[cache_key] = iris.coords.DimCoord.from_coord(lon)

        cube.remove_coord(lon)
        cube.add_dim_coord(_coordcache2[cache_key], lon_dim)
    except iris.exceptions.CoordinateNotFoundError:
        pass

    # levels coordinate
    # 'sigma_level' depreciated in the CF standard (not supported by UDUNITS)
    try:
        lev = cube.coord('Eta Centers')
        lev_dim = cube.coord_dims(lev)[0]
        lev_std_name = 'atmosphere_hybrid_sigma_pressure_coordinate'
        cache_key = lev_std_name, filename

        if _coordcache2.get(cache_key) is None:
            lev.standard_name = lev_std_name
            lev.units = iris.unit.Unit('1')
            d = nc.Dataset(filename)
            elev = d.variables['edge'][:]
            lev.bounds = np.column_stack((elev[:-1], elev[1:]))
            _coordcache2[cache_key] = iris.coords.DimCoord.from_coord(lev)

        cube.remove_coord(lev)
        cube.add_dim_coord(_coordcache2[cache_key], lev_dim)
    except iris.exceptions.CoordinateNotFoundError:
        pass

    # time: dimension -> scalar coordinate (+ add bounds)
    try:
        time_coord = cube.coord('time')
        time_dim = cube.coord_dims(time_coord)[0]

        with iris.FUTURE.context(cell_datetime_objects=True):
            tstart = time_coord.cell(0).point
        delta_t = time_coord.attributes.pop('delta_t')
        tend = tstart + timeutil.strp_relativedelta(delta_t)
        time_coord.bounds = [timeutil.time2tau(tstart),
                             timeutil.time2tau(tend)]
        if cube.shape[time_dim] == 1:
            slices_dims = [d for d in range(cube.ndim) if d != time_dim]
            return cube.slices(slices_dims).next()
    except iris.exceptions.CoordinateNotFoundError:
        pass
Example #26
0
    def test_multi_d(self):
        cube = iris.tests.stock.realistic_4d()

        # TODO: Re-instate surface_altitude & hybrid-height once we're
        # using the post-CF test results.
        cube.remove_aux_factory(cube.aux_factories[0])
        cube.remove_coord('surface_altitude')

        self.assertCML(cube, ('cube_collapsed', 'original.cml'))

        # Compare 2-stage collapsing with a single stage collapse
        # over 2 Coords.
        self.collapse_test_common(cube, 'grid_latitude', 'grid_longitude',
                                  rtol=1e-05)
        self.collapse_test_common(cube, 'grid_longitude', 'grid_latitude',
                                  rtol=1e-05)

        self.collapse_test_common(cube, 'time', 'grid_latitude', rtol=1e-05)
        self.collapse_test_common(cube, 'grid_latitude', 'time', rtol=1e-05)

        self.collapse_test_common(cube, 'time', 'grid_longitude', rtol=1e-05)
        self.collapse_test_common(cube, 'grid_longitude', 'time', rtol=1e-05)

        self.collapse_test_common(cube, 'grid_latitude', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'grid_latitude',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'grid_longitude', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'grid_longitude',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'time', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'time',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'model_level_number', 'time',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'time', 'model_level_number',
                                  rtol=5e-04)

        # Collapse 3 things at once.
        triple_collapse = cube.collapsed(['model_level_number',
                                          'time', 'grid_longitude'],
                                          iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed',
                                                   ('triple_collapse_ml_pt_'
                                                    'lon.cml')),
                                                   rtol=5e-04)

        triple_collapse = cube.collapsed(['grid_latitude',
                                          'model_level_number', 'time'],
                                          iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed',
                                                   ('triple_collapse_lat_ml'
                                                   '_pt.cml')),
                                                   rtol=0.05)
        # KNOWN PROBLEM: the previous 'rtol' is very large.
        # Numpy 1.10 and 1.11 give significantly different results here.
        # This may relate to known problems with summing over large arrays,
        # which were largely fixed in numpy 1.9 but still occur in some cases,
        # as-of numpy 1.11.

        # Ensure no side effects
        self.assertCML(cube, ('cube_collapsed', 'original.cml'))
Example #27
0
 def test_missing_lon(self):
     cube = low_res_4d()
     cube.remove_coord('grid_longitude')
     with self.assertRaises(ValueError):
         project(cube, ROBINSON)
Example #28
0
def low_res_4d():
    cube = iris.tests.stock.realistic_4d_no_derived()
    cube = cube[0:2, 0:3, ::10, ::10]
    cube.remove_coord('surface_altitude')
    return cube
Example #29
0
    def test_multi_d(self):
        cube = iris.tests.stock.realistic_4d()

        # TODO: Re-instate surface_altitude & hybrid-height once we're
        # using the post-CF test results.
        cube.remove_aux_factory(cube.aux_factories[0])
        cube.remove_coord('surface_altitude')

        self.assertCML(cube, ('cube_collapsed', 'original.cml'))

        # Compare 2-stage collapsing with a single stage collapse
        # over 2 Coords.
        self.collapse_test_common(cube, 'grid_latitude', 'grid_longitude',
                                  rtol=1e-05)
        self.collapse_test_common(cube, 'grid_longitude', 'grid_latitude',
                                  rtol=1e-05)

        self.collapse_test_common(cube, 'time', 'grid_latitude', rtol=1e-05)
        self.collapse_test_common(cube, 'grid_latitude', 'time', rtol=1e-05)

        self.collapse_test_common(cube, 'time', 'grid_longitude', rtol=1e-05)
        self.collapse_test_common(cube, 'grid_longitude', 'time', rtol=1e-05)

        self.collapse_test_common(cube, 'grid_latitude', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'grid_latitude',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'grid_longitude', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'grid_longitude',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'time', 'model_level_number',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'model_level_number', 'time',
                                  rtol=5e-04)

        self.collapse_test_common(cube, 'model_level_number', 'time',
                                  rtol=5e-04)
        self.collapse_test_common(cube, 'time', 'model_level_number',
                                  rtol=5e-04)

        # Collapse 3 things at once.
        triple_collapse = cube.collapsed(['model_level_number',
                                          'time', 'grid_longitude'],
                                          iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed',
                                                   ('triple_collapse_ml_pt_'
                                                    'lon.cml')),
                                                   rtol=5e-04)

        triple_collapse = cube.collapsed(['grid_latitude',
                                          'model_level_number', 'time'],
                                          iris.analysis.MEAN)
        self.assertCMLApproxData(triple_collapse, ('cube_collapsed',
                                                   ('triple_collapse_lat_ml'
                                                   '_pt.cml')),
                                                   rtol=0.05)
        # KNOWN PROBLEM: the previous 'rtol' is very large.
        # Numpy 1.10 and 1.11 give significantly different results here.
        # This may relate to known problems with summing over large arrays,
        # which were largely fixed in numpy 1.9 but still occur in some cases,
        # as-of numpy 1.11.

        # Ensure no side effects
        self.assertCML(cube, ('cube_collapsed', 'original.cml'))