def test_relative_vorticity_distance(self): x_min = 0.0 x_max = 100.0 dx = 1.0 x_1d = numpy.arange(x_min, x_max, dx) size = x_1d.size data_1d = x_1d * 2.0 + 1.0 data_2d = numpy.broadcast_to(data_1d[numpy.newaxis, :], (size, size)) dim_x = cf.DimensionCoordinate( data=cf.Data(x_1d, "m"), properties={"axis": "X"} ) dim_y = cf.DimensionCoordinate( data=cf.Data(x_1d, "m"), properties={"axis": "Y"} ) u = cf.Field() X = u.set_construct(cf.DomainAxis(size=dim_x.data.size)) Y = u.set_construct(cf.DomainAxis(size=dim_y.data.size)) u.set_construct(dim_x, axes=[X]) u.set_construct(dim_y, axes=[Y]) u.set_data(cf.Data(data_2d, "m/s"), axes=("Y", "X")) v = cf.Field() v.set_construct(cf.DomainAxis(size=dim_x.data.size)) v.set_construct(cf.DomainAxis(size=dim_y.data.size)) v.set_construct(dim_x, axes=[X]) v.set_construct(dim_y, axes=[Y]) v.set_data(cf.Data(data_2d, "m/s"), axes=("X", "Y")) rv = cf.relative_vorticity(u, v, one_sided_at_boundary=True) self.assertTrue((rv.array == 0.0).all())
def save_datasets(self, datasets, filename, **kwargs): """Save all datasets to one or more files) """ fields = [] shapes = {} for dataset in datasets: if dataset.shape in shapes: domain = shapes[dataset.shape] else: lines, pixels = dataset.shape # Create a grid_latitude dimension coordinate line_coord = cf.DimensionCoordinate( data=cf.Data(np.arange(lines), '1')) pixel_coord = cf.DimensionCoordinate( data=cf.Data(np.arange(pixels), '1')) domain = cf.Domain(dim={ 'lines': line_coord, 'pixels': pixel_coord }, ) shapes[dataset.shape] = domain data = cf.Data(dataset, dataset.info['units']) properties = {'standard_name': dataset.info['standard_name']} fields.append( cf.Field(properties=properties, data=data, axes=['lines', 'pixels'], domain=domain)) cf.write(fields, filename, fmt='NETCDF4')
def test_relative_vorticity_distance(self): if self.test_only and inspect.stack()[0][3] not in self.test_only: returncf x_min = 0.0 x_max = 100.0 dx = 1.0 x_1d = numpy.arange(x_min, x_max, dx) size = x_1d.size data_1d = x_1d * 2.0 + 1.0 data_2d = numpy.broadcast_to(data_1d[numpy.newaxis, :], (size, size)) dim_x = cf.DimensionCoordinate(data=cf.Data(x_1d, 'm'), properties={'axis': 'X'}) dim_y = cf.DimensionCoordinate(data=cf.Data(x_1d, 'm'), properties={'axis': 'Y'}) u = cf.Field() X = u.set_construct(cf.DomainAxis(size=dim_x.data.size)) Y = u.set_construct(cf.DomainAxis(size=dim_y.data.size)) u.set_construct(dim_x, axes=[X]) u.set_construct(dim_y, axes=[Y]) u.set_data(cf.Data(data_2d, 'm/s'), axes=('Y', 'X')) v = cf.Field() v.set_construct(cf.DomainAxis(size=dim_x.data.size)) v.set_construct(cf.DomainAxis(size=dim_y.data.size)) v.set_construct(dim_x, axes=[X]) v.set_construct(dim_y, axes=[Y]) v.set_data(cf.Data(data_2d, 'm/s'), axes=('X', 'Y')) rv = cf.relative_vorticity(u, v, one_sided_at_boundary=True) self.assertTrue((rv.array == 0.0).all())
def test_DimensionCoordinate_convert_reference_time(self): d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="gregorian")) self.assertTrue((d.array == [1.0, 2, 3]).all()) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31.0, 60.0, 91.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="gregorian"), cf.dt("2004-03-01 00:00:00", calendar="gregorian"), cf.dt("2004-04-01 00:00:00", calendar="gregorian"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="360_day")) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [30.0, 60.0, 90.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="360_day"), cf.dt("2004-03-01 00:00:00", calendar="360_day"), cf.dt("2004-04-01 00:00:00", calendar="360_day"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="noleap")) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31.0, 59.0, 90.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="noleap"), cf.dt("2004-03-01 00:00:00", calendar="noleap"), cf.dt("2004-04-01 00:00:00", calendar="noleap"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all())
def test_DimensionCoordinate_convert_reference_time(self): d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='gregorian')) self.assertTrue((d.array == [1., 2, 3]).all()) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31., 60., 91.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='gregorian'), cf.dt('2004-03-01 00:00:00', calendar='gregorian'), cf.dt('2004-04-01 00:00:00', calendar='gregorian') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='360_day')) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [30., 60., 90.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='360_day'), cf.dt('2004-03-01 00:00:00', calendar='360_day'), cf.dt('2004-04-01 00:00:00', calendar='360_day') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='noleap')) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31., 59., 90.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='noleap'), cf.dt('2004-03-01 00:00:00', calendar='noleap'), cf.dt('2004-04-01 00:00:00', calendar='noleap') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all())
def test_relative_vorticity_latlong(self): lat_min = -90.0 lat_max = 90.0 dlat = 1.0 lat_1d = numpy.arange(lat_min, lat_max, dlat) lat_size = lat_1d.size lon_min = 0.0 lon_max = 359.0 dlon = 1.0 lon_1d = numpy.arange(lon_min, lon_max, dlon) lon_size = lon_1d.size u_1d = lat_1d * 2.0 + 1.0 u_2d = numpy.broadcast_to(u_1d[numpy.newaxis, :], (lon_size, lat_size)) v_1d = lon_1d * 2.0 + 1.0 v_2d = numpy.broadcast_to(v_1d[:, numpy.newaxis], (lon_size, lat_size)) v_2d = v_2d * numpy.cos(lat_1d * numpy.pi / 180.0)[numpy.newaxis, :] rv_array = ( u_2d / cf.Data(6371229.0, "meters") * numpy.tan(lat_1d * numpy.pi / 180.0)[numpy.newaxis, :] ) dim_x = cf.DimensionCoordinate( data=cf.Data(lon_1d, "degrees_east"), properties={"axis": "X"} ) dim_y = cf.DimensionCoordinate( data=cf.Data(lat_1d, "degrees_north"), properties={"axis": "Y"} ) u = cf.Field() u.set_construct(cf.DomainAxis(size=lon_1d.size)) u.set_construct(cf.DomainAxis(size=lat_1d.size)) u.set_construct(dim_x) u.set_construct(dim_y) u.set_data(cf.Data(u_2d, "m/s"), axes=("X", "Y")) u.cyclic("X", period=360.0) v = cf.Field() v.set_construct(cf.DomainAxis(size=lon_1d.size)) v.set_construct(cf.DomainAxis(size=lat_1d.size)) v.set_construct(dim_x) v.set_construct(dim_y) v.set_data(cf.Data(v_2d, "m/s"), axes=("X", "Y")) v.cyclic("X", period=360.0) rv = cf.relative_vorticity(u, v, wrap=False) self.assertTrue(numpy.allclose(rv.array, rv_array))
def test_relative_vorticity_latlong(self): if self.test_only and inspect.stack()[0][3] not in self.test_only: return lat_min = -90.0 lat_max = 90.0 dlat = 1.0 lat_1d = numpy.arange(lat_min, lat_max, dlat) lat_size = lat_1d.size lon_min = 0.0 lon_max = 359.0 dlon = 1.0 lon_1d = numpy.arange(lon_min, lon_max, dlon) lon_size = lon_1d.size u_1d = lat_1d * 2.0 + 1.0 u_2d = numpy.broadcast_to(lat_1d[numpy.newaxis, :], (lon_size, lat_size)) v_1d = lon_1d * 2.0 + 1.0 v_2d = numpy.broadcast_to(lon_1d[:, numpy.newaxis], (lon_size, lat_size)) v_2d = v_2d * numpy.cos(lat_1d * numpy.pi / 180.0)[numpy.newaxis, :] rv_array = (u_2d / cf.Data(6371229.0, 'meters') * numpy.tan(lat_1d * numpy.pi / 180.0)[numpy.newaxis, :]) dim_x = cf.DimensionCoordinate(data=cf.Data(lon_1d, 'degrees_east'), properties={'axis': 'X'}) dim_y = cf.DimensionCoordinate(data=cf.Data(lat_1d, 'degrees_north'), properties={'axis': 'Y'}) u = cf.Field() u.set_construct(cf.DomainAxis(size=lon_1d.size)) u.set_construct(cf.DomainAxis(size=lat_1d.size)) u.set_construct(dim_x) u.set_construct(dim_y) u.set_data(cf.Data(u_2d, 'm/s'), axes=('X', 'Y')) u.cyclic('X', period=360.0) v = cf.Field() v.set_construct(cf.DomainAxis(size=lon_1d.size)) v.set_construct(cf.DomainAxis(size=lat_1d.size)) v.set_construct(dim_x) v.set_construct(dim_y) v.set_data(cf.Data(v_2d, 'm/s'), axes=('X', 'Y')) v.cyclic('X', period=360.0) rv = cf.relative_vorticity(u, v, wrap=True) self.assertTrue(numpy.allclose(rv.array, rv_array))
def test_write_reference_datetime(self): if self.test_only and inspect.stack()[0][3] not in self.test_only: return for reference_datetime in ("1751-2-3", "1492-12-30"): for chunksize in self.chunk_sizes: cf.chunksize(chunksize) f = cf.read(self.filename)[0] t = cf.DimensionCoordinate( data=cf.Data([123], "days since 1750-1-1")) t.standard_name = "time" axisT = f.set_construct(cf.DomainAxis(1)) f.set_construct(t, axes=[axisT]) cf.write( f, tmpfile, fmt="NETCDF4", reference_datetime=reference_datetime, ) g = cf.read(tmpfile)[0] t = g.dimension_coordinate("T") self.assertEqual( t.Units, cf.Units("days since " + reference_datetime), ("Units written were " + repr(t.Units.reftime) + " not " + repr(reference_datetime)), ) # --- End: for cf.chunksize(self.original_chunksize)
def test_write_reference_datetime(self): if self.test_only and inspect.stack()[0][3] not in self.test_only: return for reference_datetime in ('1751-2-3', '1492-12-30'): for chunksize in self.chunk_sizes: cf.chunksize(chunksize) f = cf.read(self.filename)[0] t = cf.DimensionCoordinate( data=cf.Data([123], 'days since 1750-1-1') ) t.standard_name = 'time' axisT = f.set_construct(cf.DomainAxis(1)) f.set_construct(t, axes=[axisT]) cf.write(f, tmpfile, fmt='NETCDF4', reference_datetime=reference_datetime) g = cf.read(tmpfile)[0] t = g.dimension_coordinate('T') self.assertEqual( t.Units, cf.Units('days since ' + reference_datetime), ('Units written were ' + repr(t.Units.reftime) + ' not ' + repr(reference_datetime))) # --- End: for cf.chunksize(self.original_chunksize)
def wrap_netcdf(year_o, yearpart_o, var_o, standard_name_o, units_o): var_shape = var_o.shape # Define Coordinaties start_date = (datetime.datetime(year_o, 1, 1) + datetime.timedelta(yearpart_o)).strftime('%Y-%m-%d') if var_shape[0] == 1: dim0 = cf.DimensionCoordinate(properties={'standard_name': 'time'}, data=cf.Data( 0., cf.Units('days since ' + start_date, calendar='standard'))) elif var_shape[0] == 240: nc_time = (86400.0 / count_time / divt) * np.arange(count_time * divt) dim0 = cf.DimensionCoordinate(properties={'standard_name': 'time'}, data=cf.Data( nc_time, cf.Units('seconds since ' + start_date + ' 0:3:0', calendar='standard'))) elif var_shape[0] == 241: nc_time = (86400.0 / count_time / divt) * np.arange(count_time * divt + 1) dim0 = cf.DimensionCoordinate(properties={'standard_name': 'time'}, data=cf.Data( nc_time, cf.Units('seconds since ' + start_date + ' 0:0:0', calendar='standard'))) dim1 = cf.DimensionCoordinate(data=cf.Data(latitude, 'degrees_north'), properties={'standard_name': 'latitude'}) dim2 = cf.DimensionCoordinate(data=cf.Data(longitude, 'degrees_east'), properties={'standard_name': 'longitude'}) # Define cf.Field then insert variable and coordinates f = cf.Field(properties={'standard_name': standard_name_o}) f.insert_dim(dim0) f.insert_dim(dim1) f.insert_dim(dim2) data = cf.Data(var_o, units_o) f.insert_data(data) return f
def setUp(self): self.filename = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'test_file.nc') dim1 = cf.DimensionCoordinate() dim1.standard_name = 'latitude' a = numpy.array( [-30, -23.5, -17.8123, -11.3345, -0.7, -0.2, 0, 0.2, 0.7, 11.30003, 17.8678678, 23.5, 30] ) dim1.set_data(cf.Data(a, 'degrees_north')) bounds = cf.Bounds() b = numpy.empty(a.shape + (2,)) b[:, 0] = a - 0.1 b[:, 1] = a + 0.1 bounds.set_data(cf.Data(b)) dim1.set_bounds(bounds) self.dim = dim1
def test_DimensionCoordinate_set_data(self): x = cf.DimensionCoordinate() y = x.set_data(cf.Data([1, 2, 3])) self.assertIsNone(y) self.assertTrue(x.has_data()) # Test inplace x.del_data() y = x.set_data(cf.Data([1, 2, 3]), inplace=False) self.assertIsInstance(y, cf.DimensionCoordinate) self.assertFalse(x.has_data()) self.assertTrue(y.has_data()) # Exceptions should be raised for 0-d and N-d (N>=2) data with self.assertRaises(Exception): y = x.set_data(cf.Data([[1, 2, 3]])) with self.assertRaises(Exception): y = x.set_data(cf.Data(1))
def _formula_terms(standard_name): """Return a field construct with a vertical CRS, its computed non- parametric coordinates, and the computed standard name.""" # field: air_temperature field = cf.Field() field.set_properties({"standard_name": "air_temperature", "units": "K"}) data = cf.Data([0, 1, 2], units="K", dtype="f8") # domain_axis: Z c = cf.DomainAxis() c.set_size(3) c.nc_set_dimension("z") axisZ = field.set_construct(c, key="domainaxis1", copy=False) field.set_data(data) # coordinate_reference: coordref = cf.CoordinateReference() coordref.coordinate_conversion.set_parameter( "standard_name", standard_name ) aux = cf.AuxiliaryCoordinate() aux.long_name = "Computed from parametric {} vertical coordinates".format( standard_name ) if standard_name == "atmosphere_ln_pressure_coordinate": computed_standard_name = "air_pressure" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([700, 500, 300], "hPa", dtype="f8") aux.set_data(data) bounds = cf.Bounds() data = cf.Data([[800, 600], [600, 400], [400, 200]], "hPa", dtype="f8") bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: p0 p0 = cf.DomainAncillary() p0.standard_name = ( "reference_air_pressure_for_atmosphere_vertical_coordinate" ) data = cf.Data(1000.0, units="hPa", dtype="f8") p0.set_data(data) p0_key = field.set_construct(p0, axes=(), copy=False) # domain_ancillary: Z lev = cf.DomainAncillary() lev.standard_name = standard_name data = -(aux.data / p0.data).log() lev.set_data(data) bounds = cf.Bounds() data = -(aux.bounds.data / p0.data).log() bounds.set_data(data) lev.set_bounds(bounds) lev_key = field.set_construct(lev, axes=axisZ, copy=False) # dimension_coordinate: Z levc = cf.DimensionCoordinate(source=lev) levc_key = field.set_construct(levc, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({levc_key}) coordref.coordinate_conversion.set_domain_ancillaries( {"p0": p0_key, "lev": lev_key} ) field.set_construct(coordref) elif standard_name == "atmosphere_sigma_coordinate": computed_standard_name = "air_pressure" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([700, 500, 300], "hPa", dtype="f8") aux.set_data(data) b = cf.Bounds() data = cf.Data([[800, 600], [600, 400], [400, 200]], "hPa", dtype="f8") b.set_data(data) aux.set_bounds(b) # domain_ancillary: ps ps = cf.DomainAncillary() ps.standard_name = "surface_air_pressure" data = cf.Data(1000, units="hPa", dtype="f8") ps.set_data(data) ps_key = field.set_construct(ps, axes=(), copy=False) # domain_ancillary: ptop ptop = cf.DomainAncillary() ptop.standard_name = "air_pressure_at_top_of_atmosphere_model" data = cf.Data(10, units="hPa", dtype="f8") ptop.set_data(data) ptop_key = field.set_construct(ptop, axes=(), copy=False) # domain_ancillary: sigma sigma = cf.DomainAncillary() sigma.standard_name = standard_name data = cf.Data([0.6969697, 0.49494949, 0.29292929]) sigma.set_data(data) b = cf.Bounds() data = cf.Data( [ [0.7979798, 0.5959596], [0.5959596, 0.39393939], [0.39393939, 0.19191919], ] ) b.set_data(data) sigma.set_bounds(b) sigma_key = field.set_construct(sigma, axes=axisZ, copy=False) # dimension_coordinate: sigma sigmac = cf.DimensionCoordinate(source=sigma) sigmac_key = field.set_construct(sigmac, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sigmac_key}) coordref.coordinate_conversion.set_domain_ancillaries( {"ptop": ptop_key, "ps": ps_key, "sigma": sigma_key} ) field.set_construct(coordref) elif standard_name == "atmosphere_hybrid_sigma_pressure_coordinate": computed_standard_name = "air_pressure" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([700, 500, 300], "hPa", dtype="f8") aux.set_data(data) bounds = cf.Bounds() data = cf.Data([[800, 600], [600, 400], [400, 200]], "hPa", dtype="f8") bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: ps ps = cf.DomainAncillary() ps.standard_name = "surface_air_pressure" data = cf.Data(1000, units="hPa", dtype="f8") ps.set_data(data) ps_key = field.set_construct(ps, axes=(), copy=False) # domain_ancillary: p0 p0 = cf.DomainAncillary() data = cf.Data(1000, units="hPa", dtype="f8") p0.set_data(data) p0_key = field.set_construct(p0, axes=(), copy=False) # domain_ancillary: a a = cf.DomainAncillary() data = cf.Data([0.6, 0.3, 0], dtype="f8") a.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.75, 0.45], [0.45, 0.15], [0.15, 0]]) bounds.set_data(data) a.set_bounds(bounds) a_key = field.set_construct(a, axes=axisZ, copy=False) # domain_ancillary: b b = cf.DomainAncillary() data = cf.Data([0.1, 0.2, 0.3], dtype="f8") b.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.05, 0.15], [0.15, 0.25], [0.25, 0.2]]) bounds.set_data(data) b.set_bounds(bounds) b_key = field.set_construct(b, axes=axisZ, copy=False) # dimension_coordinate: sigma sigma = cf.DimensionCoordinate() sigma.standard_name = standard_name data = cf.Data([0.6969697, 0.49494949, 0.29292929]) sigma.set_data(data) bounds = cf.Bounds() data = cf.Data( [ [0.7979798, 0.5959596], [0.5959596, 0.39393939], [0.39393939, 0.19191919], ] ) bounds.set_data(data) sigma.set_bounds(bounds) sigma_key = field.set_construct(sigma, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sigma_key}) coordref.coordinate_conversion.set_domain_ancillaries( {"p0": p0_key, "a": a_key, "b": b_key, "ps": ps_key} ) field.set_construct(coordref) elif standard_name == "atmosphere_sleve_coordinate": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([100, 200, 300], "m", dtype="f8") aux.set_data(data) bounds = cf.Bounds() data = cf.Data([[50, 150], [150, 250], [250, 350]], "m", dtype="f8") bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: ztop ztop = cf.DomainAncillary() ztop.standard_name = "altitude_at_top_of_atmosphere_model" data = cf.Data(1000, units="m", dtype="f8") ztop.set_data(data) ztop_key = field.set_construct(ztop, axes=(), copy=False) # domain_ancillary: zsurf1 zsurf1 = cf.DomainAncillary() data = cf.Data(90, units="m", dtype="f8") zsurf1.set_data(data) zsurf1_key = field.set_construct(zsurf1, axes=(), copy=False) # domain_ancillary: zsurf2 zsurf2 = cf.DomainAncillary() data = cf.Data(0.1, units="m", dtype="f8") zsurf2.set_data(data) zsurf2_key = field.set_construct(zsurf2, axes=(), copy=False) # domain_ancillary: b1 b1 = cf.DomainAncillary() data = cf.Data([0.05, 0.04, 0.03], dtype="f8") b1.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.055, 0.045], [0.045, 0.035], [0.035, 0.025]]) bounds.set_data(data) b1.set_bounds(bounds) b1_key = field.set_construct(b1, axes=axisZ, copy=False) # domain_ancillary: b2 b2 = cf.DomainAncillary() data = cf.Data([0.5, 0.4, 0.3]) b2.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.55, 0.45], [0.45, 0.35], [0.35, 0.25]]) bounds.set_data(data) b2.set_bounds(bounds) b2_key = field.set_construct(b2, axes=axisZ, copy=False) # domain_ancillary: a a = cf.DomainAncillary() data = cf.Data([0.09545, 0.19636, 0.29727]) a.set_data(data) bounds = cf.Bounds() data = cf.Data( [[0.044995, 0.145905], [0.145905, 0.246815], [0.246815, 0.347725]] ) bounds.set_data(data) a.set_bounds(bounds) a_key = field.set_construct(a, axes=axisZ, copy=False) # coordinate_reference: coordref.coordinate_conversion.set_domain_ancillaries( { "zsurf1": zsurf1_key, "a": a_key, "b1": b1_key, "b2": b2_key, "zsurf2": zsurf2_key, "ztop": ztop_key, } ) field.set_construct(coordref) elif standard_name == "ocean_sigma_coordinate": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([10, 20, 30], "m", dtype="f8") aux.set_data(data) bounds = cf.Bounds() data = cf.Data([[5, 15], [15, 25], [25, 35]], "m", dtype="f8") bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: eta eta = cf.DomainAncillary() eta.standard_name = "sea_surface_height_above_geoid" data = cf.Data(100.0, units="m") eta.set_data(data) eta_key = field.set_construct(eta, axes=(), copy=False) # domain_ancillary: sigma sigma = cf.DomainAncillary() sigma.standard_name = standard_name data = cf.Data([0.1, 0.08888888888888889, 0.07777777777777778]) sigma.set_data(data) bounds = cf.Bounds() data = cf.Data( [ [0.10555556, 0.09444444], [0.09444444, 0.08333333], [0.08333333, 0.07222222], ] ) bounds.set_data(data) sigma.set_bounds(bounds) sigma_key = field.set_construct(sigma, axes=axisZ, copy=False) # dimension_coordinate: sigma sigmac = cf.DimensionCoordinate(source=sigma) sigmac_key = field.set_construct(sigmac, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sigmac_key}) coordref.coordinate_conversion.set_domain_ancillaries( {"depth": depth_key, "eta": eta_key, "sigma": sigma_key} ) field.set_construct(coordref) elif standard_name == "ocean_s_coordinate": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([15.01701191, 31.86034296, 40.31150319], units="m") aux.set_data(data) bounds = cf.Bounds() data = cf.Data( [ [15.01701191, 23.42877638], [23.42877638, 31.86034296], [31.86034296, 40.31150319], ], units="m", ) bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: eta eta = cf.DomainAncillary() eta.standard_name = "sea_surface_height_above_geoid" data = cf.Data(100.0, units="m") eta.set_data(data) eta_key = field.set_construct(eta, axes=(), copy=False) # domain_ancillary: depth_c depth_c = cf.DomainAncillary() data = cf.Data(10.0, units="m") depth_c.set_data(data) depth_c_key = field.set_construct(depth_c, axes=(), copy=False) # domain_ancillary: a a = cf.DomainAncillary() data = cf.Data(0.5) a.set_data(data) a_key = field.set_construct(a, axes=(), copy=False) # domain_ancillary: b b = cf.DomainAncillary() data = cf.Data(0.75) b.set_data(data) b_key = field.set_construct(b, axes=(), copy=False) # domain_ancillary: s s = cf.DomainAncillary() s.standard_name = standard_name data = cf.Data([0.1, 0.08, 0.07]) s.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.10, 0.09], [0.09, 0.08], [0.08, 0.07]]) bounds.set_data(data) s.set_bounds(bounds) s_key = field.set_construct(s, axes=axisZ, copy=False) # dimension_coordinate: s sc = cf.DimensionCoordinate(source=s) sc_key = field.set_construct(sc, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sc_key}) coordref.coordinate_conversion.set_domain_ancillaries( { "depth": depth_key, "eta": eta_key, "depth_c": depth_c_key, "a": a_key, "b": b_key, "s": s_key, } ) field.set_construct(coordref) elif standard_name == "ocean_s_coordinate_g1": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([555.4, 464.32, 373.33], units="m") aux.set_data(data) bounds = cf.Bounds() data = cf.Data( [[600.85, 509.86], [509.86, 418.87], [418.87, 327.88]], units="m" ) bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: eta eta = cf.DomainAncillary() eta.standard_name = "sea_surface_height_above_geoid" data = cf.Data(100.0, units="m") eta.set_data(data) eta_key = field.set_construct(eta, axes=(), copy=False) # domain_ancillary: depth_c depth_c = cf.DomainAncillary() data = cf.Data(10.0, units="m") depth_c.set_data(data) depth_c_key = field.set_construct(depth_c, axes=(), copy=False) # domain_ancillary: C C = cf.DomainAncillary() data = cf.Data([-0.5, -0.4, -0.3]) C.set_data(data) bounds = cf.Bounds() data = cf.Data([[-0.55, -0.45], [-0.45, -0.35], [-0.35, -0.25]]) bounds.set_data(data) C.set_bounds(bounds) C_key = field.set_construct(C, axes=axisZ, copy=False) # domain_ancillary: s s = cf.DomainAncillary() s.standard_name = standard_name data = cf.Data([0.1, 0.08, 0.07]) s.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.10, 0.09], [0.09, 0.08], [0.08, 0.07]]) bounds.set_data(data) s.set_bounds(bounds) s_key = field.set_construct(s, axes=axisZ, copy=False) # dimension_coordinate: s sc = cf.DimensionCoordinate(source=s) sc_key = field.set_construct(sc, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sc_key}) coordref.coordinate_conversion.set_domain_ancillaries( { "depth": depth_key, "eta": eta_key, "depth_c": depth_c_key, "C": C_key, "s": s_key, } ) field.set_construct(coordref) elif standard_name == "ocean_s_coordinate_g2": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([555.45454545, 464.36363636, 373.36363636], units="m") aux.set_data(data) bounds = cf.Bounds() data = cf.Data( [ [600.90909091, 509.90909091], [509.90909091, 418.90909091], [418.90909091, 327.90909091], ], units="m", ) bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: eta eta = cf.DomainAncillary() eta.standard_name = "sea_surface_height_above_geoid" data = cf.Data(100.0, units="m") eta.set_data(data) eta_key = field.set_construct(eta, axes=(), copy=False) # domain_ancillary: depth_c depth_c = cf.DomainAncillary() data = cf.Data(10.0, units="m") depth_c.set_data(data) depth_c_key = field.set_construct(depth_c, axes=(), copy=False) # domain_ancillary: C C = cf.DomainAncillary() data = cf.Data([-0.5, -0.4, -0.3]) C.set_data(data) bounds = cf.Bounds() data = cf.Data([[-0.55, -0.45], [-0.45, -0.35], [-0.35, -0.25]]) bounds.set_data(data) C.set_bounds(bounds) C_key = field.set_construct(C, axes=axisZ, copy=False) # domain_ancillary: s s = cf.DomainAncillary() s.standard_name = standard_name data = cf.Data([0.1, 0.08, 0.07]) s.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.10, 0.09], [0.09, 0.08], [0.08, 0.07]]) bounds.set_data(data) s.set_bounds(bounds) s_key = field.set_construct(s, axes=axisZ, copy=False) # dimension_coordinate: s sc = cf.DimensionCoordinate(source=s) sc_key = field.set_construct(sc, axes=axisZ, copy=False) # coordinat # coordinate_reference: coordref.set_coordinates({sc_key}) coordref.coordinate_conversion.set_domain_ancillaries( { "depth": depth_key, "eta": eta_key, "depth_c": depth_c_key, "C": C_key, "s": s_key, } ) field.set_construct(coordref) elif standard_name == "ocean_sigma_z_coordinate": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data([10.0, 30.0, 40.0], "m", dtype="f8") aux.set_data(data) bounds = cf.Bounds() data = cf.Data( [[10.0, 19.0], [25.0, 35.0], [35.0, 45.0]], "m", dtype="f8" ) bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: eta eta = cf.DomainAncillary() eta.standard_name = "sea_surface_height_above_geoid" data = cf.Data(100.0, units="m") eta.set_data(data) eta_key = field.set_construct(eta, axes=(), copy=False) # domain_ancillary: depth_c depth_c = cf.DomainAncillary() data = cf.Data(10.0, units="m") depth_c.set_data(data) depth_c_key = field.set_construct(depth_c, axes=(), copy=False) # domain_ancillary: nsigma nsigma = cf.DomainAncillary() data = cf.Data(1) nsigma.set_data(data) nsigma_key = field.set_construct(nsigma, axes=(), copy=False) # domain_ancillary: zlev zlev = cf.DomainAncillary() zlev.standard_name = "altitude" data = cf.Data([20, 30, 40], units="m", dtype="f8") zlev.set_data(data) bounds = cf.Bounds() data = cf.Data([[15, 25], [25, 35], [35, 45]], units="m", dtype="f8") bounds.set_data(data) zlev.set_bounds(bounds) zlev_key = field.set_construct(zlev, axes=axisZ, copy=False) # domain_ancillary: sigma sigma = cf.DomainAncillary() sigma.standard_name = standard_name data = cf.Data([0.1, 0.08, 0.07]) sigma.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.10, 0.09], [0.09, 0.08], [0.08, 0.07]]) bounds.set_data(data) sigma.set_bounds(bounds) sigma_key = field.set_construct(sigma, axes=axisZ, copy=False) # dimension_coordinate: sigma sigmac = cf.DimensionCoordinate(source=sigma) sigmac_key = field.set_construct(sigmac, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sigmac_key}) coordref.coordinate_conversion.set_domain_ancillaries( { "depth": depth_key, "eta": eta_key, "depth_c": depth_c_key, "nsigma": nsigma_key, "zlev": zlev_key, "sigma": sigma_key, } ) field.set_construct(coordref) elif standard_name == "ocean_double_sigma_coordinate": computed_standard_name = "altitude" # Computed vertical corodinates aux.standard_name = computed_standard_name data = cf.Data( [0.15000000000000002, 0.12, 932.895], units="m", dtype="f8" ) aux.set_data(data) bounds = cf.Bounds() data = cf.Data( [ [1.50000e-01, 1.35000e-01], [1.35000e-01, 1.20000e-01], [9.22880e02, 9.32895e02], ], units="m", dtype="f8", ) bounds.set_data(data) aux.set_bounds(bounds) # domain_ancillary: depth depth = cf.DomainAncillary() depth.standard_name = "sea_floor_depth_below_geoid" data = cf.Data(-1000.0, units="m") depth.set_data(data) depth_key = field.set_construct(depth, axes=(), copy=False) # domain_ancillary: z1 z1 = cf.DomainAncillary() data = cf.Data(2, units="m") z1.set_data(data) z1_key = field.set_construct(z1, axes=(), copy=False) # domain_ancillary: z2 z2 = cf.DomainAncillary() data = cf.Data(1.5, units="m") z2.set_data(data) z2_key = field.set_construct(z2, axes=(), copy=False) # domain_ancillary: a a = cf.DomainAncillary() data = cf.Data(2.5, units="m") a.set_data(data) a_key = field.set_construct(a, axes=(), copy=False) # domain_ancillary: href href = cf.DomainAncillary() data = cf.Data(10.5, units="m") href.set_data(data) href_key = field.set_construct(href, axes=(), copy=False) # domain_ancillary: k_c k_c = cf.DomainAncillary() data = cf.Data(1) k_c.set_data(data) k_c_key = field.set_construct(k_c, axes=(), copy=False) # dimension_coordinate: sigma sigma = cf.DomainAncillary() sigma.standard_name = standard_name data = cf.Data([0.1, 0.08, 0.07]) sigma.set_data(data) bounds = cf.Bounds() data = cf.Data([[0.10, 0.09], [0.09, 0.08], [0.08, 0.07]]) bounds.set_data(data) sigma.set_bounds(bounds) sigma_key = field.set_construct(sigma, axes=axisZ, copy=False) # dimension_coordinate: sigma sigmac = cf.DimensionCoordinate(source=sigma) sigmac_key = field.set_construct(sigmac, axes=axisZ, copy=False) # coordinate_reference: coordref.set_coordinates({sigmac_key}) coordref.coordinate_conversion.set_domain_ancillaries( { "depth": depth_key, "a": a_key, "k_c": k_c_key, "z1": z1_key, "z2": z2_key, "href": href_key, "sigma": sigma_key, } ) field.set_construct(coordref) else: raise ValueError( "Bad standard name: {}, " "not an element of FormulaTerms.standard_names".format( standard_name ) ) return (field, aux, computed_standard_name)
glob.glob(path + '/wrfout_d01_' + str(year) + '-' + str(month) + '-' + str(day) + '*')) filelist = sorted(filelist) # read in using netCDF wrflist = [] for afile in filelist: wrflist.extend([Dataset(afile)]) # extract lat, lon, and height from wrffile lat = getvar(wrflist, "XLAT", meta=False)[:, 0] lon = getvar(wrflist, "XLONG", meta=False)[0, :] height = getvar(wrflist, "height", meta=False)[:, 0, 0] # patch dimensions x = cf.DimensionCoordinate(data=cf.Data(lon, units='degrees_east'), properties={'standard_name': 'longitude'}) x.axis = 'X' y = cf.DimensionCoordinate(data=cf.Data(lat, units='degrees_north'), properties={'standard_name': 'latitude'}) y.axis = 'Y' z = cf.DimensionCoordinate(data=cf.Data(height, units='m'), properties={'standard_name': 'height'}) z.axis = 'Z' # create list of all datetimes in cf format wrf_datetime_list = [] for index, item in enumerate(wrflist): wrf_datetime = cf.dt( datetime.datetime.strptime( str(getvar(wrflist[index], "Times", meta=False)), '%Y-%m-%dT%H:00:00.000000000')) wrf_datetime_list.extend([wrf_datetime])
def test_create_field(self): # Dimension coordinates dim1 = cf.DimensionCoordinate( data=cf.Data(numpy.arange(10.0), "degrees")) dim1.standard_name = "grid_latitude" dim0 = cf.DimensionCoordinate( data=cf.Data(numpy.arange(9.0) + 20, "degrees")) dim0.standard_name = "grid_longitude" dim0.data[-1] += 5 bounds = cf.Data( numpy.array([dim0.data.array - 0.5, dim0.data.array + 0.5]).transpose((1, 0))) bounds[-2, 1] = 30 bounds[-1, :] = [30, 36] dim0.set_bounds(cf.Bounds(data=bounds)) dim2 = cf.DimensionCoordinate( data=cf.Data([1.5]), bounds=cf.Bounds(data=cf.Data([[1, 2.0]]))) dim2.standard_name = "atmosphere_hybrid_height_coordinate" # Auxiliary coordinates ak = cf.DomainAncillary(data=cf.Data([10.0], "m")) ak.id = "atmosphere_hybrid_height_coordinate_ak" bounds = cf.Bounds(data=cf.Data([[5, 15.0]], units=ak.Units)) ak.set_bounds(bounds) bk = cf.DomainAncillary(data=cf.Data([20.0])) bk.id = "atmosphere_hybrid_height_coordinate_bk" bounds = cf.Bounds(data=cf.Data([[14, 26.0]])) bk.set_bounds(bounds) aux2 = cf.AuxiliaryCoordinate(data=cf.Data( numpy.arange(-45, 45, dtype="int32").reshape(10, 9), units="degree_N", )) aux2.standard_name = "latitude" aux3 = cf.AuxiliaryCoordinate(data=cf.Data( numpy.arange(60, 150, dtype="int32").reshape(9, 10), units="degreesE", )) aux3.standard_name = "longitude" aux4 = cf.AuxiliaryCoordinate(data=cf.Data( numpy.array( [ "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", ], dtype="S", ))) aux4.standard_name = "greek_letters" aux4[0] = cf.masked # Cell measures msr0 = cf.CellMeasure( data=cf.Data(1 + numpy.arange(90.0).reshape(9, 10) * 1234, "km 2")) msr0.measure = "area" # Data data = cf.Data(numpy.arange(90.0).reshape(10, 9), "m s-1") properties = {"standard_name": "eastward_wind"} f = cf.Field(properties=properties) axisX = f.set_construct(cf.DomainAxis(9)) axisY = f.set_construct(cf.DomainAxis(10)) axisZ = f.set_construct(cf.DomainAxis(1)) f.set_data(data) x = f.set_construct(dim0) y = f.set_construct(dim1, axes=[axisY]) z = f.set_construct(dim2, axes=[axisZ]) lat = f.set_construct(aux2) lon = f.set_construct(aux3, axes=["X", axisY]) f.set_construct(aux4, axes=["Y"]) ak = f.set_construct(ak, axes=["Z"]) bk = f.set_construct(bk, axes=[axisZ]) # Coordinate references coordinate_conversion = cf.CoordinateConversion( parameters={ "grid_mapping_name": "rotated_latitude_longitude", "grid_north_pole_latitude": 38.0, "grid_north_pole_longitude": 190.0, }) ref0 = cf.CoordinateReference( coordinate_conversion=coordinate_conversion, coordinates=[x, y, lat, lon], ) f.set_construct(msr0, axes=[axisX, "Y"]) f.set_construct(ref0) orog = cf.DomainAncillary() orog.standard_name = "surface_altitude" orog.set_data(cf.Data(f.array * 2, "m")) orog.transpose([1, 0], inplace=True) orog_key = f.set_construct(orog, axes=["X", axisY]) coordinate_conversion = cf.CoordinateConversion( parameters={ "standard_name": "atmosphere_hybrid_height_coordinate" }, domain_ancillaries={ "orog": orog_key, "a": ak, "b": bk }, ) ref1 = cf.CoordinateReference( coordinate_conversion=coordinate_conversion, coordinates=[z]) f.set_construct(ref1) # Field ancillary variables g = cf.FieldAncillary() g.set_data(f.data) g.transpose([1, 0], inplace=True) g.standard_name = "ancillary0" g *= 0.01 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f.data) g.standard_name = "ancillary1" g *= 0.01 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f[0, :].data) g.squeeze(inplace=True) g.standard_name = "ancillary2" g *= 0.001 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f[:, 0].data) g.squeeze(inplace=True) g.standard_name = "ancillary3" g *= 0.001 f.set_construct(g) f.flag_values = [1, 2, 4] f.flag_meanings = ["a", "bb", "ccc"] for cm in cf.CellMethod.create( "grid_longitude: mean grid_latitude: max"): f.set_construct(cm) # Write the file, and read it in cf.write(f, self.filename, verbose=0, string=True) g = cf.read(self.filename, squeeze=True, verbose=0)[0] self.assertTrue(g.equals(f, verbose=0), "Field not equal to itself read back in") x = g.dump(display=False) x = f.dump(display=False)
print(t.where(cf.gt(0.5), x=cf.masked, construct='grid_latitude').array) print("\n**Field creation**\n") print("\n**Stage 1:** The field construct is created without metadata\n") print("\n**Stage 2:** Metadata constructs are created independently.\n") print("\n**Stage 3:** The metadata constructs are inserted into the field\n") p = cf.Field(properties={'standard_name': 'precipitation_flux'}) p dc = cf.DimensionCoordinate(properties={'long_name': 'Longitude'}, data=cf.Data([0, 1, 2.])) dc fa = cf.FieldAncillary( properties={'standard_name': 'precipitation_flux status_flag'}, data=cf.Data(numpy.array([0, 0, 2], dtype='int8'))) fa p = cf.Field() p p.set_property('standard_name', 'precipitation_flux') p dc = cf.DimensionCoordinate() dc dc.set_property('long_name', 'Longitude') dc.set_data(cf.Data([1, 2, 3.])) dc fa = cf.FieldAncillary(
class DimensionCoordinateTest(unittest.TestCase): filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_file.nc') # f = cf.read(filename)[0] dim = cf.DimensionCoordinate() dim.standard_name = 'latitude' a = numpy.array([ -30, -23.5, -17.8123, -11.3345, -0.7, -0.2, 0, 0.2, 0.7, 11.30003, 17.8678678, 23.5, 30 ]) dim.set_data(cf.Data(a, 'degrees_north')) bounds = cf.Bounds() b = numpy.empty(a.shape + (2, )) b[:, 0] = a - 0.1 b[:, 1] = a + 0.1 bounds.set_data(cf.Data(b)) dim.set_bounds(bounds) def test_DimensionCoordinate__repr__str__dump(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() _ = repr(x) _ = str(x) _ = x.dump(display=False) def test_DimensionCoordinate_convert_reference_time(self): d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='gregorian')) self.assertTrue((d.array == [1., 2, 3]).all()) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31., 60., 91.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='gregorian'), cf.dt('2004-03-01 00:00:00', calendar='gregorian'), cf.dt('2004-04-01 00:00:00', calendar='gregorian') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='360_day')) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [30., 60., 90.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='360_day'), cf.dt('2004-03-01 00:00:00', calendar='360_day'), cf.dt('2004-04-01 00:00:00', calendar='360_day') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], 'months since 2004-1-1', calendar='noleap')) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31., 59., 90.]).all()) self.assertTrue((x.datetime_array == [ cf.dt('2004-02-01 00:00:00', calendar='noleap'), cf.dt('2004-03-01 00:00:00', calendar='noleap'), cf.dt('2004-04-01 00:00:00', calendar='noleap') ]).all()) self.assertTrue((d.array == [1., 2, 3]).all()) def test_DimensionCoordinate_roll(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() y = f.dimension_coordinates('Y').value() _ = x.roll(0, 3) with self.assertRaises(Exception): y.roll(0, 3) _ = x.roll(0, 3) _ = x.roll(-1, 3) with self.assertRaises(Exception): _ = x.roll(2, 3) a = x[0] _ = a.roll(0, 3) self.assertIsNone(a.roll(0, 3, inplace=True)) _ = x.roll(0, 0) _ = x.roll(0, 3, inplace=True) self.assertIsNone(x.roll(0, 0, inplace=True)) _ = x._centre(360) _ = x.flip()._centre(360) # Test roll on coordinate without bounds: g = f.copy() g.dimension_coordinate('X').del_bounds() for shift_by in [1, -1, g.shape[2]]: # vary roll direction and extent g_rolled = g.roll('X', shift=shift_by) if shift_by == g.shape[2]: # shift_by equal to the roll axis size g_rolled_0 = g.roll('X', shift=0) # A roll of the axes size, or 0, should not change the array: self.assertTrue((g_rolled.array == g.array).all()) self.assertTrue((g_rolled.array == g_rolled_0.array).all()) for index in range(0, 10): # check all elements are rolled self.assertEqual(g_rolled.array[0, index, 0], g.array[0, index, -shift_by]) def test_DimensionCoordinate_cellsize(self): d = self.dim.copy() c = d.cellsize self.assertTrue(numpy.allclose(c.array, 0.2)) self.assertTrue(d.Units.equals(cf.Units('degrees_north'))) self.assertTrue(d.bounds.Units.equals(cf.Units('degrees_north'))) d.override_units('km', inplace=True) self.assertTrue(d.Units.equals(cf.Units('km'))) self.assertTrue(d.bounds.Units.equals(cf.Units('km'))) c = d.cellsize self.assertTrue(c.Units.equals(cf.Units('km'))) d.del_bounds() c = d.cellsize self.assertTrue(numpy.allclose(c.array, 0)) def test_DimensionCoordinate_override_units(self): d = self.dim.copy() self.assertTrue(d.Units.equals(cf.Units('degrees_north'))) self.assertTrue(d.bounds.Units.equals(cf.Units('degrees_north'))) d.override_units('km', inplace=True) self.assertTrue(d.Units.equals(cf.Units('km'))) self.assertTrue(d.bounds.Units.equals(cf.Units('km'))) c = d.cellsize self.assertTrue(c.Units.equals(cf.Units('km'))) def test_DimensionCoordinate_override_calendar(self): d = self.dim.copy() self.assertTrue(d.Units.equals(cf.Units('degrees_north'))) self.assertTrue(d.bounds.Units.equals(cf.Units('degrees_north'))) d.override_units('days since 2000-01-01', inplace=True) self.assertTrue(d.Units.equals(cf.Units('days since 2000-01-01'))) self.assertTrue( d.bounds.Units.equals(cf.Units('days since 2000-01-01'))) d.override_calendar('360_day', inplace=True) self.assertTrue( d.Units.equals( cf.Units('days since 2000-01-01', calendar='360_day'))) self.assertTrue( d.bounds.Units.equals( cf.Units('days since 2000-01-01', calendar='360_day'))) d.override_calendar('365_day', inplace=True) self.assertTrue( d.Units.equals( cf.Units('days since 2000-01-01', calendar='365_day'))) self.assertTrue( d.bounds.Units.equals( cf.Units('days since 2000-01-01', calendar='365_day'))) def test_DimensionCoordinate_bounds(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() _ = x.upper_bounds _ = x.lower_bounds self.assertTrue(x.increasing) y = x.flip() self.assertTrue(y.decreasing) self.assertTrue(y.upper_bounds.equals(x.upper_bounds[::-1])) self.assertTrue(y.lower_bounds.equals(x.lower_bounds[::-1])) c = x.cellsize c = y.cellsize y.del_bounds() b = y.create_bounds() def test_DimensionCoordinate_properties(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() x.positive = 'up' self.assertEqual(x.positive, 'up') del x.positive x.axis = 'Z' self.assertEqual(x.axis, 'Z') del x.axis x.axis = 'T' self.assertEqual(x.ndim, 1) def test_DimensionCoordinate_insert_dimension(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() self.assertEqual(x.shape, (9, )) self.assertEqual(x.bounds.shape, (9, 2)) y = x.insert_dimension(0) self.assertEqual(y.shape, (1, 9)) self.assertEqual(y.bounds.shape, (1, 9, 2), y.bounds.shape) x.insert_dimension(-1, inplace=True) self.assertEqual(x.shape, (9, 1)) self.assertEqual(x.bounds.shape, (9, 1, 2), x.bounds.shape) def test_DimensionCoordinate_binary_operation(self): f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() d = x.array b = x.bounds.array d2 = numpy.expand_dims(d, -1) # -------------------------------------------------------- # Out-of-place addition # -------------------------------------------------------- c = x + 2 self.assertTrue((c.array == d + 2).all()) self.assertTrue((c.bounds.array == b + 2).all()) c = x + x self.assertTrue((c.array == d + d).all()) self.assertTrue((c.bounds.array == b + d2).all()) c = x + 2 self.assertTrue((c.array == d + 2).all()) self.assertTrue((c.bounds.array == b + 2).all()) self.assertTrue((x.array == d).all()) self.assertTrue((x.bounds.array == b).all()) # -------------------------------------------------------- # In-place addition # -------------------------------------------------------- x += 2 self.assertTrue((x.array == d + 2).all()) self.assertTrue((x.bounds.array == b + 2).all()) x += x self.assertTrue((x.array == (d + 2) * 2).all()) self.assertTrue((x.bounds.array == b + 2 + d2 + 2).all()) x += 2 self.assertTrue((x.array == (d + 2) * 2 + 2).all()) self.assertTrue((x.bounds.array == b + 2 + d2 + 2 + 2).all()) # -------------------------------------------------------- # Out-of-place addition (no bounds) # -------------------------------------------------------- f = cf.read(self.filename)[0] x = f.dimension_coordinates('X').value() x.del_bounds() self.assertFalse(x.has_bounds()) d = x.array c = x + 2 self.assertTrue((c.array == d + 2).all()) c = x + x self.assertTrue((c.array == d + d).all()) c = x + 2 self.assertTrue((c.array == d + 2).all()) self.assertTrue((x.array == d).all()) # -------------------------------------------------------- # In-place addition (no bounds) # -------------------------------------------------------- x += 2 self.assertTrue((x.array == d + 2).all()) x += x self.assertTrue((x.array == (d + 2) * 2).all()) x += 2 self.assertTrue((x.array == (d + 2) * 2 + 2).all()) def test_DimensionCoordinate_set_data(self): x = cf.DimensionCoordinate() y = x.set_data(cf.Data([1, 2, 3])) self.assertIsNone(y) self.assertTrue(x.has_data()) # Test inplace x.del_data() y = x.set_data(cf.Data([1, 2, 3]), inplace=False) self.assertIsInstance(y, cf.DimensionCoordinate) self.assertFalse(x.has_data()) self.assertTrue(y.has_data()) # Exceptions should be raised for 0-d and N-d (N>=2) data with self.assertRaises(Exception): y = x.set_data(cf.Data([[1, 2, 3]])) with self.assertRaises(Exception): y = x.set_data(cf.Data(1))
class DimensionCoordinateTest(unittest.TestCase): f = cf.example_field(1) dim = cf.DimensionCoordinate() dim.standard_name = "latitude" a = numpy.array([ -30, -23.5, -17.8123, -11.3345, -0.7, -0.2, 0, 0.2, 0.7, 11.30003, 17.8678678, 23.5, 30, ]) dim.set_data(cf.Data(a, "degrees_north")) bounds = cf.Bounds() b = numpy.empty(a.shape + (2, )) b[:, 0] = a - 0.1 b[:, 1] = a + 0.1 bounds.set_data(cf.Data(b)) dim.set_bounds(bounds) def test_DimensionCoordinate__repr__str__dump(self): x = self.f.dimension_coordinate("X") repr(x) str(x) x.dump(display=False) def test_DimensionCoordinate_convert_reference_time(self): d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="gregorian")) self.assertTrue((d.array == [1.0, 2, 3]).all()) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31.0, 60.0, 91.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="gregorian"), cf.dt("2004-03-01 00:00:00", calendar="gregorian"), cf.dt("2004-04-01 00:00:00", calendar="gregorian"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="360_day")) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [30.0, 60.0, 90.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="360_day"), cf.dt("2004-03-01 00:00:00", calendar="360_day"), cf.dt("2004-04-01 00:00:00", calendar="360_day"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all()) d = cf.DimensionCoordinate() d.set_data( cf.Data([1, 2, 3], "months since 2004-1-1", calendar="noleap")) e = d.copy() self.assertIsNone( e.convert_reference_time(calendar_months=True, inplace=True)) f = d.convert_reference_time(calendar_months=True) for x in (e, f): self.assertTrue((x.array == [31.0, 59.0, 90.0]).all()) self.assertTrue((x.datetime_array == [ cf.dt("2004-02-01 00:00:00", calendar="noleap"), cf.dt("2004-03-01 00:00:00", calendar="noleap"), cf.dt("2004-04-01 00:00:00", calendar="noleap"), ]).all()) self.assertTrue((d.array == [1.0, 2, 3]).all()) def test_DimensionCoordinate_roll(self): x = self.f.dimension_coordinate("X").copy() y = self.f.dimension_coordinate("Y") x.roll(0, 3) with self.assertRaises(Exception): y.roll(0, 3) x.roll(0, 3) x.roll(-1, 3) with self.assertRaises(Exception): x.roll(2, 3) a = x[0] a.roll(0, 3) self.assertIsNone(a.roll(0, 3, inplace=True)) x.roll(0, 0) x.roll(0, 3, inplace=True) self.assertIsNone(x.roll(0, 0, inplace=True)) x._centre(360) x.flip()._centre(360) # Test roll on coordinate without bounds: g = self.f.copy() g.dimension_coordinate("X").del_bounds() for shift_by in [1, -1, g.shape[2]]: # vary roll direction and extent g_rolled = g.roll("X", shift=shift_by) if shift_by == g.shape[2]: # shift_by equal to the roll axis size g_rolled_0 = g.roll("X", shift=0) # A roll of the axes size, or 0, should not change the array: self.assertTrue((g_rolled.array == g.array).all()) self.assertTrue((g_rolled.array == g_rolled_0.array).all()) for index in range(0, 10): # check all elements are rolled self.assertEqual(g_rolled.array[0, index, 0], g.array[0, index, -shift_by]) def test_DimensionCoordinate_cellsize(self): d = self.dim.copy() c = d.cellsize self.assertTrue(numpy.allclose(c.array, 0.2)) self.assertTrue(d.Units.equals(cf.Units("degrees_north"))) self.assertTrue(d.bounds.Units.equals(cf.Units("degrees_north"))) d.override_units("km", inplace=True) self.assertTrue(d.Units.equals(cf.Units("km"))) self.assertTrue(d.bounds.Units.equals(cf.Units("km"))) c = d.cellsize self.assertTrue(c.Units.equals(cf.Units("km"))) d.del_bounds() c = d.cellsize self.assertTrue(numpy.allclose(c.array, 0)) def test_DimensionCoordinate_override_units(self): d = self.dim.copy() self.assertTrue(d.Units.equals(cf.Units("degrees_north"))) self.assertTrue(d.bounds.Units.equals(cf.Units("degrees_north"))) d.override_units("km", inplace=True) self.assertTrue(d.Units.equals(cf.Units("km"))) self.assertTrue(d.bounds.Units.equals(cf.Units("km"))) c = d.cellsize self.assertTrue(c.Units.equals(cf.Units("km"))) def test_DimensionCoordinate_override_calendar(self): d = self.dim.copy() self.assertTrue(d.Units.equals(cf.Units("degrees_north"))) self.assertTrue(d.bounds.Units.equals(cf.Units("degrees_north"))) d.override_units("days since 2000-01-01", inplace=True) self.assertTrue(d.Units.equals(cf.Units("days since 2000-01-01"))) self.assertTrue( d.bounds.Units.equals(cf.Units("days since 2000-01-01"))) d.override_calendar("360_day", inplace=True) self.assertTrue( d.Units.equals( cf.Units("days since 2000-01-01", calendar="360_day"))) self.assertTrue( d.bounds.Units.equals( cf.Units("days since 2000-01-01", calendar="360_day"))) d.override_calendar("365_day", inplace=True) self.assertTrue( d.Units.equals( cf.Units("days since 2000-01-01", calendar="365_day"))) self.assertTrue( d.bounds.Units.equals( cf.Units("days since 2000-01-01", calendar="365_day"))) def test_DimensionCoordinate_bounds(self): x = self.f.dimension_coordinate("X") x.upper_bounds x.lower_bounds self.assertTrue(x.increasing) y = x.flip() self.assertTrue(y.decreasing) self.assertTrue(y.upper_bounds.equals(x.upper_bounds[::-1])) self.assertTrue(y.lower_bounds.equals(x.lower_bounds[::-1])) x.cellsize y.cellsize y.del_bounds() y.create_bounds() def test_DimensionCoordinate_properties(self): x = self.f.dimension_coordinate("X").copy() x.positive = "up" self.assertEqual(x.positive, "up") del x.positive x.axis = "Z" self.assertEqual(x.axis, "Z") del x.axis x.axis = "T" self.assertEqual(x.ndim, 1) def test_DimensionCoordinate_insert_dimension(self): x = self.f.dimension_coordinate("X").copy() self.assertEqual(x.shape, (9, )) self.assertEqual(x.bounds.shape, (9, 2)) y = x.insert_dimension(0) self.assertEqual(y.shape, (1, 9)) self.assertEqual(y.bounds.shape, (1, 9, 2), y.bounds.shape) x.insert_dimension(-1, inplace=True) self.assertEqual(x.shape, (9, 1)) self.assertEqual(x.bounds.shape, (9, 1, 2), x.bounds.shape) def test_DimensionCoordinate_unary_operation(self): d = self.dim self.assertLess(d.minimum(), 0) self.assertLess(d.bounds.minimum(), 0) d = abs(d) self.assertGreaterEqual(d.minimum(), 0, d.array) self.assertGreaterEqual(d.bounds.minimum(), 0, d.bounds.array) d = -d self.assertLess(d.minimum(), 0) self.assertLess(d.bounds.minimum(), 0) d = +d self.assertLess(d.minimum(), 0) self.assertLess(d.bounds.minimum(), 0) d.dtype = int d.bounds.dtype = int d = ~d def test_DimensionCoordinate_binary_operation(self): dim = self.dim c = dim.array b = dim.bounds.array c2 = numpy.expand_dims(c, -1) x = dim.copy() y = dim.copy() old = cf.bounds_combination_mode() # ------------------------------------------------------------ # Out-of-place addition # ------------------------------------------------------------ for value in ("AND", "NONE"): cf.bounds_combination_mode(value) z = x + 2 self.assertTrue((z.array == c + 2).all()) self.assertFalse(z.has_bounds()) for value in ("OR", "XOR"): cf.bounds_combination_mode(value) z = x + 2 self.assertTrue((z.array == c + 2).all()) self.assertTrue((z.bounds.array == b + 2).all()) for value in ("AND", "OR"): cf.bounds_combination_mode(value) z = x + y self.assertTrue((z.array == c + c).all()) self.assertTrue((z.bounds.array == b + b).all()) for value in ("XOR", "NONE"): cf.bounds_combination_mode(value) z = x + y self.assertTrue((z.array == c + c).all()) self.assertFalse(z.has_bounds()) x.del_bounds() for value in ("AND", "XOR", "OR", "NONE"): cf.bounds_combination_mode(value) z = x + 2 self.assertTrue((z.array == c + 2).all()) self.assertFalse(z.has_bounds()) for value in ("AND", "NONE"): cf.bounds_combination_mode(value) z = x + y self.assertTrue((z.array == c + c).all()) self.assertFalse(z.has_bounds()) for value in ("OR", "XOR"): cf.bounds_combination_mode(value) z = x + y self.assertTrue((z.array == c + c).all()) self.assertTrue((z.bounds.array == c2 + b).all()) # ------------------------------------------------------------ # In-place addition # ------------------------------------------------------------ for value in ("AND", "NONE"): cf.bounds_combination_mode(value) x = dim.copy() x += 2 self.assertTrue((x.array == c + 2).all()) self.assertFalse(x.has_bounds()) for value in ("OR", "XOR"): cf.bounds_combination_mode(value) x = dim.copy() x += 2 self.assertTrue((x.array == c + 2).all()) self.assertTrue((x.bounds.array == b + 2).all()) for value in ("AND", "OR"): cf.bounds_combination_mode(value) x = dim.copy() x += y self.assertTrue((x.array == c + c).all()) self.assertTrue((x.bounds.array == b + b).all()) for value in ("XOR", "NONE"): cf.bounds_combination_mode(value) x = dim.copy() x += y self.assertTrue((x.array == c + c).all()) self.assertFalse(x.has_bounds()) for value in ("XOR", "OR"): cf.bounds_combination_mode(value) x = dim.copy() x.del_bounds() x += y self.assertTrue((x.array == c + c).all()) self.assertTrue((x.bounds.array == c2 + b).all()) for value in ("AND", "NONE"): cf.bounds_combination_mode(value) x = dim.copy() x.del_bounds() x += y self.assertTrue((x.array == c + c).all()) self.assertFalse(x.has_bounds()) # ------------------------------------------------------------ # Reset constant # ------------------------------------------------------------ cf.bounds_combination_mode(old) def test_DimensionCoordinate_set_data(self): x = cf.DimensionCoordinate() y = x.set_data(cf.Data([1, 2, 3])) self.assertIsNone(y) self.assertTrue(x.has_data()) # Test inplace x.del_data() y = x.set_data(cf.Data([1, 2, 3]), inplace=False) self.assertIsInstance(y, cf.DimensionCoordinate) self.assertFalse(x.has_data()) self.assertTrue(y.has_data()) # Exceptions should be raised for 0-d and N-d (N>=2) data with self.assertRaises(Exception): y = x.set_data(cf.Data([[1, 2, 3]])) with self.assertRaises(Exception): y = x.set_data(cf.Data(1)) def test_DimensionCoordinate__setitem__(self): d = self.dim.copy() d.array d.bounds.array d[...] = 999 self.assertTrue(d.bounds.equals(self.dim.bounds, verbose=3)) d = self.dim.copy() e = self.dim.copy() d[...] = -e self.assertTrue(d.data.equals(-e.data, verbose=3)) self.assertTrue(d.bounds.equals(-e.bounds, verbose=3)) d = self.dim.copy() e = self.dim.copy() e.del_bounds() d[...] = -e self.assertTrue(d.data.equals(-e.data, verbose=3)) self.assertTrue(d.bounds.equals(self.dim.bounds, verbose=3))
def test_create_field(self): # Dimension coordinates dim1 = cf.DimensionCoordinate( data=cf.Data(numpy.arange(10.), 'degrees')) dim1.standard_name = 'grid_latitude' dim0 = cf.DimensionCoordinate( data=cf.Data(numpy.arange(9.) + 20, 'degrees')) dim0.standard_name = 'grid_longitude' dim0.data[-1] += 5 bounds = cf.Data(numpy.array( [dim0.data.array-0.5, dim0.data.array+0.5]).transpose((1, 0))) bounds[-2, 1] = 30 bounds[-1, :] = [30, 36] dim0.set_bounds(cf.Bounds(data=bounds)) dim2 = cf.DimensionCoordinate( data=cf.Data([1.5]), bounds=cf.Bounds(data=cf.Data([[1, 2.]])) ) dim2.standard_name = 'atmosphere_hybrid_height_coordinate' # Auxiliary coordinates ak = cf.DomainAncillary(data=cf.Data([10.], 'm')) ak.id = 'atmosphere_hybrid_height_coordinate_ak' bounds = cf.Bounds(data=cf.Data([[5, 15.]], units=ak.Units)) ak.set_bounds(bounds) bk = cf.DomainAncillary(data=cf.Data([20.])) bk.id = 'atmosphere_hybrid_height_coordinate_bk' bounds = cf.Bounds(data=cf.Data([[14, 26.]])) bk.set_bounds(bounds) aux2 = cf.AuxiliaryCoordinate( data=cf.Data(numpy.arange(-45, 45, dtype='int32').reshape(10, 9), units='degree_N')) aux2.standard_name = 'latitude' aux3 = cf.AuxiliaryCoordinate( data=cf.Data(numpy.arange(60, 150, dtype='int32').reshape(9, 10), units='degreesE')) aux3.standard_name = 'longitude' aux4 = cf.AuxiliaryCoordinate( data=cf.Data(numpy.array( ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa'], dtype='S' )) ) aux4.standard_name = 'greek_letters' aux4[0] = cf.masked # Cell measures msr0 = cf.CellMeasure( data=cf.Data(1+numpy.arange(90.).reshape(9, 10)*1234, 'km 2')) msr0.measure = 'area' # Data data = cf.Data(numpy.arange(90.).reshape(10, 9), 'm s-1') properties = {'standard_name': 'eastward_wind'} f = cf.Field(properties=properties) axisX = f.set_construct(cf.DomainAxis(9)) axisY = f.set_construct(cf.DomainAxis(10)) axisZ = f.set_construct(cf.DomainAxis(1)) f.set_data(data) x = f.set_construct(dim0) y = f.set_construct(dim1, axes=[axisY]) z = f.set_construct(dim2, axes=[axisZ]) lat = f.set_construct(aux2) lon = f.set_construct(aux3, axes=['X', axisY]) f.set_construct(aux4, axes=['Y']) ak = f.set_construct(ak, axes=['Z']) bk = f.set_construct(bk, axes=[axisZ]) # Coordinate references coordinate_conversion = cf.CoordinateConversion( parameters={'grid_mapping_name': 'rotated_latitude_longitude', 'grid_north_pole_latitude': 38.0, 'grid_north_pole_longitude': 190.0}) ref0 = cf.CoordinateReference( coordinate_conversion=coordinate_conversion, coordinates=[x, y, lat, lon] ) f.set_construct(msr0, axes=[axisX, 'Y']) f.set_construct(ref0) orog = cf.DomainAncillary() orog.standard_name = 'surface_altitude' orog.set_data(cf.Data(f.array*2, 'm')) orog.transpose([1, 0], inplace=True) orog_key = f.set_construct(orog, axes=['X', axisY]) coordinate_conversion = cf.CoordinateConversion( parameters={ 'standard_name': 'atmosphere_hybrid_height_coordinate' }, domain_ancillaries={ 'orog': orog_key, 'a': ak, 'b': bk } ) ref1 = cf.CoordinateReference( coordinate_conversion=coordinate_conversion, coordinates=[z]) f.set_construct(ref1) # Field ancillary variables g = cf.FieldAncillary() g.set_data(f.data) g.transpose([1, 0], inplace=True) g.standard_name = 'ancillary0' g *= 0.01 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f.data) g.standard_name = 'ancillary1' g *= 0.01 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f[0, :].data) g.squeeze(inplace=True) g.standard_name = 'ancillary2' g *= 0.001 f.set_construct(g) g = cf.FieldAncillary() g.set_data(f[:, 0].data) g.squeeze(inplace=True) g.standard_name = 'ancillary3' g *= 0.001 f.set_construct(g) f.flag_values = [1, 2, 4] f.flag_meanings = ['a', 'bb', 'ccc'] for cm in cf.CellMethod.create( 'grid_longitude: mean grid_latitude: max'): f.set_construct(cm) # Write the file, and read it in cf.write(f, self.filename, verbose=0, string=True) g = cf.read(self.filename, squeeze=True, verbose=0)[0] self.assertTrue(g.equals(f, verbose=0), "Field not equal to itself read back in") x = g.dump(display=False) x = f.dump(display=False)
def create(dat): """creates cf-python Field object :param dict dat: calpost_reader generated dict of data :return: cf.Field """ v = cf.Field( properties={ 'standard_name': 'mass_concentration_of_methane_in_air', 'units': 'kg m-3', }) v.set_data(dat['v'] / 1000) v.nc_set_variable('methane') if len(dat['v'].shape) == 4: nt, nz, ny, nx = dat['v'].shape has_z = True print(nt, nz, ny, nx) else: nt, ny, nx = dat['v'].shape has_z = False print('a') domain_axisT = cf.DomainAxis(nt) domain_axisT.nc_set_unlimited(True) domain_axisY = cf.DomainAxis(ny) domain_axisX = cf.DomainAxis(nx) domain_axisT.nc_set_dimension('time') domain_axisY.nc_set_dimension('y') domain_axisX.nc_set_dimension('x') axisT = v.set_construct(domain_axisT) axisY = v.set_construct(domain_axisY) axisX = v.set_construct(domain_axisX) if has_z: domain_axisZ = cf.DomainAxis(nz) domain_axisZ.nc_set_dimension('z') axisZ = v.set_construct(domain_axisZ) print(type(domain_axisY)) print(dir(domain_axisY)) print(domain_axisY.identity()) print('b') x = dat['x'] y = dat['y'] dimX = cf.DimensionCoordinate(data=x * 1000, properties={ 'standard_name': 'projection_x_coordinate', 'units': 'meters' }) dimY = cf.DimensionCoordinate(data=y * 1000, properties={ 'standard_name': 'projection_y_coordinate', 'units': 'meters' }) dimT = cf.DimensionCoordinate(data=dat['ts'], ) dimT.nc_set_variable('time') dimY.nc_set_variable('y') dimX.nc_set_variable('x') if has_z: z = dat['z'] dimZ = cf.DimensionCoordinate(data=z, properties={ 'standard_name': 'height', 'units': 'meters' }) dimZ.nc_set_variable('z') print('c') dim_t = v.set_construct(dimT, axes=domain_axisT.identity()) dim_y = v.set_construct(dimY, axes=domain_axisY.identity()) dim_x = v.set_construct(dimX, axes=domain_axisX.identity()) if has_z: v.set_construct(dimZ, axes=domain_axisZ.identity()) print('d') if has_z: v.set_data_axes([axisT, axisZ, axisY, axisX]) else: v.set_data_axes([axisT, axisY, axisX]) datum = cf.Datum(parameters={'earth_radius': 637000.0}) coordinate_conversion_h = cf.CoordinateConversion( parameters={ 'grid_mapping_name': 'lambert_conformal_conic', 'standard_parallel': (38.5, 38.5), 'longitude_of_central_meridian': -97.5, 'latitude_of_projection_origin': 38.5, }) horizontal_crs = cf.CoordinateReference( datum=datum, coordinate_conversion=coordinate_conversion_h, coordinates=[dim_x, dim_y]) v.set_construct(horizontal_crs) return v
g = q.where(q <= p45, cf.masked) print(g.array) print(g.collapse('X: mean', weights=True).array) bins = q.percentile([0, 10, 50, 90, 100], squeeze=True) print(bins.array) i = q.digitize(bins, closed_ends=True) print(i.array) a = cf.read('air_temperature.nc')[0] b = cf.read('precipitation_flux.nc')[0] print(a) print(b) c = a.regrids(b, 'conservative') print(c) import numpy lat = cf.DimensionCoordinate( data=cf.Data(numpy.arange(-90, 92.5, 2.5), 'degrees_north')) lon = cf.DimensionCoordinate( data=cf.Data(numpy.arange(0, 360, 5.0), 'degrees_east')) c = a.regrids({'latitude': lat, 'longitude': lon}, 'linear') time = cf.DimensionCoordinate() time.standard_name = 'time' time.set_data( cf.Data(numpy.arange(0.5, 60, 1), units='days since 1860-01-01', calendar='360_day')) time c = a.regridc({'T': time}, axes='T', method='linear') try: c = a.regridc({'T': time}, axes='T', method='conservative') # Raises Exception except:
u = t.where(cf.lt(273.15), x=0, y=1) print(u.array) print(t.where(u, x=-t, y=-99).array) print(t.where(cf.gt(0.5), x=cf.masked, construct='grid_latitude').array) print("\n**Field creation**\n") print("\n**Stage 1:** The field construct is created without metadata\n") print("\n**Stage 2:** Metadata constructs are created independently.\n") print("\n**Stage 3:** The metadata constructs are inserted into the field\n") p = cf.Field(properties={'standard_name': 'precipitation_flux'}) p dc = cf.DimensionCoordinate(properties={'long_name': 'Longitude'}, data=cf.Data([0, 1, 2.])) dc fa = cf.FieldAncillary( properties={'standard_name': 'precipitation_flux status_flag'}, data=cf.Data(numpy.array([0, 0, 2], dtype='int8'))) fa p = cf.Field() p p.set_property('standard_name', 'precipitation_flux') p dc = cf.DimensionCoordinate() dc dc.set_property('long_name', 'Longitude') dc.set_data(cf.Data([1, 2, 3.])) dc fa = cf.FieldAncillary(data=cf.Data(numpy.array([0, 0, 2], dtype='int8')))
def save_datasets(self, datasets, filename, **kwargs): """Save all datasets to one or more files.""" LOG.info('Saving datasets to NetCDF4/CF.') fields = [] shapes = {} for dataset in datasets: if dataset.shape in shapes: domain = shapes[dataset.shape] else: lines, pixels = dataset.shape area = dataset.info.get('area') add_time = False try: # Create a longitude auxiliary coordinate lat = cf.AuxiliaryCoordinate( data=cf.Data(area.lats, 'degrees_north')) lat.standard_name = 'latitude' # Create a latitude auxiliary coordinate lon = cf.AuxiliaryCoordinate( data=cf.Data(area.lons, 'degrees_east')) lon.standard_name = 'longitude' aux = [lat, lon] add_time = True except AttributeError: LOG.info('No longitude and latitude data to save.') aux = None try: grid_mapping = create_grid_mapping(area) units = area.proj_dict.get('units', 'm') line_coord = cf.DimensionCoordinate( data=cf.Data(area.proj_y_coords, units)) line_coord.standard_name = "projection_y_coordinate" pixel_coord = cf.DimensionCoordinate( data=cf.Data(area.proj_x_coords, units)) pixel_coord.standard_name = "projection_x_coordinate" add_time = True except (AttributeError, NotImplementedError): LOG.info('No grid mapping to save.') grid_mapping = None line_coord = cf.DimensionCoordinate( data=cf.Data(np.arange(lines), '1')) line_coord.standard_name = "line" pixel_coord = cf.DimensionCoordinate( data=cf.Data(np.arange(pixels), '1')) pixel_coord.standard_name = "pixel" start_time = cf.dt(dataset.info['start_time']) end_time = cf.dt(dataset.info['end_time']) middle_time = cf.dt((dataset.info['end_time'] - dataset.info['start_time']) / 2 + dataset.info['start_time']) # import ipdb # ipdb.set_trace() if add_time: info = dataset.info dataset = dataset[np.newaxis, :, :] dataset.info = info bounds = cf.CoordinateBounds( data=cf.Data([start_time, end_time], cf.Units('days since 1970-1-1'))) time_coord = cf.DimensionCoordinate( properties=dict(standard_name='time'), data=cf.Data(middle_time, cf.Units('days since 1970-1-1')), bounds=bounds) coords = [time_coord, line_coord, pixel_coord] else: coords = [line_coord, pixel_coord] domain = cf.Domain(dim=coords, aux=aux, ref=grid_mapping) shapes[dataset.shape] = domain data = cf.Data(dataset, dataset.info.get('units', 'm')) # import ipdb # ipdb.set_trace() wanted_keys = ['standard_name', 'long_name'] properties = { k: dataset.info[k] for k in set(wanted_keys) & set(dataset.info.keys()) } new_field = cf.Field(properties=properties, data=data, domain=domain) new_field._FillValue = dataset.fill_value try: new_field.valid_range = dataset.info['valid_range'] except KeyError: new_field.valid_range = new_field.min(), new_field.max() new_field.Conventions = 'CF-1.7' fields.append(new_field) fields[0].history = ("Created by pytroll/satpy on " + str(datetime.utcnow())) flist = cf.FieldList(fields) cf.write(flist, filename, fmt='NETCDF4', compress=6)