def ens_anom(filenames, dir_output, name_outputs, varname, numens, season, area, extreme): """Ensemble anomalies. Computation of the ensemble anomalies based on the desired value from the input variable (it can be the percentile, mean, maximum, standard deviation or trend) OUTPUT: NetCDF files of ensemble mean of climatology, selected value and anomaly maps. """ print('The name of the output files will be <variable>_{0}.txt'.format( name_outputs)) print('Number of ensemble members: {0}'.format(numens)) outfiles = [] # Reading the netCDF file of 3Dfield, for all the ensemble members var_ens = [] for ens in range(numens): ifile = filenames[ens] # print('ENSEMBLE MEMBER %s' %ens) var, varunits, lat, lon, dates, _ = read_iris(ifile) # Convertion from kg m-2 s-1 to mm/day if varunits == 'kg m-2 s-1': var = var * 86400 # there are 86400 seconds in a day varunits = 'mm/day' # Selecting a season (DJF,DJFM,NDJFM,JJA) var_season, _ = sel_season(var, dates, season) # Selecting only [latS-latN, lonW-lonE] box region var_area, lat_area, lon_area = sel_area(lat, lon, var_season, area) var_ens.append(var_area) if varunits == 'kg m-2 s-1': print('\nPrecipitation rate units were converted from kg m-2 s-1 ' 'to mm/day') print('The variable is {0} ({1})'.format(varname, varunits)) print('Original var shape: (time x lat x lon)={0}'.format(var.shape)) print('var shape after selecting season {0} and area {1}: ' '(time x lat x lon)={2}'.format(season, area, var_area.shape)) if extreme == 'mean': # Compute the time mean over the entire period, for each ens member varextreme_ens = [ np.nanmean(var_ens[i], axis=0) for i in range(numens) ] elif len(extreme.split("_")) == 2: # Compute the chosen percentile over the period, for each ens member quant = int(extreme.partition("th")[0]) varextreme_ens = [ np.nanpercentile(var_ens[i], quant, axis=0) for i in range(numens) ] elif extreme == 'maximum': # Compute the maximum value over the period, for each ensemble member varextreme_ens = [np.nanmax(var_ens[i], axis=0) for i in range(numens)] elif extreme == 'std': # Compute the standard deviation over the period, for each ens member varextreme_ens = [np.nanstd(var_ens[i], axis=0) for i in range(numens)] elif extreme == 'trend': # Compute the linear trend over the period, for each ensemble member trendmap = np.empty((var_ens[0].shape[1], var_ens[0].shape[2])) trendmap_ens = [] for i in range(numens): for jla in range(var_ens[0].shape[1]): for jlo in range(var_ens[0].shape[2]): slope, _, _, _, _ = \ stats.linregress(range(var_ens[0].shape[0]), var_ens[i][:, jla, jlo]) trendmap[jla, jlo] = slope trendmap_ens.append(trendmap.copy()) varextreme_ens = trendmap_ens varextreme_ens_np = np.array(varextreme_ens) print('Anomalies are computed with respect to the {0}'.format(extreme)) # Compute and save the anomalies with respect to the ensemble ens_anomalies = varextreme_ens_np - np.nanmean(varextreme_ens_np, axis=0) varsave = 'ens_anomalies' ofile = os.path.join(dir_output, 'ens_anomalies_{0}.nc'.format(name_outputs)) # print(ofile) print('ens_anomalies shape: (numens x lat x lon)={0}'.format( ens_anomalies.shape)) save_n_2d_fields(lat_area, lon_area, ens_anomalies, varsave, varunits, ofile) outfiles.append(ofile) # Compute and save the climatology vartimemean_ens = [np.mean(var_ens[i], axis=0) for i in range(numens)] ens_climatologies = np.array(vartimemean_ens) varsave = 'ens_climatologies' ofile = os.path.join(dir_output, 'ens_climatologies_{0}.nc'.format(name_outputs)) save_n_2d_fields(lat_area, lon_area, ens_climatologies, varsave, varunits, ofile) outfiles.append(ofile) ens_extreme = varextreme_ens_np varsave = 'ens_extreme' ofile = os.path.join(dir_output, 'ens_extreme_{0}.nc'.format(name_outputs)) save_n_2d_fields(lat_area, lon_area, ens_extreme, varsave, varunits, ofile) outfiles.append(ofile) return outfiles
climate_mean.append(np.mean(var_ok[mask, :, :], axis=0)) climat_std.append(np.std(var_ok[mask, :, :], axis=0)) dates_clim.append( pd.to_datetime('2000{:02d}01'.format(mon), format='%Y%m%d')) climate_mean = np.array(climate_mean) climat_std = np.array(climat_std) var_anom = [] for el, dat in zip(var, dates_pdh): anom = el - climate_mean[dat.month - 1, :, :] var_anom.append(anom) var_anom = np.array(var_anom) var_season, dates_season = sel_season(var_anom, dates, season) dates_seas_pdh = pd.to_datetime(dates_season) years = np.unique(dates_seas_pdh.year) var_season_tot = [] if months[0] == 12: years == years[1:] for yea in years: if months[0] == 12: init = pd.to_datetime('{:04d}{:02d}01'.format(yea - 1, months[0]), format='%Y%m%d') else: init = pd.to_datetime('{:04d}{:02d}01'.format(yea, months[0]), format='%Y%m%d')
####################### PRECOMPUTATION ####################################### #____________run ens_anom as a module varextreme_ens_np, vartimemean_ens, ensemble_mean, dates = ens_anom(inputs) dates_pdh = pd.to_datetime(dates) climatology = None if inputs['clim_compare']: if inputs['climat_file'] is None: raise ValueError('climat_file not specified') var, lat, lon, dates_clim, time_units, var_units = read3Dncfield( inputs['climat_file']) if season is not None: var_season, dates_season = sel_season(var, dates_clim, season, inputs['timestep']) else: var_season = var dates_season = dates_clim climatology_tot, _, _ = sel_area(lat, lon, var_season, inputs['area']) climatology = np.mean(climatology_tot, axis=0) if inputs['clim_sigma_value'] is None and inputs['climat_std'] is not None: var, lat, lon, dates_clim, time_units, var_units = read3Dncfield( inputs['climat_std']) if season is not None: var_season, dates_season = sel_season(var, dates_clim, season, inputs['timestep']) else:
def ens_anom(inputs): ''' \nGOAL: Computation of the ensemble anomalies based on the desired value from the input variable (it can be the percentile, mean, maximum, standard deviation or trend) OUTPUT: NetCDF files of ensemble mean of climatology, selected value and anomaly maps. ''' # User-defined packages from read_netcdf import read3Dncfield, save_N_2Dfields, readxDncfield from sel_season_area import sel_season, sel_area OUTPUTdir = inputs['OUTPUTdir'] numens = inputs['numens'] name_outputs = inputs['name_outputs'] filenames = inputs['filenames'] season = inputs['season'] area = inputs['area'] varname = inputs['varname'] extreme = inputs['extreme'] timestep = inputs['timestep'] print('The name of the output files will be <variable>_{0}.txt'.format( name_outputs)) print('Number of ensemble members: {0}'.format(numens)) #____________Reading the netCDF file of 3Dfield, for all the ensemble members var_ens = [] for ens in range(numens): ifile = filenames[ens] print('ENSEMBLE MEMBER %s' % ens) #var, lat, lon, dates, time_units, varunits = read3Dncfield(ifile) print(ifile) varss, lat, lon, dates, time_units, varunitsss, time_cal = readxDncfield( ifile) print(varss.keys()) print(varunitsss) if len(varss.keys()) == 1: var = varss.values()[0] varunits = varunitsss.values()[0] else: try: var = varss[varname] varunits = varunitsss[varname] except KeyError as ke: print( 'Unable to find right variable among the following: {}\n'. format(varss.keys())) raise ke #____________Convertion from kg m-2 s-1 to mm/day if varunits == 'kg m-2 s-1': var = var * 86400 #there are 86400 seconds in a day varunitsnew = 'mm/day' else: varunitsnew = varunits #____________Selecting a season (DJF,DJFM,NDJFM,JJA) if season is not None: var_season, dates_season = sel_season(var, dates, season, timestep) else: var_season = var dates_season = dates #____________Selecting only [latS-latN, lonW-lonE] box region var_area, lat_area, lon_area = sel_area(lat, lon, var_season, area) var_ens.append(var_area) if varunitsnew == 'mm/day': print( '\nPrecipitation rate units are converted from kg m-2 s-1 to mm/day' ) print('The variable is {0} ({1})'.format(varname, varunitsnew)) print('Original var shape: (time x lat x lon)={0}'.format(var.shape)) print( 'var shape after selecting season {0}: (time x lat x lon)={1}'.format( season, var_season.shape)) print( 'var shape after selecting season {0} and area {1}: (time x lat x lon)={2}' .format(season, area, var_area.shape)) print('Check the number of ensemble members: {0}'.format(len(var_ens))) if extreme == 'mean': #____________Compute the time mean over the entire period, for each ensemble member # MEAN varextreme_ens = [np.mean(var_ens[i], axis=0) for i in range(numens)] elif len(extreme.split("_")) == 2: #____________Compute the chosen percentile over the period, for each ensemble member # PERCENTILE q = int(extreme.partition("th")[0]) varextreme_ens = [ np.percentile(var_ens[i], q, axis=0) for i in range(numens) ] elif extreme == 'maximum': #____________Compute the maximum value over the period, for each ensemble member # MAXIMUM varextreme_ens = [np.max(var_ens[i], axis=0) for i in range(numens)] elif extreme == 'std': #____________Compute the standard deviation over the period, for each ensemble member # STANDARD DEVIATION varextreme_ens = [np.std(var_ens[i], axis=0) for i in range(numens)] elif extreme == 'trend': #____________Compute the linear trend over the period, for each ensemble member # TREND # Reshape grid to 2D (time, lat*lon) -> Y #Y=[var_ens[i].reshape(var_ens[0].shape[0],var_ens[0].shape[1]*var_ens[0].shape[2])for i in range(numens)] #print('Reshaped (time, lat*lon) variable: ',Y[0].shape) trendmap = np.empty((var_ens[0].shape[1], var_ens[0].shape[2])) trendmap_ens = [] for i in range(numens): for la in range(var_ens[0].shape[1]): for lo in range(var_ens[0].shape[2]): slope, intercept, r_value, p_value, std_err = stats.linregress( range(var_ens[0].shape[0]), var_ens[i][:, la, lo]) trendmap[la, lo] = slope trendmap_ens.append(trendmap) varextreme_ens = trendmap_ens print(len(varextreme_ens), varextreme_ens[0].shape) varextreme_ens_np = np.array(varextreme_ens) print(varextreme_ens_np.shape) print('\n------------------------------------------------------------') print('Anomalies are computed with respect to the {0}'.format(extreme)) print('------------------------------------------------------------\n') ensemble_mean = np.mean(varextreme_ens_np, axis=0) #____________Compute and save the anomalies with respect to the ensemble ens_anomalies = varextreme_ens_np - np.mean(varextreme_ens_np, axis=0) varsave = 'ens_anomalies' ofile = os.path.join(OUTPUTdir, 'ens_anomalies_{0}.nc'.format(name_outputs)) #print(ofile) print('Save the anomalies with respect to the ensemble:') print('ens_anomalies shape: (numens x lat x lon)={0}'.format( ens_anomalies.shape)) save_N_2Dfields(lat_area, lon_area, ens_anomalies, varsave, varunitsnew, ofile) #____________Compute and save the climatology vartimemean_ens = [np.mean(var_ens[i], axis=0) for i in range(numens)] ens_climatologies = np.array(vartimemean_ens) varsave = 'ens_climatologies' ofile = os.path.join(OUTPUTdir, 'ens_climatologies_{0}.nc'.format(name_outputs)) #print(ofile) print('Save the climatology:') save_N_2Dfields(lat_area, lon_area, ens_climatologies, varsave, varunitsnew, ofile) #____________Save the extreme ens_extreme = varextreme_ens_np varsave = 'ens_extreme' ofile = os.path.join(OUTPUTdir, 'ens_extreme_{0}.nc'.format(name_outputs)) #print(ofile) print('Save the extreme:') save_N_2Dfields(lat_area, lon_area, ens_extreme, varsave, varunitsnew, ofile) return varextreme_ens_np, vartimemean_ens, ensemble_mean, dates