Ejemplo n.º 1
0
def _extremum_(func,ctime,i0,i,var,spline):
    """Extremum possibly using splines"""
    nt = len(var)
    if spline and nt >= 4: # and i != 0 and i != (nt-1)
        if i == 0:
            ifirst, ilast = 0, 4
        elif i == nt-1:
            ifirst, ilast = nt-4, nt
        else:
            icenter = i - int(var[i-1] > var[i+1])
            ifirst = max(icenter-1, 0)
            ilast = ifirst + 4
            if ilast > nt:
                ilast -= 1
                ifirst -= 1
        mn_units = 'minutes since %s'%ctime[i0+ifirst]
        old_rts = cdms2.createAxis(N.asarray([ct.torel(mn_units).value for ct in ctime[i0+ifirst:i0+ilast]],dtype='d'))
        old_var = MV2.array(var[ifirst:ilast], axes=[old_rts], copyaxes=0)
        mn_rts =  cdms2.createAxis(N.arange(int(old_rts[-1]+1),dtype='d'))
        mn_var = interp1d(old_var, mn_rts, method='cubic')
        del old_var, old_rts
#       mn_var = spline_interpolate(old_rts,var[i-1:i+2],mn_rts)
#       mn_var = splev(mn_rts, splrep(old_rts,var[ifirst:ilast]))
        mn_i = func(mn_var)
        val = mn_var[mn_i]
        del mn_var
        this_ctime = cdtime.reltime(mn_i,mn_units).tocomp()
    else:
        this_ctime = ctime[i0+i]
        val = var[i]
    return val,this_ctime
Ejemplo n.º 2
0
def _extremum_(func, ctime, i0, i, var, spline):
    """Extremum possibly using splines"""
    nt = len(var)
    if spline and nt >= 4:  # and i != 0 and i != (nt-1)
        if i == 0:
            ifirst, ilast = 0, 4
        elif i == nt - 1:
            ifirst, ilast = nt - 4, nt
        else:
            icenter = i - int(var[i - 1] > var[i + 1])
            ifirst = max(icenter - 1, 0)
            ilast = ifirst + 4
            if ilast > nt:
                ilast -= 1
                ifirst -= 1
        mn_units = 'minutes since %s' % ctime[i0 + ifirst]
        old_rts = cdms2.createAxis(
            N.asarray([
                ct.torel(mn_units).value
                for ct in ctime[i0 + ifirst:i0 + ilast]
            ],
                      dtype='d'))
        old_var = MV2.array(var[ifirst:ilast], axes=[old_rts], copyaxes=0)
        mn_rts = cdms2.createAxis(N.arange(int(old_rts[-1] + 1), dtype='d'))
        mn_var = interp1d(old_var, mn_rts, method='cubic')
        del old_var, old_rts
        #       mn_var = spline_interpolate(old_rts,var[i-1:i+2],mn_rts)
        #       mn_var = splev(mn_rts, splrep(old_rts,var[ifirst:ilast]))
        mn_i = func(mn_var)
        val = mn_var[mn_i]
        del mn_var
        this_ctime = cdtime.reltime(mn_i, mn_units).tocomp()
    else:
        this_ctime = ctime[i0 + i]
        val = var[i]
    return val, this_ctime
Ejemplo n.º 3
0
# On crée un trou
xe[3:4, 20:30] = MV2.masked

# Nouvel axe temporel plus précis
from vacumm.misc.axes import create_time
#old_time = xe.getTime()
old_time = create_time((xe.shape[0], ), 'hours since 2000')
xe.setAxis(0, old_time)
dt = (old_time[1] - old_time[0]) / 10.
new_time = create_time((old_time[0], old_time[-1] + dt, dt), old_time.units)

# Interpolation
from vacumm.misc.grid.regridding import interp1d
# - nearest
xe_nea = interp1d(xe, new_time, method='nearest')
xe_nea.long_name = 'Nearest'
# - linear
xe_lin = interp1d(xe, new_time, method='linear')
xe_lin.long_name = 'Linear'
# - cubic
xe_cub = interp1d(xe, new_time, method='cubic')
xe_cub.long_name = 'Cubic'

# Plots
from matplotlib import rcParams
rcParams['font.size'] = 8
import pylab as P
from vacumm.misc.plot import yhide, xscale, savefigs, hov2, curve2
from vacumm.misc.color import cmap_jets
from genutil import minmax
Ejemplo n.º 4
0
    def plot_layer_mod_on_pro(self,
                              model,
                              profiles,
                              varname,
                              depth,
                              select=None,
                              **kwargs):
        '''Get a layer of variable for a specified depth.

        :Params:

          - **varname**: variable to process
          - **depth**: output depth(s)

          Other params, see: :func:`coloc_mod_on_pro`

        '''
        self.verbose(
            'Plotting layer of colocalized %s on %s\nvarname: %s\ndepth: %s\nselect: %s\nkwargs: %s',
            model.__class__.__name__, profiles.__class__.__name__, varname,
            depth, select, kwargs)

        lons_mod, lats_mod, deps_mod, var_mod = \
            self.coloc_mod_on_pro(
                model, profiles,
                # If varname is a list of possible names, wrap it into a
                # tuple of one element as we are requiring only one variable
                len(numpy.shape(varname)) and (varname,) or varname,
                select, **kwargs)

        odep = create_dep(is_iterable(depth) and depth or [depth])
        var_mod = var_mod.reorder('-z')
        var_mod = interp1d(var_mod, axo=odep, xmap=0,
                           xmapper=deps_mod)  # Required order: ...z
        var_mod = var_mod.reorder('z-')
        model.verbose('layer:  %s', var_mod)

        lons_pro, lats_pro, var_pro = profiles.get_layer(varname,
                                                         depth,
                                                         select=select)
        profiles.verbose('layer:  %s', var_pro)

        # =====
        # Tracés
        vmin = var_pro.min()
        vmax = var_pro.max()
        if var_mod.count():
            vmin = min(var_mod.min(), vmin)
            vmax = max(var_mod.max(), vmax)
        else:
            self.warning('No model data')
        if 'latitude' in select:
            lat_min, lat_max = select['latitude'][:2]
        else:
            la = model.get_latitude()
            lat_min, lat_max = min(la), max(la)
        if 'longitude' in select:
            lon_min, lon_max = select['longitude'][:2]
        else:
            lo = model.get_longitude()
            lon_min, lon_max = min(lo), max(lo)

        levels = auto_scale((vmin, vmax))
        vmin = levels[0]
        vmax = levels[-1]
        # Création de la palette
        cmap = cmap_magic(levels)
        # On trace de champ du modèle moyené sur la période choisie
        m = map2(lon=(lon_min, lon_max), lat=(lat_min, lat_max), show=False)
        # On trace le modèle en fond

        # =====
        msca = None
        try:
            msca = m.map.scatter(lons_mod,
                                 lats_mod,
                                 s=100,
                                 c=var_mod,
                                 vmin=vmin,
                                 vmax=vmax,
                                 cmap=cmap,
                                 label='model')
        except:
            self.exception('Failed plotting model data')
        # =====
        # Triangulation du modèle
        #        import matplotlib.tri as tri
        #        triang = tri.Triangulation(lons_mod, lats_mod)
        #        # On trace le modèle en fond
        #        mod = m.axes.tripcolor(triang, var_mod, vmin=vmin, vmax=vmax, cmap=cmap)
        # =====

        # On trace les observations avec des points plus petits
        psca = None
        try:
            psca = m.map.scatter(lons_pro,
                                 lats_pro,
                                 s=25,
                                 c=var_pro,
                                 vmin=m.vmin,
                                 vmax=m.vmax,
                                 cmap=m.cmap,
                                 label='profiles')
        except:
            self.exception('Failed plotting profile data')

        # Colorbar
        if msca is not None:
            colorbar(msca)
        elif psca is not None:
            colorbar(psca)
Ejemplo n.º 5
0
def generic(var,
            coefs,
            units='hours',
            get_tide=False,
            only_tide=False,
            filter_name='Generic',
            check_regular=False,
            strict=True,
            interp_method='cubic',
            axis=None):
    """Apply a filter to signal (cdms2 variable) using symetric coefficients. First axis is supposed to be time and regular.

    - **var**: Data to filter with first axis supposed to be time.
    - **coefs**: Second half of coefficients.
    - *strict*: Mask values where at least one value is missing in the filtering interval.
    - *filter_name*: Name to give to the filter [default: 'Generic']
    %s
    """
    # Return?
    if only_tide:
        get_tide = True

    # Coefficients
    units = unit_type(units)
    sunits = unit_type(units, string_type=True)
    coefs = coefs.astype('f')
    if coefs[-1] != 0.:
        coefs = N.concatenate((coefs, [
            0.,
        ]))
    ncoefs = (len(coefs) - 1) * 2 + 1

    # Input variable
    var = MV2.asarray(var)
    check_axes(var)

    # Input time axis
    if axis is None:
        try:
            axis = var.getOrder().index('t')
        except:
            axis = 0
    time = var.getAxis(axis)
    if check_regular:
        assert isregular(time), 'Your time axis seems not regular'
    dt = N.diff(time[:]).mean()
    if not time.attributes.has_key('units'):
        time.units = 'hours since 1970-01-01'
        print 'The time axis of your variable has no units. Assuming : ' + time.units
    if not time.isTime():
        time.designateTime(calendar=cdtime.DefaultCalendar)

    # Check time range
    time_range = time[-1] - time[0]
    coefs_units = sunits + ' ' + ' '.join(time.units.split()[1:])
    coefs_range0 = cdtime.r2r(cdtime.reltime(time[0], coefs_units), time.units)
    coefs_range1 = coefs_range0.add(ncoefs - 1, units)
    coefs_range = coefs_range1.value - coefs_range0.value
    coefs_dt = coefs_range0.add(1, units).value - coefs_range0.value
    if time_range < coefs_range:
        raise Exception, 'Your sample is shorter than the time range of your coefficients'
    nt = len(var)

    # Remap coefficients to data time axis
    tc = var.dtype.char
    #   print 'dt', dt
    #   print 'coefs_dt', coefs_dt
    if abs((coefs_dt - dt) / dt) > 0.01:
        oldx = cdms2.createAxis(N.arange(len(coefs)) * coefs_dt)
        old_coefs = MV2.array(coefs, axes=[oldx])
        newx = cdms2.createAxis(N.arange(0., max(oldx), dt))
        coefs = interp1d(old_coefs, newx, interp_method).filled()
    coefs = N.concatenate((coefs[:0:-1], coefs))
    coefs /= N.sum(coefs)
    ncoefs = len(coefs)

    # Filtering using convolution
    fvar = convolve1d(var.filled(0.), coefs, axis=axis, mode='constant')
    if var.mask is MV2.nomask:
        mask = N.zeros(nt)
    else:
        mask = var.mask.astype('f')
    fmask = convolve1d(mask, coefs, axis=axis, mode='constant', cval=1.) != 0.
    fvar = MV2.asarray(fvar)
    fvar = MV2.masked_where(fmask, fvar, copy=0)

    # Output variables
    if not only_tide:
        fvar.id = var.id + '_cotes'
        fvar.name = fvar.id
        if var.attributes.has_key('long_name'):
            fvar.long_name = 'Tide removed signal from ' + var.long_name.lower(
            )
        fvar.long_name_fr = 'Signal sans la maree'
        if var.attributes.has_key('units'):
            fvar.units = var.units
        fvar.setAxis(0, time)
        fvar.filter_coefficients = coefs
        fvar.filter_name = filter_name
        res = [
            fvar,
        ]
    if get_tide:
        tvar = var - fvar
        tvar.id = 'tidal_' + var.id
        tvar.name = tvar.id
        if var.attributes.has_key('long_name'):
            tvar.long_name = 'Tidal signal from ' + var.long_name.lower()
        if var.attributes.has_key('units'):
            tvar.units = var.units
        tvar.setAxis(0, time)
        tvar.filter_coefficients = coefs
        tvar.filter_name = filter_name
        if only_tide:
            return tvar
        res.append(tvar)

    if isinstance(res, list) and len(res) == 1:
        return res[0]
    else:
        return res
Ejemplo n.º 6
0
def generic(var,coefs,units='hours',get_tide=False,only_tide=False,filter_name='Generic',
    check_regular=False,strict=True, interp_method='cubic', axis=None):
    """Apply a filter to signal (cdms2 variable) using symetric coefficients. First axis is supposed to be time and regular.

    - **var**: Data to filter with first axis supposed to be time.
    - **coefs**: Second half of coefficients.
    - *strict*: Mask values where at least one value is missing in the filtering interval.
    - *filter_name*: Name to give to the filter [default: 'Generic']
    %s
    """
    # Return?
    if only_tide:
        get_tide = True

    # Coefficients
    units = unit_type(units)
    sunits = unit_type(units, string_type=True)
    coefs = coefs.astype('f')
    if coefs[-1] != 0.:
        coefs = N.concatenate((coefs,[0.,]))
    ncoefs = (len(coefs)-1)*2+1

    # Input variable
    var = MV2.asarray(var)
    check_axes(var)

    # Input time axis
    if axis is None:
        try:
            axis = var.getOrder().index('t')
        except:
            axis = 0
    time = var.getAxis(axis)
    if check_regular:
        assert isregular(time), 'Your time axis seems not regular'
    dt = N.diff(time[:]).mean()
    if not time.attributes.has_key('units'):
           time.units = 'hours since 1970-01-01'
           print 'The time axis of your variable has no units. Assuming : '+time.units
    if not time.isTime():
        time.designateTime(calendar=cdtime.DefaultCalendar)

    # Check time range
    time_range = time[-1]-time[0]
    coefs_units = sunits+' '+' '.join(time.units.split()[1:])
    coefs_range0 = cdtime.r2r(cdtime.reltime(time[0],coefs_units),time.units)
    coefs_range1 = coefs_range0.add(ncoefs-1,units)
    coefs_range = coefs_range1.value - coefs_range0.value
    coefs_dt = coefs_range0.add(1,units).value - coefs_range0.value
    if time_range < coefs_range:
        raise Exception,'Your sample is shorter than the time range of your coefficients'
    nt = len(var)

    # Remap coefficients to data time axis
    tc = var.dtype.char
#   print 'dt', dt
#   print 'coefs_dt', coefs_dt
    if abs((coefs_dt-dt)/dt) > 0.01:
        oldx = cdms2.createAxis(N.arange(len(coefs))*coefs_dt)
        old_coefs = MV2.array(coefs, axes=[oldx])
        newx = cdms2.createAxis(N.arange(0.,max(oldx),dt))
        coefs = interp1d(old_coefs, newx, interp_method).filled()
    coefs = N.concatenate((coefs[:0:-1],coefs))
    coefs /= N.sum(coefs)
    ncoefs = len(coefs)

    # Filtering using convolution
    fvar = convolve1d(var.filled(0.), coefs, axis=axis, mode='constant')
    if var.mask is MV2.nomask:
        mask = N.zeros(nt)
    else:
        mask = var.mask.astype('f')
    fmask = convolve1d(mask, coefs, axis=axis, mode='constant', cval=1.)!=0.
    fvar = MV2.asarray(fvar)
    fvar = MV2.masked_where(fmask, fvar, copy=0)

    # Output variables
    if not only_tide:
        fvar.id = var.id+'_cotes'
        fvar.name = fvar.id
        if var.attributes.has_key('long_name'):
            fvar.long_name = 'Tide removed signal from '+var.long_name.lower()
        fvar.long_name_fr = 'Signal sans la maree'
        if var.attributes.has_key('units'):
            fvar.units = var.units
        fvar.setAxis(0,time)
        fvar.filter_coefficients = coefs
        fvar.filter_name = filter_name
        res = [fvar,]
    if get_tide:
        tvar = var-fvar
        tvar.id = 'tidal_'+var.id
        tvar.name = tvar.id
        if var.attributes.has_key('long_name'):
            tvar.long_name = 'Tidal signal from '+var.long_name.lower()
        if var.attributes.has_key('units'):
            tvar.units = var.units
        tvar.setAxis(0,time)
        tvar.filter_coefficients = coefs
        tvar.filter_name = filter_name
        if only_tide:
            return tvar
        res.append(tvar)

    if isinstance(res, list) and len(res) == 1:
        return res[0]
    else:
        return res
# On crée un trou
xe[3:4, 20:30] = MV2.masked

# Nouvel axe temporel plus précis
from vacumm.misc.axes import create_time
#old_time = xe.getTime()
old_time=create_time((xe.shape[0], ), 'hours since 2000')
xe.setAxis(0, old_time)
dt = (old_time[1]-old_time[0])/10.
new_time = create_time((old_time[0], old_time[-1]+dt, dt), old_time.units)

# Interpolation
from vacumm.misc.grid.regridding import interp1d
# - nearest
xe_nea = interp1d(xe, new_time, method='nearest')
xe_nea.long_name = 'Nearest'
# - linear
xe_lin = interp1d(xe, new_time, method='linear')
xe_lin.long_name = 'Linear'
# - cubic
xe_cub = interp1d(xe, new_time, method='cubic')
xe_cub.long_name = 'Cubic'

# Plots
from matplotlib import rcParams ; rcParams['font.size'] = 8
import pylab as P
from vacumm.misc.plot import yhide, xscale, savefigs, hov2, curve2
from vacumm.misc.color import cmap_jets
from genutil import minmax
vmin, vmax = minmax(xe, xe_lin)
Ejemplo n.º 8
0
    def plot_layer_mod_on_pro(self, model, profiles, varname, depth, select=None, **kwargs):
        '''Get a layer of variable for a specified depth.

        :Params:

          - **varname**: variable to process
          - **depth**: output depth(s)

          Other params, see: :func:`coloc_mod_on_pro`

        '''
        self.verbose('Plotting layer of colocalized %s on %s\nvarname: %s\ndepth: %s\nselect: %s\nkwargs: %s',
            model.__class__.__name__, profiles.__class__.__name__, varname, depth, select, kwargs)

        lons_mod, lats_mod, deps_mod, var_mod = \
            self.coloc_mod_on_pro(
                model, profiles,
                # If varname is a list of possible names, wrap it into a
                # tuple of one element as we are requiring only one variable
                len(numpy.shape(varname)) and (varname,) or varname,
                select, **kwargs)

        odep = create_dep(is_iterable(depth) and depth or [depth])
        var_mod = var_mod.reorder('-z')
        var_mod = interp1d(var_mod, axo=odep, xmap=0, xmapper=deps_mod) # Required order: ...z
        var_mod = var_mod.reorder('z-')
        model.verbose('layer:  %s', var_mod)

        lons_pro, lats_pro, var_pro = profiles.get_layer(varname, depth, select=select)
        profiles.verbose('layer:  %s', var_pro)

        # =====
        # Tracés
        vmin = var_pro.min()
        vmax = var_pro.max()
        if var_mod.count():
            vmin = min(var_mod.min(), vmin)
            vmax = max(var_mod.max(), vmax)
        else:
            self.warning('No model data')
        if 'latitude' in select:
            lat_min, lat_max = select['latitude'][:2]
        else:
            la = model.get_latitude()
            lat_min, lat_max = min(la), max(la)
        if 'longitude' in select:
            lon_min, lon_max = select['longitude'][:2]
        else:
            lo = model.get_longitude()
            lon_min, lon_max = min(lo), max(lo)

        levels = auto_scale((vmin, vmax))
        vmin = levels[0]
        vmax = levels[-1]
        # Création de la palette
        cmap = cmap_magic(levels)
        # On trace de champ du modèle moyené sur la période choisie
        m = map2(lon=(lon_min, lon_max), lat=(lat_min, lat_max), show=False)
        # On trace le modèle en fond

        # =====
        msca = None
        try: msca = m.map.scatter(lons_mod, lats_mod, s=100, c=var_mod, vmin=vmin, vmax=vmax, cmap=cmap, label='model')
        except: self.exception('Failed plotting model data')
        # =====
        # Triangulation du modèle
#        import matplotlib.tri as tri
#        triang = tri.Triangulation(lons_mod, lats_mod)
#        # On trace le modèle en fond
#        mod = m.axes.tripcolor(triang, var_mod, vmin=vmin, vmax=vmax, cmap=cmap)
        # =====

        # On trace les observations avec des points plus petits
        psca = None
        try: psca = m.map.scatter(lons_pro, lats_pro, s=25, c=var_pro, vmin=m.vmin, vmax=m.vmax, cmap=m.cmap, label='profiles')
        except: self.exception('Failed plotting profile data')

        # Colorbar
        if msca is not None:
            colorbar(msca)
        elif psca is not None:
            colorbar(psca)