def test_zonal_mean_2d(self): # Running zonal_mean_2d with the core param only. self.runner.sets_to_run = ['zonal_mean_2d'] core_only_results = self.runner.get_final_parameters([self.core_param]) # Running zonal_mean_2d with a set-specific param. # We pass in both the core and this parameter. zonal_mean_2d_param = ZonalMean2dParameter() zonal_mean_2d_param.plevs = [10.0, 20.0, 30.0] both_results = self.runner.get_final_parameters( [self.core_param, zonal_mean_2d_param]) # Check that the plevs value is actually changed. for param in both_results: if param.plevs != zonal_mean_2d_param.plevs: msg = 'plevs are {} when they should be {}.' self.fail(msg.format(param.plevs, zonal_mean_2d_param.plevs)) # Running zonal_mean_2d without a CoreParameter. # When doing so, we still must have valid values for # certain parameters. another_zonal_mean_2d_param = ZonalMean2dParameter() another_zonal_mean_2d_param.reference_data_path = '/something' another_zonal_mean_2d_param.test_data_path = '/something/else' another_zonal_mean_2d_param.results_dir = '/something/else/too' zm_2d_only_results = self.runner.get_final_parameters( [another_zonal_mean_2d_param]) # Now checking that all three configs have the same output. len1, len2, len3 = len(core_only_results), len(both_results), len( zm_2d_only_results) if len1 == 0 or not (len1 == len2 == len3): msg = 'The lengths are either 0 or not equal: {} {} {}' self.fail(msg.format(len1, len2, len3))
# Running the software with the API: # python all_sets.py -d all_sets.py import numpy from acme_diags.parameter.area_mean_time_series_parameter import AreaMeanTimeSeriesParameter from acme_diags.parameter.core_parameter import CoreParameter from acme_diags.parameter.enso_diags_parameter import EnsoDiagsParameter from acme_diags.parameter.meridional_mean_2d_parameter import MeridionalMean2dParameter from acme_diags.parameter.zonal_mean_2d_parameter import ZonalMean2dParameter from acme_diags.run import Run run_object = Run() param = CoreParameter() ts_param = AreaMeanTimeSeriesParameter() m2d_param = MeridionalMean2dParameter() m2d_param.plevs = [ 200., 500., ] z2d_param = ZonalMean2dParameter() z2d_param.plevs = [ 200., 300., ] enso_param = EnsoDiagsParameter() enso_param.test_name = 'e3sm_v1' run_object.run_diags([param, ts_param, m2d_param, z2d_param, enso_param])
from acme_diags.parameter.core_parameter import CoreParameter from acme_diags.parameter.zonal_mean_2d_parameter import ZonalMean2dParameter from acme_diags.run import runner param = CoreParameter() param.reference_data_path = ( "/global/cfs/cdirs/e3sm/acme_diags/obs_for_e3sm_diags/climatology/") param.test_data_path = ( "/global/cfs/cdirs/e3sm/acme_diags/test_model_data_for_acme_diags/climatology/" ) param.test_name = "20161118.beta0.FC5COSP.ne30_ne30.edison" param.seasons = ["ANN"] # Name of the folder where the results are stored. # Change `prefix` to use your directory. prefix = "/global/cfs/cdirs/e3sm/www/<your directory>/examples" param.results_dir = os.path.join(prefix, "ex6_zonal_mean_2d_and_lat_lon_demo") # Uncomment the two lines below to just # run the diags with T and PRECT. # param.selectors += ['variables'] # param.variables = ['T', 'PRECT'] # The new changes are below. zonal_mean_2d_param = ZonalMean2dParameter() zonal_mean_2d_param.plevs = [10.0, 20.0, 30.0] runner.sets_to_run = ["zonal_mean_2d", "lat_lon"] runner.run_diags([param, zonal_mean_2d_param])
def run_diag(parameter): variables = parameter.variables seasons = parameter.seasons ref_name = getattr(parameter, "ref_name", "") test_data = utils.dataset.Dataset(parameter, test=True) ref_data = utils.dataset.Dataset(parameter, ref=True) for season in seasons: # Get the name of the data, appended with the years averaged. parameter.test_name_yrs = utils.general.get_name_and_yrs( parameter, test_data, season) parameter.ref_name_yrs = utils.general.get_name_and_yrs( parameter, ref_data, season) for var in variables: print("Variable: {}".format(var)) parameter.var_id = var mv1 = test_data.get_climo_variable(var, season) mv2 = ref_data.get_climo_variable(var, season) parameter.viewer_descr[var] = (mv1.long_name if hasattr( mv1, "long_name") else "No long_name attr in test data.") # For variables with a z-axis. if mv1.getLevel() and mv2.getLevel(): # Since the default is now stored in MeridionalMean2dParameter, # we must get it from there if the plevs param is blank. plevs = parameter.plevs if (isinstance(plevs, numpy.ndarray) and not plevs.all()) or ( not isinstance(plevs, numpy.ndarray) and not plevs): plevs = ZonalMean2dParameter().plevs # print('Selected pressure level: {}'.format(plevs)) mv1_p = utils.general.convert_to_pressure_levels( mv1, plevs, test_data, var, season) mv2_p = utils.general.convert_to_pressure_levels( mv2, plevs, ref_data, var, season) mv1_p = cdutil.averager(mv1_p, axis="y") mv2_p = cdutil.averager(mv2_p, axis="y") parameter.output_file = "-".join( [ref_name, var, season, parameter.regions[0]]) parameter.main_title = str(" ".join([var, season])) # Regrid towards the lower resolution of the two # variables for calculating the difference. if len(mv1_p.getLongitude()) < len(mv2_p.getLongitude()): mv1_reg = mv1_p lev_out = mv1_p.getLevel() lon_out = mv1_p.getLongitude() # in order to use regrid tool we need to have at least two latitude bands, so generate new grid first lat = cdms2.createAxis([0]) lat.setBounds(numpy.array([-1, 1])) lat.designateLatitude() grid = cdms2.createRectGrid(lat, lon_out) data_shape = list(mv2_p.shape) data_shape.append(1) mv2_reg = MV2.resize(mv2_p, data_shape) mv2_reg.setAxis(-1, lat) for i, ax in enumerate(mv2_p.getAxisList()): mv2_reg.setAxis(i, ax) mv2_reg = mv2_reg.regrid(grid, regridTool="regrid2")[..., 0] # Apply the mask back, since crossSectionRegrid # doesn't preserve the mask. mv2_reg = MV2.masked_where(mv2_reg == mv2_reg.fill_value, mv2_reg) elif len(mv1_p.getLongitude()) > len(mv2_p.getLongitude()): mv2_reg = mv2_p lev_out = mv2_p.getLevel() lon_out = mv2_p.getLongitude() mv1_reg = mv1_p.crossSectionRegrid(lev_out, lon_out) # In order to use regrid tool we need to have at least two # latitude bands, so generate new grid first. lat = cdms2.createAxis([0]) lat.setBounds(numpy.array([-1, 1])) lat.designateLatitude() grid = cdms2.createRectGrid(lat, lon_out) data_shape = list(mv1_p.shape) data_shape.append(1) mv1_reg = MV2.resize(mv1_p, data_shape) mv1_reg.setAxis(-1, lat) for i, ax in enumerate(mv1_p.getAxisList()): mv1_reg.setAxis(i, ax) mv1_reg = mv1_reg.regrid(grid, regridTool="regrid2")[..., 0] # Apply the mask back, since crossSectionRegrid # doesn't preserve the mask. mv1_reg = MV2.masked_where(mv1_reg == mv1_reg.fill_value, mv1_reg) else: mv1_reg = mv1_p mv2_reg = mv2_p diff = mv1_reg - mv2_reg metrics_dict = create_metrics(mv2_p, mv1_p, mv2_reg, mv1_reg, diff) parameter.var_region = "global" plot( parameter.current_set, mv2_p, mv1_p, diff, metrics_dict, parameter, ) utils.general.save_ncfiles(parameter.current_set, mv1_p, mv2_p, diff, parameter) # For variables without a z-axis. elif mv1.getLevel() is None and mv2.getLevel() is None: raise RuntimeError( "One of or both data doesn't have z dimention. Aborting.") return parameter
def run_diag(parameter): variables = parameter.variables seasons = parameter.seasons ref_name = getattr(parameter, 'ref_name', '') regions = parameter.regions test_data = utils.dataset.Dataset(parameter, test=True) ref_data = utils.dataset.Dataset(parameter, ref=True) for season in seasons: # Get the name of the data, appended with the years averaged. parameter.test_name_yrs = utils.general.get_name_and_yrs( parameter, test_data, season) parameter.ref_name_yrs = utils.general.get_name_and_yrs( parameter, ref_data, season) # Get land/ocean fraction for masking. try: land_frac = test_data.get_climo_variable('LANDFRAC', season) ocean_frac = test_data.get_climo_variable('OCNFRAC', season) except: mask_path = os.path.join(acme_diags.INSTALL_PATH, 'acme_ne30_ocean_land_mask.nc') with cdms2.open(mask_path) as f: land_frac = f('LANDFRAC') ocean_frac = f('OCNFRAC') for var in variables: print('Variable: {}'.format(var)) parameter.var_id = var mv1 = test_data.get_climo_variable(var, season) mv2 = ref_data.get_climo_variable(var, season) parameter.viewer_descr[var] = mv1.long_name if hasattr( mv1, 'long_name') else 'No long_name attr in test data.' # Special case, cdms didn't properly convert mask with fill value # -999.0, filed issue with Denis. if ref_name == 'WARREN': # This is cdms2 fix for bad mask, Denis' fix should fix this. mv2 = MV2.masked_where(mv2 == -0.9, mv2) # The following should be moved to a derived variable. if ref_name == 'AIRS': # This is cdms2 fix for bad mask, Denis' fix should fix this. mv2 = MV2.masked_where(mv2 > 1e+20, mv2) if ref_name == 'WILLMOTT' or ref_name == 'CLOUDSAT': # This is cdms2 fix for bad mask, Denis' fix should fix this. mv2 = MV2.masked_where(mv2 == -999., mv2) # The following should be moved to a derived variable. if var == 'PRECT_LAND': days_season = { 'ANN': 365, 'DJF': 90, 'MAM': 92, 'JJA': 92, 'SON': 91 } # mv1 = mv1 * days_season[season] * 0.1 # following AMWG # Approximate way to convert to seasonal cumulative # precipitation, need to have solution in derived variable, # unit convert from mm/day to cm. mv2 = mv2 / days_season[season] / \ 0.1 # Convert cm to mm/day instead. mv2.units = 'mm/day' # For variables with a z-axis. if mv1.getLevel() and mv2.getLevel(): # Since the default is now stored in ZonalMean2dParameter, # we must get it from there if the plevs param is blank. plevs = parameter.plevs if (isinstance(plevs, numpy.ndarray) and not plevs.all()) or \ (not isinstance(plevs, numpy.ndarray) and not plevs): plevs = ZonalMean2dParameter().plevs #print('Selected pressure level: {}'.format(plevs)) mv1_p = utils.general.convert_to_pressure_levels( mv1, plevs, test_data, var, season) mv2_p = utils.general.convert_to_pressure_levels( mv2, plevs, ref_data, var, season) mv1_p = cdutil.averager(mv1_p, axis='x') mv2_p = cdutil.averager(mv2_p, axis='x') parameter.output_file = '-'.join( [ref_name, var, season, parameter.regions[0]]) parameter.main_title = str(' '.join([var, season])) # Regrid towards the lower resolution of the two # variables for calculating the difference. if len(mv1_p.getLatitude()) < len(mv2_p.getLatitude()): mv1_reg = mv1_p lev_out = mv1_p.getLevel() lat_out = mv1_p.getLatitude() mv2_reg = mv2_p.crossSectionRegrid(lev_out, lat_out) # Apply the mask back, since crossSectionRegrid # doesn't preserve the mask. mv2_reg = MV2.masked_where(mv2_reg == mv2_reg.fill_value, mv2_reg) elif len(mv1_p.getLatitude()) > len(mv2_p.getLatitude()): mv2_reg = mv2_p lev_out = mv2_p.getLevel() lat_out = mv2_p.getLatitude() mv1_reg = mv1_p.crossSectionRegrid(lev_out, lat_out) # Apply the mask back, since crossSectionRegrid # doesn't preserve the mask. mv1_reg = MV2.masked_where(mv1_reg == mv1_reg.fill_value, mv1_reg) else: mv1_reg = mv1_p mv2_reg = mv2_p diff = mv1_reg - mv2_reg metrics_dict = create_metrics(mv2_p, mv1_p, mv2_reg, mv1_reg, diff) parameter.var_region = 'global' plot(parameter.current_set, mv2_p, mv1_p, diff, metrics_dict, parameter) utils.general.save_ncfiles(parameter.current_set, mv1_p, mv2_p, diff, parameter) # For variables without a z-axis. elif mv1.getLevel() is None and mv2.getLevel() is None: for region in regions: #print("Selected region: {}".format(region)) mv1_domain = utils.general.select_region( region, mv1, land_frac, ocean_frac, parameter) mv2_domain = utils.general.select_region( region, mv2, land_frac, ocean_frac, parameter) parameter.output_file = '-'.join( [ref_name, var, season, region]) parameter.main_title = str(' '.join([var, season, region])) # Regrid towards the lower resolution of the two # variables for calculating the difference. mv1_reg, mv2_reg = utils.general.regrid_to_lower_res( mv1_domain, mv2_domain, parameter.regrid_tool, parameter.regrid_method) # Special case. if var == 'TREFHT_LAND' or var == 'SST': if ref_name == 'WILLMOTT': mv2_reg = MV2.masked_where( mv2_reg == mv2_reg.fill_value, mv2_reg) land_mask = MV2.logical_or(mv1_reg.mask, mv2_reg.mask) mv1_reg = MV2.masked_where(land_mask, mv1_reg) mv2_reg = MV2.masked_where(land_mask, mv2_reg) diff = mv1_reg - mv2_reg metrics_dict = create_metrics(mv2_domain, mv1_domain, mv2_reg, mv1_reg, diff) parameter.var_region = region plot(parameter.current_set, mv2_domain, mv1_domain, diff, metrics_dict, parameter) utils.general.save_ncfiles(parameter.current_set, mv1_domain, mv2_domain, diff, parameter) else: raise RuntimeError( "Dimensions of the two variables are different. Aborting.") return parameter