def get_value(self, point, data): """ Co-location routine using nearest neighbour algorithm optimized for gridded data. This calls out to iris to do the work. """ from iris.analysis.interpolate import extract_nearest_neighbour, nearest_neighbour_data_value if not self.coord_names: # Remove any tuples in the list that do not correspond to a dimension coordinate in the cube 'data'. for coord_name, val in point.coord_tuple: if len(data.coords(coord_name, dim_coords=True)) > 0: self.coord_names.append(coord_name) if len(data.coords('altitude', dim_coords=False)) > 0 and point.altitude is not None: self.hybrid_coord = 'altitude' elif len(data.coords('air_pressure', dim_coords=False)) > 0 and point.air_pressure is not None: self.hybrid_coord = 'air_pressure' new_coord_tuple_list = [(c, getattr(point, c)) for c in self.coord_names] if self.hybrid_coord: slice = extract_nearest_neighbour(data, new_coord_tuple_list) val = nearest_neighbour_data_value(slice, [(self.hybrid_coord, getattr(point, self.hybrid_coord))]) else: val = nearest_neighbour_data_value(data, new_coord_tuple_list) return val
def processing(in_files, params): """ Main processing function to execute either on the main thread or on IPython parallel engines. """ #print in_files #print '------------' #print params # LOAD DATA #global i_coord, j_coord, l_coord station_region_indices = (params['iminmax'] + params['jminmax'] + params['lminmax']) i_coord, j_coord, l_coord = iris_tools.gcgrid_2_coords( params['grid_model_name'], params['grid_model_resolution'], region_box=station_region_indices ) def assign_coord_nd49_or_subset_ctm(cube, field, filename): """ A callback for GEOS-Chem datafields loading with Iris. If `cube` is loaded from a ND49 diagnostic file (i.e., some undefined dimension coordinates), generate the coordinates values from the grid indices of the 3D region box. (Else) If `cube` is loaded from a CTM file, extract a subset that correspond to the region box. """ #global i_coord, j_coord, l_coord cube_is_ctm = True if not cube.coords('longitude'): cube.add_dim_coord(i_coord, 0) cube_is_ctm = False if not cube.coords('latitude'): cube.add_dim_coord(j_coord, 1) cube_is_ctm = False if not cube.coords('model_level_number'): try: cube.add_dim_coord(l_coord, 2) except ValueError: # as this callback applied before applying constraints, # do nothing for, e.g., cubes related to emissions (2D) pass if cube_is_ctm: lonlat_subset = iris.Constraint(longitude=i_coord.points, latitude=j_coord.points) cube = cube.extract(lonlat_subset) tracers2load = iris.AttributeConstraint( category=lambda category: category in params['categories'], name=lambda name: name in params['tracers'] ) all_cubes = iris.load(in_files, [tracers2load] + params['other_fields'], callback=assign_coord_nd49_or_subset_ctm) tracer_cubes = all_cubes.extract(tracers2load) other_cubes = all_cubes.extract(params['other_fields'], strict=False) # datafields required for columns and profiles calculation #pedges_cube = other_cubes.extract_strict('PSURF_PEDGE-$') box_height_cube = other_cubes.extract_strict('BXHEIGHT_BXHGHT-$') try: n_air_cube = other_cubes.extract_strict('N(AIR)_BXHGHT-$') except iris.exceptions.ConstraintMismatchError: # ND49: air density datafields have a different name n_air_cube = other_cubes.extract_strict('AIRDEN_TIME-SER') # ND49: fix missing pressure level #pedges_cube = iris_tools.fix_nd49_pressure(pedges_cube) # convert units for hydrocarbon tracers for cube in tracer_cubes: iris_tools.ppbC_2_ppbv(cube) #print tracer_cubes #print "------------------------" #print tracer_cubes[0] #print "------------------------" #print other_cubes # EXTRACT AND REGRID PROFILES station_coords = [('latitude', params['station_lat']), ('longitude', params['station_lon'])] tracer_profiles = iris.cube.CubeList( [extract_nearest_neighbour(cube, station_coords) for cube in tracer_cubes] ) #pedges_profile, box_height_profile, n_air_profile = [ box_height_profile, n_air_profile = [ extract_nearest_neighbour(cube, station_coords) for cube in [box_height_cube, n_air_cube] #, pedges_cube] ] all_profiles = tracer_profiles + \ [box_height_profile, n_air_profile] #, pedges_profile] #global_topography = iris.load_cube(params['global_topography_datafile']) bh = box_height_profile.copy() gt = global_topography.copy() altitude_coord = iris_tools.get_altitude_coord(bh, gt) #print altitude_coord #return for cube in tracer_profiles + [n_air_profile]: if cube.coords('air_pressure'): cube.remove_coord('air_pressure') if cube.coords('altitude'): cube.remove_coord('altitude') cube.add_aux_coord(altitude_coord, data_dims=range(0, box_height_profile.ndim)) station_profile = extract_nearest_neighbour( #iris.load_cube(params['station_vertical_grid_file']), station_vgrid, station_coords ) regridded_tracer_profiles = iris.cube.CubeList( [regrid_profile(p, station_profile) for p in tracer_profiles] ) regridded_n_air_profile = regrid_profile(n_air_profile, station_profile) regridded_profiles = regridded_tracer_profiles + \ [regridded_n_air_profile] # CALCULATE COLUMNS columns = [iris_tools.compute_tracer_columns( p, regridded_n_air_profile, 'altitude' ) for p in regridded_tracer_profiles] tracer_columns = iris.cube.CubeList(columns) return regridded_profiles, tracer_columns
def woa_profile(lon, lat, variable='temperature', clim_type='00', resolution='1.00', full=False): # noqa """ Return an iris.cube instance from a World Ocean Atlas 2013 variable at a given lon, lat point. Parameters ---------- lon, lat: float point positions to extract the profile. Choose data `variable` from: 'temperature', 'silicate', 'salinity', 'phosphate', 'oxygen', 'o2sat', 'nitrate', and 'AOU'. Choose `clim_type` averages from: 01-12 :: monthly 13-16 :: seasonal (North Hemisphere Winter, Spring, Summer, and Autumn respectively) 00 :: annual Choose `resolution` from: 1 (1 degree), or 4 (0.25 degrees) Returns ------- Iris.cube instance with the climatology. Examples -------- >>> import matplotlib.pyplot as plt >>> from oceans.datasets import woa_profile >>> cube = woa_profile(-143, 10, variable='temperature', ... clim_type='00', resolution='1.00', full=False) >>> fig, ax = plt.subplots(figsize=(2.25, 5)) >>> z = cube.coord(axis='Z').points >>> l = ax.plot(cube[0, :].data, z) >>> ax.grid(True) >>> ax.invert_yaxis() """ import iris from iris.analysis.interpolate import extract_nearest_neighbour if variable not in ['salinity', 'temperature']: resolution = '1.00' decav = 'all' msg = '{} is only available at 1 degree resolution'.format warnings.warn(msg(variable)) else: decav = 'decav' v = dict(temperature='t', silicate='i', salinity='s', phosphate='p', oxygen='o', o2sat='O', nitrate='n', AOU='A') r = dict({'1.00': '1', '0.25': '4'}) var = v[variable] res = r[resolution] uri = ('http://data.nodc.noaa.gov/thredds/dodsC/woa/WOA13/DATA/' '{variable}/netcdf/{decav}/{resolution}/woa13_{decav}_{var}' '{clim_type}_0{res}.nc').format url = uri(**dict(variable=variable, decav=decav, resolution=resolution, var=var, clim_type=clim_type, res=res)) cubes = iris.load_raw(url) cubes = [extract_nearest_neighbour(cube, [('longitude', lon), ('latitude', lat)]) for cube in cubes] cubes = iris.cube.CubeList(cubes) if full: return cubes else: cubes = [c for c in cubes if c.var_name == '{}_an'.format(var)] return cubes[0]
def woa_profile(lon, lat, variable='temperature', clim_type='00', resolution='1.00', full=False): """Return an iris.cube instance from a World Ocean Atlas 2013 variable at a given lon, lat point. Parameters ---------- lon, lat: float point positions to extract the profile. Choose data `variable` from: 'temperature', 'silicate', 'salinity', 'phosphate', 'oxygen', 'o2sat', 'nitrate', and 'AOU'. Choose `clim_type` averages from: 01-12 :: monthly 13-16 :: seasonal (North Hemisphere Winter, Spring, Summer, and Autumn respectively) 00 :: annual Choose `resolution` from: 1 (1 degree), or 4 (0.25 degrees) Returns ------- Iris.cube instance with the climatology. Examples -------- >>> import matplotlib.pyplot as plt >>> from oceans.datasets import woa_profile >>> cube = woa_profile(-143, 10, variable='temperature', ... clim_type='00', resolution='1.00', full=False) >>> fig, ax = plt.subplots(figsize=(2.25, 5)) >>> z = cube.coord(axis='Z').points >>> l = ax.plot(cube[0, :].data, z) >>> ax.grid(True) >>> ax.invert_yaxis() """ if variable not in ['salinity', 'temperature']: resolution = '1.00' decav = 'all' msg = '{} is only available at 1 degree resolution'.format warnings.warn(msg(variable)) else: decav = 'decav' v = dict(temperature='t', silicate='i', salinity='s', phosphate='p', oxygen='o', o2sat='O', nitrate='n', AOU='A') r = dict({'1.00': '1', '0.25': '4'}) var = v[variable] res = r[resolution] uri = ("http://data.nodc.noaa.gov/thredds/dodsC/woa/WOA13/DATA/" "{variable}/netcdf/{decav}/{resolution}/woa13_{decav}_{var}" "{clim_type}_0{res}.nc").format url = uri(**dict(variable=variable, decav=decav, resolution=resolution, var=var, clim_type=clim_type, res=res)) cubes = iris.load_raw(url) cubes = [extract_nearest_neighbour(cube, [('longitude', lon), ('latitude', lat)]) for cube in cubes] cubes = iris.cube.CubeList(cubes) if full: return cubes else: cubes = [c for c in cubes if c.var_name == '{}_an'.format(var)] return cubes[0]