Пример #1
0
    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)
Пример #2
0
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
Пример #3
0
    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)
Пример #4
0
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)
Пример #5
0
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
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
    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)
Пример #13
0
    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)
Пример #14
0
    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)
Пример #15
0
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
Пример #16
0
 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
Пример #17
0
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
Пример #18
0
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')

Пример #19
0
    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)
Пример #20
0
    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)
Пример #21
0
 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
Пример #22
0
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
Пример #23
0
    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')
Пример #25
0
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)
Пример #26
0
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