def systematic_bias(self): """ Biais systematique (+1: sous-estimation du modele, -1: sur-estimation du modele) """ import numpy as np import cdms2 from vacumm.misc.grid import get_grid, set_grid map_bias = list() #Initialise une liste # Estimation de la moyenne a chaque pas de temps tps = self.obs.getTime() for i, t in enumerate(tps): map_bias.append(np.sign(self.obs[i, :, :]-self.model[i, :, :] )) map_bias = cdms2.createVariable(map_bias,typecode='f',id='computation') res = np.sum(map_bias, axis=0) res # Trouve valeurs egale a la longueur de la serie temporelle (<=> uniquement valeurs positives) one = (res==len(map_bias)).nonzero() # Trouve valeurs egales a moins la longueur de la serie temporelle (<=> uniquement valeurs negatives) mone = (res==-len(map_bias)).nonzero() self.biassyst = np.zeros(res.shape) self.biassyst[one]=1. self.biassyst[mone]=-1. self.biassyst = cdms2.createVariable(self.biassyst, typecode='f',id='syst_bias') ggm = get_grid(self.model) set_grid(self.biassyst, ggm, axes=True)
def density(temp, sal, depth=None, lat=None, potential=False, getdepth=False, getlat=False, format_axes=False): """Compute density from temperature, salinity and depth (and latitude) :Params: - **temp**: Insitu or potential temperature. - **sal**: Salinity. - **depth**, optional: Depth at temperature and salinty points. Assumed to be 0 if not found. - **lat**, optional: Latitude. Error when not found. - **potential**, optional: True to get the potential density (at atmospheric pressure). :Algo: >>> pressure = seawater.csiro.pres(depth, lat) >>> density = seawater.csiro.dens(sal, temp, depth) """ # Compute if not potential and depth is not False: # In-situ # Get depth and latitude lat = grow_lat(temp, lat, mode='raise', getvar=False) if lat is None: raise VACUMMError('No latitude found for density') depth = grow_depth(temp, depth, mode='raise', getvar=False) if N.abs(depth.max()) < N.abs(depth.min()): # positive depth = -depth if (depth.asma() < 0).any(): depth = depth - depth.min() # top=0 # Get density pres = sw_pres(depth, lat) dens = sw_dens(sal, temp, pres) del pres else: # Potential dens = sw_dens0(sal, temp) getdepth = getlat = False # Format dens.setAxisList(temp.getAxisList()) set_grid(dens, get_grid(temp)) format_var(dens, 'dens', format_axes=format_axes) # Out if not getdepth and not getlat: return dens dens = dens, if getdepth: dens += depth, if getlat: dens += lat, return dens
def systematic_bias(self): """ Biais systematique (+1: sous-estimation du modele, -1: sur-estimation du modele) """ import numpy as np import cdms2 from vacumm.misc.grid import get_grid, set_grid map_bias = list() #Initialise une liste # Estimation de la moyenne a chaque pas de temps tps = self.obs.getTime() for i, t in enumerate(tps): map_bias.append(np.sign(self.obs[i, :, :] - self.model[i, :, :])) map_bias = cdms2.createVariable(map_bias, typecode='f', id='computation') res = np.sum(map_bias, axis=0) res # Trouve valeurs egale a la longueur de la serie temporelle (<=> uniquement valeurs positives) one = (res == len(map_bias)).nonzero() # Trouve valeurs egales a moins la longueur de la serie temporelle (<=> uniquement valeurs negatives) mone = (res == -len(map_bias)).nonzero() self.biassyst = np.zeros(res.shape) self.biassyst[one] = 1. self.biassyst[mone] = -1. self.biassyst = cdms2.createVariable(self.biassyst, typecode='f', id='syst_bias') ggm = get_grid(self.model) set_grid(self.biassyst, ggm, axes=True)
def kinetic_energy(sshuv, gravity=default_gravity, format_axes=None, dxy=None): """Compute kinetic energy in m2.s-2 either from SSH or velocity on C-grid .. todo:: Rewrite it using :mod:`vacumm.data.misc.arakawa` and defining a limited number of algorithms for different staggering configurations. :Params: - **sshuv**: SSH or (U,V). - If SSH, geostrophic velocity is computed at U and V points using :func:`barotropic_geostrophic_velocity`. - If (U,V), velocities are supposed to be at V and U points. - **dxy**, optional: Horizontal resolutions (see :func:`barotropic_geostrophic_velocity`). :Return: KE at T points. """ # Init and get velocities if cdms2.isVariable(sshuv): # from SSH ke = sshuv*MV2.masked u, v = barotropic_geostrophic_velocity(sshuv, dxy=dxy, gravity=gravity, format_axes=format_axes) if format_axes is None: format_axes = False else: # from (U,V) u, v = sshuv ke = u*MV2.masked if format_axes is None: format_axes = True gridt = shiftgrid(u.getGrid(), jshift=1) set_grid(ke, gridt) # Sum contributions uf = u.filled(0.) vf = v.filled(0.) ke[..., 1:, :] = uf[..., 1:, :]**2 ke[..., 1:, :] += uf[..., :-1, :]**2 ke[..., 1:] += vf[..., :-1]**2 ke[..., 1:] += vf[..., :-1]**2 # Weight and mask count = N.zeros(ke.shape, 'i') gu = 1-N.ma.getmaskarray(u).astype('i') gv = 1-N.ma.getmaskarray(v).astype('i') count[1:] = gu[:-1] count[1:] += gu[1:] count[:, 1:] += gv[:, :-1] count[:, 1:] += gv[:, 1:] del gu, gv mask = count==0 count[mask] = 1 ke[:] /= count ke[:] = MV2.masked_where(mask, ke, copy=0) del mask, count # Format if format_axes: format_grid(gridt, 't') return format_var(ke, "ke", format_axes=False)
def density(temp, sal, depth=None, lat=None, potential=False, getdepth=False, getlat=False, format_axes=False): """Compute density from temperature, salinity and depth (and latitude) :Params: - **temp**: Insitu or potential temperature. - **sal**: Salinity. - **depth**, optional: Depth at temperature and salinty points. Assumed to be 0 if not found. - **lat**, optional: Latitude. Error when not found. - **potential**, optional: True to get the potential density (at atmospheric pressure). :Algo: >>> pressure = seawater.csiro.pres(depth, lat) >>> density = seawater.csiro.dens(sal, temp, depth) """ # Compute if not potential and depth is not False: # In-situ # Get depth and latitude lat = grow_lat(temp, lat, mode='raise', getvar=False) if lat is None: raise VACUMMError('No latitude found for density') depth = grow_depth(temp, depth, mode='raise', getvar=False) if N.abs(depth.max())<N.abs(depth.min()): # positive depth = -depth if (depth.asma()<0).any(): depth = depth-depth.min() # top=0 # Get density pres = sw_pres(depth, lat) dens = sw_dens(sal, temp, pres) ; del pres else: # Potential dens = sw_dens0(sal, temp) getdepth = getlat = False # Format dens.setAxisList(temp.getAxisList()) set_grid(dens, get_grid(temp)) format_var(dens, 'dens', format_axes=format_axes) # Out if not getdepth and not getlat: return dens dens = dens, if getdepth: dens += depth, if getlat: dens += lat, return dens
def temporal_corr(self): """ Correlation entre modele et observations - calculee en chaque point sur la dimension temporelle / Resultat => Carte de Correlation uncentered and biased """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid self.temp_corr = () #Initialise un tuple self.temp_corr = statistics.correlation(self.model, self.obs, axis=0) gg = get_grid(self.model) set_grid(self.temp_corr, gg, axes=True)
def temporal_corr(self): """ Correlation entre modele et observations - calculee en chaque point sur la dimension temporelle / Resultat => Carte de Correlation uncentered and biased """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid self.temp_corr = () #Initialise un tuple self.temp_corr = statistics.correlation(self.model, self.obs, axis = 0) gg = get_grid(self.model) set_grid(self.temp_corr, gg, axes=True)
def obs_coverage(self): """ Calcul du taux de couverture des observations en chaque point sur la periode """ import numpy as np from vacumm.misc.grid import get_grid, set_grid import cdms2 self.obs_cov = () #Initialise un tuple self.obs_cov = cdms2.createVariable(self.obs.count(axis=0),typecode='f',id='obs_cov', attributes=dict(units='%')) self.obs_cov = self.obs_cov / len(self.obs) * 100. gg = get_grid(self.obs) set_grid(self.obs_cov, gg, axes=True)
def temporal_rmsc(self): """ RMS entre modele et observations - calculee en chaque point sur la dimension temporelle / Resultat => Carte de RMS centered and biased """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid self.temp_rmsc = () #Initialise un tuple self.temp_rmsc = statistics.rms(self.model, self.obs, axis = 0, centered = 1) gg = get_grid(self.model) set_grid(self.temp_rmsc, gg, axes=True)
def temporal_rmsc(self): """ RMS entre modele et observations - calculee en chaque point sur la dimension temporelle / Resultat => Carte de RMS centered and biased """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid self.temp_rmsc = () #Initialise un tuple self.temp_rmsc = statistics.rms(self.model, self.obs, axis=0, centered=1) gg = get_grid(self.model) set_grid(self.temp_rmsc, gg, axes=True)
def obs_coverage(self): """ Calcul du taux de couverture des observations en chaque point sur la periode """ import numpy as np from vacumm.misc.grid import get_grid, set_grid import cdms2 self.obs_cov = () #Initialise un tuple self.obs_cov = cdms2.createVariable(self.obs.count(axis=0), typecode='f', id='obs_cov', attributes=dict(units='%')) self.obs_cov = self.obs_cov / len(self.obs) * 100. gg = get_grid(self.obs) set_grid(self.obs_cov, gg, axes=True)
def temporal_std(self): """ Ecart-type en chaque point geographique """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid # centered and biased std (cf. http://www2-pcmdi.llnl.gov/cdat/manuals/cdutil/cdat_utilities-2.html) self.model.temp_std = () #Initialise un tuple self.obs.temp_std = () #Initialise un tuple self.model.temp_std = statistics.std(self.model, axis=0) self.obs.temp_std = statistics.std(self.obs, axis=0) ggm = get_grid(self.model) set_grid(self.model.temp_std, ggm, axes=True) ggo = get_grid(self.obs) set_grid(self.obs.temp_std, ggm, axes=True)
def temporal_std(self): """ Ecart-type en chaque point geographique """ from genutil import statistics from vacumm.misc.grid import get_grid, set_grid # centered and biased std (cf. http://www2-pcmdi.llnl.gov/cdat/manuals/cdutil/cdat_utilities-2.html) self.model.temp_std = () #Initialise un tuple self.obs.temp_std = () #Initialise un tuple self.model.temp_std = statistics.std(self.model, axis = 0) self.obs.temp_std = statistics.std(self.obs, axis = 0) ggm = get_grid(self.model) set_grid(self.model.temp_std, ggm, axes=True) ggo = get_grid(self.obs) set_grid(self.obs.temp_std, ggm, axes=True)
def read(self): """ Lecture des fichiers NetCDF de NAR SST """ import cdms2,sys,os, glob import numpy,MV2 import cdtime from vacumm.misc.axes import create_lon from vacumm.misc.grid import create_grid, set_grid from vacumm.misc.atime import create_time from vacumm.misc.phys.units import kel2degc # -- Dans le cas d'un NAR SST on lit la grille lon lat dans le fichier grid # -- Lecture de la grille znar=self.ZONE_NAR gridfile="grid_%(znar)s.nc"%vars() f=cdms2.open(gridfile) la = f('latitude') lo = f('longitude') f.close() # -- Creation des axes longitude et latitude lat_axis = create_lon(la,id='latitude') lon_axis = create_lon(lo,id='longitude') # -- Creation de la grille grid = create_grid(lon_axis, lat_axis) # -- Creation d'un objet cdms nomme self.data et d'un tableau cumt pour les dates extraites des noms de fichiers self.data = () #Initialise un tuple # =============== ATTENTION ==================== # Initialiser self.data pour ne pas dupliquer en memoire !!!!!!!!! # ============================================ #cumt = [] # Initialise un array # -- Boucle sur les fichiers presents dans le WORKDIR #url_file_def="%(YYYY)s%(MM)s%(DD)s%(HH)s%(ext)s"%vars() #self.ctdeb # -- Ancienne methode #files = glob.glob(os.path.join(self.WORKDIR, '2*.nc')) #files.sort() # -- # -- Methode amelioree # Cree une liste files = [] # Cree la liste des fichiers correspondants a la periode consideree ctest = self.ctdeb while ctest <= self.ctfin: flnme_only = '%(#)04d%(##)02d%(###)02d*.nc'%{'#':ctest.year, '##':ctest.month, '###':ctest.day} files.extend(glob.glob(os.path.join(self.WORKDIR, flnme_only))) ctest=ctest.add(1,cdtime.Days) # -- for filename in files: # -- Lecture du fichier filename f = cdms2.open(filename) temp = f('sea_surface_temperature') # =============== ATTENTION ================================== # Verifier que temp utilise tout le temps le meme espace memoire ... voir du cote de cdms # ========================================================== f.close() # -- Extraction de la date et heure du nom du fichier #ty = numpy.int(filename[-15:-11]) #tm = numpy.int(filename[-11:-9]) #tj = numpy.int(filename[-9:-7]) #th = numpy.int(filename[-7:-5]) #tt = cdtime.comptime(ty,tm,tj,th) #cumt.append(tt) # -- Transfert de temp dans l'objet cdat self.data (concatenation) # =============== ATTENTION ==================== # Faire une variable intermediaire qui sera au prealable allouee en memoire pour eviter # trop de copies en memoire !!!!!!!!!!!!!!!! # ============================================ self.data += temp, # -- Creation de l'axe temporel #taxis = create_time(cumt) # -- MV2.concatenate pour concatener les informations dans self.data (entre autre construit l'axe temporel) self.data = MV2.concatenate(self.data) # -- Attribution de la grille a l'objet self.data set_grid(self.data, grid, axes=True) # -- Informations sur le dataset self.data.name = "NAR_SST" self.data.units = "degree_Celsius" self.data.standard_name = "satellite_sea_surface_temperature" self.data.long_name = "Satellite Sea Surface Temperature - NAR" # -- Change unit self.data = kel2degc(self.data)
def mixed_layer_depth(data, depth=None, lat=None, zaxis=None, mode=None, deltatemp=.2, deltadens=.01, kzmax=0.0005, potential=True, format_axes=False): """Get mixed layer depth from temperature and salinity :Params: - **temp**: Insitu or potential temperature. - **sal**: Salinity. - **depth**, optional: Depth at temperature and salinty points. - **lat**, optional: Latitude. - **mode**, optional: ``"deltatemp"``, ``"deltadens"``, ``"kz"`` or ``"twolayers"`` :Raise: :class:`~vacumm.VACUMMError` if can't get depth (and latitude for density). """ # TODO: positive up # Inspection if isinstance(data, tuple): # data = temp,sal temp, sal=data # Get density if mode!='deltatemp': res = density(temp, sal, depth=depth, lat=lat, format_axes=False, potential=potential, getdepth=True) if isinstance(res, tuple): dens, depth = res else: dens = res dens = dens.asma() if mode is None: mode = 'deltadens' else: temp = data[0] # Check mode if mode == 'kz': warn("Switching MLD computation mode to 'deltadens'") mode = "deltadens" elif match_var(data, 'temp', mode='nslu'): if mode is not None and mode!='deltatemp': warn("Switching MLD computation mode to 'deltatemp'") mode = 'deltatemp' temp = data elif match_var(data, 'dens', mode='nslu'): if mode in ['kz', 'deltatemp']: warn("Switching MLD computation mode to 'deltadens'") mode = None if mode is None: mode = "deltadens" dens = data elif match_var(data, 'kz', mode='nslu'): if mode is None: mode = "kz" if mode != "kz": warn("Switching MLD computation mode to 'kz'") kz = data else: if mode in ['deltadens', 'twolayers']: dens = data elif mode == "deltatemp": temp = data elif mode == "kz": kz = data elif mode is not None: raise VACUMMError("Invalid MLD computation mode : '%s'"%mode) else: raise VACUMMError("Can't guess MLD computation mode") temp = delta # Find Z dim data0 = data[0] if isinstance(data, tuple) else data depth = grow_depth(data0, depth, mode='raise', getvar=False) zaxis = get_zdim(data0, axis=zaxis) if zaxis is None: raise VACUMMError("Can't guess zaxis") slices = get_axis_slices(data0, zaxis) # Init MLD axes = data0.getAxisList() del axes[zaxis] mld = MV2.array(data0.asma()[slices['first']], copy=1, axes=axes, copyaxes=False) set_grid(mld, get_grid(data0)) format_var(mld, 'mld', format_axes=format_axes) mld[:] = MV2.masked # Two-layers if mode=='twolayers': densbot = dens[slices['first']] denstop = dens[slices['last']] del dens H = 1.5*depth[slices['first']] - 0.5*depth[slices['firstp1']] H = -1.5*depth[slices['last']] + 0.5*depth[slices['lastm1']] mld[:] = -H*(densbot-denstop)/(densbot-denstop) del H elif mode=='deltadens': denscrit = dens[slices['last']]+deltadens mld[:] = -_val2z_(dens, depth, denscrit, zaxis, -1) del dens elif mode=='deltatemp': tempcrit = temp[slices['last']]-deltatemp mld[:] = -_val2z_(temp, depth, tempcrit, zaxis, 1) elif mode=='kz': mld[:] = -_valmin2z_(kz, depth, kzmax, zaxis, 1) else: raise VACUMMError("Invalid mode for computing MLD (%s)."%mode + "Please choose one of: deltadens, twolayers") # Mask zeros mld[:] = MV2.masked_values(mld, 0., copy=0) return mld
def _template_t2ht_(self, tpl): htpl = MV2.resize(tpl.astype('l'), (self.nbins,)+tpl.shape) htpl.setAxisList([self._baxis]+tpl.getAxisList()) set_grid(htpl, get_grid(tpl)) cp_atts(tpl, htpl) return htpl
def barotropic_geostrophic_velocity(ssh, dxy=None, gravity=default_gravity, cyclic=False, format_axes=True, getu=True, getv=True, filter=None): """Get barotropic geostropic velocity from SSH on a C-grid .. note:: ssh is supposed to be at T points, ubt is computed at V points, and vbt is computed at U points. .. todo:: Rewrite it using :mod:`vacumm.data.misc.arakawa` and defining a limited number of algorithms for different staggering configurations. :Params: - **ssh**: Sea surface height. - **dxy**, optional: Horizontal resolutions (m). Resolution along X and Y are respectively at U and V points. Possible forms: - ``res``: A scalar meaning a constant resolution along X and Y. - ``(dx,dy)``: A tuple of resolutions along X and Y. - ``None``: Resolution is estimated using :func:`~vacumm.misc.grid.misc.resol`. :Return: ``(ubt,vbt)`` """ if not getu and not getv: return # Init masked if getu: ugbt = format_var(ssh * MV2.masked, 'ugbt', format_axes=False) if getv: vgbt = format_var(ssh * MV2.masked, 'vgbt', format_axes=False) # Grid tgrid = ssh.getGrid() if getu: ugrid = shiftgrid(tgrid, ishift=0.5) if getv: vgrid = shiftgrid(tgrid, jshift=0.5) if format_axes: if getv: format_grid(ugrid, 'u') if getu: format_grid(vgrid, 'v') if getu: set_grid(ugbt, vgrid) if getv: set_grid(vgbt, ugrid) # Resolutions if dxy is None: dxt, dyt = resol(ssh, proj=True, mode='local') dxu = 0.5 * (dxt[:, 1:] + dxt[:, :-1]) del dxt dyv = 0.5 * (dyt[1:, :] + dyt[:-1, :]) del dyt elif not isinstance(dxy, (list, tuple)): dxu = dyv = dxy else: dxu, dyv = dxy if getv and isinstance(dxu, N.ndarray): if cdms2.isVariable(dxu): dxu = dxu.asma() if dxu.ndim == 1: dxu.shape = 1, -1 if dxu.shape[1] == ssh.shape[-1]: dxu = dxu[:, :-1] if getu and isinstance(dyv, N.ndarray): if cdms2.isVariable(dyv): dyv = dyv.asma() if dyv.ndim == 1: dyv.shape = -1, 1 if dyv.shape[0] == ssh.shape[-2]: dyv = dyv[:-1] # Get geostrophic factor f0 = coriolis_parameter(ssh, gravity=gravity, fromvar=True).asma() bad = f0 == 0. f0[bad] = 1. f0[bad] = N.ma.masked del bad gf = gravity / f0 del f0 # Computes sshm = ssh.asma() sshm = sshm * gf del gf if getu: ugbt[..., :-1, :] = -N.ma.diff(sshm, axis=-2) / dyv del dyv if getv: vgbt[..., :-1] = N.ma.diff(sshm, axis=-1) / dxu del dxu del sshm if getu and cyclic: ugbt[..., -1] = ugbt[..., 0] if not getu: return vgbt elif not getv: return ugbt return ugbt, vgbt
from matplotlib import rc;rc('font', size=11) import cdms2, MV2 from vacumm.config import data_sample zone = dict(yc=slice(0, 40), xc=slice(10, 40)) f = cdms2.open(data_sample('swan.four.nc')) lon2d = f('longitude', **zone) lat2d = f('latitude', **zone) hs = MV2.masked_values(f('HS', squeeze=1, **zone), f['HS']._FillValue) dlon = float(f.longitude_resolution) dlat = float(f.latitude_resolution) f.close() # Affectation de la grille curvilineaire à la variable from vacumm.misc.grid import curv_grid, set_grid cgridi = curv_grid(lon2d, lat2d) hs = set_grid(hs, cgridi) # Rotation de la grid from vacumm.misc.grid import rotate_grid import numpy as N cgrido = rotate_grid(hs.getGrid(), -30) print 'Regrillage' from vacumm.misc.grid.regridding import regrid2d print ' - par SCRIP/conservative' hs_scripcons = regrid2d(hs, cgrido, 'conservative') print ' - par SCRIP/bilineaire' hs_scripbilin = regrid2d(hs, cgrido, 'bilinear')
def read(self, verbose=False, cfg=None): """ Lecture des fichiers NetCDF de NAR SST """ import cdms2,sys,os, glob import numpy,MV2 import cdtime from vacumm.misc.axes import create_lon, set_order from vacumm.misc.grid import create_grid, set_grid from vacumm.misc.atime import create_time from vacumm.misc.phys.units import kel2degc import gc # Get the configuration file information #cfg = self.get_config() #print cfg # -- Creation d'un objet cdms nomme self.data et d'un tableau cumt pour les dates extraites des noms de fichiers self.data = () #Initialise un tuple # =============== ATTENTION ==================== # Initialiser self.data pour ne pas dupliquer en memoire !!!!!!!!! # ============================================ # -- Methode amelioree # Cree une liste files = [] # Cree la liste des fichiers correspondants a la periode consideree if cfg is None: config = ConfigParser.RawConfigParser() config.read(os.path.join(self.SCRIPT_DIR,'config.cfg')) hr_satellites = config.get('Nar SST', 'hr_satellites') else: hr_satellites = cfg['Nar SST']['hr_satellites'] hr_satellites = hr_satellites.split(',') #hr_satellites = cfg['hr_satellites'] #print hr_satellites ctest = self.ctdeb while ctest <= self.ctfin: for isat, s_name in enumerate(hr_satellites): flnme_only = '%04d%02d%02d*%s*.nc'%(ctest.year, ctest.month, ctest.day, s_name) files.extend(glob.glob(os.path.join(flnme_only))) ctest=ctest.add(1,cdtime.Days) # -- if cfg is None: lomin = float(config.get('Domain', 'lomin') ) lomax = float(config.get('Domain', 'lomax') ) lamin = float(config.get('Domain', 'lamin') ) lamax = float(config.get('Domain', 'lamax') ) else: lomin = cfg['Domain']['lomin'] lomax = cfg['Domain']['lomax'] lamin = cfg['Domain']['lamin'] lamax = cfg['Domain']['lamax'] #print files if files == []: print 'No data file to read ...' else: # ---- Lecture et creation de la grille ---- # # -- Lecture du fichier filename f = cdms2.open(files[0]) lo = f.getVariable('lon') la = f.getVariable('lat') # -- Creation des axes longitude et latitude # lat_axis = create_lon(la,id='latitude') # lon_axis = create_lon(lo,id='longitude') # -- Creation de la grille grid = create_grid(lo, la) del lo, la for ifile, filename in enumerate(files): # -- Lecture du fichier filename f = cdms2.open(filename) temp2 = f('sea_surface_temperature') set_order(temp2, 'tyx') # pour que averager.py fontionne # modif J.Gatti : utilisation de l'index de qualite (0:unprocessed 1:cloudy 2:bad 3:suspect 4:acceptable 5:excellent) temp2.set_fill_value(temp2._FillValue) conf=f('proximity_confidence') MV2.putmask(temp2.data,conf.data<3,temp2._FillValue) # ne change que data MV2.putmask(temp2.mask,conf.data<3,True) # ne change que mask #autre methode #-------------------- #temp2=MV2.masked_where(conf.data<3,temp2) # ne change que mask #oldmask=temp2.mask #temp2[:]=temp2.filled() # change data mais met mask a false partout #temp2.mask=oldmask # remet le bon mask sans lien del conf # fin modif J.Gatti : utilisation de l'index de qualite # -- Attribution de la grille a l'objet self.data set_grid(temp2, grid, axes=True) temp = temp2(lon=(lomin, lomax), lat=(lamin, lamax)) if verbose: # == TEST OCCUPATION MEMOIRE === print ctest, 'Avant' #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() del temp2 if verbose: # == TEST OCCUPATION MEMOIRE === print ctest, 'Apres del' #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() # =============== ATTENTION ================================== # Verifier que temp utilise tout le temps le meme espace memoire ... voir du cote de cdms # ========================================================== f.close() # -- Transfert de temp dans l'objet cdat self.data (concatenation) # =============== ATTENTION ==================== # Faire une variable intermediaire qui sera au prealable allouee en memoire pour eviter # trop de copies en memoire !!!!!!!!!!!!!!!! # ============================================ #self.data += temp, if ifile == 0: self.data = temp else: self.data = MV2.concatenate((self.data, temp)) if verbose: # == TEST OCCUPATION MEMOIRE === print ctest, 'Avant gccollect' #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() print gc.collect() gc.collect() if verbose: # == TEST OCCUPATION MEMOIRE === print ctest, 'Apres gccollect' #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() # -- Creation de l'axe temporel #taxis = create_time(cumt) # -- MV2.concatenate pour concatener les informations dans self.data (entre autre construit l'axe temporel) #self.data = MV2.concatenate(self.data) # -- Informations sur le dataset #self.data.name = "NAR_SST" self.data.units = "degree_Celsius" self.data.standard_name = "satellite_sea_surface_temperature" self.data.long_name = "Satellite Sea Surface Temperature - NAR" # -- Change unit self.data = kel2degc(self.data)
def read(self): """ Lecture des fichiers NetCDF de NAR SST """ import cdms2, sys, os, glob import numpy, MV2 import cdtime from vacumm.misc.axes import create_lon from vacumm.misc.grid import create_grid, set_grid from vacumm.misc.atime import create_time from vacumm.misc.phys.units import kel2degc # -- Dans le cas d'un NAR SST on lit la grille lon lat dans le fichier grid # -- Lecture de la grille znar = self.ZONE_NAR gridfile = "grid_%(znar)s.nc" % vars() f = cdms2.open(gridfile) la = f('latitude') lo = f('longitude') f.close() # -- Creation des axes longitude et latitude lat_axis = create_lon(la, id='latitude') lon_axis = create_lon(lo, id='longitude') # -- Creation de la grille grid = create_grid(lon_axis, lat_axis) # -- Creation d'un objet cdms nomme self.data et d'un tableau cumt pour les dates extraites des noms de fichiers self.data = () #Initialise un tuple # =============== ATTENTION ==================== # Initialiser self.data pour ne pas dupliquer en memoire !!!!!!!!! # ============================================ #cumt = [] # Initialise un array # -- Boucle sur les fichiers presents dans le WORKDIR #url_file_def="%(YYYY)s%(MM)s%(DD)s%(HH)s%(ext)s"%vars() #self.ctdeb # -- Ancienne methode #files = glob.glob(os.path.join(self.WORKDIR, '2*.nc')) #files.sort() # -- # -- Methode amelioree # Cree une liste files = [] # Cree la liste des fichiers correspondants a la periode consideree ctest = self.ctdeb while ctest <= self.ctfin: flnme_only = '%(#)04d%(##)02d%(###)02d*.nc' % { '#': ctest.year, '##': ctest.month, '###': ctest.day } files.extend(glob.glob(os.path.join(self.WORKDIR, flnme_only))) ctest = ctest.add(1, cdtime.Days) # -- for filename in files: # -- Lecture du fichier filename f = cdms2.open(filename) temp = f('sea_surface_temperature') # =============== ATTENTION ================================== # Verifier que temp utilise tout le temps le meme espace memoire ... voir du cote de cdms # ========================================================== f.close() # -- Extraction de la date et heure du nom du fichier #ty = numpy.int(filename[-15:-11]) #tm = numpy.int(filename[-11:-9]) #tj = numpy.int(filename[-9:-7]) #th = numpy.int(filename[-7:-5]) #tt = cdtime.comptime(ty,tm,tj,th) #cumt.append(tt) # -- Transfert de temp dans l'objet cdat self.data (concatenation) # =============== ATTENTION ==================== # Faire une variable intermediaire qui sera au prealable allouee en memoire pour eviter # trop de copies en memoire !!!!!!!!!!!!!!!! # ============================================ self.data += temp, # -- Creation de l'axe temporel #taxis = create_time(cumt) # -- MV2.concatenate pour concatener les informations dans self.data (entre autre construit l'axe temporel) self.data = MV2.concatenate(self.data) # -- Attribution de la grille a l'objet self.data set_grid(self.data, grid, axes=True) # -- Informations sur le dataset self.data.name = "NAR_SST" self.data.units = "degree_Celsius" self.data.standard_name = "satellite_sea_surface_temperature" self.data.long_name = "Satellite Sea Surface Temperature - NAR" # -- Change unit self.data = kel2degc(self.data)
def _template_t2ht_(self, tpl): htpl = MV2.resize(tpl.astype('l'), (self.nbins,)+tpl.shape) htpl.setAxisList([self._baxis]+tpl.getAxisList()) set_grid(htpl, get_grid(tpl)) return htpl
def barotropic_geostrophic_velocity(ssh, dxy=None, gravity=default_gravity, cyclic=False, format_axes=True, getu=True, getv=True, filter=None): """Get barotropic geostropic velocity from SSH on a C-grid .. note:: ssh is supposed to be at T points, ubt is computed at V points, and vbt is computed at U points. .. todo:: Rewrite it using :mod:`vacumm.data.misc.arakawa` and defining a limited number of algorithms for different staggering configurations. :Params: - **ssh**: Sea surface height. - **dxy**, optional: Horizontal resolutions (m). Resolution along X and Y are respectively at U and V points. Possible forms: - ``res``: A scalar meaning a constant resolution along X and Y. - ``(dx,dy)``: A tuple of resolutions along X and Y. - ``None``: Resolution is estimated using :func:`~vacumm.misc.grid.misc.resol`. :Return: ``(ubt,vbt)`` """ if not getu and not getv: return # Init masked if getu: ugbt = format_var(ssh*MV2.masked, 'ugbt', format_axes=False) if getv: vgbt = format_var(ssh*MV2.masked, 'vgbt', format_axes=False) # Grid tgrid = ssh.getGrid() if getu: ugrid = shiftgrid(tgrid, ishift=0.5) if getv: vgrid = shiftgrid(tgrid, jshift=0.5) if format_axes: if getv: format_grid(ugrid, 'u') if getu: format_grid(vgrid, 'v') if getu: set_grid(ugbt, vgrid) if getv: set_grid(vgbt, ugrid) # Resolutions if dxy is None: dxt, dyt = resol(ssh, proj=True, mode='local') dxu = 0.5*(dxt[:, 1:]+dxt[:, :-1]) ; del dxt dyv = 0.5*(dyt[1:, :]+dyt[:-1, :]) ; del dyt elif not isinstance(dxy, (list, tuple)): dxu = dyv = dxy else: dxu, dyv = dxy if getv and isinstance(dxu, N.ndarray): if cdms2.isVariable(dxu): dxu = dxu.asma() if dxu.ndim==1: dxu.shape = 1, -1 if dxu.shape[1]==ssh.shape[-1]: dxu = dxu[:, :-1] if getu and isinstance(dyv, N.ndarray): if cdms2.isVariable(dyv): dyv = dyv.asma() if dyv.ndim==1: dyv.shape = -1, 1 if dyv.shape[0]==ssh.shape[-2]: dyv = dyv[:-1] # Get geostrophic factor f0 = coriolis_parameter(ssh, gravity=gravity, fromvar=True).asma() bad = f0==0. f0[bad] = 1. f0[bad] = N.ma.masked ; del bad gf = gravity/f0 ; del f0 # Computes sshm = ssh.asma() sshm = sshm*gf ; del gf if getu: ugbt[..., :-1, :] = -N.ma.diff(sshm, axis=-2)/dyv ; del dyv if getv: vgbt[..., :-1] = N.ma.diff(sshm, axis=-1)/dxu ; del dxu del sshm if getu and cyclic: ugbt[..., -1] = ugbt[..., 0] if not getu: return vgbt elif not getv: return ugbt return ugbt, vgbt
def read(self, verbose=False, cfg=None): """ Lecture des fichiers NetCDF de NAR SST """ import cdms2, sys, os, glob import numpy, MV2 import cdtime from vacumm.misc.axes import create_lon, set_order from vacumm.misc.grid import create_grid, set_grid from vacumm.misc.atime import create_time from vacumm.misc.phys.units import kel2degc import gc # Get the configuration file information #cfg = self.get_config() #print cfg # -- Creation d'un objet cdms nomme self.data et d'un tableau cumt pour les dates extraites des noms de fichiers self.data = () #Initialise un tuple # =============== ATTENTION ==================== # Initialiser self.data pour ne pas dupliquer en memoire !!!!!!!!! # ============================================ # -- Methode amelioree # Cree une liste files = [] # Cree la liste des fichiers correspondants a la periode consideree if cfg is None: config = configparser.RawConfigParser() config.read(os.path.join(self.SCRIPT_DIR, 'config.cfg')) hr_satellites = config.get('Nar SST', 'hr_satellites') else: hr_satellites = cfg['Nar SST']['hr_satellites'] hr_satellites = hr_satellites.split(',') #hr_satellites = cfg['hr_satellites'] #print hr_satellites ctest = self.ctdeb while ctest <= self.ctfin: for isat, s_name in enumerate(hr_satellites): flnme_only = '%04d%02d%02d*%s*.nc' % (ctest.year, ctest.month, ctest.day, s_name) files.extend(glob.glob(os.path.join(flnme_only))) ctest = ctest.add(1, cdtime.Days) # -- if cfg is None: lomin = float(config.get('Domain', 'lomin')) lomax = float(config.get('Domain', 'lomax')) lamin = float(config.get('Domain', 'lamin')) lamax = float(config.get('Domain', 'lamax')) else: lomin = cfg['Domain']['lomin'] lomax = cfg['Domain']['lomax'] lamin = cfg['Domain']['lamin'] lamax = cfg['Domain']['lamax'] #print files if files == []: print('No data file to read ...') else: # ---- Lecture et creation de la grille ---- # # -- Lecture du fichier filename f = cdms2.open(files[0]) lo = f.getVariable('lon') la = f.getVariable('lat') # -- Creation des axes longitude et latitude # lat_axis = create_lon(la,id='latitude') # lon_axis = create_lon(lo,id='longitude') # -- Creation de la grille grid = create_grid(lo, la) del lo, la for ifile, filename in enumerate(files): # -- Lecture du fichier filename f = cdms2.open(filename) temp2 = f('sea_surface_temperature') set_order(temp2, 'tyx') # pour que averager.py fontionne # modif J.Gatti : utilisation de l'index de qualite (0:unprocessed 1:cloudy 2:bad 3:suspect 4:acceptable 5:excellent) temp2.set_fill_value(temp2._FillValue) conf = f('proximity_confidence') MV2.putmask(temp2.data, conf.data < 3, temp2._FillValue) # ne change que data MV2.putmask(temp2.mask, conf.data < 3, True) # ne change que mask #autre methode #-------------------- #temp2=MV2.masked_where(conf.data<3,temp2) # ne change que mask #oldmask=temp2.mask #temp2[:]=temp2.filled() # change data mais met mask a false partout #temp2.mask=oldmask # remet le bon mask sans lien del conf # fin modif J.Gatti : utilisation de l'index de qualite # -- Attribution de la grille a l'objet self.data set_grid(temp2, grid, axes=True) temp = temp2(lon=(lomin, lomax), lat=(lamin, lamax)) if verbose: # == TEST OCCUPATION MEMOIRE === print(ctest, 'Avant') #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() del temp2 if verbose: # == TEST OCCUPATION MEMOIRE === print(ctest, 'Apres del') #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() # =============== ATTENTION ================================== # Verifier que temp utilise tout le temps le meme espace memoire ... voir du cote de cdms # ========================================================== f.close() # -- Transfert de temp dans l'objet cdat self.data (concatenation) # =============== ATTENTION ==================== # Faire une variable intermediaire qui sera au prealable allouee en memoire pour eviter # trop de copies en memoire !!!!!!!!!!!!!!!! # ============================================ #self.data += temp, if ifile == 0: self.data = temp else: self.data = MV2.concatenate((self.data, temp)) if verbose: # == TEST OCCUPATION MEMOIRE === print(ctest, 'Avant gccollect') #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() print(gc.collect()) gc.collect() if verbose: # == TEST OCCUPATION MEMOIRE === print(ctest, 'Apres gccollect') #print psutil.Process(os.getpid()).get_memory_percent() #print psutil.Process(os.getpid()).get_memory_info() #print 'CPU percent: ', psutil.cpu_percent(interval=0.1) #print 'Used phymem: ', psutil.used_phymem() #print 'Used virtmem: ', psutil.used_virtmem() # -- Creation de l'axe temporel #taxis = create_time(cumt) # -- MV2.concatenate pour concatener les informations dans self.data (entre autre construit l'axe temporel) #self.data = MV2.concatenate(self.data) # -- Informations sur le dataset #self.data.name = "NAR_SST" self.data.units = "degree_Celsius" self.data.standard_name = "satellite_sea_surface_temperature" self.data.long_name = "Satellite Sea Surface Temperature - NAR" # -- Change unit self.data = kel2degc(self.data)
from matplotlib import rc;rc('font', size=11) import cdms2, MV2 from vacumm.config import data_sample zone = dict(yc=slice(0, 40), xc=slice(10, 40)) f = cdms2.open(data_sample('swan.four.nc')) lon2d = f('longitude', **zone) lat2d = f('latitude', **zone) hs = MV2.masked_values(f('HS', squeeze=1, **zone), f['HS']._FillValue) dlon = float(f.longitude_resolution) dlat = float(f.latitude_resolution) f.close() # Affectation de la grille curvilineaire à la variable from vacumm.misc.grid import curv_grid, set_grid cgridi = curv_grid(lon2d, lat2d) hs = set_grid(hs, cgridi) # Rotation de la grid from vacumm.misc.grid import rotate_grid import numpy as N cgrido = rotate_grid(hs.getGrid(), -30) print 'Regrillage' from vacumm.misc.grid.regridding import regrid2d print ' - par natgrid' hs_nat = regrid2d(hs, cgrido, 'nat') print ' - par SCRIP/conservative' hs_scripcons = regrid2d(hs, cgrido, 'conservative') print ' - par SCRIP/bilineaire' hs_scripbilin = regrid2d(hs, cgrido, 'bilinear')
def kinetic_energy(sshuv, gravity=default_gravity, format_axes=None, dxy=None): """Compute kinetic energy in m2.s-2 either from SSH or velocity on C-grid .. todo:: Rewrite it using :mod:`vacumm.data.misc.arakawa` and defining a limited number of algorithms for different staggering configurations. :Params: - **sshuv**: SSH or (U,V). - If SSH, geostrophic velocity is computed at U and V points using :func:`barotropic_geostrophic_velocity`. - If (U,V), velocities are supposed to be at V and U points. - **dxy**, optional: Horizontal resolutions (see :func:`barotropic_geostrophic_velocity`). :Return: KE at T points. """ # Init and get velocities if cdms2.isVariable(sshuv): # from SSH ke = sshuv * MV2.masked u, v = barotropic_geostrophic_velocity(sshuv, dxy=dxy, gravity=gravity, format_axes=format_axes) if format_axes is None: format_axes = False else: # from (U,V) u, v = sshuv ke = u * MV2.masked if format_axes is None: format_axes = True gridt = shiftgrid(u.getGrid(), jshift=1) set_grid(ke, gridt) # Sum contributions uf = u.filled(0.) vf = v.filled(0.) ke[..., 1:, :] = uf[..., 1:, :]**2 ke[..., 1:, :] += uf[..., :-1, :]**2 ke[..., 1:] += vf[..., 1:]**2 ke[..., 1:] += vf[..., :-1]**2 # Weight and mask count = N.zeros(ke.shape, 'i') gu = 1 - N.ma.getmaskarray(u).astype('i') gv = 1 - N.ma.getmaskarray(v).astype('i') count[1:] = gu[:-1] count[1:] += gu[1:] count[:, 1:] += gv[:, :-1] count[:, 1:] += gv[:, 1:] del gu, gv mask = count == 0 count[mask] = 1 ke[:] /= count ke[:] = MV2.masked_where(mask, ke, copy=0) del mask, count # Format if format_axes: format_grid(gridt, 't') return format_var(ke, "ke", format_axes=False)
def mixed_layer_depth(data, depth=None, lat=None, zaxis=None, mode=None, deltatemp=.2, deltadens=.03, kzmax=0.0005, potential=True, format_axes=False): """Get mixed layer depth from temperature and salinity :Params: - **temp**: Insitu or potential temperature. - **sal**: Salinity. - **depth**, optional: Depth at temperature and salinty points. - **lat**, optional: Latitude. - **mode**, optional: ``"deltatemp"``, ``"deltadens"``, ``"kz"`` or ``"twolayers"`` :Raise: :class:`~vacumm.VACUMMError` if can't get depth (and latitude for density). """ # TODO: positive up # Inspection if isinstance(data, tuple): # data = temp,sal temp, sal = data # Get density if mode != 'deltatemp': res = density(temp, sal, depth=depth, lat=lat, format_axes=False, potential=potential, getdepth=True) if isinstance(res, tuple): dens, depth = res else: dens = res dens = dens.asma() if mode is None: mode = 'deltadens' else: temp = data[0] # Check mode if mode == 'kz': warn("Switching MLD computation mode to 'deltadens'") mode = "deltadens" elif match_var(data, 'temp', mode='nslu'): if mode is not None and mode != 'deltatemp': warn("Switching MLD computation mode to 'deltatemp'") mode = 'deltatemp' temp = data elif match_var(data, 'dens', mode='nslu'): if mode in ['kz', 'deltatemp']: warn("Switching MLD computation mode to 'deltadens'") mode = None if mode is None: mode = "deltadens" dens = data elif match_var(data, 'kz', mode='nslu'): if mode is None: mode = "kz" if mode != "kz": warn("Switching MLD computation mode to 'kz'") kz = data else: if mode in ['deltadens', 'twolayers']: dens = data elif mode == "deltatemp": temp = data elif mode == "kz": kz = data elif mode is not None: raise VACUMMError("Invalid MLD computation mode : '%s'" % mode) else: raise VACUMMError("Can't guess MLD computation mode") temp = delta # Find Z dim data0 = data[0] if isinstance(data, tuple) else data depth = grow_depth(data0, depth, mode='raise', getvar=False) zaxis = get_zdim(data0, axis=zaxis) if zaxis is None: raise VACUMMError("Can't guess zaxis") slices = get_axis_slices(data0, zaxis) # Init MLD axes = data0.getAxisList() del axes[zaxis] mld = MV2.array(data0.asma()[slices['first']], copy=1, axes=axes, copyaxes=False) set_grid(mld, get_grid(data0)) format_var(mld, 'mld', format_axes=format_axes) mld[:] = MV2.masked # Two-layers if mode == 'twolayers': densbot = dens[slices['first']] denstop = dens[slices['last']] del dens H = 1.5 * depth[slices['first']] - 0.5 * depth[slices['firstp1']] H = -1.5 * depth[slices['last']] + 0.5 * depth[slices['lastm1']] mld[:] = -H * (densbot - denstop) / (densbot - denstop) del H elif mode == 'deltadens': denscrit = dens[slices['last']] + deltadens mld[:] = -_val2z_(dens, depth, denscrit, zaxis, -1) del dens elif mode == 'deltatemp': tempcrit = temp[slices['last']] - deltatemp mld[:] = -_val2z_(temp, depth, tempcrit, zaxis, 1) elif mode == 'kz': mld[:] = -_valmin2z_(kz, depth, kzmax, zaxis, 1) else: raise VACUMMError("Invalid mode for computing MLD (%s)." % mode + "Please choose one of: deltadens, twolayers") # Mask zeros mld[:] = MV2.masked_values(mld, 0., copy=0) return mld