Пример #1
0
def test_xarray_ufuncs_deprecation():
    with pytest.warns(FutureWarning, match="xarray.ufuncs"):
        xu.cos(xr.DataArray([0, 1]))

    with pytest.warns(None) as record:
        xu.angle(xr.DataArray([0, 1]))
    assert len(record) == 0
Пример #2
0
def _horizontal_metrics_from_geographical_coordinates(latitudes, longitudes):
    """Return horizontal scale factors computed from lat, lon arrays.

        Parameters
        ----------
        latitudes : xarray dataarray
            array of latitudes from which to build the grid metrics.
            assume that the order of the dimensions is ('y','x').
        longitudes :xarray dataarray
            array of latitudes from which to build the grid metrics.
            assume that the order of the dimensions is ('y','x').

        Return
        ------
        e1 : xarray dataarray
            Array of grid cell width corresponding to cell_x_size_at_*_location
        e2 : xarray dataarray
            Array of grid cell width corresponding to cell_y_size_at_*_location
    """
    #- Define the centered first order derivatives of lat/lon arrays
    dlat_dj, dlat_di = _horizontal_gradient(latitudes)
    dlon_dj, dlon_di = _horizontal_gradient(longitudes)

    #- Define the approximate size of the cells in x and y direction
    e1 = earthrad * deg2rad \
          * sqrt(( dlon_di * cos( deg2rad * latitudes ) )**2. + dlat_di**2.)
    e2 = earthrad * deg2rad \
          * sqrt(( dlon_dj * cos( deg2rad * latitudes ) )**2. + dlat_dj**2.)

    return e1, e2
Пример #3
0
def lon_lat_to_cartesian(lon, lat, radius=1):
    """
    calculates lon, lat coordinates of a point on a sphere with
    radius radius
    """

    # Unpack xarray object into plane arrays
    if hasattr(lon, 'data'):
        lon = lon.data
    if hasattr(lat, 'data'):
        lat = lat.data

    if lon.ndim != lat.ndim:
        raise ValueError('coordinate must share the same number of dimensions')

    if lon.ndim == 1:
        lon, lat = np.meshgrid(lon, lat)

    lon_r = xu.radians(lon)
    lat_r = xu.radians(lat)

    x = radius * xu.cos(lat_r) * xu.cos(lon_r)
    y = radius * xu.cos(lat_r) * xu.sin(lon_r)
    z = radius * xu.sin(lat_r)

    return x.flatten(), y.flatten(), z.flatten()
Пример #4
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
Пример #5
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
Пример #6
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
Пример #7
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
Пример #8
0
def test_xarray_ufuncs_deprecation():
    with pytest.warns(PendingDeprecationWarning, match='xarray.ufuncs'):
        xu.cos(xr.DataArray([0, 1]))

    with pytest.warns(None) as record:
        xu.angle(xr.DataArray([0, 1]))
    record = [el.message for el in record
              if el.category == PendingDeprecationWarning]
    assert len(record) == 0
Пример #9
0
def test_xarray_ufuncs_deprecation():
    with pytest.warns(PendingDeprecationWarning, match='xarray.ufuncs'):
        xu.cos(xr.DataArray([0, 1]))

    with pytest.warns(None) as record:
        xu.angle(xr.DataArray([0, 1]))
    record = [el.message for el in record
              if el.category == PendingDeprecationWarning]
    assert len(record) == 0
Пример #10
0
 def distance_to_point(self, lat, lon):
     """
     Use Haversine formula to estimate distances from all
     gridpoints to a given location (lat, lon)
     """
     R = 6371. # Radius of earth in km
     lat = np.radians(lat)
     lon = np.radians(lon)
     dlat = lat - xu.radians(self['lat'].values)
     dlon = lon - xu.radians(self['lon'].values)
     a = xu.sin(dlat/2)**2 + xu.cos(lat) * xu.cos(xu.radians(self['lat'].values)) * \
             xu.sin(dlon/2)**2
     c = 2 * xu.arctan2(xu.sqrt(a), xu.sqrt(1.0-a))
     return R*c
Пример #11
0
 def distance_to_point(self, lat, lon):
     """
     Use Haversine formula to estimate distances from all
     gridpoints to a given location (lat, lon)
     """
     R = 6371.  # Radius of earth in km
     lat = np.radians(lat)
     lon = np.radians(lon)
     dlat = lat - xu.radians(self['lat'].values)
     dlon = lon - xu.radians(self['lon'].values)
     a = xu.sin(dlat/2)**2 + xu.cos(lat) * xu.cos(xu.radians(self['lat'].values)) * \
             xu.sin(dlon/2)**2
     c = 2 * xu.arctan2(xu.sqrt(a), xu.sqrt(1.0 - a))
     return R * c
Пример #12
0
 def test_horizontal_divergence(self):
     # TODO : in 3D test divergence of curl is zero.
     tols = {'rtol': 1e-3, 'atol': 1e-3}
     s = self.scale
     divvar = self.grd.horizontal_divergence(self.vector)
     dxdy = grids._dj(self.xv).shift(y=1) \
           / self.grd._arrays["cell_y_size_at_t_location"] # custom derivative
     actual_div = divvar.to_masked_array()
     expected_div = (xu.cos(self.xt * s) * s - xu.sin(self.yt * s) * s +
                     xu.cos(self.xt * s) * s * dxdy).to_masked_array()
     #print_array_around(expected=expected_div/s,actual=actual_div/s)
     self.assertArray2dCloseInside(actual_div / s,
                                   expected_div / s,
                                   depth=2,
                                   **tols)
Пример #13
0
 def test_horizontal_divergence(self):
     # TODO : in 3D test divergence of curl is zero.
     tols = {'rtol':1e-3,'atol':1e-3}
     s = self.scale
     divvar = self.grd.horizontal_divergence(self.vector)
     dxdy = grids._dj(self.xv).shift(y=1) \
           / self.grd._arrays["cell_y_size_at_t_location"] # custom derivative
     actual_div = divvar.to_masked_array()
     expected_div = (xu.cos(self.xt * s) * s
                   - xu.sin(self.yt * s) * s
                   + xu.cos(self.xt * s) * s * dxdy
                     ).to_masked_array()
     #print_array_around(expected=expected_div/s,actual=actual_div/s)
     self.assertArray2dCloseInside(actual_div/s,expected_div/s,
                                   depth=2,**tols)
Пример #14
0
 def test_horizontal_gradient(self):
     tols = {'rtol': 1e-3, 'atol': 1e-3}
     gradvar = self.grd.horizontal_gradient(self.tvar1)
     gradx = self.grd.horizontal_gradient(self.xt)
     #dxdy = gradx.y_component
     s = self.scale
     actual_gx = gradvar.x_component.to_masked_array()
     actual_gy = gradvar.y_component.to_masked_array()
     expected_gx = (xu.cos(self.xu * s) * s).to_masked_array()
     expected_gy = (
         -xu.sin(self.yv * s) * s
         #               + xu.cos(self.xv * s) * s * dxdy
     ).to_masked_array()
     self.assertArray2dCloseInside(actual_gx / s,
                                   expected_gx / s,
                                   depth=2,
                                   **tols)
     #print dxdy[:,20].values
     #print self.grd._arrays['cell_y_size_at_t_location'][:,20].values
     #print self.grd._arrays['cell_y_size_at_v_location'][:,20].values
     #print_array_around(expected=expected_gy/s,actual=actual_gy/s)
     self.assertArray2dCloseInside(actual_gy / s,
                                   expected_gy / s,
                                   depth=2,
                                   **tols)
Пример #15
0
def rotate_vector(u, v, angle):
    '''Rotate the vector (u, v) to (u_lon, v_lat).

    ** Input **
        u: velocity in x direction (shape: nt,nj,ni)
        v: velocity in y direction (shape: nt,nj,ni)
        angle: the angle between x and longitude (in radians, shape: nj,ni)

    ** Returns **
        u_lon: velocity in zonal direction (shape: nt,nj,ni)
        v_lat: velocity in meridional direction (shape: nt,nj,ni)
    '''
    u_lon = u * cos(angle) - v * sin(angle)
    v_lat = u * sin(angle) + v * cos(angle)

    return u_lon, v_lat
Пример #16
0
 def nearest_points(self, lat, lon, npt=1):
     """
     Use the lat-lon arrays to return a list of indices
     of the nearest npt points to the given lat-lon
     """
     # Use sin of lat lon to handle periodic
     # and not worry about if we are in negative
     # degrees
     dist = xu.hypot(xu.sin(xu.radians(self['lat'].values)) -
              xu.sin(xu.radians(lat)),\
              xu.cos(xu.radians(self['lon'].values)) - 
              xu.cos(xu.radians(lon)))
     # Get indices of the flattened array
     nearest_raw = dist.argsort(axis=None)[:npt]
     # Convert back to 2-d coords
     nearest = np.unravel_index(nearest_raw, self['lat'].shape)
     return nearest
Пример #17
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
Пример #18
0
 def test_unary(self):
     args = [0,
             np.zeros(2),
             xr.Variable(['x'], [0, 0]),
             xr.DataArray([0, 0], dims='x'),
             xr.Dataset({'y': ('x', [0, 0])})]
     for a in args:
         self.assertIdentical(a + 1, xu.cos(a))
Пример #19
0
 def setUp(self):
     self.x = np.arange(start=0, stop=101, step=10, dtype=float)
     self.y = np.arange(start=0, stop=101, step=10, dtype=float)
     self.xx, self.yy = np.meshgrid(self.x, self.y)
     self.xrx = xr.DataArray(self.xx, dims=['y', 'x'])
     self.xry = xr.DataArray(self.yy, dims=['y', 'x'])
     self.xrt = xu.sin(self.xrx / 30.) + xu.cos(self.xry / 30.)
     self.t = np.sin(self.xx / 30.) + np.cos(self.yy / 30.)
 def test_unary(self):
     args = [0,
             np.zeros(2),
             xr.Variable(['x'], [0, 0]),
             xr.DataArray([0, 0], dims='x'),
             xr.Dataset({'y': ('x', [0, 0])})]
     for a in args:
         self.assert_identical(a + 1, xu.cos(a))
Пример #21
0
 def nearest_points(self, lat, lon, npt=1):
     """
     Use the lat-lon arrays to return a list of indices
     of the nearest npt points to the given lat-lon
     """
     # Use sin of lat lon to handle periodic
     # and not worry about if we are in negative
     # degrees
     dist = xu.hypot(xu.sin(xu.radians(self['lat'].values)) -
              xu.sin(xu.radians(lat)),\
              xu.cos(xu.radians(self['lon'].values)) -
              xu.cos(xu.radians(lon)))
     # Get indices of the flattened array
     nearest_raw = dist.argsort(axis=None)[:npt]
     # Convert back to 2-d coords
     nearest = np.unravel_index(nearest_raw, self['lat'].shape)
     return nearest
Пример #22
0
 def setUp(self):
     self.x = np.arange(start=0, stop=101, step=10,dtype=float)
     self.y = np.arange(start=0, stop=101, step=10,dtype=float)
     self.xx,self.yy = np.meshgrid(self.x, self.y)
     self.xrx = xr.DataArray(self.xx,dims=['y','x'])
     self.xry = xr.DataArray(self.yy,dims=['y','x'])
     self.xrt = xu.sin(self.xrx/30.) + xu.cos(self.xry/30.)
     self.t = np.sin(self.xx/30.) + np.cos(self.yy/30.)
Пример #23
0
 def test_horizontal_laplacian(self):
     tols = {'rtol':1e-3,'atol':1e-3}
     l =  self.grd.horizontal_laplacian(self.tvar2)
     s = self.scale
     print s
     actual_lap = l.to_masked_array()
     expected_lap = (-1. *  xu.cos(self.yt * s) * s * s).to_masked_array()
     #print_array_around(expected=expected_lap/s**2,actual=actual_lap/s**2)
     self.assertArray2dCloseInside(actual_lap/s**2,expected_lap/s**2,
                                   depth=4,**tols)
Пример #24
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)
Пример #25
0
 def setUp(self):
     # only testing on a regular grid
     x = np.arange(start=0, stop=1.e7, step=1.e5,dtype=float)
     y = np.arange(start=0, stop=1.2e7, step=1.e5,dtype=float)
     x,y = np.meshgrid(x,y)
     self.grd = agrids.plane_2d_grid(ycoord=y,xcoord=x)
     self.scale = 2. * 3.14159 / 1.e7
     self.xt = self.grd._arrays['plane_x_coordinate_at_t_location']
     self.yt = self.grd._arrays['plane_y_coordinate_at_t_location']
     self.xu = self.grd.change_grid_location_t_to_u(self.xt)
     self.yu = self.grd.change_grid_location_t_to_u(self.yt)
     self.xv = self.grd.change_grid_location_t_to_v(self.xt)
     self.yv = self.grd.change_grid_location_t_to_v(self.yt)
     self.tvar1 = xu.sin(self.xt * self.scale) + xu.cos(self.yt * self.scale)
     self.uvar1 = xu.sin(self.xu * self.scale) + xu.cos(self.yu * self.scale)
     self.vvar1 = xu.sin(self.xv * self.scale) + xu.cos(self.yv * self.scale)
     self.vector = grids.VectorField2d(self.uvar1 ,self.vvar1,
                                       x_component_grid_location = 'u',
                                       y_component_grid_location = 'v')
     self.tvar2 = xu.cos(self.yt * self.scale)
Пример #26
0
 def test_horizontal_laplacian(self):
     tols = {'rtol': 1e-3, 'atol': 1e-3}
     l = self.grd.horizontal_laplacian(self.tvar2)
     s = self.scale
     print s
     actual_lap = l.to_masked_array()
     expected_lap = (-1. * xu.cos(self.yt * s) * s * s).to_masked_array()
     #print_array_around(expected=expected_lap/s**2,actual=actual_lap/s**2)
     self.assertArray2dCloseInside(actual_lap / s**2,
                                   expected_lap / s**2,
                                   depth=4,
                                   **tols)
Пример #27
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
Пример #28
0
 def setUp(self):
     # only testing on a regular grid
     x = np.arange(start=0, stop=1.e7, step=1.e5, dtype=float)
     y = np.arange(start=0, stop=1.2e7, step=1.e5, dtype=float)
     x, y = np.meshgrid(x, y)
     self.grd = agrids.plane_2d_grid(ycoord=y, xcoord=x)
     self.scale = 2. * 3.14159 / 1.e7
     self.xt = self.grd._arrays['plane_x_coordinate_at_t_location']
     self.yt = self.grd._arrays['plane_y_coordinate_at_t_location']
     self.xu = self.grd.change_grid_location_t_to_u(self.xt)
     self.yu = self.grd.change_grid_location_t_to_u(self.yt)
     self.xv = self.grd.change_grid_location_t_to_v(self.xt)
     self.yv = self.grd.change_grid_location_t_to_v(self.yt)
     self.tvar1 = xu.sin(self.xt * self.scale) + xu.cos(
         self.yt * self.scale)
     self.uvar1 = xu.sin(self.xu * self.scale) + xu.cos(
         self.yu * self.scale)
     self.vvar1 = xu.sin(self.xv * self.scale) + xu.cos(
         self.yv * self.scale)
     self.vector = grids.VectorField2d(self.uvar1,
                                       self.vvar1,
                                       x_component_grid_location='u',
                                       y_component_grid_location='v')
     self.tvar2 = xu.cos(self.yt * self.scale)
Пример #29
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
Пример #30
0
 def test_horizontal_gradient(self):
     tols = {'rtol':1e-3,'atol':1e-3}
     gradvar =  self.grd.horizontal_gradient(self.tvar1)
     gradx   =   self.grd.horizontal_gradient(self.xt)
     #dxdy = gradx.y_component
     s = self.scale
     actual_gx = gradvar.x_component.to_masked_array()
     actual_gy = gradvar.y_component.to_masked_array()
     expected_gx = (xu.cos(self.xu * s) * s).to_masked_array()
     expected_gy = (- xu.sin(self.yv * s) * s
     #               + xu.cos(self.xv * s) * s * dxdy
                    ).to_masked_array()
     self.assertArray2dCloseInside(actual_gx / s,expected_gx / s ,
                                   depth=2,**tols)
     #print dxdy[:,20].values
     #print self.grd._arrays['cell_y_size_at_t_location'][:,20].values
     #print self.grd._arrays['cell_y_size_at_v_location'][:,20].values
     #print_array_around(expected=expected_gy/s,actual=actual_gy/s)
     self.assertArray2dCloseInside(actual_gy / s,expected_gy /s ,
                                   depth=2, **tols)
Пример #31
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
Пример #32
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
Пример #33
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
Пример #34
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
Пример #35
0
def atmospheric_path_length_correction(data, cos_zen, limit=88.):
    """Perform Sun zenith angle correction.

    This function uses the correction method proposed by
    Li and Shibata (2006): https://doi.org/10.1175/JAS3682.1

    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.radians(limit))

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

    return data * corr
Пример #36
0
def atmospheric_path_length_correction(data, cos_zen, limit=88.):
    """Perform Sun zenith angle correction.

    This function uses the correction method proposed by
    Li and Shibata (2006): https://doi.org/10.1175/JAS3682.1

    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.radians(limit))

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

    return data * corr
Пример #37
0
 def test_pickle(self):
     a = 1.0
     cos_pickled = pickle.loads(pickle.dumps(xu.cos))
     self.assert_identical(cos_pickled(a), xu.cos(a))
Пример #38
0
def test_xarray_ufuncs_pickle():
    a = 1.0
    cos_pickled = pickle.loads(pickle.dumps(xu.cos))
    assert_identical(cos_pickled(a), xu.cos(a))
Пример #39
0
def test_xarray_ufuncs_deprecation():
    with pytest.warns(FutureWarning, match="xarray.ufuncs"):
        xu.cos(xr.DataArray([0, 1]))

    with assert_no_warnings():
        xu.angle(xr.DataArray([0, 1]))
Пример #40
0
def test_xarray_ufuncs_pickle():
    a = 1.0
    cos_pickled = pickle.loads(pickle.dumps(xu.cos))
    assert_identical(cos_pickled(a), xu.cos(a))
Пример #41
0
def test_xarray_ufuncs_deprecation():
    with pytest.warns(PendingDeprecationWarning, match='xarray.ufuncs'):
        xu.cos(xr.DataArray([0, 1]))
Пример #42
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)
Пример #43
0
 def test_pickle(self):
     a = 1.0
     cos_pickled = pickle.loads(pickle.dumps(xu.cos))
     self.assertIdentical(cos_pickled(a), xu.cos(a))