diff --git a/ecmean/global_mean.py b/ecmean/global_mean.py index 61a5630..0d229f7 100755 --- a/ecmean/global_mean.py +++ b/ecmean/global_mean.py @@ -83,9 +83,11 @@ def __init__(self, exp, year1, year2, config='config.yml', loglevel='WARNING', n self.loglevel = loglevel self.loggy = setup_logger(level=self.loglevel) - self.diag = Diagnostic(exp, year1, year2, config, funcname=self.__class__.__name__, - numproc=numproc, ensemble=ensemble, interface=interface, modelname=model, - addnan=addnan, silent=silent, trend=trend, line=line, outputdir=outputdir, + self.diag = Diagnostic(exp, year1, year2, config, + funcname=self.__class__.__name__, + numproc=numproc, ensemble=ensemble, interface=interface, + modelname=model, addnan=addnan, silent=silent, + trend=trend, line=line, outputdir=outputdir, xdataset=xdataset) self.face = None self.ref = None @@ -129,8 +131,13 @@ def run(self): processes = [] for varlist in weight_split(self.diag.var_all, self.diag.numproc): - core = Process(target=self.gm_worker, args=(self.util_dictionary, self.ref, self.face, self.diag, - self.varmean, self.vartrend, varlist)) + core = Process(target=self.gm_worker, args=(self.util_dictionary, + self.ref, + self.face, + self.diag, + self.varmean, + self.vartrend, + varlist)) core.start() processes.append(core) @@ -145,27 +152,41 @@ def store(self, yamlfile=None): # reorder the data to be stored for var in self.diag.var_all: gamma = self.ref[var] + + # if dictionary we have more info season, mean and standard deviation if isinstance(gamma['obs'], dict): tabval = gamma['obs']['ALL']['Global'] outval = str(tabval['mean']) + '\u00B1' + str(tabval['std']) else: outval = gamma['obs'] - if 'year1' in gamma.keys(): - years = str(gamma['year1']) + '-' + str(gamma['year2']) - else: - raise ValueError('Year1 and Year2 are not defined in the reference file') + years = f"{gamma['year1']}-{gamma['year2']}" + + # prepare output sequence using list expansion if trend is requested + out_sequence = [ + var, + gamma['longname'], + gamma['units'], + self.varmean[var]['ALL']['Global'], + *([self.vartrend[var]['ALL']['Global']] if self.diag.ftrend else []), + outval, + gamma.get('dataset', ''), + years + ] - out_sequence = [var, gamma['longname'], gamma['units'], self.varmean[var]['ALL']['Global']] - if self.diag.ftrend: - out_sequence = out_sequence + [self.vartrend[var]['ALL']['Global']] - out_sequence = out_sequence + [outval, gamma.get('dataset', ''), years] global_table.append(out_sequence) - head = ['Variable', 'Longname', 'Units', self.diag.modelname] - if self.diag.ftrend: - head = head + ['Trend'] - head = head + ['Obs.', 'Dataset', 'Years'] + # create header using list expansion if trend is requested + head = [ + 'Variable', + 'Longname', + 'Units', + self.diag.modelname, + *(['Trend'] if self.diag.ftrend else []), + 'Obs.', + 'Dataset', + 'Years' + ] # save table tablefile = self.diag.filenames('txt') @@ -173,10 +194,10 @@ def store(self, yamlfile=None): with open(tablefile, 'w', encoding='utf-8') as out: out.write(tabulate(global_table, headers=head, stralign='center', tablefmt='orgtbl')) - # reaorder + # reorder self.varmean = {var: self.varmean[var] for var in self.diag.var_all} - # save yaml fil + # save yaml file if yamlfile is None: yamlfile = self.diag.filenames('yml') @@ -251,6 +272,8 @@ def gm_worker(util, ref, face, diag, varmean, vartrend, varlist): xfield = xfield.sel(time=xfield.time.dt.year.isin(diag.years_joined)) check_time_axis(xfield.time, diag.years_joined) + + # compute here since the operation are built on this cfield = formula_wrapper(var, face, xfield).compute() for season in diag.seasons: diff --git a/ecmean/libs/masks.py b/ecmean/libs/masks.py index ceaa79e..fa09b58 100644 --- a/ecmean/libs/masks.py +++ b/ecmean/libs/masks.py @@ -80,6 +80,8 @@ def mask_field(xfield, mask_type, dom, mask): out = xfield.where(mask.data < 0.5) else: raise ValueError("ERROR: mask_field -> Mask undefined, this cannot be handled!") + else: + raise ValueError("ERROR: mask_field -> Domain undefined, this cannot be handled!") return out @@ -121,37 +123,16 @@ def select_region(xfield, region): if region == 'Global': return xfield + + if region == 'North Midlat': + lat_min, lat_max = 30.0, 90.0 + elif region == 'South Midlat': + lat_min, lat_max = -90.0, -30.0 + elif region == 'Tropical': + lat_min, lat_max = -30.0, 30.0 else: - if region == 'North Midlat': - lat_min, lat_max = 30.0, 90.0 - elif region == 'South Midlat': - lat_min, lat_max = -90.0, -30.0 - elif region == 'Tropical': - lat_min, lat_max = -30.0, 30.0 - else: - raise KeyError(region + "region not supported!!!") - - # new version more flexible than the slice one - return xfield.where((xfield.lat >= lat_min) & (xfield.lat <= lat_max)) - + raise KeyError(region + "region not supported!!!") -# def select_region_old(xfield, region): -# """Trivial function to convert region definition to xarray -# sliced array to compute the PIs or global means on selected regions""" - -# # fixed for the order of latitudes -# #xfield = xfield.sortby('lat') - - -# if region == 'Global': -# slicearray = xfield -# elif region == 'North Midlat': -# slicearray = xfield.sel(lat=slice(30, 90)) -# elif region == 'South Midlat': -# slicearray = xfield.sel(lat=slice(-90, -30)) -# elif region == 'Tropical': -# slicearray = xfield.sel(lat=slice(-30, 30)) -# else: -# sys.exit(region + "region not supported!!!") + # new version more flexible than the slice one + return xfield.where((xfield.lat >= lat_min) & (xfield.lat <= lat_max)) -# return slicearray diff --git a/ecmean/libs/plotting.py b/ecmean/libs/plotting.py index 0caba85..1532521 100644 --- a/ecmean/libs/plotting.py +++ b/ecmean/libs/plotting.py @@ -220,13 +220,9 @@ def prepare_clim_dictionaries_pi(data, clim, shortnames): del filt_piclim[k][f] # set longname, reorganize the dictionaries - data2plot = {} - cmip6 = {} + data2plot = {clim[var]['longname']: data[var] for var in shortnames} + cmip6 = {clim[var]['longname']: filt_piclim[var] for var in shortnames} longnames = [clim[var]['longname'] for var in shortnames] - for var in shortnames: - longname = clim[var]['longname'] - data2plot[longname] = data[var] - cmip6[longname] = filt_piclim[var] return data2plot, cmip6, longnames @@ -254,6 +250,7 @@ def prepare_clim_dictionaries_gm(data, clim, shortnames, seasons, regions): obsstd = {} for var in shortnames: gamma = clim[var] + obs = gamma['obs'] # extract from yaml table for obs mean and standard deviation mmm = init_mydict(seasons, regions) @@ -262,19 +259,18 @@ def prepare_clim_dictionaries_gm(data, clim, shortnames, seasons, regions): if isinstance(gamma['obs'], dict): for season in seasons: for region in regions: - mmm[season][region] = gamma['obs'][season][region]['mean'] - sss[season][region] = gamma['obs'][season][region]['std'] + mmm[season][region] = obs[season][region]['mean'] + sss[season][region] = obs[season][region]['std'] # if only global observation is available else: mmm['ALL']['Global'] = gamma['obs'] + + # Assign to obsmean and obsstd using longname as the key obsmean[gamma['longname']] = mmm obsstd[gamma['longname']] = sss # set longname, get units - data2plot = {} - units_list = [] - for var in shortnames: - data2plot[clim[var]['longname']] = data[var] - units_list.append(clim[var]['units']) + data2plot = {clim[var]['longname']: data[var] for var in shortnames} + units_list = [clim[var]['units'] for var in shortnames] return obsmean, obsstd, data2plot, units_list