lat = iris.coords.DimCoord(lat.data[:, 0], standard_name='latitude', units='degrees_N', var_name='lat') theta = iris.coords.DimCoord(theta.data, standard_name='air_potential_temperature', units='K', var_name='T') cube = iris.cube.Cube(cube, long_name='Ertel Potential Voriticity', var_name='EPV', dim_coords_and_dims=[(L_S, 0), (theta, 1), (lat, 2), (lon, 3)]) level = iris.Constraint(air_potential_temperature=300) cube = cube.extract(level) # #PATH = '/home/local/WIN/wseviou1/data/swvac/' # PATH = '../output/' # ext = 'res_test57.-70.-nu4-urlx-kt4.0.c-0020sat200.0.T85' # var = 'q' # var_name = 'potential_vorticity_of_atmosphere_layer' # res = 85 anim = False plot = True # days = [5, 10] # #days=[0,10,20,30,40,49] # #days=[0,13,15,17,19,21,23,25,100] # #days=[20,22,24,26,28,30,35,200]
def test_cube_extract_coord_which_does_not_exist(self): self.assertEqual(self.t.extract(iris.Constraint(doesnt_exist=8.1)), None)
def test_simple(self): constraint = iris.Constraint(latitude=10) cube = self.single_cube.extract(constraint) self.assertCML(cube, ('cdm', 'extract', 'lat_eq_10.cml')) constraint = iris.Constraint(latitude=lambda c: c > 10) self.assertCML(self.single_cube.extract(constraint), ('cdm', 'extract', 'lat_gt_10.cml'))
def age_of_air(run): """Calculate the age of air metrics.""" # Create metrics dictionary with MDI incase age of air # diagnostics not available metrics = { 'RMS error: tropical Age of Air': -10000., 'RMS error: NH midlatitude Age of Air': -10000. } try: # Set up to only run for 5 year period analysis_start_dt, analysis_end_dt = calculate_analysis_years(run) constraint = dict(from_dt=analysis_start_dt, to_dt=analysis_end_dt, lbproc=128) # Calculate age of air metrics if appropriate diagnostic available with warnings.catch_warnings(): warnings.filterwarnings('ignore', '.*orography.*', UserWarning) agecube = load_run_ss(run, 'monthly', 'age_of_stratospheric_air', **constraint) # m01s34i150 except iris.exceptions.ConstraintMismatchError: logger.warning('Age of air fields absent. Skipping this diagnostic.') except ValueError: logger.warning("Run length < 12 years: Can't assess age of air") else: # Create time/zonal means of age data agecube = agecube.collapsed(['longitude', 'time'], iris.analysis.MEAN) # Convert units of data from seconds to years agecube.data /= RSECS_PER_360DAY_YEAR # Create latitude bounds for area-weighted averaging agecube.coord('latitude').guess_bounds() # Convert units of height from metres to km agecube.coord('level_height').convert_units('km') # Calculate area-weighted means for tropics trop_cons = iris.Constraint(latitude=lambda lat: -10 <= lat <= 10) diag1 = weight_lat_ave(agecube.extract(trop_cons)) diag1.var_name = 'tropical_age_of_air' # Calculate area-weighted means for mid-latitudes mlat_cons = iris.Constraint(latitude=lambda lat: 35 <= lat <= 45) diag2 = weight_lat_ave(agecube.extract(mlat_cons)) diag2.var_name = 'midlat_age_of_air' # Write age of air data to CWD outfile = '{0}_age_of_air_{1}.nc' cubelist = iris.cube.CubeList([diag1, diag2]) with iris.FUTURE.context(netcdf_no_unlimited=True): iris.save(cubelist, outfile.format(run['runid'], run.period)) # Calculate metrics diag1sf6 = iai.Linear(diag1, [('level_height', ZSF6_KM)]) diag1co2 = iai.Linear(diag1, [('level_height', ZCO2_KM)]) diag2sf6 = iai.Linear(diag2, [('level_height', Z2_KM)]) diag2co2 = iai.Linear(diag2, [('level_height', Z2_KM2)]) metric1sf6 = np.sqrt(np.mean((diag1sf6.data - AGE_YRS)**2)) metric1co2 = np.sqrt(np.mean((diag1co2.data - AGE_YRS2)**2)) metric2sf6 = np.sqrt(np.mean((diag2sf6.data - AGE2_YRS)**2)) metric2co2 = np.sqrt(np.mean((diag2co2.data - AGE2_YRS2)**2)) trop_age = (metric1sf6 + metric1co2) / 2. midl_age = (metric2sf6 + metric2co2) / 2. # Add metrics to dictionary metrics['RMS error: tropical Age of Air'] = float(trop_age) metrics['RMS error: NH midlatitude Age of Air'] = float(midl_age) return metrics
def test_cube_extract_1d(self): # Extract the first value from the second coord in the cube # this result is shared with the self.t[0, 0:] test self.assertCML([self.t.extract(iris.Constraint(dim1=3.0))], ('cube_slice', '2d_to_1d_cube_slice.cml'))
import numpy import datetime import matplotlib from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.patches import Rectangle start = datetime.datetime(1851, 1, 1, 0, 0) end = datetime.datetime(2018, 12, 31, 23, 59) from get_sample import get_sample_cube egrid = iris.load_cube("/scratch/hadcc/hadcrut5/build/HadCRUT5/analysis/"+ "HadCRUT.5.0.0.0.analysis.anomalies.%d.nc" % 1, iris.Constraint(time=lambda cell: cell.point.year==1850 and\ cell.point.month==1)) (ndata, dts) = get_sample_cube(start, end, new_grid=egrid) # Plot the resulting array as a 2d colourmap fig = Figure( figsize=(19.2, 6), # Width, Height (inches) dpi=600, facecolor=(0.5, 0.5, 0.5, 1), edgecolor=None, linewidth=0.0, frameon=False, subplotpars=None, tight_layout=None) canvas = FigureCanvas(fig) matplotlib.rc('image', aspect='auto')
def extract_time(cube, start_year, start_month, start_day, end_year, end_month, end_day): """ Extract a time range from a cube. Given a time range passed in as a series of years, months and days, it returns a time-extracted cube with data only within the specified time range. Parameters ---------- cube: iris.cube.Cube input cube. start_year: int start year start_month: int start month start_day: int start day end_year: int end year end_month: int end month end_day: int end day Returns ------- iris.cube.Cube Sliced cube. Raises ------ ValueError if time ranges are outside the cube time limits """ time_coord = cube.coord('time') time_units = time_coord.units if time_units.calendar == '360_day': if start_day > 30: start_day = 30 if end_day > 30: end_day = 30 t_1 = PartialDateTime(year=int(start_year), month=int(start_month), day=int(start_day)) t_2 = PartialDateTime(year=int(end_year), month=int(end_month), day=int(end_day)) constraint = iris.Constraint(time=lambda t: t_1 <= t.point < t_2) cube_slice = cube.extract(constraint) if cube_slice is None: raise ValueError( f"Time slice {start_year:0>4d}-{start_month:0>2d}-{start_day:0>2d}" f" to {end_year:0>4d}-{end_month:0>2d}-{end_day:0>2d} is outside " f"cube time bounds {time_coord.cell(0)} to {time_coord.cell(-1)}.") # Issue when time dimension was removed when only one point as selected. if cube_slice.ndim != cube.ndim: if cube_slice.coord('time') == time_coord: logger.debug('No change needed to time.') return cube return cube_slice
def test_cell(self): cell = iris.coords.Cell(10) constraint = iris.Constraint(model_level_number=cell) sub_list = self.slices.extract(constraint) self.assertEqual(len(sub_list), 6)
def test_cell_equal_bounds(self): cell = self.slices[0].coord('level_height').cell(0) constraint = iris.Constraint(level_height=cell) sub_list = self.slices.extract(constraint) self.assertEqual(len(sub_list), 6)
def test_non_existant_coordinate(self): # Check the behaviour when a constraint is given for a coordinate which does not exist/span a dimension self.assertEqual(self.cube[0, :, :].extract(self.level_10), None) self.assertEqual(self.cube.extract(iris.Constraint(wibble=10)), None)
def test_mismatched_type(self): constraint = iris.Constraint(model_level_number='aardvark') sub_list = self.slices.extract(constraint) self.assertEqual(len(sub_list), 0)
def setUp(self): self.dec_path = tests.get_data_path( ['PP', 'globClim1', 'dec_subset.pp']) self.theta_path = tests.get_data_path(['PP', 'globClim1', 'theta.pp']) self.humidity = iris.Constraint(SN_SPECIFIC_HUMIDITY) self.theta = iris.Constraint(SN_AIR_POTENTIAL_TEMPERATURE) # Coord based constraints self.level_10 = iris.Constraint(model_level_number=10) self.level_22 = iris.Constraint(model_level_number=22) # Value based coord constraint self.level_30 = iris.Constraint(model_level_number=30) self.level_gt_30_le_3 = iris.Constraint( model_level_number=lambda c: (c > 30) | (c <= 3)) self.invalid_inequality = iris.Constraint( coord_values={'model_level_number': lambda c: c > 1000}) # bound based coord constraint self.level_height_of_model_level_number_10 = iris.Constraint( level_height=1900) self.model_level_number_10_22 = iris.Constraint( model_level_number=[10, 22]) # Invalid constraints self.pressure_950 = iris.Constraint(model_level_number=950) self.lat_30 = iris.Constraint(latitude=30) self.lat_gt_45 = iris.Constraint(latitude=lambda c: c > 45)
landmask = ~(ma.make_mask(lsmask.data.copy()) + np.zeros(rh_plv.shape)).astype( bool) # mask sea, show land seamask = (ma.make_mask(lsmask.data.copy()) + np.zeros(rh_plv.shape)).astype( bool) # mask land, show sea RHocean = rh_plv_anom.copy() Tocean = temp_plv_anom.copy() RHland = rh_plv_anom.copy() Tland = temp_plv_anom.copy() RHocean.data = ma.array(RHocean.data, mask=seamask) Tocean.data = ma.array(Tocean.data, mask=seamask) RHland.data = ma.array(RHland.data, mask=landmask) Tland.data = ma.array(Tland.data, mask=landmask) # -------------- tropics = iris.Constraint(latitude=lambda v: -30 <= v <= 30) Tocean_trop = Tocean.extract(tropics) grid_areas_trop = iris.analysis.cartography.area_weights(Tocean_trop) Tocean_trop_mean = Tocean_trop.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=grid_areas_trop) SthAm = iris.Constraint(longitude=lambda l: (290 <= l <= 315), latitude=lambda l: (-23 <= l <= 0)) RHplv_SthAm = rh_plv_anom.extract(SthAm) grid_areas_SthAm = iris.analysis.cartography.area_weights(RHplv_SthAm) RHplv_SthAm_armean = RHplv_SthAm.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=grid_areas_SthAm)
default="%s/EUSTACE/derived/ERA5_20CRv3_comparison" % \ os.getenv('SCRATCH'), type=str,required=False) args = parser.parse_args() if not os.path.isdir(args.opdir): os.makedirs(args.opdir) # Fix dask SPICE bug import dask dask.config.set(scheduler='single-threaded') # Get EUSTACE field for grid dimensions egrid = iris.load_cube(("%s/EUSTACE/1.0/1969/"+ "tas_global_eustace_0_19690312.nc") % os.getenv('SCRATCH'), iris.Constraint(cube_func=(lambda c: c.var_name == 'tas'))) # Make the 20CR climatology n=[] for m in range(1,13): mc=iris.Constraint(time=lambda cell: cell.point.month == m and \ cell.point.year > 1980 and \ cell.point.year < 2011) h=iris.load_cube('%s/20CR/version_3/monthly_means/air.2m.mon.mean.nc' % os.getenv('SCRATCH'), iris.Constraint(name='air_temperature') & mc) n.append(h.extract(mc).collapsed('time', iris.analysis.MEAN)) # Make the ERA5 climatology n5=[] for m in range(1,13):
def main(): for p_level in plot_levels: # Set pressure height contour min/max if p_level == 925: clev_min = 660. clev_max = 810. elif p_level == 850: clev_min = 1435. clev_max = 1530. elif p_level == 700: clev_min = 3090. clev_max = 3155. elif p_level == 500: clev_min = 5800. clev_max = 5890. else: print 'Contour min/max not set for this pressure level' # Set potential temperature min/max if p_level == 925: clevpt_min = 300. clevpt_max = 312. elif p_level == 850: clevpt_min = 302. clevpt_max = 310. elif p_level == 700: clevpt_min = 312. clevpt_max = 320. elif p_level == 500: clevpt_min = 325. clevpt_max = 332. else: print 'Potential temperature min/max not set for this pressure level' # Set specific humidity min/max if p_level == 925: clevsh_min = 0.012 clevsh_max = 0.020 elif p_level == 850: clevsh_min = 0.007 clevsh_max = 0.017 elif p_level == 700: clevsh_min = 0.002 clevsh_max = 0.010 elif p_level == 500: clevsh_min = 0.001 clevsh_max = 0.005 else: print 'Specific humidity min/max not set for this pressure level' #clevs_col = np.arange(clev_min, clev_max) clevs_lin = np.arange(clev_min, clev_max, 5) p_level_constraint = iris.Constraint(pressure=p_level) for plot_diag in plot_diags: for experiment_id in experiment_ids: expmin1 = experiment_id[:-1] pp_file = '%s_%s_on_p_levs_mean_by_day.pp' % (experiment_id, plot_diag) pfile = '%s%s/%s/%s' % (pp_file_path, expmin1, experiment_id, pp_file) pcube = iris.load_cube(pfile, p_level_constraint) # For each hour in cube height_pp_file = '%s_408_on_p_levs_mean_by_day.pp' % ( experiment_id) height_pfile = '%s%s/%s/%s' % (pp_file_path, expmin1, experiment_id, height_pp_file) height_cube = iris.load_cube(height_pfile, p_level_constraint) print pcube print height_cube #time_coords = cube_f.coord('time') #add_hour_of_day(pcube, pcube.coord('time')) #add_hour_of_day(height_cube, height_cube.coord('time')) iris.coord_categorisation.add_day_of_year(pcube, time_coords, name='day_of_year') iris.coord_categorisation.add_day_of_year(height_cube, time_coords, name='day_of_year') #pcube.remove_coord('time') #cube_diff.remove_coord('time') #height_cube.remove_coord('time') #height_cube_diff.remove_coord('time') #p_cube_difference = iris.analysis.maths.subtract(pcube, cube_diff, dim='hour') #height_cube_difference = iris.analysis.maths.subtract(height_cube, height_cube_diff, dim='hour') #pdb.set_trace() #del height_cube, pcube, height_cube_diff, cube_diff for t, time_cube in enumerate( pcube.slices(['grid_latitude', 'grid_longitude'])): #pdb.set_trace() print time_cube height_cube_slice = height_cube.extract( iris.Constraint(hour=time_cube.coord('hour').points)) # Get time of averagesfor plot title #h = u.num2date(np.array(time_cube.coord('hour').points, dtype=float)[0]).strftime('%H%M') h = u.num2date( np.array(time_cube.coord('time').points, dtype=float)[0]).strftime('%d%b') #Convert to India time # from_zone = tz.gettz('UTC') # to_zone = tz.gettz('Asia/Kolkata') # h_utc = u.num2date(np.array(time_cube.coord('hour').points, dtype=float)[0]).replace(tzinfo=from_zone) # h_local = h_utc.astimezone(to_zone).strftime('%H%M') fig = plt.figure(**figprops) cmap = plt.cm.RdBu_r ax = plt.axes(projection=ccrs.PlateCarree(), extent=(lon_low, lon_high, lat_low + degs_crop_bottom, lat_high - degs_crop_top)) m =\ Basemap(llcrnrlon=lon_low,llcrnrlat=lat_low,urcrnrlon=lon_high,urcrnrlat=lat_high, rsphere = 6371229) #pdb.set_trace() lat = time_cube.coord('grid_latitude').points lon = time_cube.coord('grid_longitude').points cs = time_cube.coord_system('CoordSystem') lons, lats = np.meshgrid(lon, lat) lons, lats = iris.analysis.cartography.unrotate_pole\ (lons,lats, cs.grid_north_pole_longitude, cs.grid_north_pole_latitude) x, y = m(lons, lats) if plot_diag == 'temp': min_contour = clevpt_min max_contour = clevpt_max cb_label = 'K' main_title = '8km Explicit model (dklyu) minus 8km parametrised model geopotential height (grey contours), potential temperature (colours),\ and wind (vectors) %s UTC %s IST' % ( h, h_local) tick_interval = 2 clev_number = max_contour - min_contour + 1 elif plot_diag == 'sp_hum': min_contour = clevsh_min max_contour = clevsh_max cb_label = 'kg/kg' main_title = '8km Explicit model (dklyu) minus 8km parametrised model geopotential height (grey contours), specific humidity (colours),\ and wind (vectors) %s UTC %s IST' % ( h, h_local) tick_interval = 0.002 clev_number = (max_contour - min_contour + 0.001) * (10**3) clevs = np.linspace(min_contour, max_contour, clev_number) #clevs = np.linspace(-3, 3, 32) cont = plt.contourf(x, y, time_cube.data, clevs, cmap=cmap, extend='both') #cont = iplt.contourf(time_cube, clevs, cmap=cmap, extend='both') cs_lin = iplt.contour(height_cube_slice, clevs_lin, colors='#262626', linewidths=1.) plt.clabel(cs_lin, fontsize=14, fmt='%d', color='black') #del time_cube #plt.clabel(cont, fmt='%d') #ax.stock_img() ax.coastlines(resolution='110m', color='#262626') gl = ax.gridlines(draw_labels=True, linewidth=0.5, color='#262626', alpha=0.5, linestyle='--') gl.xlabels_top = False gl.ylabels_right = False #gl.xlines = False dx, dy = 10, 10 gl.xlocator = mticker.FixedLocator( range(int(lon_low_tick), int(lon_high_tick) + dx, dx)) gl.ylocator = mticker.FixedLocator( range(int(lat_low_tick), int(lat_high_tick) + dy, dy)) gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabel_style = {'size': 12, 'color': '#262626'} #gl.xlabel_style = {'color': '#262626', 'weight': 'bold'} gl.ylabel_style = {'size': 12, 'color': '#262626'} cbar = fig.colorbar(cont, orientation='horizontal', pad=0.05, extend='both') cbar.set_label('%s' % cb_label, fontsize=10, color='#262626') #cbar.set_label(time_cube.units, fontsize=10, color='#262626') cbar.set_ticks( np.arange(min_contour, max_contour + tick_interval, tick_interval)) ticks = (np.arange(min_contour, max_contour + tick_interval, tick_interval)) cbar.set_ticklabels(['${%.1f}$' % i for i in ticks]) cbar.ax.tick_params(labelsize=10, color='#262626') #main_title='Mean Rainfall for EMBRACE Period -%s UTC (%s IST)' % (h, h_local) #main_title=time_cube.standard_name.title().replace('_',' ') #model_info = re.sub(r'[(\']', ' ', model_info) #model_info = re.sub(r'[\',)]', ' ', model_info) #print model_info file_save_name = '%s_%s_%s_hPa_and_geop_height_%s' % ( experiment_id, plot_diag, p_level, h) save_dir = '%s%s/%s' % (save_path, experiment_id, plot_diag) if not os.path.exists('%s' % save_dir): os.makedirs('%s' % (save_dir)) #plt.show() #fig.savefig('%s/%s_notitle.png' % (save_dir, file_save_name), format='png', bbox_inches='tight') plt.title('%s UTC' % (h)) fig.savefig('%s/%s_short_title.png' % (save_dir, file_save_name), format='png', bbox_inches='tight') #model_info=re.sub('(.{68} )', '\\1\n', str(model_name_convert_title.main(experiment_id)), 0, re.DOTALL) #plt.title('\n'.join(wrap('%s\n%s' % (main_title, model_info), 1000,replace_whitespace=False)), fontsize=16) #fig.savefig('%s/%s.png' % (save_dir, file_save_name), format='png', bbox_inches='tight') fig.clf() plt.close() #del time_cube gc.collect()
def test_cell_different_bounds(self): cell = iris.coords.Cell(10, bound=(9, 11)) constraint = iris.Constraint(model_level_number=cell) sub_list = self.slices.extract(constraint) self.assertEqual(len(sub_list), 0)
def getSeasConstr(name): sncon = {'ann': iris.Constraint(month_number=lambda cell: 1 <= cell <= 12), 'mj' : iris.Constraint(month_number=lambda cell: 5 <= cell <= 6), 'jj' : iris.Constraint(month_number=lambda cell: 6 <= cell <= 7), 'ja' : iris.Constraint(month_number=lambda cell: 7 <= cell <= 8), 'as' : iris.Constraint(month_number=lambda cell: 8 <= cell <= 9), 'so' : iris.Constraint(month_number=lambda cell: 9 <= cell <= 10), 'jan' : iris.Constraint(month_number=lambda cell: cell == 1), 'feb' : iris.Constraint(month_number=lambda cell: cell == 2), 'mar' : iris.Constraint(month_number=lambda cell: cell == 3), 'apr' : iris.Constraint(month_number=lambda cell: cell == 4), 'may' : iris.Constraint(month_number=lambda cell: cell == 5), 'jun' : iris.Constraint(month_number=lambda cell: cell == 6), 'jul' : iris.Constraint(month_number=lambda cell: cell == 7), 'aug' : iris.Constraint(month_number=lambda cell: cell == 8), 'sep' : iris.Constraint(month_number=lambda cell: cell == 9), 'oct' : iris.Constraint(month_number=lambda cell: cell == 10), 'nov' : iris.Constraint(month_number=lambda cell: cell == 11), 'dec' : iris.Constraint(month_number=lambda cell: cell == 12), 'djf': iris.Constraint(month_number=lambda cell: (cell == 12) | (1 <= cell <= 2)), 'mam': iris.Constraint(month_number=lambda cell: 3 <= cell <= 5), 'jja': iris.Constraint(month_number=lambda cell: 6 <= cell <= 8), 'jas': iris.Constraint(month_number=lambda cell: 7 <= cell <= 9), 'jjas': iris.Constraint(month_number=lambda cell: 6 <= cell <= 9), 'mjjas': iris.Constraint(month_number=lambda cell: 5<= cell<=9), 'son': iris.Constraint(month_number=lambda cell: 9 <= cell <= 11) } return(sncon[name])
def setUp(self): """ Set up cubes and sitelists for use in testing SpotExtraction. The envisaged scenario is an island (1) surrounded by water (0). Land-sea Orography Diagnostic 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 0 1 1 1 0 0 1 2 1 0 5 6 7 8 9 0 1 1 1 0 0 2 3 2 0 10 11 12 13 14 0 1 1 1 0 0 1 2 1 0 15 16 17 18 19 0 0 0 0 0 0 0 0 0 0 20 21 22 23 24 """ # Set up diagnostic data cube and neighbour cubes. diagnostic_data = np.arange(25).reshape(5, 5) xcoord = iris.coords.DimCoord( np.linspace(0, 40, 5), standard_name='longitude', units='degrees') ycoord = iris.coords.DimCoord( np.linspace(0, 40, 5), standard_name='latitude', units='degrees') attributes = { 'mosg__grid_domain': 'global', 'mosg__grid_type': 'standard'} diagnostic_cube_xy = iris.cube.Cube( diagnostic_data, standard_name="air_temperature", units='K', dim_coords_and_dims=[(ycoord, 1), (xcoord, 0)], attributes=attributes) diagnostic_cube_yx = iris.cube.Cube( diagnostic_data.T, standard_name="air_temperature", units='K', dim_coords_and_dims=[(ycoord, 0), (xcoord, 1)], attributes=attributes) diagnostic_cube_hash = create_coordinate_hash(diagnostic_cube_yx) # neighbours, each group is for a point under two methods, e.g. # [ 0. 0. 0.] is the nearest point to the first spot site, whilst # [ 1. 1. -1.] is the nearest land point to the same site. neighbours = np.array([[[0., 0., 0.], [1., 1., -1.]], [[0., 0., -1.], [1., 1., 0.]], [[2., 2., 0.], [2., 2., 0.]], [[2., 2., 1.], [2., 2., 1.]]]) altitudes = np.array([0, 1, 3, 2]) latitudes = np.array([10, 10, 20, 20]) longitudes = np.array([10, 10, 20, 20]) wmo_ids = np.arange(4) grid_attributes = ['x_index', 'y_index', 'vertical_displacement'] neighbour_methods = ['nearest', 'nearest_land'] neighbour_cube = build_spotdata_cube( neighbours, 'grid_neighbours', 1, altitudes, latitudes, longitudes, wmo_ids, grid_attributes=grid_attributes, neighbour_methods=neighbour_methods) neighbour_cube.attributes['model_grid_hash'] = diagnostic_cube_hash coordinate_cube = neighbour_cube.extract( iris.Constraint(neighbour_selection_method_name='nearest') & iris.Constraint(grid_attributes_key=['x_index', 'y_index'])) coordinate_cube.data = np.rint(coordinate_cube.data).astype(int) self.latitudes = latitudes self.longitudes = longitudes self.diagnostic_cube_xy = diagnostic_cube_xy self.diagnostic_cube_yx = diagnostic_cube_yx self.neighbours = neighbours self.neighbour_cube = neighbour_cube self.coordinate_cube = coordinate_cube
def plot_cross_section_for_seasons(data_path="", i_start=0, j_start=0, i_end=-1, j_end=-1, var_name=None): name_constraint = iris.Constraint( cube_func=lambda c: c.var_name == var_name) data_cube = iris.load_cube(data_path, constraint=name_constraint) fig = plt.figure() impath = os.path.join( NEMO_IMAGES_DIR, "vert_sect_{0}_{1}_{2}_{3}_{4}.jpeg".format(var_name, i_start, j_start, i_end, j_end)) #Add month_number coordinate #coord_categorisation.add_month_number(cube, "time") coord_categorisation.add_season(data_cube, "time") cube_seasonal = data_cube.aggregated_by("season", analysis.MEAN) nplots = cube_seasonal.shape[0] ncols = 2 nrows = nplots // ncols if nplots % ncols == 0 else nplots // ncols + 1 b, lons, lats = nemo_commons.get_basemap_and_coordinates_from_file( T_FILE_PATH, resolution="i") print("lons shape: ", lons.shape) gs = gridspec.GridSpec(ncols=ncols + 1, nrows=nrows + 1, width_ratios=[1, 1, 0.05], hspace=0.3) # +1 for the colorbar and for map bath_path = os.path.join(EXP_DIR, "bathy_meter.nc") the_mask = nemo_commons.get_mask(path=bath_path) depths = Dataset(T_FILE_PATH).variables["deptht"][:] bathymetry = Dataset(bath_path).variables["Bathymetry"][:] vert_mask = np.ma.masked_all(depths.shape + bathymetry.shape) for lev, di in enumerate(depths): not_mask_j, not_mask_i = np.where(di < bathymetry * 0.95) vert_mask[lev, not_mask_j, not_mask_i] = 1 lons_sel, lats_sel = None, None depths_2d = None vmin = None vmax = None nx, ny = None, None dists_2d = None season_to_section = {} for i, season in zip(list(range(nplots)), cube_seasonal.coord("season").points): data = cube_seasonal.extract( iris.Constraint(season=season)).data.squeeze() assert data.ndim == 3 _, ny, nx = data.shape if i_end == -1: i_end = nx - 1 if j_end == -1: j_end = ny - 1 j_mask, i_mask = np.where(~the_mask) print("mask shape: ", the_mask.shape) print("data shape: ", data.shape) data[:, j_mask, i_mask] = np.ma.masked i_list, j_list = get_section_hor_indices(i_start=i_start, i_end=i_end, j_start=j_start, j_end=j_end) data_sel = data[:, j_list, i_list] data_sel = np.ma.masked_where(vert_mask[:, j_list, i_list].mask, data_sel) print("data_sel shape: ", data_sel.shape) if lons_sel is None: lons_sel = lons[j_list, i_list] lats_sel = lats[j_list, i_list] p_start = (lats[j_start, i_start], lons[j_start, i_start]) dists = [ GreatCircleDistance(p_start, (the_lat, the_lon)).km for the_lat, the_lon in zip(lats_sel, lons_sel) ] dists_2d, depths_2d = np.meshgrid(dists, depths) season_to_section[season] = data_sel if vmin is None: vmin = data_sel.min() else: vmin = min(vmin, data_sel.min()) if vmax is None: vmax = data_sel.max() else: vmax = max(vmax, data_sel.max()) delta = 1.0 clevs = np.arange(np.floor(vmin), vmax + delta, delta) cmap = cm.get_cmap("jet", len(clevs) - 1) if clevs is not None: bn = BoundaryNorm(clevs, len(clevs) - 1) else: bn = None print("{0}: ".format(var_name), vmin, vmax) cs = None ax = None for i, season in zip(list(range(nplots)), cube_seasonal.coord("season").points): print(season) row = i // ncols col = i % ncols ax = fig.add_subplot(gs[row, col]) ax.set_title(season.upper()) data = season_to_section[season] print(data.min(), data.max()) #to_plot = np.ma.masked_where(~the_mask, data) #print to_plot.min(), to_plot.max() #cs = ax.pcolormesh(dists_2d, depths_2d, data, norm = bn, cmap = cmap) cs = ax.contourf(dists_2d, depths_2d, data, levels=clevs, cmap=cmap) #cs = ax.pcolormesh(dists_2d, depths_2d, data, norm = bn, cmap = cmap) #b.drawcoastlines(linewidth=cpp.COASTLINE_WIDTH) #b.drawparallels(np.arange(-90, 90, 2)) #b.drawmeridians(np.arange(-180, 180, 2)) if col != 0: ax.yaxis.set_ticks([]) ax.xaxis.set_ticks([]) assert isinstance(ax, Axes) ax.invert_yaxis() ax.set_ylim(80, 0) # Disregard areas deeper than 150 m if row == 0 and col == 0: ax.set_ylabel("Depth (m)", fontdict={"fontsize": 20}) cb = plt.colorbar(cs, ticks=clevs[::2], cax=fig.add_subplot(gs[:nrows, ncols])) ax = fig.add_subplot(gs[nrows, :]) x, y = b(lons, lats) b.drawcoastlines(linewidth=cpp.COASTLINE_WIDTH) b.fillcontinents() assert isinstance(ax, Axes) ax.add_line( Line2D([x[j_start, i_start], x[j_end, i_end]], [y[j_start, i_start], y[j_end, i_end]], linewidth=3)) fig.savefig(impath, bbox_inches="tight") pass
def load_min_max_LST(season_filepath, REGION): if REGION != 'EUROPE': left_lon = float(REGIONS[REGION][0]) right_lon = float(REGIONS[REGION][2]) lower_lat = float(REGIONS[REGION][1]) upper_lat = float(REGIONS[REGION][3]) lat_constraint = iris.Constraint( latitude=lambda c: lower_lat <= c.point <= upper_lat) lon_constraint = iris.Constraint( longitude=lambda c: left_lon <= c.point <= right_lon) lst_warm_max = iris.load( season_filepath, 'Coverage of Maximum Land Surface Temperature in Warm Window (PMW)' ) lst_warm_max = lst_warm_max.extract(lat_constraint) lst_warm_max = lst_warm_max.extract(lon_constraint) lst_cold_max = iris.load( season_filepath, 'Coverage of Maximum Land Surface Temperature in Cold Window (PMW)' ) lst_cold_max = lst_cold_max.extract(lat_constraint) lst_cold_max = lst_cold_max.extract(lon_constraint) lst_cold_min = iris.load( season_filepath, 'Coverage of Minimum Land Surface Temperature in Cold Window (PMW)' ) lst_cold_min = lst_cold_min.extract(lat_constraint) lst_cold_min = lst_cold_min.extract(lon_constraint) else: lst_warm_max = iris.load( season_filepath, 'Coverage of Maximum Land Surface Temperature in Warm Window (PMW)' ) lst_cold_max = iris.load( season_filepath, 'Coverage of Maximum Land Surface Temperature in Cold Window (PMW)' ) lst_cold_min = iris.load( season_filepath, 'Coverage of Minimum Land Surface Temperature in Cold Window (PMW)' ) lons = lst_warm_max[0].coord('longitude').points lats = lst_warm_max[0].coord('latitude').points num_of_years = len(lst_warm_max) shape1 = lst_cold_max[0].shape[0] shape2 = lst_cold_max[0].shape[1] lst_warm_max_data = np.zeros((num_of_years, shape1, shape2)) lst_cold_max_data = np.zeros((num_of_years, shape1, shape2)) lst_cold_min_data = np.zeros((num_of_years, shape1, shape2)) for i in range(num_of_years): lst_warm_max_data[i, :] = lst_warm_max[i].data lst_cold_max_data[i, :] = lst_cold_max[i].data lst_cold_min_data[i, :] = lst_cold_min[i].data average_lst_warm_max = np.mean(lst_warm_max_data, axis=0) average_lst_cold_max = np.mean(lst_cold_max_data, axis=0) average_lst_cold_min = np.mean(lst_cold_min_data, axis=0) return lst_warm_max_data, lst_cold_max_data, lst_cold_min_data, average_lst_warm_max, average_lst_cold_max, average_lst_cold_min, lons, lats
def multi_age_plot(run): """ Plot results. This function is plotting the results of the function age_of_air for each run against observations. """ # Run age_of_air for each run. # Age_of_air returns metrics and writes results into an *.nc in the current # working directory. # To make this function independent of the previous call to age_of_air, # age_of_air is run again for each run in this function # # This behaviour is due to the convention that only metric_functions can # return metric values, multi_functions are supposed to # only produce plots (see __init__.py). ###################################### # Set up constraints to deal with loading data trop_cons = iris.Constraint( cube_func=lambda c: c.var_name == 'tropical_age_of_air') midl_cons = iris.Constraint( cube_func=lambda c: c.var_name == 'midlat_age_of_air') # Set up generic input file name infile = '{0}_age_of_air_{1}.nc' # Create control filename cntlfile = infile.format(run['suite_id1'], run['period']) # Create experiment filename exptfile = infile.format(run['suite_id2'], run['period']) # If no control data then stop ... if not os.path.exists(cntlfile): logger.warning('Age of air for control absent. skipping ...') return # Create tropics plot fig = plt.figure() ax1 = plt.gca() # Plot OBS plt.plot(AGE_YRS, ZSF6_KM, linestyle='-', marker='s', color='black', label='SF6 obs') plt.plot(AGE_YRS2, ZCO2_KM, linestyle='-', marker='D', color='black', label='CO2 obs') # Plot control diag = iris.load_cube(cntlfile, trop_cons) levs = diag.coord('level_height').points plt.plot(diag.data, levs, label=run['suite_id1']) # Plot experiment if os.path.exists(exptfile): diag = iris.load_cube(exptfile, trop_cons) levs = diag.coord('level_height').points plt.plot(diag.data, levs, label=run['suite_id2']) ax1.set_title('Tropical mean age profile (10S-10N)') ax1.set_xlabel('Mean age (years)') ax1.set_ylabel('Height (km)') ax1.set_ylim(16, 34) ax1.legend(loc='upper left') fig.savefig('age_tropics.png') plt.close() # Create midlats plot fig = plt.figure() ax1 = plt.gca() # Plot OBS plt.plot(AGE2_YRS, Z2_KM, linestyle='-', marker='s', color='black', label='SF6 obs') plt.plot(AGE2_YRS2, Z2_KM2, linestyle='-', marker='D', color='black', label='CO2 obs') # Plot control diag = iris.load_cube(cntlfile, midl_cons) levs = diag.coord('level_height').points plt.plot(diag.data, levs, label=run['suite_id1']) # Plot experiment if os.path.exists(exptfile): diag = iris.load_cube(exptfile, midl_cons) levs = diag.coord('level_height').points plt.plot(diag.data, levs, label=run['suite_id2']) ax1.set_title('Midlatitude mean age profile (35N-45N)') ax1.set_xlabel('Mean age (years)') ax1.set_ylabel('Height (km)') ax1.set_ylim(16, 34) ax1.legend(loc='upper left') fig.savefig('age_midlatitudes.png') plt.close()
import os import math import pickle import Meteorographica as mg import matplotlib from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure import cartopy import cartopy.crs as ccrs # Get the 20CR data ic=twcr.load('prmsl',datetime.datetime(2009,3,12,18), version='2c') ic=ic.extract(iris.Constraint(member=1)) # Need to resize data so it's dimensions are a multiple of 8 (3*2-fold pool) class ResizeLayer(tf.keras.layers.Layer): def __init__(self, newsize=None, **kwargs): super(ResizeLayer, self).__init__(**kwargs) self.resize_newsize = newsize def build(self, input_shape): self.resize_newsize *= 1 def call(self, input): return tf.image.resize_images(input, self.resize_newsize, align_corners=True) def get_config(self): return {'newsize': self.resize_newsize} # Padding and pruning functions for periodic boundary conditions
def test_cube_extract_0d(self): # Extract the first value from each of the coords in the cube # this result is shared with the self.t[0, 0] test self.assertCML([self.t.extract(iris.Constraint(dim1=3.0, dim2=iris.coords.Cell(0, (0, 1))))], ('cube_slice', '2d_to_0d_cube_slice.cml'))
import matplotlib.patches as patch import numpy as np import cartopy.crs as ccrs from cis.data_io.gridded_data import make_from_cube def load_callback(cube, field, fname): variable_attributes = ['date_metadata_modified', 'date_issued', 'date_modified', 'date_created', 'isccp_input_files', 'time_coverage_start', 'time_coverage_end', 'isccp_month', 'id', 'history'] for a in variable_attributes: cube.attributes.pop(a) months=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] for i in range(12): directory = '/Users/clim_proc/Documents/POC MPhys Project/Modis/ISCCP data/data/international-satellite-cloud-climate-project-isccp-h-series-data/access/isccp-basic/hgm/' filelist = glob(directory+'ISCCP-Basic*GLOBAL*0'+str(i+1)+'*99.9999*') c = iris.load(filelist[0], iris.Constraint(cube_func=lambda x: x.var_name=='cldamt_types'), callback=load_callback).concatenate_cube()[:,1,...] no = 0 for filename in filelist[1:]: year = int(filename.split('.')[4]) c += (iris.load(filename, iris.Constraint(cube_func=lambda x: x.var_name=='cldamt_types'), callback=load_callback).concatenate_cube())[:,1,...] no += 1 print(no+1, ' of ', len(filelist), ' done') mean = c/no fig=plt.figure(figsize=(15,15))#, dpi=300) ax = plt.axes(projection=ccrs.PlateCarree()) ax.coastlines() ax.set_title=(months[i]) make_from_cube(c).plot(ax=ax)
def test_cube_extract_2d(self): # Do nothing - return the original self.assertCML([self.t.extract(iris.Constraint())], ('cube_slice', '2d_orig.cml'))
TX = TX.concatenate_cube() TN = iris.load(tmin) TN = TN.concatenate_cube() #Initialize Indices TXx_MON = iris.cube.CubeList() TNx_MON = iris.cube.CubeList() TXn_MON = iris.cube.CubeList() TNn_MON = iris.cube.CubeList() DTR_MON = iris.cube.CubeList() FD_MON = iris.cube.CubeList() TR_MON = iris.cube.CubeList() for i in range(len(YEARS)): print(YEARS[i]) year_constraint = iris.Constraint( time=lambda c: c.point.year == int(YEARS[i])) #initialize different indice TXx_MONTHS = iris.cube.CubeList() TXn_MONTHS = iris.cube.CubeList() TNx_MONTHS = iris.cube.CubeList() TNn_MONTHS = iris.cube.CubeList() DTR_MONTHS = iris.cube.CubeList() FD_MONTHS = iris.cube.CubeList() TR_MONTHS = iris.cube.CubeList() TN_YEAR = TN.extract(year_constraint) TX_YEAR = TX.extract(year_constraint) for MONTH in MONTHS: print(MONTH)
def test_cube_extract_coord_with_non_existant_values(self): self.assertEqual(self.t.extract(iris.Constraint(dim1=8)), None)
def read_cp4(explicit, temporal, variable, start_year, start_month, end_year, end_month): if explicit: explicit_str = 'explicit-4km' else: explicit_str = 'param-25km' if start_year <= 2007: present_future = 'present' else: present_future = 'future' # match variable names with longer names used in directory structure var_directory = dict() var_directory['psl'] = 'mean_sea_level_pressure' var_directory['prsn'] = 'snowfall' var_directory['huss'] = 'near_surface_air_specific_humidity' var_directory['hfls'] = 'surface_latent_heat_flux' var_directory['tas'] = 'near_surface_air_temperature' var_directory['ps'] = 'surface_pressure' var_directory['rlut'] = 'outgoing_longwave_radiation' var_directory['hfss'] = 'surface_sensible_heat_flux' var_directory['pr'] = 'precipitation' nmonths_per_year = 12 ndays_per_month = 30 basedir = '/badc/impala/data/' + explicit_str + '/' + present_future + '/' + temporal + '/' + var_directory[ variable] + '/' all_cubes = iris.cube.CubeList() varConstraint = iris.Constraint( cube_func=(lambda c: c.var_name == variable)) print('reading {res} {y:04d}/{m:02d} to {y2:04d}/{m2:02d}'.format( res=explicit_str, y=start_year, m=start_month, y2=end_year, m2=end_month)) for y in range(start_year, end_year + 1): if temporal == 'mon': ncdir = basedir if y == start_year: first_month = start_month else: first_month = 1 if y == end_year: last_month = end_month else: last_month = nmonths_per_year first_date_str = '{y:04d}{m:02d}-'.format(y=y, m=first_month) last_date_str = '{y:04d}{m:02d}'.format(y=y, m=last_month) filename = variable + '_' + explicit_str + '_' + present_future + '_' + first_date_str + last_date_str + '.nc' #print('opening', filename) try: this_cube = iris.load_cube(ncdir + filename, varConstraint) except OSError as err: print(filename) raise err all_cubes.append(this_cube) else: for m in range(1, nmonths_per_year + 1): if y == start_year and m < start_month: continue if y == end_year and m > end_month: break ncdir = basedir + '{y:04d}/{m:02d}/'.format(y=y, m=m) for d in range(ndays_per_month): filename = variable + '_' + explicit_str + '_' + present_future + '_{y:04d}{m:02d}{d:02d}.nc'.format( y=y, m=m, d=d + 1) #print('opening', filename) try: this_cube = iris.load_cube(ncdir + filename, varConstraint) except OSError as err: print(filename) raise err all_cubes.append(this_cube) iris.util.unify_time_units(all_cubes) equalise_attributes(all_cubes) cubes = all_cubes.concatenate() return cubes[0]
def test_combined(self): constraint = iris.Constraint(latitude=lambda c: c > 10, longitude=lambda c: c >= 10) self.assertCML(self.single_cube.extract(constraint), ('cdm', 'extract', 'lat_gt_10_and_lon_ge_10.cml'))
def get_sample(min_lon=-180,max_lon=360,min_lat=-90,max_lat=90, start=datetime.datetime(1851,1,1,0,0), end=datetime.datetime(1900,12,31,23,59), climatology=None, climstart=1961,climend=1991, new_grid=None): # Load the model data e=[] dts=None for member in range(1,81): m = [] for year in range(start.year,end.year+1): h=iris.load_cube('%s/20CR/version_3/monthly_means/%04d/PRMSL.%04d.mnmean_mem%03d.nc' % (os.getenv('SCRATCH'),year,year,member), iris.Constraint(name='Pressure reduced to MSL') & iris.Constraint(time=lambda cell: \ start <= cell.point <=end)) dty=h.coords('time')[0].units.num2date(h.coords('time')[0].points) # Anomalise if climatology is not None: for tidx in range(len(dty)): midx=dty[tidx].month-1 h.data[tidx,:,:] -= climatology[midx].data if new_grid is not None: h = h.regrid(new_grid,iris.analysis.Nearest()) # Reduce to area of interest h.coord('latitude').guess_bounds() h.coord('longitude').guess_bounds() h=h.extract(iris.Constraint(longitude=lambda v: min_lon <= v <= max_lon, latitude =lambda v: min_lat <= v <= max_lat)) h.attributes=None h2=h if len(m)>0: # Workaround for metadata bug from varying versions of HDF library h2=m[0].copy() h2.data=h.data h2.remove_coord('time') h2.add_dim_coord(h.coord('time'),data_dim=0) m.append(h2) e.append(iris.cube.CubeList(m).concatenate_cube()) if member==1: if dts is None: dts=dty else: dts=numpy.concatenate(dts,dty) # Get area averages ntp=e[0].data.shape[0] w = iris.analysis.cartography.area_weights(e[0]) ndata=numpy.ma.array(numpy.zeros((ntp,80)),mask=True) for t in range(ntp): for m in range(80): ndata[:,m]=e[m].collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=w).data return (ndata,dts)