def test_picking_equality_misc(self): items_to_test = [ cf_units.Unit("hours since 2007-01-15 12:06:00", calendar=cf_units.CALENDAR_STANDARD), cf_units.as_unit('1'), cf_units.as_unit('meters'), cf_units.as_unit('no-unit'), cf_units.as_unit('unknown') ] for orig_item in items_to_test: for protocol, reconstructed_item in self.pickle_then_unpickle(orig_item): fail_msg = ('Items are different after pickling at protocol %s.' '\nOrig item: %r\nNew item: %r' % (protocol, orig_item, reconstructed_item) ) self.assertEqual(orig_item, reconstructed_item, fail_msg)
def test_picking_equality_misc(self): items_to_test = [ cf_units.Unit("hours since 2007-01-15 12:06:00", calendar=cf_units.CALENDAR_STANDARD), cf_units.as_unit('1'), cf_units.as_unit('meters'), cf_units.as_unit('no-unit'), cf_units.as_unit('unknown') ] for orig_item in items_to_test: for protocol, reconst_item in self.pickle_then_unpickle(orig_item): fail_msg = ('Items are different after pickling ' 'at protocol {}.\nOrig item: {!r}\nNew item: {!r}') fail_msg = fail_msg.format(protocol, orig_item, reconst_item) self.assertEqual(orig_item, reconst_item, fail_msg)
def test_non_cf_unit_with_calendar(self): # On passing as_unit a cf_unit.Unit-like object (not a cf_unit.Unit # object) with calendar, ensure that a cf_unit.Unit is returned # with the same calendar specified in the original unit-like object. unit = StubUnit('360_day') target = copy.copy(unit) result = as_unit(unit) self._assert_unit_equal(result, target)
def test_non_cf_unit_no_calendar(self): # On passing as_unit a cf_unit.Unit-like object (not a cf_unit.Unit # object) with no calendar, ensure that a cf_unit.Unit is returned # with default calendar (Gregorian). unit = StubUnit() result = as_unit(unit) self.assertEqual(result.calendar, "gregorian") self.assertIsInstance(result, Unit)
def test_cf_unit(self): # Ensure that as_unit returns the same cf_unit.Unit object and # remains unchanged. unit = Unit('hours since 1970-01-01 00:00:00', calendar='360_day') target = copy.copy(unit) result = as_unit(unit) self._assert_unit_equal(result, target) self.assertIs(result, unit)
def test_non_cf_unit_no_calendar(self): # On passing as_unit a cf_unit.Unit-like object (not a cf_unit.Unit # object) with no calendar, ensure that a cf_unit.Unit is returned # with default calendar (Gregorian). unit = StubUnit() target = copy.copy(unit) result = as_unit(unit) self.assertEqual(result.calendar, 'gregorian') self.assertIsInstance(result, Unit)
def test_default_units(self): # Note: using a CDL string as a test data reference, rather than a binary file. ref_cdl = """ netcdf cm_attr { dimensions: axv = 3 ; ayv = 2 ; variables: int64 qqv(ayv, axv) ; qqv:long_name = "qq" ; qqv:ancillary_variables = "my_av" ; qqv:cell_measures = "area: my_areas" ; int64 ayv(ayv) ; ayv:long_name = "y" ; int64 axv(axv) ; axv:units = "1" ; axv:long_name = "x" ; double my_av(axv) ; my_av:long_name = "refs" ; double my_areas(ayv, axv) ; my_areas:long_name = "areas" ; data: axv = 11, 12, 13; ayv = 21, 22; my_areas = 110., 120., 130., 221., 231., 241.; } """ nc_path = cdl_to_nc(ref_cdl) # Load with iris.fileformats.netcdf.load_cubes, and check expected content. cubes = list(load_cubes(nc_path)) self.assertEqual(len(cubes), 1) self.assertEqual(cubes[0].units, as_unit("unknown")) self.assertEqual(cubes[0].coord("y").units, as_unit("unknown")) self.assertEqual(cubes[0].coord("x").units, as_unit(1)) self.assertEqual(cubes[0].ancillary_variable("refs").units, as_unit("unknown")) self.assertEqual(cubes[0].cell_measure("areas").units, as_unit("unknown"))
def _get_CF_coordinate_units(coord): """ Return a CF compliant coordinate unit from a given Coord. Tries common units based on coordinate standard names if needed. :param coord: A data_io.Coord.Coord object :return: a valid cf_units.Unit :raises ValueError for invalid CF units (which can't be fixed) """ from cf_units import as_unit coordinate_unit_mappings = {'latitude': 'degrees_north', 'longitude': 'degrees_east'} try: coord_unit = as_unit(coord.units) except ValueError as e: if e.args[0].startswith('[UT_UNKNOWN]') and coord.standard_name in coordinate_unit_mappings: # For some common coordinates we can fix this... coord_unit = as_unit(coordinate_unit_mappings[coord.standard_name]) logging.warning("Converting units for {coord} from {old} to the CF-compliant units: {new}" .format(**{'coord': coord.standard_name, 'old': coord.units, 'new': coord_unit})) else: # Otherwise give up raise e return coord_unit
def get_attr_units(cf_var, attributes): attr_units = getattr(cf_var, CF_ATTR_UNITS, UNKNOWN_UNIT_STRING) if not attr_units: attr_units = UNKNOWN_UNIT_STRING # Sanitise lat/lon units. if attr_units in UD_UNITS_LAT or attr_units in UD_UNITS_LON: attr_units = "degrees" # Graceful loading of invalid units. try: cf_units.as_unit(attr_units) except ValueError: # Using converted unicode message. Can be reverted with Python 3. msg = "Ignoring netCDF variable {!r} invalid units {!r}".format( cf_var.cf_name, attr_units) warnings.warn(msg) attributes["invalid_units"] = attr_units attr_units = UNKNOWN_UNIT_STRING if np.issubdtype(cf_var.dtype, np.str_): attr_units = NO_UNIT_STRING if any( hasattr(cf_var.cf_data, name) for name in ("flag_values", "flag_masks", "flag_meanings")): attr_units = cf_units._NO_UNIT_STRING # Get any assoicated calendar for a time reference coordinate. if cf_units.as_unit(attr_units).is_time_reference(): attr_calendar = getattr(cf_var, CF_ATTR_CALENDAR, None) if attr_calendar: attr_units = cf_units.Unit(attr_units, calendar=attr_calendar) return attr_units
def hourly2daily(hourly_cube): ''' Aggregates the hourly precipitation cube into daily_cube :param iris.cube: hourly cube to be aggregated in daily ''' # raise exception is not only one year in a cube? icat.add_day_of_year(hourly_cube, 'time') hourly_cube.coord('time').bounds = None #print(hourly_cube.coord('day_of_year')) print(hourly_cube.coord('day_of_year').points[-80:]) print(hourly_cube.coord('day_of_year').points[:80]) #print(hourly_cube.coord('day_of_year').bounds) if hourly_cube.units in ['kg/m2/s', 'kg m-2 s-1', 'mm day-1', 'mm/day']: daily_data = hourly_cube.aggregated_by('day_of_year', iana.MEAN) elif hourly_cube.units in ['mm', 'mm/h', 'mm h-1', 'mm/3hr', 'mm hour-1']: print('summing hourly') daily_data = hourly_cube.aggregated_by('day_of_year', iana.SUM) daily_data.units = cf_units.as_unit('mm day-1') else: raise ValueError('wrong units: {}'.format(hourly_cube.units)) # daily_data.name = 'precipitation_rate' return daily_data
def units(self, unit): self._units = cf_units.as_unit(unit)
def test_known_unit_str(self): u_str = "m" expected = Unit("m") result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_already_unit(self): u = Unit("m") result = unit.as_unit(u) self.assertIs(result, u)
def test_no_unit_str(self): u_str = "no_unit" expected = Unit("no_unit") result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_unknown_str(self): u_str = "unknown" expected = Unit("unknown") result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_not_unit_str(self): u_str = "wibble" emsg = "Failed to parse unit" with self.assertRaisesRegex(ValueError, emsg): unit.as_unit(u_str)
def units(self, unit): self._metadata_manager.units = cf_units.as_unit(unit)
def test_no_unit_str(self): u_str = 'no_unit' expected = Unit('no_unit') result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_unknown_str(self): u_str = 'unknown' expected = Unit('unknown') result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_already_unit(self): u = Unit('m') result = unit.as_unit(u) self.assertIs(result, u)
def test_known_unit_str(self): u_str = 'm' expected = Unit('m') result = unit.as_unit(u_str) self.assertEqual(expected, result)
def test_not_unit_str(self): u_str = 'wibble' msg = 'Failed to parse unit' with self.assertRaisesRegexp(ValueError, msg): unit.as_unit(u_str)
def test_not_unit_str(self): u_str = 'wibble' emsg = 'Failed to parse unit' with six.assertRaisesRegex(self, ValueError, emsg): unit.as_unit(u_str)