def fieldmean(resource): """ calculating of a weighted field mean :param resource: str or list of str containing the netCDF files pathes :return list: timeseries of the averaged values per timepstep """ data = get_values(resource) # np.squeeze(ds.variables[variable][:]) # dim = data.shape LOGGER.debug(data.shape) if len(data.shape) == 3: # TODO if data.shape == 2 , 4 ... lats, lons = get_coordinates(resource, unrotate=False) lats = array(lats) if len(lats.shape) == 2: lats = lats[:, 0] else: LOGGER.debug('Latitudes not reduced to 1D') # TODO: calculat weighed average with 2D lats (rotated pole coordinates) # lats, lons = get_coordinates(resource, unrotate=False) # if len(lats.shape) == 2: # lats, lons = get_coordinates(resource) lat_index = get_index_lat(resource) LOGGER.debug('lats dimension %s ' % len(lats.shape)) LOGGER.debug('lats index %s' % lat_index) lat_w = sqrt(cos(lats * radians(1))) meanLon = average(data, axis=lat_index, weights=lat_w) meanTimeserie = average(meanLon, axis=1) LOGGER.debug('fieldmean calculated') else: LOGGER.error('not 3D shaped data. Average can not be calculated') return meanTimeserie
def map_spatial_analog(ncfile, variable='dissimilarity', cmap='viridis', title='Spatial analog'): """Return a matplotlib Figure instance showing a map of the dissimilarity measure. """ import netCDF4 as nc from blackswan import utils from mpl_toolkits.axes_grid import make_axes_locatable import matplotlib.axes as maxes try: var = utils.get_values(ncfile, variable) LOGGER.info('Data loaded') lats, lons = utils.get_coordinates(ncfile, variable=variable, unrotate=False) if len(lats.shape) == 1: cyclic_var, cyclic_lons = add_cyclic_point(var, coord=lons) lons = cyclic_lons.data var = cyclic_var with nc.Dataset(ncfile) as D: V = D.variables[variable] lon, lat = map(float, V.target_location.split(',')) LOGGER.info('Lat and lon loaded') except Exception as e: msg = 'Failed to get data for plotting: {0}\n{1}'.format(ncfile, e) LOGGER.exception(msg) raise Exception(msg) try: fig = plt.figure(facecolor='w', edgecolor='k') fig.subplots_adjust(top=.95, bottom=.05, left=.03, right=.95) ax = plt.axes( projection=ccrs.Robinson(central_longitude=int(np.mean(lons)))) divider = make_axes_locatable(ax) cax = divider.new_horizontal("4%", pad=0.15, axes_class=maxes.Axes) fig.add_axes(cax) ax.plot(lon, lat, marker='o', mfc='#292421', ms=13, transform=ccrs.PlateCarree()) ax.plot(lon, lat, marker='o', mfc='#ffffff', ms=7, transform=ccrs.PlateCarree()) cs = ax.contourf(lons, lats, var, 60, transform=ccrs.PlateCarree(), cmap=cmap, interpolation='nearest') ax.coastlines(color='k', linewidth=.8) ax.set_title(title) cb = plt.colorbar(cs, cax=cax, orientation='vertical') cb.set_label(u"– Dissimilarity +") # ha='left', va='center') cb.set_ticks([]) except: msg = 'failed to plot graphic' LOGGER.exception(msg) LOGGER.info('Plot created and figure saved') return fig
def map_robustness(signal, high_agreement_mask, low_agreement_mask, variable=None, cmap='seismic', title=None, file_extension='png'): """ generates a graphic for the output of the ensembleRobustness process for a lat/long file. :param signal: netCDF file containing the signal difference over time :param highagreement: :param lowagreement: :param variable: :param cmap: default='seismic', :param title: default='Model agreement of signal' :returns str: path/to/file.png """ from blackswan import utils from numpy import mean, ma if variable is None: variable = utils.get_variable(signal) try: var_signal = utils.get_values(signal) mask_l = utils.get_values(low_agreement_mask) mask_h = utils.get_values(high_agreement_mask) # mask_l = ma.masked_where(low < 0.5, low) # mask_h = ma.masked_where(high < 0.5, high) # mask_l[mask_l == 0] = np.nan # mask_h[mask_h == 0] = np.nan LOGGER.info('data loaded') lats, lons = utils.get_coordinates(signal, unrotate=True) if len(lats.shape) == 1: cyclic_var, cyclic_lons = add_cyclic_point(var_signal, coord=lons) mask_l, cyclic_lons = add_cyclic_point(mask_l, coord=lons) mask_h, cyclic_lons = add_cyclic_point(mask_h, coord=lons) lons = cyclic_lons.data var_signal = cyclic_var LOGGER.info('lat lon loaded') minval = round(np.nanmin(var_signal)) maxval = round(np.nanmax(var_signal)+.5) LOGGER.info('prepared data for plotting') except: msg = 'failed to get data for plotting' LOGGER.exception(msg) raise Exception(msg) try: fig = plt.figure(facecolor='w', edgecolor='k') ax = plt.axes(projection=ccrs.Robinson(central_longitude=int(mean(lons)))) norm = MidpointNormalize(midpoint=0) cs = plt.contourf(lons, lats, var_signal, 60, norm=norm, transform=ccrs.PlateCarree(), cmap=cmap, interpolation='nearest') cl = plt.contourf(lons, lats, mask_l, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '/']) ch = plt.contourf(lons, lats, mask_h, 1, transform=ccrs.PlateCarree(), colors='none', hatches=[None, '.']) # artists, labels = ch.legend_elements() # plt.legend(artists, labels, handleheight=2) # plt.clim(minval,maxval) ax.coastlines() ax.gridlines() # ax.set_global() if title is None: plt.title('%s with Agreement' % variable) else: plt.title(title) plt.colorbar(cs) plt.annotate('// = low model ensemble agreement', (0, 0), (0, -10), xycoords='axes fraction', textcoords='offset points', va='top') plt.annotate('.. = high model ensemble agreement', (0, 0), (0, -20), xycoords='axes fraction', textcoords='offset points', va='top') graphic = fig2plot(fig=fig, file_extension=file_extension) plt.close() LOGGER.info('Plot created and figure saved') except: msg = 'failed to plot graphic' LOGGER.exception(msg) return graphic
def localdims_par(resource, ap=0.5, variable=None, distance='euclidean'): """ calculating of a local dimentions and persistence :param resource: str or list of str containing the netCDF file path :return 2 arrays: local dimentions and persistence """ # =================================================== # only for linux try: mkl_rt = ctypes.CDLL('libmkl_rt.so') nth = mkl_rt.mkl_get_max_threads() mkl_rt.mkl_set_num_threads(ctypes.byref(ctypes.c_int(64))) nth = mkl_rt.mkl_get_max_threads() environ['MKL_NUM_THREADS'] = str(nth) environ['OMP_NUM_THREADS'] = str(nth) except: pass # ================================================================ if variable is None: variable = get_variable(resource) data = get_values(resource, variable=variable) lat_index = get_index_lat(resource, variable=variable) lon_index = get_index_lon(resource, variable=variable) # TODO: should be 3D with TIME first. # Think how to operate with 4D and unknown stucture (lat,lon,level,time) for expample. # dat=data.reshape((data.shape[0],data.shape[1]*data.shape[2])) global glob_dat glob_dat = data.reshape( (data.shape[0], data.shape[lat_index] * data.shape[lon_index])) # Quantile definition global glob_quanti glob_quanti = 0.98 # npoints=np.size(dat,0) # npoints=np.size(data,0) npoints = len(data[:, 0]) dim = np.empty((npoints)) dim.fill(np.nan) theta = np.empty((npoints)) theta.fill(np.nan) global glob_abal glob_abal = ap global glob_distance glob_distance = distance # global dat as list to be used by pool.map l_dat = [glob_dat[i, :].reshape(1, -1) for i in range(npoints)] # multi CPU pool = Pool() res_p = pool.map(_calc_dist, l_dat) pool.close() pool.join() # collect results for i, j in enumerate(res_p): dim[i] = res_p[i][0] theta[i] = res_p[i][1] return dim, theta
def localdims(resource, ap=0.5, variable=None, distance='euclidean'): """ calculating of a local dimentions and persistence :param resource: str or list of str containing the netCDF file path :return 2 arrays: local dimentions and persistence """ if variable is None: variable = get_variable(resource) data = get_values(resource, variable=variable) lat_index = get_index_lat(resource, variable=variable) lon_index = get_index_lon(resource, variable=variable) # TODO: should be 3D with TIME first. # Think how to operate with 4D and unknown stucture (lat,lon,level,time) for expample. # dat=data.reshape((data.shape[0],data.shape[1]*data.shape[2])) dat = data.reshape( (data.shape[0], data.shape[lat_index] * data.shape[lon_index])) # Quantile definition quanti = 0.98 # npoints=np.size(dat,0) # npoints=np.size(data,0) npoints = len(data[:, 0]) dim = np.empty((npoints)) dim.fill(np.nan) theta = np.empty((npoints)) theta.fill(np.nan) l = 0 # Calculation of total distance matrix dist = cdist(dat, dat, metric=distance) print np.shape(dist) # 0.5 = Python and Mathlab, 1 = R abal = ap # abal=0.5 for l in range(npoints): distance = dist[:, l] logdista = -np.log(distance) x = logdista[~np.isinf(logdista)] logdista = x[~np.isnan(x)] thresh = mquantiles(logdista, quanti, alphap=abal, betap=abal) # NOT ORIGINAL logdista = -np.log(distance) Li = [ i for i in range(len(logdista)) if (logdista[i] > thresh) and (logdista[i] < 0) ] Ti = np.diff(Li) N = len(Ti) q = 1. - quanti Si = Ti - 1 Ncc = [i for i in range(len(Si)) if (Si[i] > 0)] Nc = len(Ncc) theta[l] = (sum(q * Si) + N + Nc - np.sqrt(( (sum(q * Si) + N + Nc)**2) - 8 * Nc * sum(q * Si))) / (2 * sum(q * Si)) logdista = np.sort(logdista) findidx = [ i for i in range(len(logdista)) if (logdista[i] > thresh) and (logdista[i] < 0) ] logextr = logdista[findidx[0]:len(logdista) - 1] # logextr=logdista[findidx[[1]]:(length(logdista)-1)] dim[l] = 1 / np.mean(logextr - thresh) return dim, theta