def _add_available_aux_coords(self, cube, filenames): from iris.aux_factory import HybridPressureFactory from iris.coords import AuxCoord from iris.exceptions import CoordinateNotFoundError import iris if cube.coords('hybrid A coefficient at layer midpoints'): # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa cube.coord('hybrid A coefficient at layer midpoints').convert_units('hPa') try: surface_pressure = cube.coord('surface pressure') except iris.exceptions.CoordinateNotFoundError as e: # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level with demote_warnings(): surface_pressure_cubes = iris.load(filenames, 'atmospheric pressure at interfaces', callback=self.load_multiple_files_callback) surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:, -1, :, :] surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) surface_pressure.convert_units('hPa') if len(cube.coords(long_name='hybrid level at layer midpoints')) > 0: cube.add_aux_factory(HybridPressureFactory(delta=cube.coord('hybrid A coefficient at layer midpoints'), sigma=cube.coord('hybrid B coefficient at layer midpoints'), surface_air_pressure=surface_pressure))
def test_preserves_lazy(self): test_bounds = np.array([[[11.0, 12.0], [12.0, 13.0], [13.0, 14.0]], [[21.0, 22.0], [22.0, 23.0], [23.0, 24.0]]]) test_points = np.array([[11.1, 12.2, 13.3], [21.4, 22.5, 23.6]]) lazy_points = as_lazy_data(test_points) lazy_bounds = as_lazy_data(test_bounds) coord = AuxCoord(points=lazy_points, bounds=lazy_bounds, units='m') coord.convert_units('ft') self.assertTrue(coord.has_lazy_points()) self.assertTrue(coord.has_lazy_bounds()) test_points_ft = Unit('m').convert(test_points, 'ft') test_bounds_ft = Unit('m').convert(test_bounds, 'ft') self.assertArrayAllClose(coord.points, test_points_ft) self.assertArrayAllClose(coord.bounds, test_bounds_ft)
def _add_available_aux_coords(self, cube, filenames): import iris from iris.aux_factory import HybridPressureFactory from iris.coords import AuxCoord from iris.exceptions import CoordinateNotFoundError # Only do this for fields with a vertical component - this check is a bit hacky though (doesn't consider 3D with no time...) if cube.ndim == 4: # Only read the first file for these coefficients as they are time-independant and iris won't merge them hybrid_a = _get_cubes(filenames, 'hybrid A coefficient at layer midpoints') hybrid_b = _get_cubes(filenames, 'hybrid B coefficient at layer midpoints') hybrid_a_coord = AuxCoord(points=hybrid_a[0].data, long_name='hybrid A coefficient at layer midpoints', units='Pa') hybrid_b_coord = AuxCoord(points=hybrid_b[0].data, long_name='hybrid B coefficient at layer midpoints', units='1') if cube.coords('surface pressure'): surface_pressure = cube.coord('surface pressure') else: try: # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level surface_pressure_cubes = _get_cubes(filenames, 'atmospheric pressure at interfaces', callback=self.load_multiple_files_callback) surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:,-1,:,:] surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) except ValueError: # Try and get it from the vphysc stream v_files = ['_'.join(f.split('_')[:-1]) + '_vphysc.nc' for f in filenames] try: surface_pressure_cubes = _get_cubes(v_files, 'atmospheric pressure at interfaces', callback=self.load_multiple_files_callback) except: # If we can't do that then just exit - there must be a cleaner way to do this... return surface_pressure_cube = surface_pressure_cubes.concatenate_cube()[:,-1,:,:] surface_pressure = AuxCoord(points=surface_pressure_cube.data, long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa hybrid_a_coord.convert_units('hPa') surface_pressure.convert_units('hPa') cube.add_aux_coord(hybrid_a_coord, (1,)) cube.add_aux_coord(hybrid_b_coord, (1,)) if len(cube.coords(long_name='hybrid level at layer midpoints')) > 0: cube.add_aux_factory(HybridPressureFactory(delta=hybrid_a_coord, sigma=hybrid_b_coord, surface_air_pressure=surface_pressure))
def _add_available_aux_coords(self, cube, filenames): from iris.aux_factory import HybridPressureFactory from iris.coords import AuxCoord from cis.data_io.netcdf import read ps_filenames = [ f.replace('concbc', 'ps_TL95L80_192x48NH_3hr') for f in filenames ] # These will be the same for all files hybrid_a = read(ps_filenames[0], 'a')['a'] hybrid_b = read(ps_filenames[0], 'b')['b'] hybrid_a_coord = AuxCoord( points=hybrid_a[:], long_name='vertical coordinate formula term: a(k)', units='Pa') hybrid_b_coord = AuxCoord( points=hybrid_b[:], long_name='vertical coordinate formula term: b(k)', units='1') # This needs to be from each file and then merged surface_pressure_cube = _get_cubes( ps_filenames, 'ps', callback=self.load_multiple_files_callback).concatenate_cube() surface_pressure = AuxCoord(points=surface_pressure_cube.data, standard_name='surface_air_pressure', long_name='surface pressure', units='Pa') # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa hybrid_a_coord.convert_units('hPa') surface_pressure.convert_units('hPa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) cube.add_aux_coord(hybrid_a_coord, (1, )) cube.add_aux_coord(hybrid_b_coord, (1, )) cube.add_aux_factory( HybridPressureFactory(delta=hybrid_a_coord, sigma=hybrid_b_coord, surface_air_pressure=surface_pressure))
def _add_available_aux_coords(self, cube, filenames): import iris from iris.aux_factory import HybridPressureFactory from iris.coords import AuxCoord from iris.exceptions import CoordinateNotFoundError # Only do this for fields with a vertical component - this check is a bit hacky though (doesn't consider 3D with no time...) if cube.ndim == 4: # Only read the first file for these coefficients as they are time-independant and iris won't merge them hybrid_a = _get_cubes(filenames, 'hybrid A coefficient at layer midpoints') hybrid_b = _get_cubes(filenames, 'hybrid B coefficient at layer midpoints') hybrid_a_coord = AuxCoord( points=hybrid_a[0].data, long_name='hybrid A coefficient at layer midpoints', units='Pa', var_name='hyam') hybrid_b_coord = AuxCoord( points=hybrid_b[0].data, long_name='hybrid B coefficient at layer midpoints', units='1', var_name='hybm') if cube.coords('surface pressure'): surface_pressure = cube.coord('surface pressure') elif cube.coords('surface_air_pressure'): surface_pressure = cube.coord('surface_air_pressure') else: try: # If there isn't a surface pressure coordinate we can try loading it manually surface_pressure_cube = _get_cubes( filenames, 'surface_air_pressure', callback=self.load_multiple_files_callback ).concatenate_cube() surface_pressure = AuxCoord( points=surface_pressure_cube.data, standard_name='surface_air_pressure', long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) except ValueError: try: # If there isn't a surface pressure coordinate we can try and pull out the lowest pressure level surface_pressure_cubes = _get_cubes( filenames, 'atmospheric pressure at interfaces', callback=self.load_multiple_files_callback) surface_pressure_cube = surface_pressure_cubes.concatenate_cube( )[:, -1, :, :] surface_pressure = AuxCoord( points=surface_pressure_cube.data, long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) except ValueError: # Try and get it from the vphysc stream v_files = [ '_'.join(f.split('_')[:-1]) + '_vphyscm.nc' for f in filenames ] try: surface_pressure_cubes = _get_cubes( v_files, 'atmospheric pressure at interfaces', callback=self.load_multiple_files_callback) except: # If we can't do that then just exit - there must be a cleaner way to do this... return surface_pressure_cube = surface_pressure_cubes.concatenate_cube( )[:, -1, :, :] surface_pressure = AuxCoord( points=surface_pressure_cube.data, long_name='surface pressure', units='Pa') cube.add_aux_coord(surface_pressure, (0, 2, 3)) # First convert the hybrid coefficients to hPa, so that air pressure will be in hPa hybrid_a_coord.convert_units('hPa') surface_pressure.convert_units('hPa') cube.add_aux_coord(hybrid_a_coord, (1, )) cube.add_aux_coord(hybrid_b_coord, (1, )) if len(cube.coords( long_name='hybrid level at layer midpoints')) > 0: cube.add_aux_factory( HybridPressureFactory( delta=hybrid_a_coord, sigma=hybrid_b_coord, surface_air_pressure=surface_pressure))
def create_data_object(self, filenames, variable): logging.debug("Creating data object for variable " + variable) variables = [("ER2_IMU/Longitude", "x"), ("ER2_IMU/Latitude", "y"), ("ER2_IMU/gps_time", "t"), ("State/Pressure", "p"), ("DataProducts/Altitude", "z"), ("header/date", ""), (variable, '')] logging.info("Listing coordinates: " + str(variables)) var_data = read_many_files_individually(filenames, [v[0] for v in variables]) date_times = [] for times, date in zip(var_data['ER2_IMU/gps_time'], var_data['header/date']): # Date is stored as an array (of length 92??) of floats with format: yyyymmdd date_str = str(int(date[0])) t_unit = Unit('hours since {}-{}-{} 00:00:00'.format( date_str[0:4], date_str[4:6], date_str[6:8])) date_times.append( t_unit.convert(get_data(times), cis_standard_time_unit)) # time_data = utils.concatenate([get_data(i) for i in var_data['ER2_IMU/gps_time']]) # date_str = str(int(var_data['header/date'][0][0])) # Flatten the data by taking the 0th column of the transpose time_coord = DimCoord(utils.concatenate(date_times).T[0], standard_name='time', units=cis_standard_time_unit) # TODO This won't work for multiple files since the altitude bins are different for each flight... alt_data = utils.concatenate( [get_data(i) for i in var_data["DataProducts/Altitude"]]) alt_coord = DimCoord(alt_data[0], standard_name='altitude', units='m') pres_data = utils.concatenate( [get_data(i) for i in var_data["State/Pressure"]]) pres_coord = AuxCoord(pres_data, standard_name='air_pressure', units='atm') # Fix the air-pressure units pres_coord.convert_units('hPa') lat_data = utils.concatenate( [get_data(i) for i in var_data['ER2_IMU/Latitude']]) lat_coord = AuxCoord(lat_data.T[0], standard_name='latitude') lon_data = utils.concatenate( [get_data(i) for i in var_data['ER2_IMU/Longitude']]) lon_coord = AuxCoord(lon_data.T[0], standard_name='longitude') data = utils.concatenate([get_data(i) for i in var_data[variable]]) metadata = get_metadata(var_data[variable][0]) cube = Cube(np.ma.masked_invalid(data), long_name=metadata.misc['Description'], units=self.clean_units(metadata.units), dim_coords_and_dims=[(alt_coord, 1), (time_coord, 0)], aux_coords_and_dims=[(lat_coord, (0, )), (lon_coord, (0, )), (pres_coord, (0, 1))]) gd = GriddedData.make_from_cube(cube) return gd