def _extremum_(func,ctime,i0,i,var,spline): """Extremum possibly using splines""" nt = len(var) if spline and nt >= 4: # and i != 0 and i != (nt-1) if i == 0: ifirst, ilast = 0, 4 elif i == nt-1: ifirst, ilast = nt-4, nt else: icenter = i - int(var[i-1] > var[i+1]) ifirst = max(icenter-1, 0) ilast = ifirst + 4 if ilast > nt: ilast -= 1 ifirst -= 1 mn_units = 'minutes since %s'%ctime[i0+ifirst] old_rts = cdms2.createAxis(N.asarray([ct.torel(mn_units).value for ct in ctime[i0+ifirst:i0+ilast]],dtype='d')) old_var = MV2.array(var[ifirst:ilast], axes=[old_rts], copyaxes=0) mn_rts = cdms2.createAxis(N.arange(int(old_rts[-1]+1),dtype='d')) mn_var = interp1d(old_var, mn_rts, method='cubic') del old_var, old_rts # mn_var = spline_interpolate(old_rts,var[i-1:i+2],mn_rts) # mn_var = splev(mn_rts, splrep(old_rts,var[ifirst:ilast])) mn_i = func(mn_var) val = mn_var[mn_i] del mn_var this_ctime = cdtime.reltime(mn_i,mn_units).tocomp() else: this_ctime = ctime[i0+i] val = var[i] return val,this_ctime
def _extremum_(func, ctime, i0, i, var, spline): """Extremum possibly using splines""" nt = len(var) if spline and nt >= 4: # and i != 0 and i != (nt-1) if i == 0: ifirst, ilast = 0, 4 elif i == nt - 1: ifirst, ilast = nt - 4, nt else: icenter = i - int(var[i - 1] > var[i + 1]) ifirst = max(icenter - 1, 0) ilast = ifirst + 4 if ilast > nt: ilast -= 1 ifirst -= 1 mn_units = 'minutes since %s' % ctime[i0 + ifirst] old_rts = cdms2.createAxis( N.asarray([ ct.torel(mn_units).value for ct in ctime[i0 + ifirst:i0 + ilast] ], dtype='d')) old_var = MV2.array(var[ifirst:ilast], axes=[old_rts], copyaxes=0) mn_rts = cdms2.createAxis(N.arange(int(old_rts[-1] + 1), dtype='d')) mn_var = interp1d(old_var, mn_rts, method='cubic') del old_var, old_rts # mn_var = spline_interpolate(old_rts,var[i-1:i+2],mn_rts) # mn_var = splev(mn_rts, splrep(old_rts,var[ifirst:ilast])) mn_i = func(mn_var) val = mn_var[mn_i] del mn_var this_ctime = cdtime.reltime(mn_i, mn_units).tocomp() else: this_ctime = ctime[i0 + i] val = var[i] return val, this_ctime
# On crée un trou xe[3:4, 20:30] = MV2.masked # Nouvel axe temporel plus précis from vacumm.misc.axes import create_time #old_time = xe.getTime() old_time = create_time((xe.shape[0], ), 'hours since 2000') xe.setAxis(0, old_time) dt = (old_time[1] - old_time[0]) / 10. new_time = create_time((old_time[0], old_time[-1] + dt, dt), old_time.units) # Interpolation from vacumm.misc.grid.regridding import interp1d # - nearest xe_nea = interp1d(xe, new_time, method='nearest') xe_nea.long_name = 'Nearest' # - linear xe_lin = interp1d(xe, new_time, method='linear') xe_lin.long_name = 'Linear' # - cubic xe_cub = interp1d(xe, new_time, method='cubic') xe_cub.long_name = 'Cubic' # Plots from matplotlib import rcParams rcParams['font.size'] = 8 import pylab as P from vacumm.misc.plot import yhide, xscale, savefigs, hov2, curve2 from vacumm.misc.color import cmap_jets from genutil import minmax
def plot_layer_mod_on_pro(self, model, profiles, varname, depth, select=None, **kwargs): '''Get a layer of variable for a specified depth. :Params: - **varname**: variable to process - **depth**: output depth(s) Other params, see: :func:`coloc_mod_on_pro` ''' self.verbose( 'Plotting layer of colocalized %s on %s\nvarname: %s\ndepth: %s\nselect: %s\nkwargs: %s', model.__class__.__name__, profiles.__class__.__name__, varname, depth, select, kwargs) lons_mod, lats_mod, deps_mod, var_mod = \ self.coloc_mod_on_pro( model, profiles, # If varname is a list of possible names, wrap it into a # tuple of one element as we are requiring only one variable len(numpy.shape(varname)) and (varname,) or varname, select, **kwargs) odep = create_dep(is_iterable(depth) and depth or [depth]) var_mod = var_mod.reorder('-z') var_mod = interp1d(var_mod, axo=odep, xmap=0, xmapper=deps_mod) # Required order: ...z var_mod = var_mod.reorder('z-') model.verbose('layer: %s', var_mod) lons_pro, lats_pro, var_pro = profiles.get_layer(varname, depth, select=select) profiles.verbose('layer: %s', var_pro) # ===== # Tracés vmin = var_pro.min() vmax = var_pro.max() if var_mod.count(): vmin = min(var_mod.min(), vmin) vmax = max(var_mod.max(), vmax) else: self.warning('No model data') if 'latitude' in select: lat_min, lat_max = select['latitude'][:2] else: la = model.get_latitude() lat_min, lat_max = min(la), max(la) if 'longitude' in select: lon_min, lon_max = select['longitude'][:2] else: lo = model.get_longitude() lon_min, lon_max = min(lo), max(lo) levels = auto_scale((vmin, vmax)) vmin = levels[0] vmax = levels[-1] # Création de la palette cmap = cmap_magic(levels) # On trace de champ du modèle moyené sur la période choisie m = map2(lon=(lon_min, lon_max), lat=(lat_min, lat_max), show=False) # On trace le modèle en fond # ===== msca = None try: msca = m.map.scatter(lons_mod, lats_mod, s=100, c=var_mod, vmin=vmin, vmax=vmax, cmap=cmap, label='model') except: self.exception('Failed plotting model data') # ===== # Triangulation du modèle # import matplotlib.tri as tri # triang = tri.Triangulation(lons_mod, lats_mod) # # On trace le modèle en fond # mod = m.axes.tripcolor(triang, var_mod, vmin=vmin, vmax=vmax, cmap=cmap) # ===== # On trace les observations avec des points plus petits psca = None try: psca = m.map.scatter(lons_pro, lats_pro, s=25, c=var_pro, vmin=m.vmin, vmax=m.vmax, cmap=m.cmap, label='profiles') except: self.exception('Failed plotting profile data') # Colorbar if msca is not None: colorbar(msca) elif psca is not None: colorbar(psca)
def generic(var, coefs, units='hours', get_tide=False, only_tide=False, filter_name='Generic', check_regular=False, strict=True, interp_method='cubic', axis=None): """Apply a filter to signal (cdms2 variable) using symetric coefficients. First axis is supposed to be time and regular. - **var**: Data to filter with first axis supposed to be time. - **coefs**: Second half of coefficients. - *strict*: Mask values where at least one value is missing in the filtering interval. - *filter_name*: Name to give to the filter [default: 'Generic'] %s """ # Return? if only_tide: get_tide = True # Coefficients units = unit_type(units) sunits = unit_type(units, string_type=True) coefs = coefs.astype('f') if coefs[-1] != 0.: coefs = N.concatenate((coefs, [ 0., ])) ncoefs = (len(coefs) - 1) * 2 + 1 # Input variable var = MV2.asarray(var) check_axes(var) # Input time axis if axis is None: try: axis = var.getOrder().index('t') except: axis = 0 time = var.getAxis(axis) if check_regular: assert isregular(time), 'Your time axis seems not regular' dt = N.diff(time[:]).mean() if not time.attributes.has_key('units'): time.units = 'hours since 1970-01-01' print 'The time axis of your variable has no units. Assuming : ' + time.units if not time.isTime(): time.designateTime(calendar=cdtime.DefaultCalendar) # Check time range time_range = time[-1] - time[0] coefs_units = sunits + ' ' + ' '.join(time.units.split()[1:]) coefs_range0 = cdtime.r2r(cdtime.reltime(time[0], coefs_units), time.units) coefs_range1 = coefs_range0.add(ncoefs - 1, units) coefs_range = coefs_range1.value - coefs_range0.value coefs_dt = coefs_range0.add(1, units).value - coefs_range0.value if time_range < coefs_range: raise Exception, 'Your sample is shorter than the time range of your coefficients' nt = len(var) # Remap coefficients to data time axis tc = var.dtype.char # print 'dt', dt # print 'coefs_dt', coefs_dt if abs((coefs_dt - dt) / dt) > 0.01: oldx = cdms2.createAxis(N.arange(len(coefs)) * coefs_dt) old_coefs = MV2.array(coefs, axes=[oldx]) newx = cdms2.createAxis(N.arange(0., max(oldx), dt)) coefs = interp1d(old_coefs, newx, interp_method).filled() coefs = N.concatenate((coefs[:0:-1], coefs)) coefs /= N.sum(coefs) ncoefs = len(coefs) # Filtering using convolution fvar = convolve1d(var.filled(0.), coefs, axis=axis, mode='constant') if var.mask is MV2.nomask: mask = N.zeros(nt) else: mask = var.mask.astype('f') fmask = convolve1d(mask, coefs, axis=axis, mode='constant', cval=1.) != 0. fvar = MV2.asarray(fvar) fvar = MV2.masked_where(fmask, fvar, copy=0) # Output variables if not only_tide: fvar.id = var.id + '_cotes' fvar.name = fvar.id if var.attributes.has_key('long_name'): fvar.long_name = 'Tide removed signal from ' + var.long_name.lower( ) fvar.long_name_fr = 'Signal sans la maree' if var.attributes.has_key('units'): fvar.units = var.units fvar.setAxis(0, time) fvar.filter_coefficients = coefs fvar.filter_name = filter_name res = [ fvar, ] if get_tide: tvar = var - fvar tvar.id = 'tidal_' + var.id tvar.name = tvar.id if var.attributes.has_key('long_name'): tvar.long_name = 'Tidal signal from ' + var.long_name.lower() if var.attributes.has_key('units'): tvar.units = var.units tvar.setAxis(0, time) tvar.filter_coefficients = coefs tvar.filter_name = filter_name if only_tide: return tvar res.append(tvar) if isinstance(res, list) and len(res) == 1: return res[0] else: return res
def generic(var,coefs,units='hours',get_tide=False,only_tide=False,filter_name='Generic', check_regular=False,strict=True, interp_method='cubic', axis=None): """Apply a filter to signal (cdms2 variable) using symetric coefficients. First axis is supposed to be time and regular. - **var**: Data to filter with first axis supposed to be time. - **coefs**: Second half of coefficients. - *strict*: Mask values where at least one value is missing in the filtering interval. - *filter_name*: Name to give to the filter [default: 'Generic'] %s """ # Return? if only_tide: get_tide = True # Coefficients units = unit_type(units) sunits = unit_type(units, string_type=True) coefs = coefs.astype('f') if coefs[-1] != 0.: coefs = N.concatenate((coefs,[0.,])) ncoefs = (len(coefs)-1)*2+1 # Input variable var = MV2.asarray(var) check_axes(var) # Input time axis if axis is None: try: axis = var.getOrder().index('t') except: axis = 0 time = var.getAxis(axis) if check_regular: assert isregular(time), 'Your time axis seems not regular' dt = N.diff(time[:]).mean() if not time.attributes.has_key('units'): time.units = 'hours since 1970-01-01' print 'The time axis of your variable has no units. Assuming : '+time.units if not time.isTime(): time.designateTime(calendar=cdtime.DefaultCalendar) # Check time range time_range = time[-1]-time[0] coefs_units = sunits+' '+' '.join(time.units.split()[1:]) coefs_range0 = cdtime.r2r(cdtime.reltime(time[0],coefs_units),time.units) coefs_range1 = coefs_range0.add(ncoefs-1,units) coefs_range = coefs_range1.value - coefs_range0.value coefs_dt = coefs_range0.add(1,units).value - coefs_range0.value if time_range < coefs_range: raise Exception,'Your sample is shorter than the time range of your coefficients' nt = len(var) # Remap coefficients to data time axis tc = var.dtype.char # print 'dt', dt # print 'coefs_dt', coefs_dt if abs((coefs_dt-dt)/dt) > 0.01: oldx = cdms2.createAxis(N.arange(len(coefs))*coefs_dt) old_coefs = MV2.array(coefs, axes=[oldx]) newx = cdms2.createAxis(N.arange(0.,max(oldx),dt)) coefs = interp1d(old_coefs, newx, interp_method).filled() coefs = N.concatenate((coefs[:0:-1],coefs)) coefs /= N.sum(coefs) ncoefs = len(coefs) # Filtering using convolution fvar = convolve1d(var.filled(0.), coefs, axis=axis, mode='constant') if var.mask is MV2.nomask: mask = N.zeros(nt) else: mask = var.mask.astype('f') fmask = convolve1d(mask, coefs, axis=axis, mode='constant', cval=1.)!=0. fvar = MV2.asarray(fvar) fvar = MV2.masked_where(fmask, fvar, copy=0) # Output variables if not only_tide: fvar.id = var.id+'_cotes' fvar.name = fvar.id if var.attributes.has_key('long_name'): fvar.long_name = 'Tide removed signal from '+var.long_name.lower() fvar.long_name_fr = 'Signal sans la maree' if var.attributes.has_key('units'): fvar.units = var.units fvar.setAxis(0,time) fvar.filter_coefficients = coefs fvar.filter_name = filter_name res = [fvar,] if get_tide: tvar = var-fvar tvar.id = 'tidal_'+var.id tvar.name = tvar.id if var.attributes.has_key('long_name'): tvar.long_name = 'Tidal signal from '+var.long_name.lower() if var.attributes.has_key('units'): tvar.units = var.units tvar.setAxis(0,time) tvar.filter_coefficients = coefs tvar.filter_name = filter_name if only_tide: return tvar res.append(tvar) if isinstance(res, list) and len(res) == 1: return res[0] else: return res
# On crée un trou xe[3:4, 20:30] = MV2.masked # Nouvel axe temporel plus précis from vacumm.misc.axes import create_time #old_time = xe.getTime() old_time=create_time((xe.shape[0], ), 'hours since 2000') xe.setAxis(0, old_time) dt = (old_time[1]-old_time[0])/10. new_time = create_time((old_time[0], old_time[-1]+dt, dt), old_time.units) # Interpolation from vacumm.misc.grid.regridding import interp1d # - nearest xe_nea = interp1d(xe, new_time, method='nearest') xe_nea.long_name = 'Nearest' # - linear xe_lin = interp1d(xe, new_time, method='linear') xe_lin.long_name = 'Linear' # - cubic xe_cub = interp1d(xe, new_time, method='cubic') xe_cub.long_name = 'Cubic' # Plots from matplotlib import rcParams ; rcParams['font.size'] = 8 import pylab as P from vacumm.misc.plot import yhide, xscale, savefigs, hov2, curve2 from vacumm.misc.color import cmap_jets from genutil import minmax vmin, vmax = minmax(xe, xe_lin)
def plot_layer_mod_on_pro(self, model, profiles, varname, depth, select=None, **kwargs): '''Get a layer of variable for a specified depth. :Params: - **varname**: variable to process - **depth**: output depth(s) Other params, see: :func:`coloc_mod_on_pro` ''' self.verbose('Plotting layer of colocalized %s on %s\nvarname: %s\ndepth: %s\nselect: %s\nkwargs: %s', model.__class__.__name__, profiles.__class__.__name__, varname, depth, select, kwargs) lons_mod, lats_mod, deps_mod, var_mod = \ self.coloc_mod_on_pro( model, profiles, # If varname is a list of possible names, wrap it into a # tuple of one element as we are requiring only one variable len(numpy.shape(varname)) and (varname,) or varname, select, **kwargs) odep = create_dep(is_iterable(depth) and depth or [depth]) var_mod = var_mod.reorder('-z') var_mod = interp1d(var_mod, axo=odep, xmap=0, xmapper=deps_mod) # Required order: ...z var_mod = var_mod.reorder('z-') model.verbose('layer: %s', var_mod) lons_pro, lats_pro, var_pro = profiles.get_layer(varname, depth, select=select) profiles.verbose('layer: %s', var_pro) # ===== # Tracés vmin = var_pro.min() vmax = var_pro.max() if var_mod.count(): vmin = min(var_mod.min(), vmin) vmax = max(var_mod.max(), vmax) else: self.warning('No model data') if 'latitude' in select: lat_min, lat_max = select['latitude'][:2] else: la = model.get_latitude() lat_min, lat_max = min(la), max(la) if 'longitude' in select: lon_min, lon_max = select['longitude'][:2] else: lo = model.get_longitude() lon_min, lon_max = min(lo), max(lo) levels = auto_scale((vmin, vmax)) vmin = levels[0] vmax = levels[-1] # Création de la palette cmap = cmap_magic(levels) # On trace de champ du modèle moyené sur la période choisie m = map2(lon=(lon_min, lon_max), lat=(lat_min, lat_max), show=False) # On trace le modèle en fond # ===== msca = None try: msca = m.map.scatter(lons_mod, lats_mod, s=100, c=var_mod, vmin=vmin, vmax=vmax, cmap=cmap, label='model') except: self.exception('Failed plotting model data') # ===== # Triangulation du modèle # import matplotlib.tri as tri # triang = tri.Triangulation(lons_mod, lats_mod) # # On trace le modèle en fond # mod = m.axes.tripcolor(triang, var_mod, vmin=vmin, vmax=vmax, cmap=cmap) # ===== # On trace les observations avec des points plus petits psca = None try: psca = m.map.scatter(lons_pro, lats_pro, s=25, c=var_pro, vmin=m.vmin, vmax=m.vmax, cmap=m.cmap, label='profiles') except: self.exception('Failed plotting profile data') # Colorbar if msca is not None: colorbar(msca) elif psca is not None: colorbar(psca)