Esempio n. 1
0
def angle2xyz(azi, zen):
    """Convert azimuth and zenith to cartesian."""
    azi = xu.deg2rad(azi)
    zen = xu.deg2rad(zen)
    x = xu.sin(zen) * xu.sin(azi)
    y = xu.sin(zen) * xu.cos(azi)
    z = xu.cos(zen)
    return x, y, z
Esempio n. 2
0
def angle2xyz(azi, zen):
    """Convert azimuth and zenith to cartesian."""
    azi = xu.deg2rad(azi)
    zen = xu.deg2rad(zen)
    x = xu.sin(zen) * xu.sin(azi)
    y = xu.sin(zen) * xu.cos(azi)
    z = xu.cos(zen)
    return x, y, z
Esempio n. 3
0
def lonlat2xyz(lon, lat):
    """Convert lon lat to cartesian."""
    lat = xu.deg2rad(lat)
    lon = xu.deg2rad(lon)
    x = xu.cos(lat) * xu.cos(lon)
    y = xu.cos(lat) * xu.sin(lon)
    z = xu.sin(lat)
    return x, y, z
Esempio n. 4
0
def lonlat2xyz(lon, lat):
    """Convert lon lat to cartesian."""
    lat = xu.deg2rad(lat)
    lon = xu.deg2rad(lon)
    x = xu.cos(lat) * xu.cos(lon)
    y = xu.cos(lat) * xu.sin(lon)
    z = xu.sin(lat)
    return x, y, z
Esempio n. 5
0
def overturning_improved(run):
    #  Better method: use the actual layer pressure intervals to weight the integral
    field = (run.V * run.dP * cos(deg2rad(run.lat)))
    if 'lon' in field.dims:
        field = field.mean(dim='lon')
    factor = 2*np.pi*physconst.rearth/physconst.gravit*1E-9
    psi = np.cumsum( field, axis=field.get_axis_num('lev'))*factor
    return psi
Esempio n. 6
0
    def __call__(self, projectables, **kwargs):
        projectables = self.check_areas(projectables)

        day_data = projectables[0]
        night_data = projectables[1]

        lim_low = np.cos(np.deg2rad(self.lim_low))
        lim_high = np.cos(np.deg2rad(self.lim_high))
        try:
            coszen = xu.cos(xu.deg2rad(projectables[2]))
        except IndexError:
            from pyorbital.astronomy import cos_zen
            LOG.debug("Computing sun zenith angles.")
            # Get chunking that matches the data
            try:
                chunks = day_data.sel(bands=day_data['bands'][0]).chunks
            except KeyError:
                chunks = day_data.chunks
            lons, lats = day_data.attrs["area"].get_lonlats_dask(chunks)
            coszen = xr.DataArray(cos_zen(day_data.attrs["start_time"], lons,
                                          lats),
                                  dims=['y', 'x'],
                                  coords=[day_data['y'], day_data['x']])
        # Calculate blending weights
        coszen -= np.min((lim_high, lim_low))
        coszen /= np.abs(lim_low - lim_high)
        coszen = coszen.clip(0, 1)

        # Apply enhancements to get images
        day_data = enhance2dataset(day_data)
        night_data = enhance2dataset(night_data)

        # Adjust bands so that they match
        # L/RGB -> RGB/RGB
        # LA/RGB -> RGBA/RGBA
        # RGB/RGBA -> RGBA/RGBA
        day_data = add_bands(day_data, night_data['bands'])
        night_data = add_bands(night_data, day_data['bands'])

        # Replace missing channel data with zeros
        day_data = zero_missing_data(day_data, night_data)
        night_data = zero_missing_data(night_data, day_data)

        # Get merged metadata
        attrs = combine_metadata(day_data, night_data)

        # Blend the two images together
        data = (1 - coszen) * night_data + coszen * day_data
        data.attrs = attrs

        # Split to separate bands so the mode is correct
        data = [data.sel(bands=b) for b in data['bands']]

        return super(DayNightCompositor, self).__call__(data, **kwargs)
Esempio n. 7
0
    def __call__(self, projectables, **kwargs):

        day_data = projectables[0]
        night_data = projectables[1]

        lim_low = np.cos(np.deg2rad(self.lim_low))
        lim_high = np.cos(np.deg2rad(self.lim_high))
        try:
            coszen = xu.cos(xu.deg2rad(projectables[2]))
        except IndexError:
            from pyorbital.astronomy import cos_zen
            LOG.debug("Computing sun zenith angles.")
            # Get chunking that matches the data
            try:
                chunks = day_data.sel(bands=day_data['bands'][0]).chunks
            except KeyError:
                chunks = day_data.chunks
            lons, lats = day_data.attrs["area"].get_lonlats_dask(chunks)
            coszen = xr.DataArray(cos_zen(day_data.attrs["start_time"],
                                          lons, lats),
                                  dims=['y', 'x'],
                                  coords=[day_data['y'], day_data['x']])
        # Calculate blending weights
        coszen -= np.min((lim_high, lim_low))
        coszen /= np.abs(lim_low - lim_high)
        coszen = coszen.clip(0, 1)

        # Apply enhancements to get images
        day_data = enhance2dataset(day_data)
        night_data = enhance2dataset(night_data)

        # Adjust bands so that they match
        # L/RGB -> RGB/RGB
        # LA/RGB -> RGBA/RGBA
        # RGB/RGBA -> RGBA/RGBA
        day_data = add_bands(day_data, night_data['bands'])
        night_data = add_bands(night_data, day_data['bands'])

        # Get merged metadata
        attrs = combine_metadata(day_data, night_data)

        # Blend the two images together
        data = (1 - coszen) * night_data + coszen * day_data
        data.attrs = attrs

        # Split to separate bands so the mode is correct
        data = [data.sel(bands=b) for b in data['bands']]

        res = super(DayNightCompositor, self).__call__(data, **kwargs)

        return res
Esempio n. 8
0
def _prep_overturning(inputfield, lat=None, lev=None, levax=0):
    if lat is None:
        try: lat = inputfield.lat
        except:
            raise ValueError('Need to supply latitude array if input data is not self-describing.')
    if lev is None:
        try:
            lev = inputfield.lev
        except:
            raise ValueError('Need to supply pressure array if input data is not self-describing.')
    lat_rad = deg2rad(lat)
    coslat = cos(lat_rad)
    field = inputfield * coslat
    try: levax = field.get_axis_num('lev')
    except: pass
    return field, lat, lev, levax
Esempio n. 9
0
def sunzen_corr_cos(data, cos_zen, limit=88.):
    """Perform Sun zenith angle correction.

    The correction is based on the provided cosine of the zenith
    angle (*cos_zen*).  The correction is limited
    to *limit* degrees (default: 88.0 degrees).  For larger zenith
    angles, the correction is the same as at the *limit*.  Both *data*
    and *cos_zen* are given as 2-dimensional Numpy arrays or Numpy
    MaskedArrays, and they should have equal shapes.

    """

    # Convert the zenith angle limit to cosine of zenith angle
    limit = xu.cos(xu.deg2rad(limit))

    # Cosine correction
    corr = 1. / cos_zen
    # Use constant value (the limit) for larger zenith
    # angles
    corr = corr.where(cos_zen > limit).fillna(1 / limit)

    return data * corr
Esempio n. 10
0
def sunzen_corr_cos(data, cos_zen, limit=88.):
    """Perform Sun zenith angle correction.

    The correction is based on the provided cosine of the zenith
    angle (*cos_zen*).  The correction is limited
    to *limit* degrees (default: 88.0 degrees).  For larger zenith
    angles, the correction is the same as at the *limit*.  Both *data*
    and *cos_zen* are given as 2-dimensional Numpy arrays or Numpy
    MaskedArrays, and they should have equal shapes.

    """

    # Convert the zenith angle limit to cosine of zenith angle
    limit = xu.cos(xu.deg2rad(limit))

    # Cosine correction
    corr = 1. / cos_zen
    # Use constant value (the limit) for larger zenith
    # angles
    corr = corr.where(cos_zen > limit).fillna(1 / limit)

    return data * corr
Esempio n. 11
0
    def __call__(self, projectables, **info):
        projectables = self.check_areas(projectables)
        vis = projectables[0]
        if vis.attrs.get("sunz_corrected"):
            LOG.debug("Sun zen correction already applied")
            return vis

        if hasattr(vis.attrs["area"], 'name'):
            area_name = vis.attrs["area"].name
        else:
            area_name = 'swath' + str(vis.shape)
        key = (vis.attrs["start_time"], area_name)
        tic = time.time()
        LOG.debug("Applying sun zen correction")
        if len(projectables) == 1:
            coszen = self.coszen.get(key)
            if coszen is None:
                from pyorbital.astronomy import cos_zen
                LOG.debug("Computing sun zenith angles.")
                lons, lats = vis.attrs["area"].get_lonlats_dask(CHUNK_SIZE)

                coszen = xr.DataArray(cos_zen(vis.attrs["start_time"],
                                              lons, lats),
                                      dims=['y', 'x'],
                                      coords=[vis['y'], vis['x']])
                coszen = coszen.where((coszen > 0.035) & (coszen < 1))
                self.coszen[key] = coszen
        else:
            coszen = xu.cos(xu.deg2rad(projectables[1]))
            self.coszen[key] = coszen

        proj = self._apply_correction(vis, coszen)
        proj.attrs = vis.attrs.copy()
        self.apply_modifier_info(vis, proj)
        LOG.debug(
            "Sun-zenith correction applied. Computation time: %5.1f (sec)",
            time.time() - tic)
        return proj
Esempio n. 12
0
    def __call__(self, projectables, **info):
        projectables = self.check_areas(projectables)
        vis = projectables[0]
        if vis.attrs.get("sunz_corrected"):
            LOG.debug("Sun zen correction already applied")
            return vis

        if hasattr(vis.attrs["area"], 'name'):
            area_name = vis.attrs["area"].name
        else:
            area_name = 'swath' + str(vis.shape)
        key = (vis.attrs["start_time"], area_name)
        tic = time.time()
        LOG.debug("Applying sun zen correction")
        if len(projectables) == 1:
            coszen = self.coszen.get(key)
            if coszen is None:
                from pyorbital.astronomy import cos_zen
                LOG.debug("Computing sun zenith angles.")
                lons, lats = vis.attrs["area"].get_lonlats_dask(CHUNK_SIZE)

                coszen = xr.DataArray(cos_zen(vis.attrs["start_time"], lons,
                                              lats),
                                      dims=['y', 'x'],
                                      coords=[vis['y'], vis['x']])
                coszen = coszen.where((coszen > 0.035) & (coszen < 1))
                self.coszen[key] = coszen
        else:
            coszen = xu.cos(xu.deg2rad(projectables[1]))
            self.coszen[key] = coszen

        proj = self._apply_correction(vis, coszen)
        proj.attrs = vis.attrs.copy()
        self.apply_modifier_info(vis, proj)
        LOG.debug(
            "Sun-zenith correction applied. Computation time: %5.1f (sec)",
            time.time() - tic)
        return proj
Esempio n. 13
0
def eady_growth_rate(data):
    """Calculate the local Eady Growth rate.
    Following Vallis (2017) p.354.

        EGR = 0.31*du/dz*f/N

    Parameters
    ----------
        data : xarray.DataSet
        The Isca dataset.  Requires fields 'temp', 'ps', 'pfull' and 'phalf'

    Returns a new xarray.DataArray of growth rate values on phalf levels,
    in s^-1.
    """
    N2 = ixr.brunt_vaisala(data)
    f = 2.0 * omega * xruf.sin(xruf.deg2rad(data.lat))

    dz = ixr.domain.calculate_dz(data)
    du = ixr.domain.diff_pfull(data.ucomp, data)

    N = xruf.sqrt(N2.where(N2 > 0))

    egr = 0.31 * du / dz * f / N
    return np.abs(egr)
Esempio n. 14
0
def run_crefl(refl,
              coeffs,
              lon,
              lat,
              sensor_azimuth,
              sensor_zenith,
              solar_azimuth,
              solar_zenith,
              avg_elevation=None,
              percent=False):
    """Run main crefl algorithm.

    All input parameters are per-pixel values meaning they are the same size
    and shape as the input reflectance data, unless otherwise stated.

    :param reflectance_bands: tuple of reflectance band arrays
    :param coefficients: tuple of coefficients for each band (see `get_coefficients`)
    :param lon: input swath longitude array
    :param lat: input swath latitude array
    :param sensor_azimuth: input swath sensor azimuth angle array
    :param sensor_zenith: input swath sensor zenith angle array
    :param solar_azimuth: input swath solar azimuth angle array
    :param solar_zenith: input swath solar zenith angle array
    :param avg_elevation: average elevation (usually pre-calculated and stored in CMGDEM.hdf)
    :param percent: True if input reflectances are on a 0-100 scale instead of 0-1 scale (default: False)

    """
    # FUTURE: Find a way to compute the average elevation before hand
    (ah2o, bh2o, ao3, tau) = coeffs

    # Get digital elevation map data for our granule, set ocean fill value to 0
    if avg_elevation is None:
        LOG.debug("No average elevation information provided in CREFL")
        #height = np.zeros(lon.shape, dtype=np.float)
        height = 0.
    else:
        row = ((90.0 - lat) * avg_elevation.shape[0] / 180.0).astype(np.int32)
        col = ((lon + 180.0) * avg_elevation.shape[1] / 360.0).astype(np.int32)
        height = avg_elevation[row, col].astype(np.float64)
        # negative heights aren't allowed, clip to 0
        height = height.where(height >= 0., 0.0)
        del lat, lon, row, col

    mus = xu.cos(xu.deg2rad(solar_zenith))
    muv = xu.cos(xu.deg2rad(sensor_zenith))
    phi = solar_azimuth - sensor_azimuth

    del solar_azimuth, solar_zenith, sensor_zenith, sensor_azimuth

    sphalb, rhoray, TtotraytH2O, tOG = get_atm_variables(
        mus, muv, phi, height, (ah2o, bh2o, ao3, tau))

    if rhoray.shape[1] != refl.shape[1]:
        LOG.debug(
            "Interpolating CREFL calculations for higher resolution bands")
        # Assume we need to interpolate
        # FIXME: Do real bilinear interpolation instead of "nearest"
        factor = int(refl.shape[1] / rhoray.shape[1])
        rhoray = np.repeat(np.repeat(rhoray, factor, axis=0), factor, axis=1)
        tOG = np.repeat(np.repeat(tOG, factor, axis=0), factor, axis=1)
        TtotraytH2O = np.repeat(np.repeat(TtotraytH2O, factor, axis=0),
                                factor,
                                axis=1)
        # if average height wasn't provided then this should stay a scalar
        if sphalb.size != 1:
            # otherwise make it the same size as the other arrays
            sphalb = np.repeat(np.repeat(sphalb, factor, axis=0),
                               factor,
                               axis=1)

    # Note: Assume that fill/invalid values are either NaN or we are dealing
    # with masked arrays
    if percent:
        corr_refl = ((refl / 100.) / tOG - rhoray) / TtotraytH2O
    else:
        corr_refl = (refl / tOG - rhoray) / TtotraytH2O
    corr_refl /= (1.0 + corr_refl * sphalb)
    return corr_refl.clip(REFLMIN, REFLMAX)