Exemple #1
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
Exemple #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
Exemple #3
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
Exemple #4
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